speccore 5.70.0 → 5.71.0

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.
Files changed (84) hide show
  1. package/README.md +25 -11
  2. package/dist/cli.js +2 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/about.d.ts.map +1 -1
  5. package/dist/commands/about.js +4 -3
  6. package/dist/commands/about.js.map +1 -1
  7. package/dist/commands/analyze.js +16 -11
  8. package/dist/commands/analyze.js.map +1 -1
  9. package/dist/commands/ask.d.ts.map +1 -1
  10. package/dist/commands/ask.js +5 -4
  11. package/dist/commands/ask.js.map +1 -1
  12. package/dist/commands/change.js +30 -7
  13. package/dist/commands/change.js.map +1 -1
  14. package/dist/commands/context.js +3 -3
  15. package/dist/commands/context.js.map +1 -1
  16. package/dist/commands/dashboard.d.ts.map +1 -1
  17. package/dist/commands/dashboard.js +2 -1
  18. package/dist/commands/dashboard.js.map +1 -1
  19. package/dist/commands/dev.js +5 -4
  20. package/dist/commands/dev.js.map +1 -1
  21. package/dist/commands/diff.js +2 -2
  22. package/dist/commands/diff.js.map +1 -1
  23. package/dist/commands/doc2spec.js +4 -4
  24. package/dist/commands/doc2spec.js.map +1 -1
  25. package/dist/commands/done.js +2 -2
  26. package/dist/commands/done.js.map +1 -1
  27. package/dist/commands/execute.js +29 -26
  28. package/dist/commands/execute.js.map +1 -1
  29. package/dist/commands/handover.js +1 -1
  30. package/dist/commands/handover.js.map +1 -1
  31. package/dist/commands/help.js +3 -2
  32. package/dist/commands/help.js.map +1 -1
  33. package/dist/commands/import.js +1 -1
  34. package/dist/commands/import.js.map +1 -1
  35. package/dist/commands/init.d.ts.map +1 -1
  36. package/dist/commands/init.js +97 -18
  37. package/dist/commands/init.js.map +1 -1
  38. package/dist/commands/iteration/create.d.ts.map +1 -1
  39. package/dist/commands/iteration/create.js +69 -4
  40. package/dist/commands/iteration/create.js.map +1 -1
  41. package/dist/commands/iteration/split.d.ts.map +1 -1
  42. package/dist/commands/iteration/split.js +111 -102
  43. package/dist/commands/iteration/split.js.map +1 -1
  44. package/dist/commands/iteration-from-global.js +8 -8
  45. package/dist/commands/iteration-from-global.js.map +1 -1
  46. package/dist/commands/lifecycle.js +3 -3
  47. package/dist/commands/lifecycle.js.map +1 -1
  48. package/dist/commands/merge-check.js +1 -1
  49. package/dist/commands/merge-check.js.map +1 -1
  50. package/dist/commands/pattern.js +1 -1
  51. package/dist/commands/pattern.js.map +1 -1
  52. package/dist/commands/plan.js +2 -1
  53. package/dist/commands/plan.js.map +1 -1
  54. package/dist/commands/retro.d.ts.map +1 -1
  55. package/dist/commands/retro.js +2 -1
  56. package/dist/commands/retro.js.map +1 -1
  57. package/dist/commands/status-panel.d.ts.map +1 -1
  58. package/dist/commands/status-panel.js +14 -12
  59. package/dist/commands/status-panel.js.map +1 -1
  60. package/dist/commands/sync.js +6 -6
  61. package/dist/commands/sync.js.map +1 -1
  62. package/dist/commands/task/new.js +31 -16
  63. package/dist/commands/task/new.js.map +1 -1
  64. package/dist/commands/trace.js +3 -3
  65. package/dist/commands/trace.js.map +1 -1
  66. package/dist/commands/welcome.js +2 -1
  67. package/dist/commands/welcome.js.map +1 -1
  68. package/dist/core/analyze-engine.js +5 -5
  69. package/dist/core/analyze-engine.js.map +1 -1
  70. package/dist/core/ask-engine.js +1 -1
  71. package/dist/core/ask-engine.js.map +1 -1
  72. package/dist/core/name-validator.js +1 -1
  73. package/dist/core/name-validator.js.map +1 -1
  74. package/dist/core/next-steps.js +2 -2
  75. package/dist/core/next-steps.js.map +1 -1
  76. package/dist/core/reverse-sync.js +2 -2
  77. package/dist/core/reverse-sync.js.map +1 -1
  78. package/dist/core/risk-scorer.js +2 -2
  79. package/dist/core/risk-scorer.js.map +1 -1
  80. package/dist/core/state.js +1 -1
  81. package/dist/core/state.js.map +1 -1
  82. package/dist/core/validator.js +9 -9
  83. package/dist/core/validator.js.map +1 -1
  84. package/package.json +1 -1
@@ -27,12 +27,14 @@ async function iterationCreateCommand(options) {
27
27
  // Create directory structure
28
28
  await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '000-overview'));
29
29
  await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'sources'));
30
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'materials'));
31
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'prototypes'));
32
30
  await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'converted'));
33
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'images'));
31
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'features'));
32
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'assets', 'extracted'));
33
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'assets', 'prototypes'));
34
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'assets', 'designs'));
35
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '010-requirements', 'assets', 'screenshots'));
34
36
  await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '020-specs'));
35
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '030-tasks', 'plans'));
37
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(iterationDir, '030-tasks'));
36
38
  // Create default files
37
39
  await createIterationFiles(iterationDir, fullName, options);
38
40
  // Update ITERATIONS index
@@ -57,6 +59,69 @@ async function iterationCreateCommand(options) {
57
59
  }
58
60
  }
59
61
  async function createIterationFiles(iterationDir, fullName, options) {
62
+ // 010-requirements/README.md — 目录规范说明
63
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(iterationDir, '010-requirements', 'README.md'), `# 需求文档目录规范
64
+
65
+ > 本目录存放本期迭代的全部需求相关文档与素材
66
+
67
+ ## 目录结构
68
+
69
+ \`\`\`
70
+ 010-requirements/
71
+ ├── README.md ← 本文件
72
+ ├── INDEX.md ← 需求文档索引(自动生成/维护)
73
+ ├── sources/ ← [只读] 原始 PRD/Word/PDF,任何人不得修改
74
+ │ └── README.md
75
+ ├── converted/ ← [自动生成] doc2spec 转换后的 Markdown 规格
76
+ │ └── *.md
77
+ ├── features/ ← [手动维护] 按功能模块组织的需求补充
78
+ │ └── {feature}/
79
+ │ └── README.md
80
+ └── assets/
81
+ ├── extracted/ ← doc2spec 提取的图片/媒体文件
82
+ ├── prototypes/ ← 产品原型(Axure/Figma/墨刀等)
83
+ ├── designs/ ← UI 设计稿
84
+ └── screenshots/ ← 参考截图/竞品分析
85
+ \`\`\`
86
+
87
+ ## 使用规范
88
+
89
+ 1. **sources/** — 放产品提供的原始文档,不要直接编辑
90
+ 2. **converted/** — doc2spec 命令自动输出转换后的 MD,人工不修改
91
+ 3. **features/** — 按功能模块手动补充需求细节,每个模块一个子目录
92
+ 4. **assets/** — 所有图片/原型/设计稿统一放这里,按子目录分类
93
+
94
+ ## analyze 读取顺序
95
+
96
+ AI 分析需求时默认按以下优先级读取:
97
+
98
+ 1. \`INDEX.md\` — 了解需求全貌和文件清单
99
+ 2. \`converted/*.md\` — doc2spec 转换后的规格(核心)
100
+ 3. \`features/*/README.md\` — 功能级补充需求
101
+ 4. \`assets/prototypes/\` 和 \`designs/\` — 原型和设计稿参考
102
+ `);
103
+ // 010-requirements/INDEX.md — 需求文档索引
104
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(iterationDir, '010-requirements', 'INDEX.md'), `# 本期需求文档索引
105
+
106
+ > 迭代:${fullName}
107
+ > 更新:${new Date().toISOString().split('T')[0]}
108
+
109
+ ## 文档清单
110
+
111
+ | 类型 | 路径 | 状态 | 说明 |
112
+ | :--- | :--- | :--- | :--- |
113
+ | 原始文档 | sources/ | 待补充 | 放 PRD/Word/PDF |
114
+ | 转换规格 | converted/ | 待生成 | doc2spec 输出 |
115
+ | 功能补充 | features/ | 待补充 | 按模块组织 |
116
+ | 原型素材 | assets/prototypes/ | 待补充 | 产品原型 |
117
+ | 设计素材 | assets/designs/ | 待补充 | UI 设计稿 |
118
+
119
+ ## 分析配置
120
+
121
+ - **默认读取**:converted/*.md + features/*/README.md
122
+ - **指定文档**:speccore analyze -I ${options.name} --req converted/login.md
123
+ - **全部文档**:speccore analyze -I ${options.name} --scope all
124
+ `);
60
125
  // REQUIREMENT.md
61
126
  await (0, fs_extra_1.writeFile)((0, path_1.join)(iterationDir, '020-specs', 'REQUIREMENT.md'), `# 本期需求文档
62
127
 
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/iteration/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/iteration/create.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/iteration/split.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAkBD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+QzF"}
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/iteration/split.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAkBD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgRzF"}
@@ -56,10 +56,11 @@ async function iterationSplitCommand(options) {
56
56
  for (const task of tasks) {
57
57
  const taskDir = (0, path_1.join)(iterDir, task.id || `Task-${String(tasks.indexOf(task) + 1).padStart(3, '0')}`);
58
58
  await (0, fs_extra_1.ensureDir)(taskDir);
59
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '00-specs'));
59
60
  if (task.req)
60
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'REQ.md'), task.req);
61
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'REQ.md'), task.req);
61
62
  if (task.tech)
62
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'TECH.md'), task.tech);
63
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'TECH.md'), task.tech);
63
64
  logger_1.logger.info(` ✅ 创建: ${taskDir}`);
64
65
  }
65
66
  }
@@ -365,57 +366,26 @@ function filterTemplateNoise(sections) {
365
366
  }
366
367
  async function createTaskFromSection(iterationDir, taskId, section, allPlatforms) {
367
368
  const taskDir = (0, path_1.join)(iterationDir, '030-tasks', taskId);
368
- // 如果 section 有指定平台则只创建该平台,否则创建全部平台
369
369
  const taskPlatforms = section.platform ? [section.platform] : allPlatforms;
370
+ const complexity = section._complexity || { estimatedHours: 2, priority: 'medium', complexity: 'medium', apiCount: 0, dbCount: 0, pageCount: 0, wordCount: 0 };
371
+ const owner = section._owner || '未分配';
372
+ const today = new Date().toISOString().split('T')[0];
373
+ // ── 1. 元信息目录 ──
374
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '.meta'));
375
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.meta', 'type'), 'feature');
376
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.meta', 'status'), 'todo');
377
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.meta', 'owner'), owner);
378
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.meta', 'created-at'), today);
379
+ // ── 2. 共享契约 ──
370
380
  await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '_shared'));
371
- // Create per-platform directories: backend services under backend/, frontend under frontend/
372
- for (const platform of taskPlatforms) {
373
- if (platform.startsWith('后台') || platform === 'backend') {
374
- // Backend service: e.g., 后台管理端 → backend/管理端
375
- const service = platform.replace(/^后台/, '').trim() || 'default';
376
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, 'backend', service || platform));
377
- }
378
- else {
379
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, 'frontend', platform));
380
- }
381
- }
382
- // Always create a common backend directory for shared backend specs
383
- if (!taskPlatforms.some(p => p.startsWith('后台'))) {
384
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, 'backend'));
385
- }
386
- // Write task type
387
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.task-type'), 'feature');
388
- // Write TEST.md — auto-generated test outline
389
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'TEST.md'), generateTestOutline(section));
390
- // Write REVIEW.md — auto-generated code review checklist
391
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'REVIEW.md'), generateReviewChecklist(section));
392
- // Write SCHEMA.md — DB schema template (only if DB content detected)
393
- if (section.content.match(/数据库|数据表|表结构|DDL|ALTER|建表|索引/)) {
394
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'SCHEMA.md'), generateSchemaTemplate(section));
395
- }
396
- // Write DEPLOY.md — deployment checklist
397
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'DEPLOY.md'), generateDeployChecklist(section));
398
- // Generate API_CONTRACT.yaml in _shared/
399
381
  const contractYaml = generateApiContract(section);
400
382
  if (contractYaml) {
401
383
  await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '_shared', 'API_CONTRACT.yaml'), contractYaml);
402
384
  }
403
- // Generate ERROR_CODES.md
404
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'ERROR_CODES.md'), generateErrorCodes(section));
405
- // Generate ADR.md (only if tech stack detected)
406
- const adr = generateAdr(section);
407
- if (adr) {
408
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'ADR.md'), adr);
409
- }
410
- // Generate RISK.md — risk assessment + rollback
411
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'RISK.md'), generateRiskTemplate(section));
412
- // Generate DEPS.md — dependency manifest
413
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'DEPS.md'), generateDepsTemplate(section));
414
- // Generate MONITOR.md — monitoring points
415
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'MONITOR.md'), generateMonitorTemplate(section));
416
- // Write REQ.md(含自动生成的 AC)
385
+ // ── 3. 执行前核心规格 00-specs/ ──
386
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '00-specs'));
417
387
  const acItems = generateAcceptanceCriteria(section);
418
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'REQ.md'), `# ${section.name}
388
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'REQ.md'), `# ${section.name}
419
389
 
420
390
  ## 需求描述
421
391
 
@@ -425,10 +395,9 @@ ${section.content}
425
395
 
426
396
  ${acItems}
427
397
  `);
428
- // Write TECH.md(根据 section 内容注入框架)
429
398
  const apiLines = section.content.split('\n').filter(l => l.includes('| GET') || l.includes('| POST') || l.includes('| PUT') || l.includes('| DELETE') || l.includes('| PATCH'));
430
399
  const apiDesc = apiLines.length > 0 ? apiLines.map(l => `- ${l.trim()}`).join('\n') : '- 待补充(从 REQ.md 提取接口列表)';
431
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'TECH.md'), `# ${section.name} - 技术方案
400
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'TECH.md'), `# ${section.name} - 技术方案
432
401
 
433
402
  > ⚠️ 本文档由 split 自动生成框架,AI 执行时会自动填充。
434
403
 
@@ -455,21 +424,10 @@ ${apiDesc}
455
424
  - 接口测试覆盖正常/异常/边界
456
425
  - 自动化测试通过后方可提 PR
457
426
  `);
458
- // Write API_CONTRACT.yaml if APIs detected
459
- if (apiLines.length > 0) {
460
- const contracts = apiLines.map(l => {
461
- const parts = l.split('|').map(p => p.trim()).filter(Boolean);
462
- const method = (parts[0] || 'GET').toUpperCase();
463
- const path = parts[1] || '/api/unknown';
464
- const desc = parts[2] || path;
465
- return ` ${path}:\n ${method}:\n summary: "${desc}"\n description: "<!-- AI-FILL -->"`;
466
- }).join('\n');
467
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'API_CONTRACT.yaml'), `# ${section.name} - API Contract\n# Auto-generated from split\n\npaths:\n${contracts}\n`);
427
+ if (section.content.match(/数据库|数据表|表结构|DDL|ALTER|建表|索引/)) {
428
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'SCHEMA.md'), generateSchemaTemplate(section));
468
429
  }
469
- // Write TASK.md
470
- const complexity = section._complexity || { estimatedHours: 2, priority: 'medium', complexity: 'medium', apiCount: 0, dbCount: 0, pageCount: 0, wordCount: 0 };
471
- const owner = section._owner || '未分配';
472
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', 'TASK.md'), `# ${section.name}
430
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'TASK.md'), `# ${section.name}
473
431
 
474
432
  ## 任务信息
475
433
  - 类型: feature
@@ -482,54 +440,105 @@ ${apiDesc}
482
440
  ## 变更履历
483
441
  | 时间 | 变更内容 | 变更人 |
484
442
  | :--- | :--- | :--- |
485
- | ${new Date().toISOString().split('T')[0]} | 创建任务 | CLI |
443
+ | ${today} | 创建任务 | CLI |
486
444
 
487
- ## 产出物
445
+ ## 产出物清单
488
446
  | 产出物 | 状态 | 路径 |
489
447
  | :--- | :--- | :--- |
490
- | REQ.md | ✅ | ./REQ.md |
491
- | TECH.md | ✅ | ./TECH.md |
492
- | TASK.md | ✅ | ./TASK.md |
493
- | TEST.md | | ./TEST.md |
494
- | REVIEW.md | ✅ | ./REVIEW.md |
448
+ | REQ.md | ✅ | ./00-specs/REQ.md |
449
+ | TECH.md | ✅ | ./00-specs/TECH.md |
450
+ | TASK.md | ✅ | ./00-specs/TASK.md |
451
+ | SCHEMA.md | | ./00-specs/SCHEMA.md |
495
452
  | API_CONTRACT.yaml | ✅ | ./_shared/API_CONTRACT.yaml |
496
- | DEPLOY.md | | ./DEPLOY.md |
497
- | SCHEMA.md | | ./SCHEMA.md |
498
- | ERROR_CODES.md | | ./ERROR_CODES.md |
499
- | ADR.md | | ./ADR.md |
500
- | RISK.md | | ./RISK.md |
501
- | DEPS.md | | ./DEPS.md |
502
- | MONITOR.md | | ./MONITOR.md |
453
+ | TEST.md | | ./99-artifacts/TEST.md |
454
+ | REVIEW.md | | ./99-artifacts/REVIEW.md |
455
+ | DEPLOY.md | | ./99-artifacts/DEPLOY.md |
456
+ | ERROR_CODES.md | | ./99-artifacts/ERROR_CODES.md |
457
+ | ADR.md | | ./99-artifacts/ADR.md |
458
+ | RISK.md | | ./99-artifacts/RISK.md |
459
+ | DEPS.md | | ./99-artifacts/DEPS.md |
460
+ | MONITOR.md | ⏳ | ./99-artifacts/MONITOR.md |
461
+ | CHANGELOG.md | ✅ | ./00-specs/CHANGELOG.md |
462
+ `);
463
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '00-specs', 'CHANGELOG.md'), `# ${section.name} - 变更记录
464
+
465
+ | 时间 | 版本 | 变更内容 | 变更人 |
466
+ | :--- | :--- | :--- | :--- |
467
+ | ${today} | v1.0 | 初始创建 | CLI |
503
468
  `);
504
- // Copy to each platform directory (backend services + frontend platforms)
505
- const reqContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, 'backend', 'REQ.md'), 'utf-8');
506
- const techContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, 'backend', 'TECH.md'), 'utf-8');
507
- const taskContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, 'backend', 'TASK.md'), 'utf-8');
508
- const testContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, 'backend', 'TEST.md'), 'utf-8');
509
- const reviewContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, 'backend', 'REVIEW.md'), 'utf-8');
469
+ // API_CONTRACT.yaml(按接口)统一放 _shared/
470
+ if (apiLines.length > 0) {
471
+ const contracts = apiLines.map(l => {
472
+ const parts = l.split('|').map(p => p.trim()).filter(Boolean);
473
+ const method = (parts[0] || 'GET').toUpperCase();
474
+ const path = parts[1] || '/api/unknown';
475
+ const desc = parts[2] || path;
476
+ return ` ${path}:\n ${method}:\n summary: "${desc}"\n description: "<!-- AI-FILL -->"`;
477
+ }).join('\n');
478
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '_shared', 'API_CONTRACT.yaml'), `# ${section.name} - API Contract\n# Auto-generated from split\n\npaths:\n${contracts}\n`);
479
+ }
480
+ // ── 4. 执行产出 99-artifacts/ ──
481
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '99-artifacts'));
482
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'TEST.md'), generateTestOutline(section));
483
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'REVIEW.md'), generateReviewChecklist(section));
484
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'DEPLOY.md'), generateDeployChecklist(section));
485
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'ERROR_CODES.md'), generateErrorCodes(section));
486
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'RISK.md'), generateRiskTemplate(section));
487
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'DEPS.md'), generateDepsTemplate(section));
488
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'MONITOR.md'), generateMonitorTemplate(section));
489
+ const adr = generateAdr(section);
490
+ if (adr) {
491
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '99-artifacts', 'ADR.md'), adr);
492
+ }
493
+ // ── 5. 实现目录 10-backend/ 20-20-frontend/ ──
494
+ for (const platform of taskPlatforms) {
495
+ if (platform.startsWith('后台') || platform === 'backend') {
496
+ const service = platform.replace(/^后台/, '').trim() || 'default';
497
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '10-backend', service || platform, 'src'));
498
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '10-backend', service || platform, 'tests'));
499
+ }
500
+ else {
501
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '20-frontend', platform, 'src'));
502
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '20-frontend', platform, 'tests'));
503
+ }
504
+ }
505
+ if (!taskPlatforms.some(p => p.startsWith('后台'))) {
506
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '10-backend', 'src'));
507
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, '10-backend', 'tests'));
508
+ }
509
+ // ── 6. 平台目录内复制核心规格 ──
510
+ const reqContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, '00-specs', 'REQ.md'), 'utf-8');
511
+ const techContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, '00-specs', 'TECH.md'), 'utf-8');
512
+ const taskContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, '00-specs', 'TASK.md'), 'utf-8');
513
+ const testContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, '99-artifacts', 'TEST.md'), 'utf-8');
514
+ const reviewContent = await (0, fs_extra_1.readFile)((0, path_1.join)(taskDir, '99-artifacts', 'REVIEW.md'), 'utf-8');
510
515
  for (const platform of taskPlatforms) {
511
516
  if (platform.startsWith('后台') || platform === 'backend') {
512
517
  const service = platform.replace(/^后台/, '').trim() || platform;
513
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, 'backend', service));
514
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', service, 'REQ.md'), reqContent);
515
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', service, 'TECH.md'), techContent);
516
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', service, 'TASK.md'), taskContent);
517
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', service, 'TEST.md'), testContent);
518
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'backend', service, 'REVIEW.md'), reviewContent);
518
+ const svcDir = (0, path_1.join)(taskDir, '10-backend', service);
519
+ await (0, fs_extra_1.ensureDir)(svcDir);
520
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(svcDir, 'REQ.md'), reqContent);
521
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(svcDir, 'TECH.md'), techContent);
522
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(svcDir, 'TASK.md'), taskContent);
523
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(svcDir, 'TEST.md'), testContent);
524
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(svcDir, 'REVIEW.md'), reviewContent);
519
525
  }
520
526
  else {
521
- await (0, fs_extra_1.ensureDir)((0, path_1.join)(taskDir, 'frontend', platform));
522
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'REQ.md'), reqContent);
523
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'TASK.md'), taskContent);
524
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'TEST.md'), testContent);
525
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'REVIEW.md'), reviewContent);
526
- // 前端专属文件
527
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'COMPONENT_TREE.md'), generateComponentTree(section, platform));
528
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'ROUTES.md'), generateRoutesDoc(section, platform));
529
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'STATE.md'), generateStateDoc(section, platform));
530
- await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, 'frontend', platform, 'STYLE_GUIDE.md'), generateStyleGuide(section, platform));
527
+ const feDir = (0, path_1.join)(taskDir, '20-frontend', platform);
528
+ await (0, fs_extra_1.ensureDir)(feDir);
529
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'REQ.md'), reqContent);
530
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'TASK.md'), taskContent);
531
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'TEST.md'), testContent);
532
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'REVIEW.md'), reviewContent);
533
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'README.md'), `# ${section.name} - ${platform}\n\n前端实现目录。\n`);
534
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'COMPONENT_TREE.md'), generateComponentTree(section, platform));
535
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'ROUTES.md'), generateRoutesDoc(section, platform));
536
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'STATE.md'), generateStateDoc(section, platform));
537
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(feDir, 'STYLE_GUIDE.md'), generateStyleGuide(section, platform));
531
538
  }
532
539
  }
540
+ // ── 7. 问题追踪 ──
541
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.issues.md'), `# ${section.name} - 问题追踪\n\n> 执行过程中发现的问题记录于此。\n\n`);
533
542
  }
534
543
  async function updateProjectGraph(iterationDir, sections) {
535
544
  const graphPath = (0, path_1.join)(iterationDir, '000-overview', 'PROJECT_GRAPH.md');
@@ -677,7 +686,7 @@ async function strictSplitPreview(sections, platforms, iterationDir) {
677
686
  const taskId = `Task-${String(i + 1).padStart(3, '0')}`;
678
687
  // Determine target directory
679
688
  const target = s.platform
680
- ? (s.platform.startsWith('后台') ? `backend/${s.platform.replace(/^后台/, '')}` : `frontend/${s.platform}`)
689
+ ? (s.platform.startsWith('后台') ? `backend/${s.platform.replace(/^后台/, '')}` : `20-frontend/${s.platform}`)
681
690
  : platforms.join(' + ');
682
691
  logger_1.logger.info(`── ${taskId}: ${s.name} ──`);
683
692
  logger_1.logger.info(` 端: ${target}`);
@@ -757,7 +766,7 @@ async function generateImpactGraph(iterationDir, sections, platforms) {
757
766
  const taskDir = (0, path_1.join)(iterationDir, '030-tasks', taskId);
758
767
  if (await (0, fs_extra_1.pathExists)(taskDir)) {
759
768
  // 生成风险报告并嵌入 TASK.md
760
- const taskMdPath = (0, path_1.join)(taskDir, 'backend', 'TASK.md');
769
+ const taskMdPath = (0, path_1.join)(taskDir, '00-specs', 'TASK.md');
761
770
  const riskReport = (0, risk_scorer_1.generateRiskReport)(risk);
762
771
  await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.risk'), riskReport);
763
772
  if (await (0, fs_extra_1.pathExists)(taskMdPath)) {
@@ -768,7 +777,7 @@ async function generateImpactGraph(iterationDir, sections, platforms) {
768
777
  }
769
778
  }
770
779
  // Inject risk section into TASK.md if it exists
771
- const riskTaskPath = (0, path_1.join)(taskDir, 'backend', 'TASK.md');
780
+ const riskTaskPath = (0, path_1.join)(taskDir, '00-specs', 'TASK.md');
772
781
  if (await (0, fs_extra_1.pathExists)(riskTaskPath)) {
773
782
  let taskMd = await (0, fs_extra_1.readFile)(riskTaskPath, 'utf-8');
774
783
  if (!taskMd.includes('## 风险评估')) {
@@ -915,7 +924,7 @@ async function injectTechFromAnalysis(iterationDir, taskDir, sectionName) {
915
924
  const depSection = analysis.match(/### 接口依赖[\s\S]*?(?=###|$)/);
916
925
  if (!techSection && !dbSection && !depSection)
917
926
  return;
918
- const techPath = (0, path_1.join)(taskDir, 'backend', 'TECH.md');
927
+ const techPath = (0, path_1.join)(taskDir, '00-specs', 'TECH.md');
919
928
  let tech = await (0, fs_extra_1.readFile)(techPath, 'utf-8');
920
929
  const note = '\n\n> 以下内容自动从 ANALYSIS.md 注入\n\n';
921
930
  if (techSection && !tech.includes(techSection[0].trim())) {