openmatrix 0.2.6 → 0.2.7

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.
@@ -34,6 +34,20 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.brainstormCommand = void 0;
37
+ exports.handleCompleteMode = handleCompleteMode;
38
+ exports.mergeSessionResults = mergeSessionResults;
39
+ exports.outputCompleteResult = outputCompleteResult;
40
+ exports.outputSessionNotFound = outputSessionNotFound;
41
+ exports.loadTaskContent = loadTaskContent;
42
+ exports.loadTaskFromDefaultFile = loadTaskFromDefaultFile;
43
+ exports.loadTaskFromSpecifiedFile = loadTaskFromSpecifiedFile;
44
+ exports.extractTaskTitle = extractTaskTitle;
45
+ exports.createNewSession = createNewSession;
46
+ exports.outputNewSession = outputNewSession;
47
+ exports.outputNewSessionJson = outputNewSessionJson;
48
+ exports.outputNewSessionText = outputNewSessionText;
49
+ exports.buildSmartQuestionSession = buildSmartQuestionSession;
50
+ exports.convertToBrainstormQuestions = convertToBrainstormQuestions;
37
51
  // src/cli/commands/brainstorm.ts
38
52
  const commander_1 = require("commander");
39
53
  const state_manager_js_1 = require("../../storage/state-manager.js");
@@ -58,132 +72,177 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
58
72
  await fs.mkdir(path.join(omPath, 'tasks'), { recursive: true });
59
73
  await fs.mkdir(path.join(omPath, 'approvals'), { recursive: true });
60
74
  await fs.mkdir(path.join(omPath, 'brainstorm'), { recursive: true });
61
- // 确保 .openmatrix 被 git 忽略
62
75
  await (0, gitignore_js_1.ensureOpenmatrixGitignore)(basePath);
63
76
  const stateManager = new state_manager_js_1.StateManager(omPath);
64
77
  await stateManager.initialize();
65
78
  const brainstormPath = path.join(omPath, 'brainstorm', 'session.json');
66
79
  // --complete 模式:头脑风暴完成,输出 start 所需信息
67
80
  if (options.complete) {
68
- try {
69
- const sessionData = await fs.readFile(brainstormPath, 'utf-8');
70
- const session = JSON.parse(sessionData);
71
- // 更新状态
72
- session.status = 'ready_to_start';
73
- // 如果传入了结果,合并
74
- if (options.results) {
75
- try {
76
- const results = JSON.parse(options.results);
77
- session.answers = { ...session.answers, ...results.answers };
78
- session.insights = [...session.insights, ...(results.insights || [])];
79
- session.designNotes = [...session.designNotes, ...(results.designNotes || [])];
80
- }
81
- catch {
82
- // 忽略解析错误
83
- }
84
- }
85
- await fs.writeFile(brainstormPath, JSON.stringify(session, null, 2));
86
- if (options.json) {
87
- console.log(JSON.stringify({
88
- status: 'ready_to_start',
89
- message: '头脑风暴完成,准备执行任务',
90
- taskInput: session.taskInput,
91
- taskTitle: session.taskTitle,
92
- answers: session.answers,
93
- insights: session.insights,
94
- designNotes: session.designNotes,
95
- hint: '使用 /om:start 开始执行任务'
96
- }));
97
- }
98
- else {
99
- console.log('✅ 头脑风暴完成!');
100
- console.log(` 任务: ${session.taskTitle}`);
101
- console.log('\n📋 收集的洞察:');
102
- session.insights.forEach((insight, i) => {
103
- console.log(` ${i + 1}. ${insight}`);
104
- });
105
- console.log('\n📝 设计要点:');
106
- session.designNotes.forEach((note, i) => {
107
- console.log(` ${i + 1}. ${note}`);
108
- });
109
- console.log('\n🚀 使用 /om:start 开始执行任务');
110
- }
111
- return;
112
- }
113
- catch {
114
- if (options.json) {
115
- console.log(JSON.stringify({
116
- status: 'error',
117
- message: '没有进行中的头脑风暴会话'
118
- }));
119
- }
120
- else {
121
- console.log('❌ 没有进行中的头脑风暴会话');
122
- console.log(' 使用 openmatrix brainstorm <task> 开始新的头脑风暴');
123
- }
124
- return;
125
- }
81
+ await handleCompleteMode(brainstormPath, options);
82
+ return;
126
83
  }
127
84
  // 获取任务内容
85
+ const taskContent = await loadTaskContent(input, basePath, options);
86
+ if (!taskContent)
87
+ return;
88
+ // 创建新的头脑风暴会话
89
+ await createNewSession(taskContent, basePath, brainstormPath, options);
90
+ });
91
+ /**
92
+ * 处理 --complete 模式:标记头脑风暴完成,输出 start 所需信息
93
+ */
94
+ async function handleCompleteMode(brainstormPath, options) {
95
+ try {
96
+ const sessionData = await fs.readFile(brainstormPath, 'utf-8');
97
+ const session = JSON.parse(sessionData);
98
+ session.status = 'ready_to_start';
99
+ mergeSessionResults(session, options.results);
100
+ await fs.writeFile(brainstormPath, JSON.stringify(session, null, 2));
101
+ outputCompleteResult(session, options.json);
102
+ }
103
+ catch {
104
+ outputSessionNotFound(options.json);
105
+ }
106
+ }
107
+ /**
108
+ * 合并外部传入的结果到已有会话
109
+ */
110
+ function mergeSessionResults(session, resultsJson) {
111
+ if (!resultsJson)
112
+ return;
113
+ try {
114
+ const results = JSON.parse(resultsJson);
115
+ session.answers = { ...session.answers, ...results.answers };
116
+ session.insights = [...session.insights, ...(results.insights || [])];
117
+ session.designNotes = [...session.designNotes, ...(results.designNotes || [])];
118
+ }
119
+ catch {
120
+ // 忽略解析错误
121
+ }
122
+ }
123
+ /**
124
+ * 输出 complete 模式的结果
125
+ */
126
+ function outputCompleteResult(session, jsonMode) {
127
+ if (jsonMode) {
128
+ console.log(JSON.stringify({
129
+ status: 'ready_to_start',
130
+ message: '头脑风暴完成,准备执行任务',
131
+ taskInput: session.taskInput,
132
+ taskTitle: session.taskTitle,
133
+ answers: session.answers,
134
+ insights: session.insights,
135
+ designNotes: session.designNotes,
136
+ hint: '使用 /om:start 开始执行任务'
137
+ }));
138
+ }
139
+ else {
140
+ console.log('✅ 头脑风暴完成!');
141
+ console.log(` 任务: ${session.taskTitle}`);
142
+ console.log('\n📋 收集的洞察:');
143
+ session.insights.forEach((insight, i) => {
144
+ console.log(` ${i + 1}. ${insight}`);
145
+ });
146
+ console.log('\n📝 设计要点:');
147
+ session.designNotes.forEach((note, i) => {
148
+ console.log(` ${i + 1}. ${note}`);
149
+ });
150
+ console.log('\n🚀 使用 /om:start 开始执行任务');
151
+ }
152
+ }
153
+ /**
154
+ * 输出会话未找到的错误信息
155
+ */
156
+ function outputSessionNotFound(jsonMode) {
157
+ if (jsonMode) {
158
+ console.log(JSON.stringify({
159
+ status: 'error',
160
+ message: '没有进行中的头脑风暴会话'
161
+ }));
162
+ }
163
+ else {
164
+ console.log('❌ 没有进行中的头脑风暴会话');
165
+ console.log(' 使用 openmatrix brainstorm <task> 开始新的头脑风暴');
166
+ }
167
+ }
168
+ /**
169
+ * 从输入参数或文件加载任务内容,返回 null 表示加载失败(已输出错误)
170
+ */
171
+ async function loadTaskContent(input, basePath, options) {
128
172
  let taskContent = input;
129
173
  if (!taskContent) {
130
- const defaultPath = path.join(basePath, 'TASK.md');
131
- try {
132
- taskContent = await fs.readFile(defaultPath, 'utf-8');
133
- if (!options.json) {
134
- console.log(`📄 读取任务文件: ${defaultPath}`);
135
- }
174
+ return loadTaskFromDefaultFile(basePath, options.json);
175
+ }
176
+ else if (taskContent.endsWith('.md')) {
177
+ return loadTaskFromSpecifiedFile(taskContent, input, options.json);
178
+ }
179
+ return taskContent;
180
+ }
181
+ /**
182
+ * 从默认 TASK.md 文件加载任务内容
183
+ */
184
+ async function loadTaskFromDefaultFile(basePath, jsonMode) {
185
+ const defaultPath = path.join(basePath, 'TASK.md');
186
+ try {
187
+ const content = await fs.readFile(defaultPath, 'utf-8');
188
+ if (!jsonMode) {
189
+ console.log(`📄 读取任务文件: ${defaultPath}`);
136
190
  }
137
- catch {
138
- if (options.json) {
139
- console.log(JSON.stringify({
140
- status: 'error',
141
- message: '请提供任务文件路径或描述'
142
- }));
143
- }
144
- else {
145
- console.log(' 请提供任务文件路径或描述');
146
- console.log(' 用法: openmatrix brainstorm <task.md>');
147
- console.log(' 或创建 TASK.md 文件');
148
- }
149
- return;
191
+ return content;
192
+ }
193
+ catch {
194
+ if (jsonMode) {
195
+ console.log(JSON.stringify({ status: 'error', message: '请提供任务文件路径或描述' }));
196
+ }
197
+ else {
198
+ console.log('❌ 请提供任务文件路径或描述');
199
+ console.log(' 用法: openmatrix brainstorm <task.md>');
200
+ console.log(' 或创建 TASK.md 文件');
150
201
  }
202
+ return null;
151
203
  }
152
- else if (taskContent.endsWith('.md')) {
153
- try {
154
- taskContent = await fs.readFile(taskContent, 'utf-8');
155
- if (!options.json) {
156
- console.log(`📄 读取任务文件: ${input}`);
157
- }
204
+ }
205
+ /**
206
+ * 从用户指定的 .md 文件加载任务内容
207
+ */
208
+ async function loadTaskFromSpecifiedFile(filePath, displayName, jsonMode) {
209
+ try {
210
+ const content = await fs.readFile(filePath, 'utf-8');
211
+ if (!jsonMode) {
212
+ console.log(`📄 读取任务文件: ${displayName}`);
158
213
  }
159
- catch {
160
- if (options.json) {
161
- console.log(JSON.stringify({
162
- status: 'error',
163
- message: `无法读取文件: ${input}`
164
- }));
165
- }
166
- else {
167
- console.log(`❌ 无法读取文件: ${input}`);
168
- }
169
- return;
214
+ return content;
215
+ }
216
+ catch {
217
+ if (jsonMode) {
218
+ console.log(JSON.stringify({ status: 'error', message: `无法读取文件: ${displayName}` }));
170
219
  }
220
+ else {
221
+ console.log(`❌ 无法读取文件: ${displayName}`);
222
+ }
223
+ return null;
171
224
  }
172
- // 从任务内容提取标题
225
+ }
226
+ /**
227
+ * 从任务内容中提取标题
228
+ */
229
+ function extractTaskTitle(taskContent) {
173
230
  const lines = taskContent.split('\n');
174
- let taskTitle = '未命名任务';
175
231
  for (const line of lines) {
176
232
  const match = line.match(/^#\s+(.+)$/);
177
233
  if (match) {
178
- taskTitle = match[1].trim();
179
- break;
234
+ return match[1].trim();
180
235
  }
181
236
  }
182
- // 生成头脑风暴问题 — 使用智能管道
237
+ return '未命名任务';
238
+ }
239
+ /**
240
+ * 创建新的头脑风暴会话并输出
241
+ */
242
+ async function createNewSession(taskContent, basePath, brainstormPath, options) {
243
+ const taskTitle = extractTaskTitle(taskContent);
183
244
  const questions = await generateSmartQuestions(taskContent, basePath);
184
- // 检测是否涉及垂直领域
185
245
  const domainDetection = detectVerticalDomain(taskContent);
186
- // 创建会话
187
246
  const session = {
188
247
  status: 'brainstorming',
189
248
  taskInput: taskContent,
@@ -195,42 +254,58 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
195
254
  suggestResearch: domainDetection.isVertical ? domainDetection.domain : undefined
196
255
  };
197
256
  await fs.writeFile(brainstormPath, JSON.stringify(session, null, 2));
198
- if (options.json) {
199
- // JSON 输出供 Skill 解析
200
- const output = {
201
- status: 'brainstorming',
202
- message: '开始头脑风暴',
203
- taskTitle,
204
- questions: questions.map(q => ({
205
- id: q.id,
206
- question: q.question,
207
- header: q.header,
208
- options: q.options,
209
- multiSelect: q.multiSelect
210
- })),
211
- hint: '请逐一回答问题,完成后再调用 --complete'
212
- };
213
- // 如果检测到垂直领域,添加建议
214
- if (domainDetection.isVertical) {
215
- output.suggestResearch = domainDetection.domain;
216
- output.researchHint = `检测到垂直领域「${domainDetection.domain}」,建议先进行领域调研`;
217
- }
218
- console.log(JSON.stringify(output));
257
+ outputNewSession(taskTitle, questions, domainDetection, options.json);
258
+ }
259
+ /**
260
+ * 输出新头脑风暴会话的信息
261
+ */
262
+ function outputNewSession(taskTitle, questions, domainDetection, jsonMode) {
263
+ if (jsonMode) {
264
+ outputNewSessionJson(taskTitle, questions, domainDetection);
219
265
  }
220
266
  else {
221
- console.log('\n🧠 开始头脑风暴...\n');
222
- console.log(`📋 任务: ${taskTitle}\n`);
223
- if (domainDetection.isVertical) {
224
- console.log(`🔍 检测到垂直领域: ${domainDetection.domain}`);
225
- console.log(' 建议使用 /om:research 进行领域调研\n');
226
- }
227
- console.log('需要探索以下问题:');
228
- questions.forEach((q, i) => {
229
- console.log(` ${i + 1}. ${q.question}`);
230
- });
231
- console.log('\n💡 使用 /om:brainstorm 技能进行交互式问答');
267
+ outputNewSessionText(taskTitle, questions, domainDetection);
232
268
  }
233
- });
269
+ }
270
+ /**
271
+ * JSON 模式输出新会话信息
272
+ */
273
+ function outputNewSessionJson(taskTitle, questions, domainDetection) {
274
+ const output = {
275
+ status: 'brainstorming',
276
+ message: '开始头脑风暴',
277
+ taskTitle,
278
+ questions: questions.map(q => ({
279
+ id: q.id,
280
+ question: q.question,
281
+ header: q.header,
282
+ options: q.options,
283
+ multiSelect: q.multiSelect
284
+ })),
285
+ hint: '请逐一回答问题,完成后再调用 --complete'
286
+ };
287
+ if (domainDetection.isVertical) {
288
+ output.suggestResearch = domainDetection.domain;
289
+ output.researchHint = `检测到垂直领域「${domainDetection.domain}」,建议先进行领域调研`;
290
+ }
291
+ console.log(JSON.stringify(output));
292
+ }
293
+ /**
294
+ * 文本模式输出新会话信息
295
+ */
296
+ function outputNewSessionText(taskTitle, questions, domainDetection) {
297
+ console.log('\n🧠 开始头脑风暴...\n');
298
+ console.log(`📋 任务: ${taskTitle}\n`);
299
+ if (domainDetection.isVertical) {
300
+ console.log(`🔍 检测到垂直领域: ${domainDetection.domain}`);
301
+ console.log(' 建议使用 /om:research 进行领域调研\n');
302
+ }
303
+ console.log('需要探索以下问题:');
304
+ questions.forEach((q, i) => {
305
+ console.log(` ${i + 1}. ${q.question}`);
306
+ });
307
+ console.log('\n💡 使用 /om:brainstorm 技能进行交互式问答');
308
+ }
234
309
  /**
235
310
  * 检测是否可能需要领域调研
236
311
  * 不硬编码领域,只判断是否像垂直领域任务
@@ -268,8 +343,24 @@ function detectVerticalDomain(taskContent) {
268
343
  function generateBrainstormQuestions(taskContent, taskTitle) {
269
344
  const questions = [];
270
345
  const content = taskContent.toLowerCase();
271
- // 问题 1: 核心目标
272
- questions.push({
346
+ questions.push(createCoreObjectiveQuestion());
347
+ questions.push(createUserValueQuestion());
348
+ if (content.includes('架构') || content.includes('系统') || content.includes('集成') || content.includes('多个')) {
349
+ questions.push(createComplexityQuestion());
350
+ }
351
+ if (content.includes('技术') || content.includes('框架') || content.includes('库')) {
352
+ questions.push(createTechConstraintsQuestion());
353
+ }
354
+ questions.push(createRisksQuestion());
355
+ questions.push(createAcceptanceQuestion());
356
+ questions.push(createPriorityQuestion());
357
+ questions.push(createQualityQuestion());
358
+ questions.push(createExecutionModeQuestion());
359
+ questions.push(createE2ETestsQuestion());
360
+ return questions;
361
+ }
362
+ function createCoreObjectiveQuestion() {
363
+ return {
273
364
  id: 'core_objective',
274
365
  question: '这个任务的核心目标是什么?想要解决什么问题?',
275
366
  header: '核心目标',
@@ -281,9 +372,10 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
281
372
  ],
282
373
  multiSelect: false,
283
374
  why: '明确核心目标有助于选择正确的实现策略和质量标准'
284
- });
285
- // 问题 2: 用户价值
286
- questions.push({
375
+ };
376
+ }
377
+ function createUserValueQuestion() {
378
+ return {
287
379
  id: 'user_value',
288
380
  question: '这个任务为用户带来什么价值?最终用户是谁?',
289
381
  header: '用户价值',
@@ -295,41 +387,40 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
295
387
  ],
296
388
  multiSelect: false,
297
389
  why: '了解目标用户有助于设计合适的接口和交互方式'
298
- });
299
- // 问题 3: 实现复杂度 - 如果任务内容包含复杂关键词
300
- if (content.includes('架构') || content.includes('系统') || content.includes('集成') || content.includes('多个')) {
301
- questions.push({
302
- id: 'complexity',
303
- question: '这个任务的实现复杂度如何?需要哪些关键组件?',
304
- header: '复杂度',
305
- options: [
306
- { label: '简单', description: '单一功能,少量代码修改' },
307
- { label: '中等', description: '需要多个组件协作,有依赖关系' },
308
- { label: '复杂', description: '涉及架构调整,需要仔细规划' },
309
- { label: '非常复杂', description: '大型重构或新系统,需要分阶段实施' }
310
- ],
311
- multiSelect: false,
312
- why: '复杂度评估有助于决定是否需要分阶段实施和额外的设计审查'
313
- });
314
- }
315
- // 问题 4: 技术约束 - 如果涉及技术选型
316
- if (content.includes('技术') || content.includes('框架') || content.includes('库')) {
317
- questions.push({
318
- id: 'tech_constraints',
319
- question: '有哪些技术约束或偏好?需要使用/避免什么技术?',
320
- header: '技术约束',
321
- options: [
322
- { label: '使用现有技术栈', description: '复用项目已有的技术选择' },
323
- { label: '引入新技术', description: '需要引入新的库或框架' },
324
- { label: '保持技术中立', description: '不引入新依赖,使用原生方案' },
325
- { label: '需要技术调研', description: '技术选型不确定,需要先调研' }
326
- ],
327
- multiSelect: false,
328
- why: '技术约束影响实现方案和后续维护成本'
329
- });
330
- }
331
- // 问题 5: 风险评估
332
- questions.push({
390
+ };
391
+ }
392
+ function createComplexityQuestion() {
393
+ return {
394
+ id: 'complexity',
395
+ question: '这个任务的实现复杂度如何?需要哪些关键组件?',
396
+ header: '复杂度',
397
+ options: [
398
+ { label: '简单', description: '单一功能,少量代码修改' },
399
+ { label: '中等', description: '需要多个组件协作,有依赖关系' },
400
+ { label: '复杂', description: '涉及架构调整,需要仔细规划' },
401
+ { label: '非常复杂', description: '大型重构或新系统,需要分阶段实施' }
402
+ ],
403
+ multiSelect: false,
404
+ why: '复杂度评估有助于决定是否需要分阶段实施和额外的设计审查'
405
+ };
406
+ }
407
+ function createTechConstraintsQuestion() {
408
+ return {
409
+ id: 'tech_constraints',
410
+ question: '有哪些技术约束或偏好?需要使用/避免什么技术?',
411
+ header: '技术约束',
412
+ options: [
413
+ { label: '使用现有技术栈', description: '复用项目已有的技术选择' },
414
+ { label: '引入新技术', description: '需要引入新的库或框架' },
415
+ { label: '保持技术中立', description: '不引入新依赖,使用原生方案' },
416
+ { label: '需要技术调研', description: '技术选型不确定,需要先调研' }
417
+ ],
418
+ multiSelect: false,
419
+ why: '技术约束影响实现方案和后续维护成本'
420
+ };
421
+ }
422
+ function createRisksQuestion() {
423
+ return {
333
424
  id: 'risks',
334
425
  question: '这个任务可能面临哪些风险或挑战?',
335
426
  header: '风险',
@@ -341,9 +432,10 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
341
432
  ],
342
433
  multiSelect: true,
343
434
  why: '识别风险有助于提前规划应对策略'
344
- });
345
- // 问题 6: 验收标准
346
- questions.push({
435
+ };
436
+ }
437
+ function createAcceptanceQuestion() {
438
+ return {
347
439
  id: 'acceptance',
348
440
  question: '如何判断任务完成?有哪些验收标准?',
349
441
  header: '验收标准',
@@ -355,9 +447,10 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
355
447
  ],
356
448
  multiSelect: true,
357
449
  why: '明确的验收标准有助于判断任务完成度'
358
- });
359
- // 问题 7: 实现优先级
360
- questions.push({
450
+ };
451
+ }
452
+ function createPriorityQuestion() {
453
+ return {
361
454
  id: 'priority',
362
455
  question: '这个任务的优先级如何?是否需要 MVP 版本?',
363
456
  header: '优先级',
@@ -369,9 +462,10 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
369
462
  ],
370
463
  multiSelect: false,
371
464
  why: '优先级决定资源分配和实施策略'
372
- });
373
- // 问题 8: 质量级别
374
- questions.push({
465
+ };
466
+ }
467
+ function createQualityQuestion() {
468
+ return {
375
469
  id: 'quality',
376
470
  question: '选择质量门禁级别(决定测试覆盖、Lint、安全扫描等要求)',
377
471
  header: '质量级别',
@@ -382,9 +476,10 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
382
476
  ],
383
477
  multiSelect: false,
384
478
  why: '质量级别影响任务拆分、测试要求和执行时间'
385
- });
386
- // 问题 9: 执行模式
387
- questions.push({
479
+ };
480
+ }
481
+ function createExecutionModeQuestion() {
482
+ return {
388
483
  id: 'execution_mode',
389
484
  question: '选择执行模式(控制 AI 执行过程中的审批节点)',
390
485
  header: '执行模式',
@@ -395,10 +490,10 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
395
490
  ],
396
491
  multiSelect: false,
397
492
  why: '执行模式决定自动化程度和人工干预频率'
398
- });
399
- // 问题 10: E2E 测试(必填)
400
- // E2E 测试是必问问题,由用户在问答中选择是否启用
401
- questions.push({
493
+ };
494
+ }
495
+ function createE2ETestsQuestion() {
496
+ return {
402
497
  id: 'e2e_tests',
403
498
  question: '是否启用端到端 (E2E) 测试?(适用于 Web/Mobile/GUI 项目,耗时较长)',
404
499
  header: 'E2E 测试',
@@ -408,54 +503,57 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
408
503
  ],
409
504
  multiSelect: false,
410
505
  why: 'E2E 测试能验证完整用户流程,但增加执行时间'
411
- });
412
- return questions;
506
+ };
413
507
  }
414
508
  /**
415
509
  * 智能问题生成 — 使用 SmartQuestionAnalyzer + InteractiveQuestionGenerator
416
510
  */
417
511
  async function generateSmartQuestions(taskContent, basePath) {
418
512
  try {
419
- // 1. 解析任务为 ParsedTask
420
- const parser = new task_parser_js_1.TaskParser();
421
- const parsedTask = parser.parse(taskContent);
422
- // 2. 分析项目上下文 + 推断答案
423
- const analyzer = new smart_question_analyzer_js_1.SmartQuestionAnalyzer(basePath);
424
- const analysisResult = await analyzer.analyze(taskContent, parsedTask);
425
- // 3. 映射推断结果为规范 brainstorm ID
426
- const inferenceMap = (0, answer_mapper_js_1.translateAnalyzerInferences)(analysisResult.inferences);
427
- // 4. 创建问题生成器 + 设置推断
428
- const questionGen = new interactive_question_generator_js_1.InteractiveQuestionGenerator();
429
- questionGen.setInferences(inferenceMap);
430
- // 5. 生成基础问题 + 上下文问题
431
- const session = questionGen.startSession(parsedTask);
432
- questionGen.addContextualQuestions(parsedTask, session.questions);
433
- // 6. 转换为 BrainstormQuestion[] 格式
434
- const questions = session.questions
435
- .filter(q => !session.skippedQuestionIds?.includes(q.id)) // 跳过高置信度推断的问题
436
- .sort((a, b) => (a.priority ?? 5) - (b.priority ?? 5))
437
- .map(q => ({
438
- id: q.id,
439
- question: q.question,
440
- header: q.category,
441
- options: (q.options || []).map(o => ({
442
- label: o.label,
443
- description: o.description || ''
444
- })),
445
- multiSelect: q.type === 'multiple',
446
- why: ''
447
- }));
448
- // 7. 追加领域分析问题(底层逻辑思考)
449
- const domainQuestions = generateDomainAnalysisQuestions(taskContent);
450
- questions.push(...domainQuestions);
513
+ const session = await buildSmartQuestionSession(taskContent, basePath);
514
+ const questions = convertToBrainstormQuestions(session);
515
+ questions.push(...generateDomainAnalysisQuestions(taskContent));
451
516
  return questions;
452
517
  }
453
518
  catch (error) {
454
- // Fallback: 如果智能管道出错,使用静态问题
455
519
  console.error(`⚠️ 智能问题生成失败,使用静态问题: ${error instanceof Error ? error.message : error}`);
456
520
  return generateBrainstormQuestions(taskContent, '');
457
521
  }
458
522
  }
523
+ /**
524
+ * 构建智能问题会话:解析任务 → 分析推断 → 生成问题
525
+ */
526
+ async function buildSmartQuestionSession(taskContent, basePath) {
527
+ const parser = new task_parser_js_1.TaskParser();
528
+ const parsedTask = parser.parse(taskContent);
529
+ const analyzer = new smart_question_analyzer_js_1.SmartQuestionAnalyzer(basePath);
530
+ const analysisResult = await analyzer.analyze(taskContent, parsedTask);
531
+ const inferenceMap = (0, answer_mapper_js_1.translateAnalyzerInferences)(analysisResult.inferences);
532
+ const questionGen = new interactive_question_generator_js_1.InteractiveQuestionGenerator();
533
+ questionGen.setInferences(inferenceMap);
534
+ const session = questionGen.startSession(parsedTask);
535
+ questionGen.addContextualQuestions(parsedTask, session.questions);
536
+ return session;
537
+ }
538
+ /**
539
+ * 将智能会话问题转换为 BrainstormQuestion[] 格式
540
+ */
541
+ function convertToBrainstormQuestions(session) {
542
+ return session.questions
543
+ .filter(q => !session.skippedQuestionIds?.includes(q.id))
544
+ .sort((a, b) => (a.priority ?? 5) - (b.priority ?? 5))
545
+ .map(q => ({
546
+ id: q.id,
547
+ question: q.question,
548
+ header: q.category,
549
+ options: (q.options || []).map(o => ({
550
+ label: o.label,
551
+ description: o.description || ''
552
+ })),
553
+ multiSelect: q.type === 'multiple',
554
+ why: ''
555
+ }));
556
+ }
459
557
  /**
460
558
  * 领域分析问题 — 底层逻辑思考
461
559
  *
@@ -467,11 +565,16 @@ async function generateSmartQuestions(taskContent, basePath) {
467
565
  */
468
566
  function generateDomainAnalysisQuestions(taskContent) {
469
567
  const questions = [];
470
- const content = taskContent.toLowerCase();
471
- // ===== 问题 1: 领域实体建模 =====
568
+ questions.push(createDomainEntitiesQuestion(taskContent));
569
+ questions.push(createDataFlowQuestion());
570
+ questions.push(createInvariantsQuestion());
571
+ questions.push(createCoreScenariosQuestion());
572
+ return questions;
573
+ }
574
+ function createDomainEntitiesQuestion(taskContent) {
472
575
  const entityHints = extractEntities(taskContent);
473
576
  if (entityHints.length > 0) {
474
- questions.push({
577
+ return {
475
578
  id: 'domain_entities',
476
579
  question: `从任务描述中识别到以下核心实体,请确认或补充:\n${entityHints.map(e => ` • ${e}`).join('\n')}`,
477
580
  header: '领域实体',
@@ -482,25 +585,24 @@ function generateDomainAnalysisQuestions(taskContent) {
482
585
  ],
483
586
  multiSelect: false,
484
587
  why: '明确领域实体是设计数据模型和 API 的基础'
485
- });
486
- }
487
- else {
488
- questions.push({
489
- id: 'domain_entities',
490
- question: '这个系统涉及哪些核心领域实体?它们之间是什么关系?(如 用户-订单-商品)',
491
- header: '领域实体',
492
- options: [
493
- { label: '单一实体', description: '系统围绕一个核心实体(如用户管理)' },
494
- { label: '2-3 个实体', description: '少量实体间有简单关系(如用户-文章)' },
495
- { label: '多实体复杂关系', description: '多个实体间有多对多等复杂关系' },
496
- { label: '我来说明', description: '在"其他"中描述具体实体' }
497
- ],
498
- multiSelect: false,
499
- why: '明确领域实体是设计数据模型和 API 的基础'
500
- });
588
+ };
501
589
  }
502
- // ===== 问题 2: 数据流分析 =====
503
- questions.push({
590
+ return {
591
+ id: 'domain_entities',
592
+ question: '这个系统涉及哪些核心领域实体?它们之间是什么关系?(如 用户-订单-商品)',
593
+ header: '领域实体',
594
+ options: [
595
+ { label: '单一实体', description: '系统围绕一个核心实体(如用户管理)' },
596
+ { label: '2-3 个实体', description: '少量实体间有简单关系(如用户-文章)' },
597
+ { label: '多实体复杂关系', description: '多个实体间有多对多等复杂关系' },
598
+ { label: '我来说明', description: '在"其他"中描述具体实体' }
599
+ ],
600
+ multiSelect: false,
601
+ why: '明确领域实体是设计数据模型和 API 的基础'
602
+ };
603
+ }
604
+ function createDataFlowQuestion() {
605
+ return {
504
606
  id: 'data_flow',
505
607
  question: '数据在系统中如何流转?(从输入到存储到输出)',
506
608
  header: '数据流',
@@ -513,9 +615,10 @@ function generateDomainAnalysisQuestions(taskContent) {
513
615
  ],
514
616
  multiSelect: false,
515
617
  why: '数据流决定架构选型(请求驱动 vs 事件驱动 vs 流处理)'
516
- });
517
- // ===== 问题 3: 不变量/约束 =====
518
- questions.push({
618
+ };
619
+ }
620
+ function createInvariantsQuestion() {
621
+ return {
519
622
  id: 'invariants',
520
623
  question: '系统中存在哪些关键不变量或业务约束?(什么条件必须永远成立)',
521
624
  header: '不变量',
@@ -527,9 +630,10 @@ function generateDomainAnalysisQuestions(taskContent) {
527
630
  ],
528
631
  multiSelect: true,
529
632
  why: '不变量决定了哪些地方需要加锁、事务、校验和防御性编程'
530
- });
531
- // ===== 问题 4: 核心场景链路 =====
532
- questions.push({
633
+ };
634
+ }
635
+ function createCoreScenariosQuestion() {
636
+ return {
533
637
  id: 'core_scenarios',
534
638
  question: '从用户视角,核心操作链路是什么?(用户会走过的关键路径)',
535
639
  header: '场景链路',
@@ -542,8 +646,7 @@ function generateDomainAnalysisQuestions(taskContent) {
542
646
  ],
543
647
  multiSelect: true,
544
648
  why: '核心场景链路决定了 MVP 的功能范围和优先级排序'
545
- });
546
- return questions;
649
+ };
547
650
  }
548
651
  /**
549
652
  * 从任务描述中提取可能的领域实体