@@ -445,6 +445,33 @@ export async function analyzeCommand(options: AnalyzeOptions): Promise<void> {
445445 logger . info ( '🧠 知识图谱已刷新' ) ;
446446 } catch { }
447447 }
448+
449+ // ── v6.61.0+: Phase 1 完成后自动触发 Phase 2 ──
450+ if ( ! options . phase && ! isTaskLevel && options . iteration ) {
451+ // 检查是否有多个端
452+ const platforms = await parsePlatformList ( ) ;
453+ if ( platforms . length > 1 ) {
454+ logger . info ( '' ) ;
455+ logger . info ( `🔄 Phase 1 已完成,检测到 ${ platforms . length } 个端 (${ platforms . join ( ', ' ) } )` ) ;
456+ logger . info ( '🚀 自动进入 Phase 2:生成各端专属文档...' ) ;
457+ logger . info ( '' ) ;
458+
459+ // 自动输出 Phase 2 的 prompt
460+ const phase2Prompt = await buildMultiDocPrompt ( 'analyze' , {
461+ iteration : options . iteration ,
462+ task : options . task ,
463+ type : options . type ,
464+ scope : options . scope ,
465+ withCode : options . withCode ,
466+ platform : options . platform ,
467+ phase : '2' // ← 关键:设置为 Phase 2
468+ } ) ;
469+ process . stdout . write ( `[SPECCORE_PROMPT]\n${ phase2Prompt } ` ) ;
470+ process . exitCode = 10 ;
471+ return ;
472+ }
473+ }
474+
448475 return ;
449476 }
450477
@@ -1054,9 +1081,17 @@ async function buildMultiDocPrompt(command: string, ctx: { iteration?: string; t
10541081 } ;
10551082 const includeDocs = isTask ? ( DOC_MATRIX [ taskType ] || DOC_MATRIX [ 'feature' ] ) : DOC_MATRIX [ 'feature' ] ;
10561083
1057- // ── v6.60.0+: 一次性生成所有文档(不再分 Phase 1/Phase 2)──
1058- // AI 在一次执行中同时生成 global/ 和 {端}/ 的所有文档
1084+ // ── v6.61.0+: 恢复 Phase 1/Phase 2 分步逻辑,但 CLI 自动触发 Phase 2 ──
1085+ // Phase 1: 生成全局文档(global/REQUIREMENT.md、ANALYSIS.md、DEPS.md 等)
1086+ // Phase 2: 生成各端专属文档({端}/TECH.md、TEST.md、UI_SPEC.md 等)
1087+ const GLOBAL_DOCS = [ 'REQUIREMENT.md' , 'ANALYSIS.md' , 'TECH.md' , 'RISK.md' , 'DEPS.md' , 'REVIEW.md' , 'MONITOR.md' ] ;
1088+ const PLATFORM_DOCS = [ 'TECH.md' , 'TEST.md' , 'UI_SPEC.md' ] ;
10591089 let taskDocs = docs . filter ( ( [ n ] ) => includeDocs . includes ( n ) ) ;
1090+ if ( ctx . phase === '1' ) {
1091+ taskDocs = taskDocs . filter ( ( [ n ] ) => GLOBAL_DOCS . includes ( n ) ) ;
1092+ } else if ( ctx . phase === '2' ) {
1093+ taskDocs = taskDocs . filter ( ( [ n ] ) => PLATFORM_DOCS . includes ( n ) ) ;
1094+ }
10601095
10611096 // ── 任务级文档覆盖:00-specs/ 使用任务级文档集(v6.44.0+) ──
10621097 if ( isTask && ! ctx . phase ) {
@@ -1193,8 +1228,36 @@ async function buildMultiDocPrompt(command: string, ctx: { iteration?: string; t
11931228 prompt += `- 全局跨端文档写入 020-specs/global/(REQUIREMENT.md、DEPS.md、RISK.md 等)\n` ;
11941229 prompt += `- **不要生成**其他端的子目录和文档\n` ;
11951230 }
1196- // v6.60.0+: 一次性生成所有文档(global/ + {端}/)
1197- prompt += `## 要求\n1. Read .speccore/PATTERNS/TEMPLATES/specs/ 下的专业模板(如目录不存在或为空,用你的专业知识自由撰写,绝不允许产出一行垃圾)\n` ;
1231+ // ── v6.61.0+: 阶段专属指令(Phase 2)──
1232+ if ( ctx . phase === '2' ) {
1233+ prompt += `## 要求\n\n` ;
1234+ prompt += `### Step 1: 读取全局上下文(Phase 1 产出)\n` ;
1235+ prompt += `依次 Read 以下文件,建立全局技术架构认知:\n` ;
1236+ prompt += `- Read .speccore/CONSTITUTION.md\n` ;
1237+ prompt += `- Read 020-specs/PLATFORMS.md → 获取端列表\n` ;
1238+ prompt += `- Read 020-specs/global/REQUIREMENT.md → 需求规格\n` ;
1239+ prompt += `- Read 020-specs/global/ANALYSIS.md → 分析报告\n` ;
1240+ prompt += `- Read 020-specs/global/TECH.md → 整体技术架构\n` ;
1241+ prompt += `- Read 020-specs/global/RISK.md、DEPS.md、REVIEW.md、MONITOR.md(如存在)\n\n` ;
1242+ prompt += `### Step 2: 为每个端撰写专属文档\n` ;
1243+ prompt += `根据全局上下文,为 PLATFORMS.md 中的**每个端**分别撰写:\n` ;
1244+ prompt += `- **{端}/TECH.md**:该端专属技术方案(必须对齐 global/TECH.md 架构)\n` ;
1245+ prompt += ` - ⚠️ **必须包含「业务-代码映射」章节**:在 TECH.md 末尾添加表格,列出本端涉及的业务模块及其对应的代码实体(文件/表/API/组件等),关系类型由你根据技术栈自主决定(如 api_controller、uses_table、page、component、route、middleware、interceptor、gateway 等)\n` ;
1246+ prompt += ` - 表格格式:| 业务模块 | 代码实体 | 关系类型 | 说明 |\n` ;
1247+ prompt += ` - 示例:| 会议室档案 | backend/RoomController.java | api_controller | REST 控制器 |\n` ;
1248+ prompt += ` - 示例:| 会议室档案 | admin-web/src/pages/RoomList.vue | page | 列表页 |\n` ;
1249+ prompt += `- **{端}/TEST.md**:该端专属测试计划\n` ;
1250+ prompt += `- **{端}/UI_SPEC.md**:该端专属 UI 规格(仅前端端需要)\n\n` ;
1251+ prompt += `### Step 3: 一致性检查\n` ;
1252+ prompt += `- 各端 TECH.md 的技术选型必须与 global/TECH.md 一致\n` ;
1253+ prompt += `- UI_SPEC.md 的字段映射必须与后端 API 响应字段一一对应\n` ;
1254+ prompt += `- TEST.md 必须覆盖 REQUIREMENT.md 中该端的验收标准\n\n` ;
1255+ prompt += `### 写入方式\n` ;
1256+ prompt += `逐端写入,每个端一次 --apply 调用:\n` ;
1257+ prompt += `speccore analyze --apply '{"TECH.md":"...","TEST.md":"...","UI_SPEC.md":"..."}' -I ${ iter } --platform {端名}\n\n` ;
1258+ } else {
1259+ // v6.61.0+: 一次性生成所有文档(global/ + {端}/)
1260+ prompt += `## 要求\n1. Read .speccore/PATTERNS/TEMPLATES/specs/ 下的专业模板(如目录不存在或为空,用你的专业知识自由撰写,绝不允许产出一行垃圾)\n` ;
11981261 const templateMap : Record < string , string > = {
11991262 'ANALYSIS.md' : 'ANALYSIS-template.md' , 'TECH.md' : 'TECH-template.md' , 'TEST.md' : 'TEST-template.md' ,
12001263 'REVIEW.md' : 'REVIEW-template.md' , 'RISK.md' : 'RISK-template.md' , 'DEPS.md' : 'DEPS-template.md' ,
@@ -1319,6 +1382,7 @@ async function buildMultiDocPrompt(command: string, ctx: { iteration?: string; t
13191382 prompt += `- **{端}/MONITOR.md**:该端专属监控指标\n` ;
13201383 prompt += `- **{端}/UI_SPEC.md**:前端端专属 UI 规格,字段映射必须与后端 API 响应字段一一对应\n` ;
13211384 prompt += `- 分析完成后会自动生成 QUALITY_AUDIT.md 质量报告,检查各端内容是否完整\n` ;
1385+ }
13221386 // 步骤 2-7 已在上面的 phase 分支中处理
13231387 const taskFlag = isTask && ctx . task ? ` --task ${ ctx . task } ` : '' ;
13241388 const platformFlag = ctx . platform ? ` --platform ${ ctx . platform } ` : '' ;
0 commit comments