openmatrix 0.1.37 → 0.1.39
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/brainstorm.js +169 -34
- package/dist/cli/commands/start.js +87 -1
- package/package.json +1 -1
- package/skills/brainstorm.md +132 -31
- package/skills/start.md +178 -6
|
@@ -220,35 +220,170 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
|
|
|
220
220
|
function generateBrainstormQuestions(taskContent, taskTitle) {
|
|
221
221
|
const questions = [];
|
|
222
222
|
const content = taskContent.toLowerCase();
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
223
|
+
const title = taskTitle.toLowerCase();
|
|
224
|
+
// 检测任务类型
|
|
225
|
+
const isGame = /游戏|game|玩家|player|塔防|td|rpg|射击|shooter|角色|character|关卡|level|boss|技能|skill|武器|weapon|敌人|enemy/.test(content + title);
|
|
226
|
+
const isAPI = /api|接口|后端|backend|rest|graphql|微服务|microservice/.test(content + title);
|
|
227
|
+
const isCLI = /cli|命令行|command|工具|tool|脚本|script/.test(content + title);
|
|
228
|
+
const isLibrary = /库|library|sdk|包|package|npm|组件|component/.test(content + title);
|
|
229
|
+
// 根据任务类型生成不同的问题
|
|
230
|
+
if (isGame) {
|
|
231
|
+
// ========== 游戏专用问题 ==========
|
|
232
|
+
questions.push({
|
|
233
|
+
id: 'game_type',
|
|
234
|
+
question: '这是什么类型的游戏?核心玩法是什么?',
|
|
235
|
+
header: '游戏类型',
|
|
236
|
+
options: [
|
|
237
|
+
{ label: '塔防 (TD)', description: '放置防御塔,阻止敌人到达终点' },
|
|
238
|
+
{ label: 'RPG', description: '角色扮演,升级成长' },
|
|
239
|
+
{ label: '射击/动作', description: '实时战斗,操作为主' },
|
|
240
|
+
{ label: '策略/模拟', description: '资源管理,策略决策' }
|
|
241
|
+
],
|
|
242
|
+
multiSelect: false,
|
|
243
|
+
why: '游戏类型决定核心机制和技术架构'
|
|
244
|
+
});
|
|
245
|
+
questions.push({
|
|
246
|
+
id: 'target_player',
|
|
247
|
+
question: '目标玩家是谁?',
|
|
248
|
+
header: '目标玩家',
|
|
249
|
+
options: [
|
|
250
|
+
{ label: '休闲玩家', description: '简单易上手,碎片时间游玩' },
|
|
251
|
+
{ label: '硬核玩家', description: '深度策略,挑战性高' },
|
|
252
|
+
{ label: '全年龄', description: '老少皆宜,难度适中' },
|
|
253
|
+
{ label: '核心玩家', description: '游戏爱好者,追求高品质' }
|
|
254
|
+
],
|
|
255
|
+
multiSelect: false,
|
|
256
|
+
why: '目标玩家决定游戏难度和设计风格'
|
|
257
|
+
});
|
|
258
|
+
questions.push({
|
|
259
|
+
id: 'game_platform',
|
|
260
|
+
question: '游戏运行在什么平台?',
|
|
261
|
+
header: '平台',
|
|
262
|
+
options: [
|
|
263
|
+
{ label: 'Web 浏览器', description: 'HTML5/Canvas/WebGL' },
|
|
264
|
+
{ label: '移动端', description: 'iOS/Android 原生或混合' },
|
|
265
|
+
{ label: 'PC 桌面', description: 'Electron/原生应用' },
|
|
266
|
+
{ label: '跨平台', description: '同时支持多个平台' }
|
|
267
|
+
],
|
|
268
|
+
multiSelect: true,
|
|
269
|
+
why: '平台决定技术选型和性能优化方向'
|
|
270
|
+
});
|
|
271
|
+
questions.push({
|
|
272
|
+
id: 'game_features',
|
|
273
|
+
question: '游戏包含哪些核心功能?',
|
|
274
|
+
header: '核心功能',
|
|
275
|
+
options: [
|
|
276
|
+
{ label: '多人对战', description: '实时/PVP/联机' },
|
|
277
|
+
{ label: '单机闯关', description: '关卡/剧情模式' },
|
|
278
|
+
{ label: '存档系统', description: '保存/加载进度' },
|
|
279
|
+
{ label: '成就/排行榜', description: '激励机制' }
|
|
280
|
+
],
|
|
281
|
+
multiSelect: true,
|
|
282
|
+
why: '核心功能决定开发优先级和工作量'
|
|
283
|
+
});
|
|
284
|
+
questions.push({
|
|
285
|
+
id: 'art_style',
|
|
286
|
+
question: '美术风格是什么?素材如何获取?',
|
|
287
|
+
header: '美术',
|
|
288
|
+
options: [
|
|
289
|
+
{ label: '程序化生成', description: '用代码绘制图形' },
|
|
290
|
+
{ label: '像素风', description: '复古像素艺术' },
|
|
291
|
+
{ label: '使用免费素材', description: 'OpenGameArt 等资源' },
|
|
292
|
+
{ label: '需要美术设计', description: '需要定制美术资源' }
|
|
293
|
+
],
|
|
294
|
+
multiSelect: false,
|
|
295
|
+
why: '美术方案影响开发成本和视觉效果'
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
else if (isAPI) {
|
|
299
|
+
// ========== API 专用问题 ==========
|
|
300
|
+
questions.push({
|
|
301
|
+
id: 'api_consumer',
|
|
302
|
+
question: 'API 的调用方是谁?',
|
|
303
|
+
header: '调用方',
|
|
304
|
+
options: [
|
|
305
|
+
{ label: '前端应用', description: 'Web/Mobile 前端调用' },
|
|
306
|
+
{ label: '第三方开发者', description: '公开 API 供外部使用' },
|
|
307
|
+
{ label: '内部服务', description: '微服务间调用' },
|
|
308
|
+
{ label: '混合场景', description: '多种调用方' }
|
|
309
|
+
],
|
|
310
|
+
multiSelect: false,
|
|
311
|
+
why: '调用方决定 API 设计和文档要求'
|
|
312
|
+
});
|
|
313
|
+
questions.push({
|
|
314
|
+
id: 'api_auth',
|
|
315
|
+
question: '需要什么样的认证授权?',
|
|
316
|
+
header: '认证',
|
|
317
|
+
options: [
|
|
318
|
+
{ label: '无认证', description: '公开 API,无需认证' },
|
|
319
|
+
{ label: 'API Key', description: '简单的密钥认证' },
|
|
320
|
+
{ label: 'JWT/OAuth', description: '用户身份认证' },
|
|
321
|
+
{ label: '需要调研', description: '认证方案待定' }
|
|
322
|
+
],
|
|
323
|
+
multiSelect: false,
|
|
324
|
+
why: '认证方式影响安全架构'
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else if (isCLI) {
|
|
328
|
+
// ========== CLI 专用问题 ==========
|
|
329
|
+
questions.push({
|
|
330
|
+
id: 'cli_user',
|
|
331
|
+
question: 'CLI 工具的主要使用者是谁?',
|
|
332
|
+
header: '使用者',
|
|
333
|
+
options: [
|
|
334
|
+
{ label: '开发者', description: '开发流程辅助工具' },
|
|
335
|
+
{ label: '运维人员', description: '部署/运维自动化' },
|
|
336
|
+
{ label: '普通用户', description: '非技术用户也能使用' },
|
|
337
|
+
{ label: 'CI/CD', description: '自动化流程中使用' }
|
|
338
|
+
],
|
|
339
|
+
multiSelect: true,
|
|
340
|
+
why: '使用者决定交互设计和文档要求'
|
|
341
|
+
});
|
|
342
|
+
questions.push({
|
|
343
|
+
id: 'cli_output',
|
|
344
|
+
question: 'CLI 的输出格式要求?',
|
|
345
|
+
header: '输出',
|
|
346
|
+
options: [
|
|
347
|
+
{ label: '人类可读', description: '彩色、表格、友好提示' },
|
|
348
|
+
{ label: 'JSON 机器读', description: '结构化输出,便于解析' },
|
|
349
|
+
{ label: '两种都支持', description: '通过参数切换' },
|
|
350
|
+
{ label: '静默模式', description: '最少输出,仅错误' }
|
|
351
|
+
],
|
|
352
|
+
multiSelect: false,
|
|
353
|
+
why: '输出格式影响用户体验和自动化集成'
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
// ========== 通用问题 ==========
|
|
358
|
+
questions.push({
|
|
359
|
+
id: 'core_objective',
|
|
360
|
+
question: '这个任务的核心目标是什么?想要解决什么问题?',
|
|
361
|
+
header: '核心目标',
|
|
362
|
+
options: [
|
|
363
|
+
{ label: '实现新功能', description: '添加新的功能特性,扩展系统能力' },
|
|
364
|
+
{ label: '修复问题', description: '修复 Bug 或解决已知问题' },
|
|
365
|
+
{ label: '重构优化', description: '改进代码结构、性能或可维护性' },
|
|
366
|
+
{ label: '技术探索', description: '探索新技术方案,验证可行性' }
|
|
367
|
+
],
|
|
368
|
+
multiSelect: false,
|
|
369
|
+
why: '明确核心目标有助于选择正确的实现策略和质量标准'
|
|
370
|
+
});
|
|
371
|
+
questions.push({
|
|
372
|
+
id: 'user_value',
|
|
373
|
+
question: '这个任务为用户带来什么价值?最终用户是谁?',
|
|
374
|
+
header: '用户价值',
|
|
375
|
+
options: [
|
|
376
|
+
{ label: '开发者', description: '主要用户是开发者,需要清晰的 API 和文档' },
|
|
377
|
+
{ label: '终端用户', description: '主要用户是终端用户,需要良好的用户体验' },
|
|
378
|
+
{ label: '运维人员', description: '主要用户是运维,需要稳定性和可观测性' },
|
|
379
|
+
{ label: '内部团队', description: '主要用户是内部团队,需要高效协作支持' }
|
|
380
|
+
],
|
|
381
|
+
multiSelect: false,
|
|
382
|
+
why: '了解目标用户有助于设计合适的接口和交互方式'
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
// ========== 通用问题(所有类型都有) ==========
|
|
386
|
+
// 实现复杂度 - 如果任务内容包含复杂关键词
|
|
252
387
|
if (content.includes('架构') || content.includes('系统') || content.includes('集成') || content.includes('多个')) {
|
|
253
388
|
questions.push({
|
|
254
389
|
id: 'complexity',
|
|
@@ -264,8 +399,8 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
|
|
|
264
399
|
why: '复杂度评估有助于决定是否需要分阶段实施和额外的设计审查'
|
|
265
400
|
});
|
|
266
401
|
}
|
|
267
|
-
//
|
|
268
|
-
if (content.includes('技术') || content.includes('框架') || content.includes('库')) {
|
|
402
|
+
// 技术约束 - 如果涉及技术选型
|
|
403
|
+
if (content.includes('技术') || content.includes('框架') || content.includes('库') || content.includes('技术栈')) {
|
|
269
404
|
questions.push({
|
|
270
405
|
id: 'tech_constraints',
|
|
271
406
|
question: '有哪些技术约束或偏好?需要使用/避免什么技术?',
|
|
@@ -280,7 +415,7 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
|
|
|
280
415
|
why: '技术约束影响实现方案和后续维护成本'
|
|
281
416
|
});
|
|
282
417
|
}
|
|
283
|
-
//
|
|
418
|
+
// 风险评估
|
|
284
419
|
questions.push({
|
|
285
420
|
id: 'risks',
|
|
286
421
|
question: '这个任务可能面临哪些风险或挑战?',
|
|
@@ -294,7 +429,7 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
|
|
|
294
429
|
multiSelect: true,
|
|
295
430
|
why: '识别风险有助于提前规划应对策略'
|
|
296
431
|
});
|
|
297
|
-
//
|
|
432
|
+
// 验收标准
|
|
298
433
|
questions.push({
|
|
299
434
|
id: 'acceptance',
|
|
300
435
|
question: '如何判断任务完成?有哪些验收标准?',
|
|
@@ -308,7 +443,7 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
|
|
|
308
443
|
multiSelect: true,
|
|
309
444
|
why: '明确的验收标准有助于判断任务完成度'
|
|
310
445
|
});
|
|
311
|
-
//
|
|
446
|
+
// 实现优先级
|
|
312
447
|
questions.push({
|
|
313
448
|
id: 'priority',
|
|
314
449
|
question: '这个任务的优先级如何?是否需要 MVP 版本?',
|
|
@@ -58,6 +58,7 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
58
58
|
.option('-q, --quality <level>', '质量级别 (strict|balanced|fast)')
|
|
59
59
|
.option('-t, --tech-stack <stack>', '技术栈 (逗号分隔,如 "TypeScript,Vue.js,PostgreSQL")')
|
|
60
60
|
.option('--docs <level>', '文档级别 (full|basic|minimal|none)')
|
|
61
|
+
.option('--brainstorm-answers <json>', '从 brainstorm 传递的答案 JSON')
|
|
61
62
|
.action(async (input, options) => {
|
|
62
63
|
const basePath = process.cwd();
|
|
63
64
|
const omPath = path.join(basePath, '.openmatrix');
|
|
@@ -101,6 +102,53 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
101
102
|
}
|
|
102
103
|
return;
|
|
103
104
|
}
|
|
105
|
+
// 检查 brainstorm 状态 (状态校验)
|
|
106
|
+
const brainstormPath = path.join(omPath, 'brainstorm', 'session.json');
|
|
107
|
+
try {
|
|
108
|
+
const brainstormContent = await fs.readFile(brainstormPath, 'utf-8');
|
|
109
|
+
const brainstormSession = JSON.parse(brainstormContent);
|
|
110
|
+
if (brainstormSession.status === 'brainstorming') {
|
|
111
|
+
// 检查是否有未回答的问题
|
|
112
|
+
const answeredCount = Object.keys(brainstormSession.answers || {}).length;
|
|
113
|
+
const totalQuestions = brainstormSession.questions?.length || 0;
|
|
114
|
+
if (answeredCount < totalQuestions && !options.brainstormAnswers) {
|
|
115
|
+
// brainstorm 未完成,且没有传递答案
|
|
116
|
+
if (options.json) {
|
|
117
|
+
console.log(JSON.stringify({
|
|
118
|
+
status: 'error',
|
|
119
|
+
code: 'BRAINSTORM_INCOMPLETE',
|
|
120
|
+
message: '头脑风暴未完成',
|
|
121
|
+
details: {
|
|
122
|
+
taskTitle: brainstormSession.taskTitle,
|
|
123
|
+
answeredCount,
|
|
124
|
+
totalQuestions,
|
|
125
|
+
missingQuestions: brainstormSession.questions
|
|
126
|
+
?.filter((q) => !brainstormSession.answers?.[q.id])
|
|
127
|
+
?.map((q) => ({ question: q.question, header: q.header })) || []
|
|
128
|
+
},
|
|
129
|
+
hint: '请先完成头脑风暴: /om:brainstorm,或传递 --brainstorm-answers 参数'
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log('⚠️ 头脑风暴未完成!');
|
|
134
|
+
console.log(` 任务: ${brainstormSession.taskTitle}`);
|
|
135
|
+
console.log(` 进度: ${answeredCount}/${totalQuestions} 问题已回答`);
|
|
136
|
+
console.log('\n 未回答的问题:');
|
|
137
|
+
brainstormSession.questions
|
|
138
|
+
?.filter((q) => !brainstormSession.answers?.[q.id])
|
|
139
|
+
?.forEach((q, i) => {
|
|
140
|
+
console.log(` ${i + 1}. [${q.header}] ${q.question}`);
|
|
141
|
+
});
|
|
142
|
+
console.log('\n 💡 请先完成头脑风暴: /om:brainstorm');
|
|
143
|
+
console.log(' 或传递 --brainstorm-answers 参数跳过此检查');
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// brainstorm 文件不存在,继续执行
|
|
151
|
+
}
|
|
104
152
|
// 构建任务内容
|
|
105
153
|
let taskContent = input;
|
|
106
154
|
// 如果提供了 --title 和 --description,构建任务内容
|
|
@@ -163,6 +211,24 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
163
211
|
}
|
|
164
212
|
const parser = new task_parser_js_1.TaskParser();
|
|
165
213
|
const parsedTask = parser.parse(taskContent);
|
|
214
|
+
// 解析 brainstorm 答案 (如果有)
|
|
215
|
+
let brainstormContext = {};
|
|
216
|
+
if (options.brainstormAnswers) {
|
|
217
|
+
try {
|
|
218
|
+
brainstormContext = JSON.parse(options.brainstormAnswers);
|
|
219
|
+
if (!options.json) {
|
|
220
|
+
console.log('\n🧠 使用 brainstorm 收集的信息:');
|
|
221
|
+
if (brainstormContext.answers) {
|
|
222
|
+
Object.entries(brainstormContext.answers).forEach(([key, value]) => {
|
|
223
|
+
console.log(` - ${key}: ${Array.isArray(value) ? value.join(', ') : value}`);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// 忽略解析错误
|
|
230
|
+
}
|
|
231
|
+
}
|
|
166
232
|
if (!options.json) {
|
|
167
233
|
console.log(`\n📋 任务: ${parsedTask.title}`);
|
|
168
234
|
console.log(` 目标: ${parsedTask.goals.join(', ')}`);
|
|
@@ -172,7 +238,27 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
172
238
|
console.log('\n🔧 拆解任务...');
|
|
173
239
|
}
|
|
174
240
|
const planner = new task_planner_js_1.TaskPlanner();
|
|
175
|
-
|
|
241
|
+
// 构建 planner 上下文,包含 brainstorm 信息
|
|
242
|
+
// 注意: TaskPlanner.breakdown 需要 Record<string, string> 类型
|
|
243
|
+
const plannerContext = {};
|
|
244
|
+
if (brainstormContext.answers) {
|
|
245
|
+
plannerContext.brainstormAnswers = JSON.stringify(brainstormContext.answers);
|
|
246
|
+
}
|
|
247
|
+
if (brainstormContext.insights && brainstormContext.insights.length > 0) {
|
|
248
|
+
plannerContext.insights = brainstormContext.insights.join('; ');
|
|
249
|
+
}
|
|
250
|
+
if (brainstormContext.designNotes && brainstormContext.designNotes.length > 0) {
|
|
251
|
+
plannerContext.designNotes = brainstormContext.designNotes.join('; ');
|
|
252
|
+
}
|
|
253
|
+
// 添加技术栈信息
|
|
254
|
+
if (options.techStack) {
|
|
255
|
+
plannerContext.techStack = options.techStack;
|
|
256
|
+
}
|
|
257
|
+
// 添加质量级别
|
|
258
|
+
if (options.quality) {
|
|
259
|
+
plannerContext.qualityLevel = options.quality;
|
|
260
|
+
}
|
|
261
|
+
const subTasks = planner.breakdown(parsedTask, plannerContext);
|
|
176
262
|
// 创建任务到状态管理器
|
|
177
263
|
for (const subTask of subTasks) {
|
|
178
264
|
await stateManager.createTask({
|
package/package.json
CHANGED
package/skills/brainstorm.md
CHANGED
|
@@ -14,9 +14,37 @@ OpenMatrix 独立运行,使用自己的头脑风暴流程。
|
|
|
14
14
|
</objective>
|
|
15
15
|
|
|
16
16
|
<process>
|
|
17
|
-
1.
|
|
17
|
+
1. **检查现有会话 (断点续传)**
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
**首先检查** `.openmatrix/brainstorm/session.json` 是否存在且未完成:
|
|
20
|
+
```bash
|
|
21
|
+
# 检查现有会话状态
|
|
22
|
+
cat .openmatrix/brainstorm/session.json 2>/dev/null
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**如果存在未完成的会话**:
|
|
26
|
+
- 读取 `session.status`、`session.questions`、`session.answers`
|
|
27
|
+
- 计算未回答的问题: `questions.filter(q => !answers[q.id])`
|
|
28
|
+
- 询问用户是否继续:
|
|
29
|
+
```typescript
|
|
30
|
+
AskUserQuestion({
|
|
31
|
+
questions: [{
|
|
32
|
+
question: `发现未完成的头脑风暴会话: "${session.taskTitle}",已回答 ${Object.keys(session.answers).length}/${session.questions.length} 个问题。是否继续?`,
|
|
33
|
+
header: "恢复会话",
|
|
34
|
+
options: [
|
|
35
|
+
{ label: "✅ 继续回答", description: "从上次中断的地方继续" },
|
|
36
|
+
{ label: "🔄 重新开始", description: "丢弃之前的回答,重新开始" }
|
|
37
|
+
],
|
|
38
|
+
multiSelect: false
|
|
39
|
+
}]
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
- 如果选择"继续回答",只问未回答的问题
|
|
43
|
+
- 如果选择"重新开始",继续下面的初始化流程
|
|
44
|
+
|
|
45
|
+
2. **初始化头脑风暴会话**
|
|
46
|
+
|
|
47
|
+
如果 `$ARGUMENTS` 为空,先询问用户任务内容:
|
|
20
48
|
```typescript
|
|
21
49
|
AskUserQuestion({
|
|
22
50
|
questions: [{
|
|
@@ -32,6 +60,12 @@ OpenMatrix 独立运行,使用自己的头脑风暴流程。
|
|
|
32
60
|
openmatrix brainstorm "$ARGUMENTS" --json
|
|
33
61
|
```
|
|
34
62
|
|
|
63
|
+
**CLI 会根据任务关键词自动选择问题类型**:
|
|
64
|
+
- 游戏 (game/游戏/玩家) → 游戏专用问题
|
|
65
|
+
- API (api/接口/后端) → API 专用问题
|
|
66
|
+
- CLI (cli/命令行/工具) → CLI 专用问题
|
|
67
|
+
- 其他 → 通用问题
|
|
68
|
+
|
|
35
69
|
这会返回:
|
|
36
70
|
```json
|
|
37
71
|
{
|
|
@@ -51,25 +85,44 @@ OpenMatrix 独立运行,使用自己的头脑风暴流程。
|
|
|
51
85
|
}
|
|
52
86
|
```
|
|
53
87
|
|
|
54
|
-
2.
|
|
88
|
+
2. **交互式问答 (必须收集答案)**
|
|
89
|
+
|
|
90
|
+
**重要**: 必须收集所有答案,用于后续传递给 CLI。
|
|
55
91
|
|
|
56
92
|
对每个问题使用 `AskUserQuestion` 进行提问:
|
|
57
93
|
|
|
58
94
|
```typescript
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
95
|
+
// 收集答案的对象
|
|
96
|
+
const collectedAnswers: Record<string, string | string[]> = {};
|
|
97
|
+
const collectedInsights: string[] = [];
|
|
98
|
+
|
|
99
|
+
// 对每个问题提问
|
|
100
|
+
for (const q of questions) {
|
|
101
|
+
const response = await AskUserQuestion({
|
|
102
|
+
questions: [{
|
|
103
|
+
question: q.question,
|
|
104
|
+
header: q.header,
|
|
105
|
+
options: q.options,
|
|
106
|
+
multiSelect: q.multiSelect
|
|
107
|
+
}]
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// 记录答案
|
|
111
|
+
collectedAnswers[q.id] = response.answers[q.question] || response.answers['0'];
|
|
112
|
+
|
|
113
|
+
// 记录洞察 (根据答案推导)
|
|
114
|
+
if (q.id === 'core_objective') {
|
|
115
|
+
collectedInsights.push(`核心目标: ${collectedAnswers[q.id]}`);
|
|
116
|
+
}
|
|
117
|
+
// ... 其他洞察
|
|
118
|
+
}
|
|
67
119
|
```
|
|
68
120
|
|
|
69
121
|
**收集回答并记录洞察**:
|
|
70
122
|
- 每个回答后,思考其含义
|
|
71
123
|
- 记录可能的设计决策
|
|
72
124
|
- 识别潜在风险
|
|
125
|
+
- **必须保存到 session.answers 对象中**
|
|
73
126
|
|
|
74
127
|
3. **深入追问** (可选)
|
|
75
128
|
|
|
@@ -134,28 +187,76 @@ OpenMatrix 独立运行,使用自己的头脑风暴流程。
|
|
|
134
187
|
})
|
|
135
188
|
```
|
|
136
189
|
|
|
137
|
-
6.
|
|
190
|
+
6. **保存答案并执行 start**
|
|
191
|
+
|
|
192
|
+
**关键步骤**: 必须将收集的答案保存到 CLI,然后再启动执行。
|
|
138
193
|
|
|
139
194
|
如果用户选择"开始执行":
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
195
|
+
|
|
196
|
+
**步骤 1**: 构建结果 JSON (必须包含所有收集的答案):
|
|
197
|
+
```typescript
|
|
198
|
+
const resultsJson = JSON.stringify({
|
|
199
|
+
answers: collectedAnswers, // 用户对每个问题的回答
|
|
200
|
+
insights: collectedInsights, // 推导出的洞察
|
|
201
|
+
designNotes: collectedNotes // 设计笔记
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**步骤 2**: 调用 CLI 保存结果并标记完成:
|
|
206
|
+
```bash
|
|
207
|
+
# 必须传递 --results 参数,否则答案不会被保存!
|
|
208
|
+
openmatrix brainstorm --complete --results '$RESULTS_JSON' --json
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
实际执行示例:
|
|
212
|
+
```bash
|
|
213
|
+
# 使用单引号包裹 JSON,避免 shell 解析问题
|
|
214
|
+
openmatrix brainstorm --complete --results '{"answers":{"core_objective":"实现新功能","user_value":"终端用户"},"insights":["核心目标是实现新功能"],"designNotes":[]}' --json
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**步骤 3**: 调用 CLI 启动任务执行:
|
|
218
|
+
```bash
|
|
219
|
+
# 使用 --brainstorm-answers 参数传递收集的信息
|
|
220
|
+
openmatrix start "$TASK_INPUT" \
|
|
221
|
+
--title "$TASK_TITLE" \
|
|
222
|
+
--quality "$QUALITY_LEVEL" \
|
|
223
|
+
--mode "$MODE" \
|
|
224
|
+
--brainstorm-answers '$RESULTS_JSON' \
|
|
225
|
+
--json
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
实际执行示例:
|
|
229
|
+
```bash
|
|
230
|
+
openmatrix start "实现用户登录功能" \
|
|
231
|
+
--title "用户登录功能" \
|
|
232
|
+
--quality balanced \
|
|
233
|
+
--mode auto \
|
|
234
|
+
--brainstorm-answers '{"answers":{"core_objective":"实现新功能","user_value":"终端用户"},"insights":["核心目标是实现新功能"],"designNotes":[]}' \
|
|
235
|
+
--json
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**步骤 4**: 读取 CLI 返回的 SubagentTask 列表并执行:
|
|
239
|
+
```typescript
|
|
240
|
+
// CLI 返回 JSON 格式的任务列表
|
|
241
|
+
const result = JSON.parse(cliOutput);
|
|
242
|
+
if (result.status === 'continue' && result.subagentTasks.length > 0) {
|
|
243
|
+
// 使用 Agent 工具执行每个 SubagentTask
|
|
244
|
+
for (const task of result.subagentTasks) {
|
|
245
|
+
await Agent({
|
|
246
|
+
subagent_type: task.subagent_type,
|
|
247
|
+
description: task.description,
|
|
248
|
+
prompt: task.prompt,
|
|
249
|
+
isolation: task.isolation
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**注意事项**:
|
|
256
|
+
- 必须先调用 `--complete --results` 保存答案
|
|
257
|
+
- 然后调用 `openmatrix start` 并传递 `--brainstorm-answers`
|
|
258
|
+
- 最后读取返回的 SubagentTask 列表并执行
|
|
259
|
+
- 不要直接执行任务,必须通过 `/om:start` 启动
|
|
159
260
|
|
|
160
261
|
</process>
|
|
161
262
|
|
package/skills/start.md
CHANGED
|
@@ -3,6 +3,25 @@ name: om:start
|
|
|
3
3
|
description: 启动新的任务执行周期
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
## 📊 进度状态指示器
|
|
7
|
+
|
|
8
|
+
在执行过程中,始终显示当前进度状态:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
12
|
+
║ OpenMatrix 执行流程 ║
|
|
13
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
14
|
+
║ [1/6] 🧠 Brainstorm → 深入理解需求 ║
|
|
15
|
+
║ [2/6] 📋 Plan → 拆解任务,制定计划 ║
|
|
16
|
+
║ [3/6] 🔧 Develop → 编写代码实现 ║
|
|
17
|
+
║ [4/6] ✅ Verify → 测试、Lint、安全扫描 ║
|
|
18
|
+
║ [5/6] 🎯 Accept → 验收确认 ║
|
|
19
|
+
║ [6/6] 📦 Complete → 提交、部署 ║
|
|
20
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
21
|
+
|
|
22
|
+
📍 当前位置: Step X/6 - [阶段名称]
|
|
23
|
+
```
|
|
24
|
+
|
|
6
25
|
<EXTREMELY-IMPORTANT>
|
|
7
26
|
## 必须使用此 Skill 的情况
|
|
8
27
|
|
|
@@ -74,6 +93,22 @@ description: 启动新的任务执行周期
|
|
|
74
93
|
- 如果 `$ARGUMENTS` 是任务描述 → 直接使用
|
|
75
94
|
- 如果无参数 → 使用 AskUserQuestion 询问用户要执行的任务
|
|
76
95
|
|
|
96
|
+
6. **检查 brainstorm 会话 (重要)**
|
|
97
|
+
|
|
98
|
+
检查 `.openmatrix/brainstorm/session.json` 是否存在:
|
|
99
|
+
- 如果存在且 `status === 'ready_to_start'`,读取收集的信息:
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"taskInput": "任务描述",
|
|
103
|
+
"taskTitle": "任务标题",
|
|
104
|
+
"answers": { "core_objective": "...", ... },
|
|
105
|
+
"insights": ["洞察1", "洞察2"],
|
|
106
|
+
"designNotes": ["设计要点1"]
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
- 将这些信息用于后续的任务分析和质量级别推荐
|
|
110
|
+
- **从 brainstorm 继承的答案可以跳过重复提问**
|
|
111
|
+
|
|
77
112
|
---
|
|
78
113
|
|
|
79
114
|
## Step 1: 展示理解 + 选择质量级别
|
|
@@ -139,9 +174,43 @@ AskUserQuestion({
|
|
|
139
174
|
|
|
140
175
|
## Step 2: 展示执行计划 + 执行模式
|
|
141
176
|
|
|
142
|
-
**调用 CLI
|
|
177
|
+
**调用 CLI 拆解任务(传入任务描述和质量配置):**
|
|
178
|
+
|
|
143
179
|
```bash
|
|
144
|
-
|
|
180
|
+
# 基本调用
|
|
181
|
+
openmatrix start "$TASK_INPUT" --quality "$QUALITY_LEVEL" --mode "$MODE" --json
|
|
182
|
+
|
|
183
|
+
# 如果有 brainstorm 信息,传递额外参数
|
|
184
|
+
openmatrix start "$TASK_INPUT" \
|
|
185
|
+
--quality "$QUALITY_LEVEL" \
|
|
186
|
+
--mode "$MODE" \
|
|
187
|
+
--title "$TASK_TITLE" \
|
|
188
|
+
--tech-stack "$TECH_STACK" \
|
|
189
|
+
--json
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**参数说明:**
|
|
193
|
+
- `$TASK_INPUT`: 任务描述或文件路径
|
|
194
|
+
- `$QUALITY_LEVEL`: fast | balanced | strict
|
|
195
|
+
- `$MODE`: auto | confirm-key | confirm-all
|
|
196
|
+
- `$TASK_TITLE`: 从 brainstorm 继承的任务标题
|
|
197
|
+
- `$TECH_STACK`: 技术栈 (逗号分隔)
|
|
198
|
+
|
|
199
|
+
**重要**: CLI 会自动:
|
|
200
|
+
1. 解析任务
|
|
201
|
+
2. 拆解为子任务
|
|
202
|
+
3. 创建任务文件到 `.openmatrix/tasks/`
|
|
203
|
+
4. 返回待执行的 SubagentTask 列表
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
**📍 Step 2 完成 → 下一步: Step 3 执行**
|
|
208
|
+
|
|
209
|
+
输出进度提示:
|
|
210
|
+
```
|
|
211
|
+
✅ Step 2/6 完成 - 任务计划已生成
|
|
212
|
+
📊 统计: X 个任务, 预计 Y 分钟
|
|
213
|
+
➡️ 下一步: Step 3 - 开始执行任务
|
|
145
214
|
```
|
|
146
215
|
|
|
147
216
|
**展示执行计划:**
|
|
@@ -204,8 +273,22 @@ AskUserQuestion({
|
|
|
204
273
|
|
|
205
274
|
## Step 3: 执行
|
|
206
275
|
|
|
276
|
+
**📍 当前进度: Step 3/6 - 执行任务**
|
|
277
|
+
|
|
207
278
|
**重要**: 从此步骤开始,除非遇到风险操作、meeting 或失败,否则**不得暂停询问用户**。
|
|
208
279
|
|
|
280
|
+
### 执行开始提示
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
284
|
+
║ 🚀 开始执行任务 ║
|
|
285
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
286
|
+
║ 质量级别: balanced ║
|
|
287
|
+
║ 执行模式: auto ║
|
|
288
|
+
║ 总任务数: X ║
|
|
289
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
290
|
+
```
|
|
291
|
+
|
|
209
292
|
### 执行循环
|
|
210
293
|
|
|
211
294
|
```
|
|
@@ -284,13 +367,102 @@ while (有待执行任务) {
|
|
|
284
367
|
|
|
285
368
|
### 执行完成
|
|
286
369
|
|
|
370
|
+
**📍 Step 3/6 完成 → 显示执行总结**
|
|
371
|
+
|
|
287
372
|
```
|
|
288
|
-
|
|
373
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
374
|
+
║ ✅ Step 3/6 完成 - 执行阶段结束 ║
|
|
375
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
376
|
+
║ 📊 执行统计: ║
|
|
377
|
+
║ • 总任务: X ║
|
|
378
|
+
║ • 成功: X ║
|
|
379
|
+
║ • 失败: X ║
|
|
380
|
+
║ • 跳过: X ║
|
|
381
|
+
║ ║
|
|
382
|
+
║ 📝 文件改动: 3 个文件 ║
|
|
383
|
+
║ 🔗 Git Commits: 2 个 ║
|
|
384
|
+
║ ║
|
|
385
|
+
║ ➡️ 下一步: Step 4 - 验证阶段 (自动运行) ║
|
|
386
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Step 4: 验证 (Verify)
|
|
392
|
+
|
|
393
|
+
**📍 当前进度: Step 4/6 - 验证质量门禁**
|
|
394
|
+
|
|
395
|
+
自动执行验证 (根据质量级别):
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
🔍 验证阶段开始...
|
|
399
|
+
|
|
400
|
+
[1/5] 🏗️ 编译检查 → npm run build
|
|
401
|
+
[2/5] 🧪 测试运行 → npm test
|
|
402
|
+
[3/5] 📊 覆盖率检查 → npm test -- --coverage
|
|
403
|
+
[4/5] 🔍 Lint 检查 → npm run lint
|
|
404
|
+
[5/5] 🔒 安全扫描 → npm audit
|
|
405
|
+
|
|
406
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
407
|
+
║ ✅ Step 4/6 完成 - 验证通过 ║
|
|
408
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
409
|
+
║ Tests: ✅ 15/15 passed, 85% coverage ║
|
|
410
|
+
║ Build: ✅ Success ║
|
|
411
|
+
║ Lint: ✅ No errors ║
|
|
412
|
+
║ Security: ✅ No vulnerabilities ║
|
|
413
|
+
║ ║
|
|
414
|
+
║ ➡️ 下一步: Step 5 - 验收阶段 ║
|
|
415
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
289
419
|
|
|
290
|
-
|
|
291
|
-
🔗 Commits: 2 个
|
|
420
|
+
## Step 5: 验收 (Accept)
|
|
292
421
|
|
|
293
|
-
|
|
422
|
+
**📍 当前进度: Step 5/6 - 最终验收**
|
|
423
|
+
|
|
424
|
+
检查验收标准:
|
|
425
|
+
|
|
426
|
+
```
|
|
427
|
+
📋 验收标准检查:
|
|
428
|
+
|
|
429
|
+
[✅] 1. 所有功能按预期工作
|
|
430
|
+
[✅] 2. 测试覆盖率达到要求
|
|
431
|
+
[✅] 3. 无 Lint 错误
|
|
432
|
+
[✅] 4. 无安全漏洞
|
|
433
|
+
|
|
434
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
435
|
+
║ ✅ Step 5/6 完成 - 验收通过 ║
|
|
436
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
437
|
+
║ 验收结果: ✅ 全部通过 ║
|
|
438
|
+
║ ║
|
|
439
|
+
║ ➡️ 下一步: Step 6 - 完成阶段 ║
|
|
440
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Step 6: 完成 (Complete)
|
|
446
|
+
|
|
447
|
+
**📍 当前进度: Step 6/6 - 最终提交**
|
|
448
|
+
|
|
449
|
+
```
|
|
450
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
451
|
+
║ 🎉 Step 6/6 完成 - 任务全部完成! ║
|
|
452
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
453
|
+
║ 📊 总结: ║
|
|
454
|
+
║ • 总任务: X ║
|
|
455
|
+
║ • 成功: X ║
|
|
456
|
+
║ • 失败: X ║
|
|
457
|
+
║ • 耗时: X 分钟 ║
|
|
458
|
+
║ ║
|
|
459
|
+
║ 📝 文件改动: X 个文件 ║
|
|
460
|
+
║ 🔗 Git Commits: X 个 ║
|
|
461
|
+
║ ║
|
|
462
|
+
║ 🎯 下一步建议: ║
|
|
463
|
+
║ • git push (如需推送) ║
|
|
464
|
+
║ • /om:report (查看详细报告) ║
|
|
465
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
294
466
|
```
|
|
295
467
|
|
|
296
468
|
---
|