openmatrix 0.1.98 → 0.2.1
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/impl/coder-agent.js +42 -42
- package/dist/agents/impl/executor-agent.js +75 -75
- package/dist/agents/impl/planner-agent.js +63 -63
- package/dist/agents/impl/reviewer-agent.js +66 -66
- package/dist/agents/impl/tester-agent.js +56 -56
- package/dist/cli/commands/report.js +45 -45
- package/dist/cli/commands/start.js +163 -34
- package/dist/cli/commands/step.js +62 -35
- package/dist/orchestrator/ai-reviewer.d.ts +29 -1
- package/dist/orchestrator/ai-reviewer.js +312 -207
- package/dist/orchestrator/approval-manager.js +14 -13
- package/dist/orchestrator/executor.d.ts +10 -1
- package/dist/orchestrator/executor.js +56 -2
- package/dist/orchestrator/meeting-manager.js +32 -31
- package/dist/orchestrator/phase-executor.js +7 -5
- package/dist/orchestrator/scheduler.d.ts +8 -6
- package/dist/orchestrator/scheduler.js +53 -22
- package/dist/orchestrator/state-machine.js +2 -2
- package/dist/orchestrator/task-planner.d.ts +81 -2
- package/dist/orchestrator/task-planner.js +683 -122
- package/dist/storage/state-manager.d.ts +6 -0
- package/dist/storage/state-manager.js +28 -0
- package/package.json +55 -55
- package/scripts/build-check.js +19 -19
- package/scripts/install-skills.js +57 -57
- package/skills/approve.md +250 -250
- package/skills/auto.md +298 -298
- package/skills/brainstorm.md +455 -495
- package/skills/meeting.md +324 -363
- package/skills/om.md +112 -112
- package/skills/openmatrix.md +112 -112
- package/skills/start.md +63 -97
- package/dist/cli/commands/upgrade.d.ts +0 -2
- package/dist/cli/commands/upgrade.js +0 -329
- package/dist/orchestrator/task-planner.old.d.ts +0 -87
- package/dist/orchestrator/task-planner.old.js +0 -444
package/skills/start.md
CHANGED
|
@@ -101,7 +101,8 @@ git init
|
|
|
101
101
|
| 情况 | 处理方式 |
|
|
102
102
|
|------|---------|
|
|
103
103
|
| 已存在(来自 `/om:brainstorm`) | 读取文件内容 → **立即执行 Step 4 必选问题**(质量等级、E2E、执行模式) |
|
|
104
|
-
|
|
|
104
|
+
| 不存在,但 `.openmatrix/research/context.json` 存在 | 读取研究上下文 → 提取 goals/constraints/deliverables → **执行 Step 4 必选问题** |
|
|
105
|
+
| 均不存在 | 根据用户输入解析 |
|
|
105
106
|
|
|
106
107
|
> ⚠️ **注意**: 即使 `tasks-input.json` 已存在,Step 4 必选问题仍然必须执行!
|
|
107
108
|
> - 开发任务:质量等级、E2E、执行模式必须由用户选择
|
|
@@ -109,6 +110,20 @@ git init
|
|
|
109
110
|
- `$ARGUMENTS` 为任务描述 → 直接使用
|
|
110
111
|
- 无参数 → AskUserQuestion 询问任务内容
|
|
111
112
|
|
|
113
|
+
**检测研究上下文(当 tasks-input.json 不存在时):**
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
cat .openmatrix/research/context.json 2>/dev/null || echo "NO_RESEARCH"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
如果检测到研究上下文:
|
|
120
|
+
1. 读取 `.openmatrix/research/context.json`,提取 `topic`、`domain`、`goals`、`constraints`、`deliverables`、`reportPath`
|
|
121
|
+
2. 读取 `RESEARCH.md` 内容作为领域知识
|
|
122
|
+
3. 告知用户:"🔬 检测到「${domain}」领域研究结果,将作为任务基础"
|
|
123
|
+
4. 在 Step 6 中,AI 只需**确认/补充** goals,而非从头提取
|
|
124
|
+
5. Step 7 写入 `tasks-input.json` 时,将研究 goals 与 AI 补充的 goals 合并
|
|
125
|
+
6. Step 8 的 CLI 调用必须增加 `--research-context @.openmatrix/research/context.json` 参数
|
|
126
|
+
|
|
112
127
|
### Step 3: 智能分析任务类型
|
|
113
128
|
|
|
114
129
|
判断是开发任务还是非开发任务,这决定 Step 4 需要问哪些问题。
|
|
@@ -124,92 +139,50 @@ git init
|
|
|
124
139
|
|
|
125
140
|
---
|
|
126
141
|
|
|
127
|
-
|
|
142
|
+
### Step 4: 必选问题(不可跳过,不可使用默认值,必须通过 AskUserQuestion 让用户选择)
|
|
128
143
|
|
|
129
|
-
|
|
130
|
-
**不允许使用任何默认值。必须通过 AskUserQuestion 让用户选择。**
|
|
131
|
-
**如果没有执行 Step 4 就进入 Step 5+,任务执行失败。**
|
|
144
|
+
根据 `goalTypes` 字段判断需要询问哪些问题:
|
|
132
145
|
|
|
133
|
-
|
|
146
|
+
| goalTypes | 需要询问 |
|
|
147
|
+
|-----------|---------|
|
|
148
|
+
| `development` | 4.1 质量等级 → 4.2 E2E → 4.3 执行模式 |
|
|
149
|
+
| `testing` | 仅 4.3 执行模式 |
|
|
150
|
+
| `documentation` / `other` | 仅 4.3 执行模式 |
|
|
134
151
|
|
|
135
|
-
|
|
152
|
+
#### 4.1 质量等级(仅 `goalTypes: development`)
|
|
136
153
|
|
|
137
|
-
|
|
138
|
-
|---------|---------------|
|
|
139
|
-
| **开发任务**(新功能、Bug修复、重构) | 4.1 质量等级 + 4.2 E2E + 4.3 执行模式 |
|
|
140
|
-
| **测试任务**(纯测试、写测试用例) | 仅 4.3 执行模式 |
|
|
141
|
-
| **非开发任务**(文档、配置、纯阅读) | 仅 4.3 执行模式 |
|
|
154
|
+
AskUserQuestion: `header: "质量等级"`, `multiSelect: false`
|
|
142
155
|
|
|
143
|
-
|
|
144
|
-
- `development` → 开发任务 → 问 4.1 + 4.2 + 4.3
|
|
145
|
-
- `testing` → 测试任务 → 仅问 4.3
|
|
146
|
-
- `documentation` / `other` → 非开发任务 → 仅问 4.3
|
|
156
|
+
**question:** 选择质量等级(决定测试覆盖、Lint、安全扫描等要求)
|
|
147
157
|
|
|
148
|
-
|
|
158
|
+
| label | description |
|
|
159
|
+
|-------|-------------|
|
|
160
|
+
| `strict` | TDD + >80%覆盖率 + 严格Lint + 安全扫描 — 生产级代码 |
|
|
161
|
+
| `balanced (推荐)` | >60%覆盖率 + Lint + 安全扫描 — 日常开发 |
|
|
162
|
+
| `fast` | 无质量门禁 — 快速原型/验证 |
|
|
149
163
|
|
|
150
|
-
#### 4.
|
|
164
|
+
#### 4.2 E2E 测试(仅 `development` 且选 strict/balanced,选 `fast` 跳过)
|
|
151
165
|
|
|
152
|
-
|
|
166
|
+
AskUserQuestion: `header: "E2E 测试"`, `multiSelect: false`
|
|
153
167
|
|
|
154
|
-
|
|
155
|
-
AskUserQuestion({
|
|
156
|
-
questions: [
|
|
157
|
-
{
|
|
158
|
-
question: "选择质量等级(决定测试覆盖、Lint、安全扫描等要求):",
|
|
159
|
-
header: "质量等级",
|
|
160
|
-
options: [
|
|
161
|
-
{ label: "strict", description: "TDD + >80%覆盖率 + 严格Lint + 安全扫描 — 生产级代码" },
|
|
162
|
-
{ label: "balanced (推荐)", description: ">60%覆盖率 + Lint + 安全扫描 — 日常开发" },
|
|
163
|
-
{ label: "fast", description: "无质量门禁 — 快速原型/验证" }
|
|
164
|
-
],
|
|
165
|
-
multiSelect: false
|
|
166
|
-
}
|
|
167
|
-
]
|
|
168
|
-
})
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
#### 4.2 E2E 测试(仅开发任务且选 strict/balanced 时)
|
|
172
|
-
|
|
173
|
-
如果开发任务且用户选择了 `strict` 或 `balanced`,继续询问:
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
AskUserQuestion({
|
|
177
|
-
questions: [
|
|
178
|
-
{
|
|
179
|
-
question: "是否启用端到端 (E2E) 测试?(适用于 Web/Mobile/GUI 项目,耗时较长)",
|
|
180
|
-
header: "E2E 测试",
|
|
181
|
-
options: [
|
|
182
|
-
{ label: "启用 E2E 测试", description: "使用 Playwright/Cypress 等框架进行端到端测试" },
|
|
183
|
-
{ label: "不启用 (推荐)", description: "仅进行单元测试和集成测试,节省时间" }
|
|
184
|
-
],
|
|
185
|
-
multiSelect: false
|
|
186
|
-
}
|
|
187
|
-
]
|
|
188
|
-
})
|
|
189
|
-
```
|
|
168
|
+
**question:** 是否启用端到端 (E2E) 测试?(适用于 Web/Mobile/GUI 项目,耗时较长)
|
|
190
169
|
|
|
191
|
-
|
|
170
|
+
| label | description |
|
|
171
|
+
|-------|-------------|
|
|
172
|
+
| `不启用 (推荐)` | 仅进行单元测试和集成测试,节省时间 |
|
|
173
|
+
| `启用 E2E 测试` | 使用 Playwright/Cypress 等框架进行端到端测试 |
|
|
192
174
|
|
|
193
175
|
#### 4.3 执行模式(所有任务必选)
|
|
194
176
|
|
|
195
|
-
|
|
177
|
+
AskUserQuestion: `header: "执行模式"`, `multiSelect: false`
|
|
196
178
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
{ label: "全自动执行 (推荐)", description: "全自动执行,无需人工审批,遇到阻塞自动 Meeting" },
|
|
205
|
-
{ label: "关键节点确认", description: "plan/merge/deploy 时暂停确认" },
|
|
206
|
-
{ label: "每阶段确认", description: "每个阶段(develop/verify/accept)完成后暂停" }
|
|
207
|
-
],
|
|
208
|
-
multiSelect: false
|
|
209
|
-
}
|
|
210
|
-
]
|
|
211
|
-
})
|
|
212
|
-
```
|
|
179
|
+
**question:** 选择执行模式(控制 AI 执行过程中的审批节点)
|
|
180
|
+
|
|
181
|
+
| label | description |
|
|
182
|
+
|-------|-------------|
|
|
183
|
+
| `全自动执行 (推荐)` | 全自动执行,无需人工审批,遇到阻塞自动 Meeting |
|
|
184
|
+
| `关键节点确认` | plan/merge/deploy 时暂停确认 |
|
|
185
|
+
| `每阶段确认` | 每个阶段(develop/verify/accept)完成后暂停 |
|
|
213
186
|
|
|
214
187
|
### Step 5: 可选问题(仅复杂任务)
|
|
215
188
|
|
|
@@ -245,6 +218,8 @@ AskUserQuestion({
|
|
|
245
218
|
- **deliverables**: 交付物列表
|
|
246
219
|
- **plan**: 技术方案、模块划分、接口设计、关键决策
|
|
247
220
|
|
|
221
|
+
**研究上下文集成**: 如果已加载研究领域,AI 应基于 `RESEARCH.md` 中的领域知识确认/补充 goals,而非从零提取。`plan` 字段应包含领域技术栈、架构模式等知识。
|
|
222
|
+
|
|
248
223
|
**goalTypes 标注示例:**
|
|
249
224
|
|
|
250
225
|
| Goal | Type | 理由 |
|
|
@@ -273,6 +248,7 @@ AskUserQuestion({
|
|
|
273
248
|
|
|
274
249
|
> **注意**: `quality`、`mode`、`e2eTests` 不写入文件,由 Step 8 的 CLI 参数传递。
|
|
275
250
|
> **goalTypes** 必须与 goals 数组长度一致,一一对应。
|
|
251
|
+
> **研究上下文集成**: 如果检测到 `.openmatrix/research/context.json`,将研究的 goals/constraints/deliverables 作为基础,与 AI 提取的内容合并(去重后)。
|
|
276
252
|
|
|
277
253
|
### Step 8: 调用 CLI 创建任务 ⚠️ 不可跳过
|
|
278
254
|
|
|
@@ -283,6 +259,11 @@ AskUserQuestion({
|
|
|
283
259
|
openmatrix start --tasks-json @.openmatrix/tasks-input.json --quality <质量等级> --mode <执行模式> --json
|
|
284
260
|
```
|
|
285
261
|
|
|
262
|
+
如果存在 `.openmatrix/research/context.json`,增加 `--research-context` 参数:
|
|
263
|
+
```bash
|
|
264
|
+
openmatrix start --tasks-json @.openmatrix/tasks-input.json --research-context @.openmatrix/research/context.json --quality <质量等级> --mode <执行模式> --json
|
|
265
|
+
```
|
|
266
|
+
|
|
286
267
|
如果启用了 E2E 测试,加上 `--e2e-tests`:
|
|
287
268
|
```bash
|
|
288
269
|
openmatrix start --tasks-json @.openmatrix/tasks-input.json --quality balanced --mode auto --e2e-tests --json
|
|
@@ -376,31 +357,16 @@ openmatrix step --json
|
|
|
376
357
|
|
|
377
358
|
**交互式审批流程(非全自动模式):**
|
|
378
359
|
|
|
379
|
-
当到达审批点时,使用 `openmatrix approve --json`(不带 ID
|
|
360
|
+
当到达审批点时,使用 `openmatrix approve --json`(不带 ID)查看待审批项,**先在界面展示审批内容摘要**,再用简短 AskUserQuestion 请求确认:
|
|
380
361
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
[审批内容摘要]
|
|
391
|
-
|
|
392
|
-
是否批准?",
|
|
393
|
-
header: "审批",
|
|
394
|
-
options: [
|
|
395
|
-
{ label: "批准", description: "同意继续执行" },
|
|
396
|
-
{ label: "拒绝", description: "拒绝并停止执行" },
|
|
397
|
-
{ label: "查看详情", description: "查看完整审批内容后再决定" }
|
|
398
|
-
],
|
|
399
|
-
multiSelect: false
|
|
400
|
-
}
|
|
401
|
-
]
|
|
402
|
-
})
|
|
403
|
-
```
|
|
362
|
+
AskUserQuestion: `header: "审批"`, `multiSelect: false`
|
|
363
|
+
**question:** 是否批准此审批请求?(详情已展示在上方)
|
|
364
|
+
|
|
365
|
+
| label | description |
|
|
366
|
+
|-------|-------------|
|
|
367
|
+
| 批准 | 同意继续执行 |
|
|
368
|
+
| 拒绝 | 拒绝并停止执行 |
|
|
369
|
+
| 查看详情 | 查看完整审批内容后再决定 |
|
|
404
370
|
|
|
405
371
|
用户选择后,执行对应命令:
|
|
406
372
|
- 批准: `openmatrix approve <approval-id> -d approve --json`
|
|
@@ -1,329 +0,0 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.upgradeCommand = void 0;
|
|
40
|
-
// src/cli/commands/upgrade.ts
|
|
41
|
-
const commander_1 = require("commander");
|
|
42
|
-
const upgrade_detector_js_1 = require("../../orchestrator/upgrade-detector.js");
|
|
43
|
-
const readline = __importStar(require("readline"));
|
|
44
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
45
|
-
exports.upgradeCommand = new commander_1.Command('upgrade')
|
|
46
|
-
.description('自动检测项目可改进点并提供升级建议')
|
|
47
|
-
.argument('[hint]', '用户提示 (可选,用于聚焦检测方向)')
|
|
48
|
-
.option('--json', '输出 JSON 格式 (供 Skill 解析)')
|
|
49
|
-
.option('--auto', '自动执行所有改进建议 (无需确认)')
|
|
50
|
-
.option('--categories <items>', '指定检测类别 (逗号分隔)', 'bug,quality,capability,ux,style,security,common')
|
|
51
|
-
.option('--min-priority <level>', '最小优先级 (critical|high|medium|low)', 'low')
|
|
52
|
-
.option('--max <number>', '最大建议数量', '50')
|
|
53
|
-
.option('--scan <dirs>', '扫描目录 (逗号分隔)', 'src,skills,tests,docs')
|
|
54
|
-
.option('--interactive', '交互式选择要执行的改进', false)
|
|
55
|
-
.action(async (hint, options) => {
|
|
56
|
-
const projectRoot = process.cwd();
|
|
57
|
-
// 解析配置
|
|
58
|
-
const config = {
|
|
59
|
-
userHint: hint,
|
|
60
|
-
categories: options.categories.split(',').map((c) => c.trim()),
|
|
61
|
-
minPriority: options.minPriority,
|
|
62
|
-
maxSuggestions: parseInt(options.max),
|
|
63
|
-
scanDirs: options.scan.split(',').map((d) => d.trim())
|
|
64
|
-
};
|
|
65
|
-
// 创建检测器
|
|
66
|
-
const detector = new upgrade_detector_js_1.UpgradeDetector(projectRoot, config);
|
|
67
|
-
if (!options.json) {
|
|
68
|
-
console.log(chalk_1.default.bold.cyan('\n🔍 OpenMatrix 升级检测器'));
|
|
69
|
-
console.log('━'.repeat(42));
|
|
70
|
-
console.log(`📁 项目路径: ${projectRoot}`);
|
|
71
|
-
if (hint) {
|
|
72
|
-
console.log(`💡 用户提示: ${hint}`);
|
|
73
|
-
}
|
|
74
|
-
console.log('\n⏳ 正在扫描项目...\n');
|
|
75
|
-
}
|
|
76
|
-
try {
|
|
77
|
-
// 执行检测
|
|
78
|
-
const result = await detector.detect();
|
|
79
|
-
// JSON 输出
|
|
80
|
-
if (options.json) {
|
|
81
|
-
console.log(JSON.stringify(result, null, 2));
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
// 显示结果
|
|
85
|
-
displayResult(result);
|
|
86
|
-
// 交互式选择
|
|
87
|
-
if (options.interactive && result.suggestions.length > 0) {
|
|
88
|
-
const selected = await interactiveSelect(result.suggestions);
|
|
89
|
-
if (selected.length > 0) {
|
|
90
|
-
await executeSelected(selected, result.projectType);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else if (options.auto && result.suggestions.length > 0) {
|
|
94
|
-
// 自动执行所有
|
|
95
|
-
await executeAll(result.suggestions, result.projectType);
|
|
96
|
-
}
|
|
97
|
-
else if (result.suggestions.length > 0) {
|
|
98
|
-
// 询问用户
|
|
99
|
-
const shouldExecute = await askForExecution();
|
|
100
|
-
if (shouldExecute) {
|
|
101
|
-
await executeAll(result.suggestions, result.projectType);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
if (options.json) {
|
|
107
|
-
console.log(JSON.stringify({ error: String(error) }));
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
console.error(chalk_1.default.red('\n❌ 检测失败:'), error);
|
|
111
|
-
}
|
|
112
|
-
process.exit(1);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
/**
|
|
116
|
-
* 显示检测结果
|
|
117
|
-
*/
|
|
118
|
-
function displayResult(result) {
|
|
119
|
-
const { projectType, projectName, suggestions, summary } = result;
|
|
120
|
-
console.log(chalk_1.default.bold(`📦 项目: ${projectName}`));
|
|
121
|
-
console.log(` 类型: ${formatProjectType(projectType)}`);
|
|
122
|
-
console.log(` 扫描时间: ${new Date(result.timestamp).toLocaleString()}\n`);
|
|
123
|
-
// 摘要
|
|
124
|
-
console.log(chalk_1.default.bold('📊 检测摘要'));
|
|
125
|
-
console.log('━'.repeat(42));
|
|
126
|
-
const categoryLabels = {
|
|
127
|
-
bug: '🐛 代码缺陷',
|
|
128
|
-
quality: '🔧 代码质量',
|
|
129
|
-
capability: '📦 缺失能力',
|
|
130
|
-
ux: '👤 用户体验',
|
|
131
|
-
style: '🎨 代码风格',
|
|
132
|
-
security: '🔒 安全问题',
|
|
133
|
-
common: '⚠️ 常见问题',
|
|
134
|
-
prompt: '🤖 Prompt 问题',
|
|
135
|
-
skill: '⚡ Skill 问题',
|
|
136
|
-
agent: '🧠 Agent 配置'
|
|
137
|
-
};
|
|
138
|
-
for (const [cat, count] of Object.entries(summary.byCategory)) {
|
|
139
|
-
if (count > 0) {
|
|
140
|
-
console.log(` ${categoryLabels[cat]}: ${chalk_1.default.yellow(count)}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
console.log(`\n 总计: ${chalk_1.default.bold(summary.total)} 个建议`);
|
|
144
|
-
console.log(` 可自动修复: ${chalk_1.default.green(summary.autoFixable)} 个\n`);
|
|
145
|
-
if (suggestions.length === 0) {
|
|
146
|
-
console.log(chalk_1.default.green('✅ 未发现问题,项目状态良好!\n'));
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
// 详细建议
|
|
150
|
-
console.log(chalk_1.default.bold('📋 改进建议'));
|
|
151
|
-
console.log('━'.repeat(42) + '\n');
|
|
152
|
-
// 按优先级分组
|
|
153
|
-
const critical = suggestions.filter(s => s.priority === 'critical');
|
|
154
|
-
const high = suggestions.filter(s => s.priority === 'high');
|
|
155
|
-
const medium = suggestions.filter(s => s.priority === 'medium');
|
|
156
|
-
const low = suggestions.filter(s => s.priority === 'low');
|
|
157
|
-
if (critical.length > 0) {
|
|
158
|
-
console.log(chalk_1.default.red.bold('🚨 关键问题:\n'));
|
|
159
|
-
for (const s of critical) {
|
|
160
|
-
displaySuggestion(s);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (high.length > 0) {
|
|
164
|
-
console.log(chalk_1.default.yellow.bold('⚠️ 高优先级:\n'));
|
|
165
|
-
for (const s of high) {
|
|
166
|
-
displaySuggestion(s);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
if (medium.length > 0) {
|
|
170
|
-
console.log(chalk_1.default.blue.bold('📋 中优先级:\n'));
|
|
171
|
-
for (const s of medium) {
|
|
172
|
-
displaySuggestion(s);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (low.length > 0) {
|
|
176
|
-
console.log(chalk_1.default.gray.bold('💡 低优先级:\n'));
|
|
177
|
-
for (const s of low.slice(0, 10)) { // 限制显示
|
|
178
|
-
displaySuggestion(s);
|
|
179
|
-
}
|
|
180
|
-
if (low.length > 10) {
|
|
181
|
-
console.log(chalk_1.default.gray(` ... 还有 ${low.length - 10} 个低优先级建议\n`));
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
// 提示
|
|
185
|
-
console.log(chalk_1.default.gray('━'.repeat(42)));
|
|
186
|
-
console.log(chalk_1.default.gray('💡 提示:'));
|
|
187
|
-
console.log(chalk_1.default.gray(' --interactive 交互式选择改进项'));
|
|
188
|
-
console.log(chalk_1.default.gray(' --auto 自动执行所有改进'));
|
|
189
|
-
console.log();
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* 显示单个建议
|
|
193
|
-
*/
|
|
194
|
-
function displaySuggestion(s) {
|
|
195
|
-
const priorityColors = {
|
|
196
|
-
critical: chalk_1.default.red,
|
|
197
|
-
high: chalk_1.default.yellow,
|
|
198
|
-
medium: chalk_1.default.blue,
|
|
199
|
-
low: chalk_1.default.gray
|
|
200
|
-
};
|
|
201
|
-
const categoryIcons = {
|
|
202
|
-
bug: '🐛',
|
|
203
|
-
quality: '🔧',
|
|
204
|
-
capability: '📦',
|
|
205
|
-
ux: '👤',
|
|
206
|
-
style: '🎨',
|
|
207
|
-
security: '🔒',
|
|
208
|
-
common: '⚠️',
|
|
209
|
-
prompt: '🤖',
|
|
210
|
-
skill: '⚡',
|
|
211
|
-
agent: '🧠'
|
|
212
|
-
};
|
|
213
|
-
const color = priorityColors[s.priority];
|
|
214
|
-
console.log(` ${color(`[${s.id}]`)} ${categoryIcons[s.category]} ${s.title}`);
|
|
215
|
-
console.log(` 位置: ${s.location.file}${s.location.line ? `:${s.location.line}` : ''}`);
|
|
216
|
-
console.log(` 建议: ${chalk_1.default.gray(s.suggestion)}`);
|
|
217
|
-
if (s.autoFixable) {
|
|
218
|
-
console.log(` ${chalk_1.default.green('✓ 可自动修复')}`);
|
|
219
|
-
}
|
|
220
|
-
console.log();
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* 格式化项目类型
|
|
224
|
-
*/
|
|
225
|
-
function formatProjectType(type) {
|
|
226
|
-
const labels = {
|
|
227
|
-
openmatrix: '🤖 OpenMatrix',
|
|
228
|
-
'ai-project': '🧠 AI 项目',
|
|
229
|
-
nodejs: '📦 Node.js',
|
|
230
|
-
typescript: '📘 TypeScript',
|
|
231
|
-
python: '🐍 Python',
|
|
232
|
-
go: '🔷 Go',
|
|
233
|
-
rust: '🦀 Rust',
|
|
234
|
-
java: '☕ Java',
|
|
235
|
-
csharp: '💜 C#',
|
|
236
|
-
cpp: '⚙️ C/C++',
|
|
237
|
-
php: '🐘 PHP',
|
|
238
|
-
unknown: '❓ 未知'
|
|
239
|
-
};
|
|
240
|
-
return labels[type];
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* 交互式选择
|
|
244
|
-
*/
|
|
245
|
-
async function interactiveSelect(suggestions) {
|
|
246
|
-
console.log(chalk_1.default.bold.cyan('\n🎯 交互式选择'));
|
|
247
|
-
console.log('━'.repeat(42));
|
|
248
|
-
console.log('选择要执行的改进项 (空格选择,回车确认):\n');
|
|
249
|
-
const rl = readline.createInterface({
|
|
250
|
-
input: process.stdin,
|
|
251
|
-
output: process.stdout
|
|
252
|
-
});
|
|
253
|
-
// 显示选项
|
|
254
|
-
suggestions.forEach((s, i) => {
|
|
255
|
-
console.log(` [ ] ${i + 1}. ${s.title} (${s.priority})`);
|
|
256
|
-
});
|
|
257
|
-
console.log('\n输入序号 (用逗号分隔),或输入 "all" 选择全部:');
|
|
258
|
-
return new Promise((resolve) => {
|
|
259
|
-
rl.question('> ', (answer) => {
|
|
260
|
-
rl.close();
|
|
261
|
-
if (answer.trim().toLowerCase() === 'all') {
|
|
262
|
-
resolve(suggestions);
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
const indices = answer.split(',')
|
|
266
|
-
.map(s => parseInt(s.trim()) - 1)
|
|
267
|
-
.filter(i => i >= 0 && i < suggestions.length);
|
|
268
|
-
resolve(indices.map(i => suggestions[i]));
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* 询问是否执行
|
|
274
|
-
*/
|
|
275
|
-
async function askForExecution() {
|
|
276
|
-
const rl = readline.createInterface({
|
|
277
|
-
input: process.stdin,
|
|
278
|
-
output: process.stdout
|
|
279
|
-
});
|
|
280
|
-
return new Promise((resolve) => {
|
|
281
|
-
rl.question('\n是否执行这些改进? (y/N) ', (answer) => {
|
|
282
|
-
rl.close();
|
|
283
|
-
resolve(answer.trim().toLowerCase() === 'y');
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* 执行选中的改进
|
|
289
|
-
*/
|
|
290
|
-
async function executeSelected(suggestions, projectType) {
|
|
291
|
-
console.log(chalk_1.default.bold.cyan('\n🚀 执行改进'));
|
|
292
|
-
console.log('━'.repeat(42));
|
|
293
|
-
console.log(`选择了 ${suggestions.length} 个改进项\n`);
|
|
294
|
-
// 这里需要调用 /om:start 来执行实际的改进
|
|
295
|
-
// 输出 JSON 格式供 Skill 解析
|
|
296
|
-
console.log(JSON.stringify({
|
|
297
|
-
action: 'execute_upgrades',
|
|
298
|
-
projectType,
|
|
299
|
-
suggestions: suggestions.map(s => ({
|
|
300
|
-
id: s.id,
|
|
301
|
-
title: s.title,
|
|
302
|
-
category: s.category,
|
|
303
|
-
priority: s.priority,
|
|
304
|
-
location: s.location,
|
|
305
|
-
suggestion: s.suggestion
|
|
306
|
-
}))
|
|
307
|
-
}, null, 2));
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* 执行所有改进
|
|
311
|
-
*/
|
|
312
|
-
async function executeAll(suggestions, projectType) {
|
|
313
|
-
console.log(chalk_1.default.bold.cyan('\n🚀 自动执行所有改进'));
|
|
314
|
-
console.log('━'.repeat(42));
|
|
315
|
-
// 输出 JSON 供 Skill 处理
|
|
316
|
-
console.log(JSON.stringify({
|
|
317
|
-
action: 'execute_all_upgrades',
|
|
318
|
-
projectType,
|
|
319
|
-
count: suggestions.length,
|
|
320
|
-
suggestions: suggestions.map(s => ({
|
|
321
|
-
id: s.id,
|
|
322
|
-
title: s.title,
|
|
323
|
-
category: s.category,
|
|
324
|
-
priority: s.priority,
|
|
325
|
-
location: s.location,
|
|
326
|
-
suggestion: s.suggestion
|
|
327
|
-
}))
|
|
328
|
-
}, null, 2));
|
|
329
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import type { ParsedTask } from '../types/index.js';
|
|
2
|
-
export interface TaskBreakdown {
|
|
3
|
-
taskId: string;
|
|
4
|
-
title: string;
|
|
5
|
-
description: string;
|
|
6
|
-
priority: 'P0' | 'P1' | 'P2' | 'P3';
|
|
7
|
-
dependencies: string[];
|
|
8
|
-
estimatedComplexity: 'low' | 'medium' | 'high';
|
|
9
|
-
assignedAgent: 'planner' | 'coder' | 'tester' | 'reviewer' | 'researcher' | 'executor';
|
|
10
|
-
acceptanceCriteria?: string[];
|
|
11
|
-
testTaskId?: string;
|
|
12
|
-
phase: 'design' | 'develop' | 'verify' | 'accept';
|
|
13
|
-
}
|
|
14
|
-
export interface UserAnswers {
|
|
15
|
-
objective?: string;
|
|
16
|
-
techStack?: string[];
|
|
17
|
-
testCoverage?: string;
|
|
18
|
-
documentationLevel?: string;
|
|
19
|
-
additionalContext?: Record<string, string>;
|
|
20
|
-
/** 是否启用 E2E 测试 */
|
|
21
|
-
e2eTests?: boolean;
|
|
22
|
-
/** E2E 测试类型 (web/mobile/gui) */
|
|
23
|
-
e2eType?: 'web' | 'mobile' | 'gui';
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* TaskPlanner - 任务拆解器
|
|
27
|
-
*
|
|
28
|
-
* 增强版特性:
|
|
29
|
-
* 1. 更细粒度的任务拆分 (每个目标拆分为设计+实现+测试)
|
|
30
|
-
* 2. 测试任务配对 (每个开发任务自动生成对应测试任务)
|
|
31
|
-
* 3. 验收标准注入 (从用户回答中提取)
|
|
32
|
-
* 4. 用户上下文注入 (将用户回答注入任务描述)
|
|
33
|
-
* 5. 依赖关系分析 (自动分析任务间依赖)
|
|
34
|
-
*/
|
|
35
|
-
export declare class TaskPlanner {
|
|
36
|
-
private userAnswers;
|
|
37
|
-
constructor(userAnswers?: UserAnswers);
|
|
38
|
-
/**
|
|
39
|
-
* 设置用户回答
|
|
40
|
-
*/
|
|
41
|
-
setUserAnswers(answers: UserAnswers): void;
|
|
42
|
-
/**
|
|
43
|
-
* Break down a parsed task into sub-tasks
|
|
44
|
-
*
|
|
45
|
-
* 增强版: 生成更细粒度的任务,包含设计、开发、测试配对
|
|
46
|
-
*/
|
|
47
|
-
breakdown(parsedTask: ParsedTask, answers: Record<string, string>): TaskBreakdown[];
|
|
48
|
-
/**
|
|
49
|
-
* 提取用户上下文
|
|
50
|
-
*/
|
|
51
|
-
private extractUserContext;
|
|
52
|
-
/**
|
|
53
|
-
* 解析数组类型的回答
|
|
54
|
-
*/
|
|
55
|
-
private parseArrayAnswer;
|
|
56
|
-
/**
|
|
57
|
-
* 构建任务描述 (注入用户上下文)
|
|
58
|
-
*/
|
|
59
|
-
private buildTaskDescription;
|
|
60
|
-
/**
|
|
61
|
-
* 构建测试任务描述
|
|
62
|
-
*/
|
|
63
|
-
private buildTestDescription;
|
|
64
|
-
/**
|
|
65
|
-
* 构建 E2E 测试任务描述
|
|
66
|
-
*/
|
|
67
|
-
private buildE2ETestDescription;
|
|
68
|
-
/**
|
|
69
|
-
* 获取 E2E 测试类型配置
|
|
70
|
-
*/
|
|
71
|
-
private getE2ETypeConfig;
|
|
72
|
-
/**
|
|
73
|
-
* 生成用户流程测试用例
|
|
74
|
-
*/
|
|
75
|
-
private generateUserFlows;
|
|
76
|
-
/**
|
|
77
|
-
* 解析覆盖率数值
|
|
78
|
-
*/
|
|
79
|
-
private parseCoverage;
|
|
80
|
-
/**
|
|
81
|
-
* 生成验收标准
|
|
82
|
-
*/
|
|
83
|
-
private generateAcceptanceCriteria;
|
|
84
|
-
private generateTaskId;
|
|
85
|
-
private determinePriority;
|
|
86
|
-
private estimateComplexity;
|
|
87
|
-
}
|