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.
- package/README.md +25 -11
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/about.d.ts.map +1 -1
- package/dist/commands/about.js +4 -3
- package/dist/commands/about.js.map +1 -1
- package/dist/commands/analyze.js +16 -11
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +5 -4
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/change.js +30 -7
- package/dist/commands/change.js.map +1 -1
- package/dist/commands/context.js +3 -3
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +2 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/dev.js +5 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diff.js +2 -2
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doc2spec.js +4 -4
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/done.js +2 -2
- package/dist/commands/done.js.map +1 -1
- package/dist/commands/execute.js +29 -26
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/handover.js +1 -1
- package/dist/commands/handover.js.map +1 -1
- package/dist/commands/help.js +3 -2
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/import.js +1 -1
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +97 -18
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/iteration/create.d.ts.map +1 -1
- package/dist/commands/iteration/create.js +69 -4
- package/dist/commands/iteration/create.js.map +1 -1
- package/dist/commands/iteration/split.d.ts.map +1 -1
- package/dist/commands/iteration/split.js +111 -102
- package/dist/commands/iteration/split.js.map +1 -1
- package/dist/commands/iteration-from-global.js +8 -8
- package/dist/commands/iteration-from-global.js.map +1 -1
- package/dist/commands/lifecycle.js +3 -3
- package/dist/commands/lifecycle.js.map +1 -1
- package/dist/commands/merge-check.js +1 -1
- package/dist/commands/merge-check.js.map +1 -1
- package/dist/commands/pattern.js +1 -1
- package/dist/commands/pattern.js.map +1 -1
- package/dist/commands/plan.js +2 -1
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/retro.d.ts.map +1 -1
- package/dist/commands/retro.js +2 -1
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/status-panel.d.ts.map +1 -1
- package/dist/commands/status-panel.js +14 -12
- package/dist/commands/status-panel.js.map +1 -1
- package/dist/commands/sync.js +6 -6
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/task/new.js +31 -16
- package/dist/commands/task/new.js.map +1 -1
- package/dist/commands/trace.js +3 -3
- package/dist/commands/trace.js.map +1 -1
- package/dist/commands/welcome.js +2 -1
- package/dist/commands/welcome.js.map +1 -1
- package/dist/core/analyze-engine.js +5 -5
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-engine.js +1 -1
- package/dist/core/ask-engine.js.map +1 -1
- package/dist/core/name-validator.js +1 -1
- package/dist/core/name-validator.js.map +1 -1
- package/dist/core/next-steps.js +2 -2
- package/dist/core/next-steps.js.map +1 -1
- package/dist/core/reverse-sync.js +2 -2
- package/dist/core/reverse-sync.js.map +1 -1
- package/dist/core/risk-scorer.js +2 -2
- package/dist/core/risk-scorer.js.map +1 -1
- package/dist/core/state.js +1 -1
- package/dist/core/state.js.map +1 -1
- package/dist/core/validator.js +9 -9
- package/dist/core/validator.js.map +1 -1
- 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', '
|
|
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'
|
|
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":";;AAaA,
|
|
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,
|
|
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
|
-
//
|
|
404
|
-
await (0, fs_extra_1.
|
|
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, '
|
|
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, '
|
|
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
|
-
|
|
459
|
-
|
|
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
|
-
|
|
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
|
-
| ${
|
|
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
|
-
|
|
|
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
|
-
|
|
|
497
|
-
|
|
|
498
|
-
|
|
|
499
|
-
|
|
|
500
|
-
|
|
|
501
|
-
|
|
|
502
|
-
|
|
|
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
|
-
//
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
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
|
-
|
|
514
|
-
await (0, fs_extra_1.
|
|
515
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
516
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
517
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
518
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
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
|
-
|
|
522
|
-
await (0, fs_extra_1.
|
|
523
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
524
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
525
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
526
|
-
|
|
527
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
528
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
529
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
530
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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())) {
|