speccore 8.3.285 → 8.3.295
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/.agents/skills/spec-run/SKILL.md +16 -0
- package/.agents/skills/spec-task-create/SKILL.md +15 -0
- package/.agents/skills/spec-unitize/SKILL.md +16 -0
- package/README.en.md +16 -3
- package/README.md +23 -8
- package/dist/cli.js +59 -12
- package/dist/cli.js.map +1 -1
- package/dist/commands/about.d.ts.map +1 -1
- package/dist/commands/about.js +5 -0
- package/dist/commands/about.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +77 -5
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/ask.js +2 -2
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/code-index.d.ts.map +1 -1
- package/dist/commands/code-index.js +20 -9
- package/dist/commands/code-index.js.map +1 -1
- package/dist/commands/doc2spec.js +32 -60
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/execute.d.ts +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +15 -1
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/help.js +14 -5
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +14 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/iteration/taskify.d.ts.map +1 -1
- package/dist/commands/iteration/taskify.js +132 -7
- package/dist/commands/iteration/taskify.js.map +1 -1
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +193 -25
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/status-panel.d.ts +1 -0
- package/dist/commands/status-panel.d.ts.map +1 -1
- package/dist/commands/status-panel.js +180 -54
- package/dist/commands/status-panel.js.map +1 -1
- package/dist/commands/task/new.d.ts +16 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +232 -14
- package/dist/commands/task/new.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +78 -1
- package/dist/commands/verify.js.map +1 -1
- package/dist/core/analyze-engine.d.ts.map +1 -1
- package/dist/core/analyze-engine.js +6 -10
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-llm.d.ts +7 -0
- package/dist/core/ask-llm.d.ts.map +1 -1
- package/dist/core/ask-llm.js +45 -0
- package/dist/core/ask-llm.js.map +1 -1
- package/dist/core/code-graph/incremental-build.d.ts +2 -0
- package/dist/core/code-graph/incremental-build.d.ts.map +1 -1
- package/dist/core/code-graph/incremental-build.js +6 -5
- package/dist/core/code-graph/incremental-build.js.map +1 -1
- package/dist/core/code-graph/index.d.ts +2 -0
- package/dist/core/code-graph/index.d.ts.map +1 -1
- package/dist/core/code-graph/index.js +12 -5
- package/dist/core/code-graph/index.js.map +1 -1
- package/dist/core/code-scanner.d.ts +19 -4
- package/dist/core/code-scanner.d.ts.map +1 -1
- package/dist/core/code-scanner.js +193 -77
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/excel-extract.d.ts +16 -2
- package/dist/core/excel-extract.d.ts.map +1 -1
- package/dist/core/excel-extract.js +54 -12
- package/dist/core/excel-extract.js.map +1 -1
- package/dist/core/git-integration.d.ts +2 -1
- package/dist/core/git-integration.d.ts.map +1 -1
- package/dist/core/git-integration.js +38 -14
- package/dist/core/git-integration.js.map +1 -1
- package/dist/core/global-counters.d.ts +3 -0
- package/dist/core/global-counters.d.ts.map +1 -1
- package/dist/core/global-counters.js +21 -7
- package/dist/core/global-counters.js.map +1 -1
- package/dist/core/intent-recognition.d.ts.map +1 -1
- package/dist/core/intent-recognition.js +173 -27
- package/dist/core/intent-recognition.js.map +1 -1
- package/dist/core/plan-store.d.ts +1 -0
- package/dist/core/plan-store.d.ts.map +1 -1
- package/dist/core/plan-store.js.map +1 -1
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +168 -140
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/spec-paths.d.ts.map +1 -1
- package/dist/core/spec-paths.js +3 -0
- package/dist/core/spec-paths.js.map +1 -1
- package/dist/core/spec-skeleton.d.ts.map +1 -1
- package/dist/core/spec-skeleton.js +6 -2
- package/dist/core/spec-skeleton.js.map +1 -1
- package/dist/core/stage-aliases.d.ts +40 -0
- package/dist/core/stage-aliases.d.ts.map +1 -0
- package/dist/core/stage-aliases.js +110 -0
- package/dist/core/stage-aliases.js.map +1 -0
- package/dist/core/state.d.ts +11 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/state.js +33 -2
- package/dist/core/state.js.map +1 -1
- package/dist/core/structured-extractor.d.ts.map +1 -1
- package/dist/core/structured-extractor.js +7 -0
- package/dist/core/structured-extractor.js.map +1 -1
- package/dist/core/ui-verify/index.d.ts +2 -2
- package/dist/core/ui-verify/index.d.ts.map +1 -1
- package/dist/core/ui-verify/index.js +3 -1
- package/dist/core/ui-verify/index.js.map +1 -1
- package/dist/core/ui-verify/smoke-engine.d.ts.map +1 -1
- package/dist/core/ui-verify/smoke-engine.js +36 -0
- package/dist/core/ui-verify/smoke-engine.js.map +1 -1
- package/dist/core/ui-verify/spec-generator.d.ts +32 -1
- package/dist/core/ui-verify/spec-generator.d.ts.map +1 -1
- package/dist/core/ui-verify/spec-generator.js +205 -21
- package/dist/core/ui-verify/spec-generator.js.map +1 -1
- package/dist/core/ui-verify/types.d.ts +2 -0
- package/dist/core/ui-verify/types.d.ts.map +1 -1
- package/dist/utils/synonyms.d.ts.map +1 -1
- package/dist/utils/synonyms.js +15 -0
- package/dist/utils/synonyms.js.map +1 -1
- package/package.json +3 -2
- package/templates/api-design-example.md +338 -0
- package/templates/ci/github-actions.yml +44 -0
- package/templates/database-example.md +223 -0
- package/templates/deploy-docker/README.md +284 -0
- package/templates/deploy-docker/deploy-remote.sh +79 -0
- package/templates/deploy-docker/docker-compose.yml +113 -0
- package/templates/deploy-docker/frontend.Dockerfile +43 -0
- package/templates/deploy-docker/nginx.conf +30 -0
- package/templates/deploy-examples.yaml +436 -0
- package/templates/deploy-java/Dockerfile +50 -0
- package/templates/deploy-java/README.md +212 -0
- package/templates/deploy-java/deploy.sh +120 -0
- package/templates/deploy-java/spring-boot.service +35 -0
- package/templates/html/speccore-ask-explain.html +10 -0
- package/templates/html/speccore-ask-guide.html +10 -0
- package/templates/html/speccore-ask-match.html +10 -0
- package/templates/html/speccore-ask-pipeline.html +1 -0
- package/templates/html/speccore-ask-result.html +10 -0
- package/templates/html/speccore-help.html +241 -0
- package/templates/html/speccore-setup-guide.html +289 -0
- package/templates/security-example.md +226 -0
- package/templates/verify-spec-example.yaml +138 -0
|
@@ -161,6 +161,35 @@ function extractTopic(task) {
|
|
|
161
161
|
// 4. fallback 到 hash
|
|
162
162
|
return slugify(task.name || task.functionalUnit || 'task');
|
|
163
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* 构建任务目录名 topic(v8.3.294+)
|
|
166
|
+
*
|
|
167
|
+
* bugfix 任务带模块血缘:目录名拼为「{模块英文}-{bug内容英文}」(如 Task-003-login-flow-timeout-crash),
|
|
168
|
+
* 同一模块的 bug 任务在 030-tasks/bugfix/ 下自然相邻,方便浏览。
|
|
169
|
+
* 模块名 AI 英译(moduleTopic)优先、拼音兜底(toSlug 内置 pinyin),
|
|
170
|
+
* 与功能单元命名「LLM 英译 + 拼音兜底」模式一致。
|
|
171
|
+
* 其余任务类型保持原语义(functionalUnit → topic → name 链)。
|
|
172
|
+
*/
|
|
173
|
+
function buildTaskTopic(sec, taskType) {
|
|
174
|
+
const functionalUnit = sec.functionalUnit || '';
|
|
175
|
+
const bugTopic = sec._topic || '';
|
|
176
|
+
if (taskType === 'bugfix') {
|
|
177
|
+
// 模块名:AI 英译 moduleTopic 优先 → functionalUnit 拼音兜底
|
|
178
|
+
const moduleSlug = sec._moduleTopic
|
|
179
|
+
|| (functionalUnit ? (0, global_counters_1.toSlug)(functionalUnit) : '');
|
|
180
|
+
// bug 内容名:AI 英译 topic 优先 → 任务名拼音兜底
|
|
181
|
+
const bugSlug = bugTopic || (0, global_counters_1.toSlug)(sec.name || 'bug');
|
|
182
|
+
if (moduleSlug && bugSlug) {
|
|
183
|
+
// 防重复:bug 内容名已含模块名时不再叠加(如 topic 写全了 login-flow-timeout)
|
|
184
|
+
if (bugSlug.startsWith(moduleSlug))
|
|
185
|
+
return bugSlug.slice(0, 40);
|
|
186
|
+
// 模块名前段(≤15)+ 内容名,总长受 nextTaskId 的 40 字符上限约束
|
|
187
|
+
return `${moduleSlug.slice(0, 15)}-${bugSlug}`.slice(0, 40);
|
|
188
|
+
}
|
|
189
|
+
return (moduleSlug || bugSlug).slice(0, 40);
|
|
190
|
+
}
|
|
191
|
+
return functionalUnit || bugTopic || slugify(sec.name);
|
|
192
|
+
}
|
|
164
193
|
/**
|
|
165
194
|
* 生成子任务全局唯一 ID
|
|
166
195
|
* 格式: Task-{父任务ID}-{端名}
|
|
@@ -704,6 +733,11 @@ async function iterationTaskifyCommand(options) {
|
|
|
704
733
|
section._taskType = taskType;
|
|
705
734
|
// 保存 topic slug,用于生成任务目录名(v8.3.77+: 多层提取)
|
|
706
735
|
section._topic = extractTopic(task);
|
|
736
|
+
// v8.3.294+: 透传 AI 提供的模块英文 slug(bugfix 目录名「模块名-内容名」拼接用),
|
|
737
|
+
// 仅接受合法英文短横线格式,非法时回退拼音兜底
|
|
738
|
+
if (task.moduleTopic && /^[a-z0-9-]+$/.test(task.moduleTopic)) {
|
|
739
|
+
section._moduleTopic = task.moduleTopic;
|
|
740
|
+
}
|
|
707
741
|
// 保存 AI 生成的实际内容(用于写入 REQ.md / TECH.md)
|
|
708
742
|
if (task.reqContent)
|
|
709
743
|
section._reqContent = task.reqContent;
|
|
@@ -712,6 +746,13 @@ async function iterationTaskifyCommand(options) {
|
|
|
712
746
|
// v7.4.0+: 保存 AI 生成的 DEV_GUIDE 内容
|
|
713
747
|
if (task.devGuideContent)
|
|
714
748
|
section._devGuideContent = task.devGuideContent;
|
|
749
|
+
// v8.3.291: 保存 AI 输出的依赖关系与临时 ID——dependencies 此前只用于日志展示,
|
|
750
|
+
// 从未写入 _dependsOn,导致 plan 拓扑排期 / execute 依赖分支合并永远拿空数组
|
|
751
|
+
if (task.id)
|
|
752
|
+
section._aiId = String(task.id);
|
|
753
|
+
if (Array.isArray(task.dependencies)) {
|
|
754
|
+
section._aiDeps = task.dependencies.filter((d) => typeof d === 'string' && d.trim());
|
|
755
|
+
}
|
|
715
756
|
if (task.sourceFile)
|
|
716
757
|
section._sourceFile = task.sourceFile;
|
|
717
758
|
if (task.functionalUnit)
|
|
@@ -984,6 +1025,44 @@ async function iterationTaskifyCommand(options) {
|
|
|
984
1025
|
}
|
|
985
1026
|
logger_1.logger.info('');
|
|
986
1027
|
}
|
|
1028
|
+
// ── v8.3.291: 预分配任务 ID 并解析 AI 依赖关系 ──
|
|
1029
|
+
// 修复:AI 返回的 dependencies 字段此前只用于日志展示(仅 1055 行 const deps),
|
|
1030
|
+
// 从未写入 section._dependsOn,导致 TASK.md「依赖任务」恒为「无」,
|
|
1031
|
+
// 下游 plan 拓扑分阶段 / execute 依赖分支合并(prepareTaskBranch)全部失效。
|
|
1032
|
+
// 预分配 ID 后建立「AI 临时 id → 实际 taskId」映射,把 dependencies 解析为实际 ID。
|
|
1033
|
+
const aiIdToTaskId = new Map();
|
|
1034
|
+
for (const sec of sections) {
|
|
1035
|
+
// v8.3.294+: bugfix 任务目录名拼「模块英文-内容英文」,其余类型保持原链
|
|
1036
|
+
const taskType = sec._taskType || 'feature';
|
|
1037
|
+
const taskTopic = buildTaskTopic(sec, taskType);
|
|
1038
|
+
const { id: taskId } = await (0, global_counters_1.nextTaskId)(sec.name, taskTopic);
|
|
1039
|
+
sec._taskId = taskId;
|
|
1040
|
+
const aiId = sec._aiId;
|
|
1041
|
+
if (aiId)
|
|
1042
|
+
aiIdToTaskId.set(aiId, taskId);
|
|
1043
|
+
}
|
|
1044
|
+
let resolvedDepCount = 0;
|
|
1045
|
+
for (const sec of sections) {
|
|
1046
|
+
const rawDeps = sec._aiDeps;
|
|
1047
|
+
if (!rawDeps || rawDeps.length === 0)
|
|
1048
|
+
continue;
|
|
1049
|
+
const resolved = [];
|
|
1050
|
+
for (const dep of rawDeps) {
|
|
1051
|
+
const mapped = aiIdToTaskId.get(dep);
|
|
1052
|
+
if (mapped) {
|
|
1053
|
+
resolved.push(mapped);
|
|
1054
|
+
resolvedDepCount++;
|
|
1055
|
+
}
|
|
1056
|
+
else {
|
|
1057
|
+
// 无法映射的依赖(AI 引用了不存在的任务 ID)保留原始引用,execute 阶段会给出提示
|
|
1058
|
+
resolved.push(dep);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
sec._dependsOn = resolved;
|
|
1062
|
+
}
|
|
1063
|
+
if (resolvedDepCount > 0) {
|
|
1064
|
+
logger_1.logger.info(` 🔗 已解析 ${resolvedDepCount} 条任务依赖关系`);
|
|
1065
|
+
}
|
|
987
1066
|
// 逐任务交互确认
|
|
988
1067
|
const createdSections = [];
|
|
989
1068
|
const moduleFilter = (unit) => {
|
|
@@ -1007,7 +1086,8 @@ async function iterationTaskifyCommand(options) {
|
|
|
1007
1086
|
}
|
|
1008
1087
|
const complexity = sec._complexity || {};
|
|
1009
1088
|
const taskType = sec._taskType || 'feature';
|
|
1010
|
-
|
|
1089
|
+
// 依赖已在上方预分配阶段解析为实际 taskId(v8.3.291)
|
|
1090
|
+
const deps = (sec._dependsOn || []);
|
|
1011
1091
|
const acs = (tasks[i].acceptanceCriteria || []);
|
|
1012
1092
|
// 展示任务摘要
|
|
1013
1093
|
logger_1.logger.info(`\n ━━━━ 任务 ${i + 1}/${sections.length} ━━━━`);
|
|
@@ -1035,9 +1115,10 @@ async function iterationTaskifyCommand(options) {
|
|
|
1035
1115
|
}
|
|
1036
1116
|
// 使用保存的 topic slug 生成任务ID
|
|
1037
1117
|
// v8.3.33: 优先使用 functionalUnit 作为 topic,使目录名更有意义
|
|
1118
|
+
// v8.3.291: taskId 已在预分配阶段生成(依赖解析需要),此处直接复用
|
|
1038
1119
|
const taskTopic = sec.functionalUnit || sec._topic || slugify(sec.name);
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1120
|
+
const taskId = sec._taskId;
|
|
1121
|
+
void taskTopic;
|
|
1041
1122
|
await createTaskFromSection(iterDirFull, taskId, sec, allPlatforms, taskType, sections);
|
|
1042
1123
|
createdSections.push(sec);
|
|
1043
1124
|
logger_1.logger.info(` ✅ 创建: ${taskId} - [${taskType}] ${sec.name}`);
|
|
@@ -1400,7 +1481,9 @@ async function iterationTaskifyCommand(options) {
|
|
|
1400
1481
|
logger_1.logger.info(`Platforms: ${platforms.join(', ')}`);
|
|
1401
1482
|
// ── 预分配任务 ID(确保所有路径使用计数器,避免编号重复) ──
|
|
1402
1483
|
for (const section of sections) {
|
|
1403
|
-
|
|
1484
|
+
// v8.3.294+: bugfix 任务目录名拼「模块英文-内容英文」,其余类型保持原链
|
|
1485
|
+
const taskType = section._taskType || 'feature';
|
|
1486
|
+
const topic = buildTaskTopic(section, taskType);
|
|
1404
1487
|
const { id: taskId } = await (0, global_counters_1.nextTaskId)(section.name, topic);
|
|
1405
1488
|
section._taskId = taskId;
|
|
1406
1489
|
}
|
|
@@ -2341,6 +2424,29 @@ ${!isBk && docSet.hasComponentTree ? '| COMPONENT_TREE.md | ⏳ | ./COMPONENT_TR
|
|
|
2341
2424
|
logger_1.logger.info(` 📄 VERIFY_SPEC.yaml 已自动生成(${routeResult.routes.length} 个场景)`);
|
|
2342
2425
|
}
|
|
2343
2426
|
}
|
|
2427
|
+
else {
|
|
2428
|
+
// v8.3.293+: 无源码可扫描(首次建设/需求阶段)时,从 020-specs 的 UI_SPEC
|
|
2429
|
+
// 「元素标识约定」清单 + 业务流程生成流程场景骨架,selector 按清单自动装配,
|
|
2430
|
+
// 弥合「分析阶段元素约定」与「冒烟配置生成阶段」之间的断链。
|
|
2431
|
+
const specTexts = [];
|
|
2432
|
+
for (const [specKey, specBody] of Object.entries(specContents)) {
|
|
2433
|
+
if (specKey.includes(platformName) && /(UI_SPEC|TEST)\.md$/.test(specKey)
|
|
2434
|
+
&& !specBody.includes('SPEC-SKELETON')) {
|
|
2435
|
+
specTexts.push(specBody);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
if (specTexts.length > 0) {
|
|
2439
|
+
const spec = (0, ui_verify_1.generateSpecFromUiSpec)(specTexts.join('\n\n'), {
|
|
2440
|
+
baseUrl: 'http://localhost:3000',
|
|
2441
|
+
platform: platformName,
|
|
2442
|
+
name: `${section.name} - ${platformName} UI 验证`,
|
|
2443
|
+
});
|
|
2444
|
+
if (spec.scenarios.length > 0) {
|
|
2445
|
+
await (0, ui_verify_1.writeVerifySpec)(spec, (0, path_1.join)(subtaskDir, 'VERIFY_SPEC.yaml'));
|
|
2446
|
+
logger_1.logger.info(` 📄 VERIFY_SPEC.yaml 已按 UI_SPEC 元素清单生成(${spec.scenarios.length} 个流程场景)`);
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2344
2450
|
}
|
|
2345
2451
|
catch {
|
|
2346
2452
|
// 静默失败:源码不可用或扫描失败时不阻断 split 流程
|
|
@@ -2787,9 +2893,25 @@ async function generateImpactGraph(iterationDir, sections, platforms) {
|
|
|
2787
2893
|
}
|
|
2788
2894
|
// 语义依赖检测
|
|
2789
2895
|
const semanticDeps = detectSemanticDependencies(sections);
|
|
2896
|
+
// v8.3.291: 显式输出 AI 声明的依赖(_dependsOn),优先级高于文本/语义推断——
|
|
2897
|
+
// 这是 plan 拓扑排期与 execute 依赖分支合并的权威依据
|
|
2898
|
+
const explicitDeps = new Map();
|
|
2899
|
+
for (const s of sections) {
|
|
2900
|
+
const taskId = s._taskId;
|
|
2901
|
+
const declared = s._dependsOn;
|
|
2902
|
+
if (taskId && declared && declared.length > 0)
|
|
2903
|
+
explicitDeps.set(taskId, declared);
|
|
2904
|
+
}
|
|
2790
2905
|
impact += '\n## Dependencies\n\n';
|
|
2791
|
-
if (uniqueDeps.length > 0 || semanticDeps.size > 0) {
|
|
2906
|
+
if (uniqueDeps.length > 0 || semanticDeps.size > 0 || explicitDeps.size > 0) {
|
|
2792
2907
|
impact += '| Consumer | -> | Producer | 类型 |\n| :--- | :---: | :--- | :--- |\n';
|
|
2908
|
+
// 任务声明的依赖(权威,最先列出)
|
|
2909
|
+
for (const [from, targets] of explicitDeps) {
|
|
2910
|
+
const fromName = sections.find(s => s._taskId === from)?.name || from;
|
|
2911
|
+
for (const target of targets) {
|
|
2912
|
+
impact += `| ${from}: ${fromName.slice(0, 20)} | → | ${target} | 任务声明 |\n`;
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2793
2915
|
// API 依赖
|
|
2794
2916
|
for (const d of uniqueDeps)
|
|
2795
2917
|
impact += `| ${d.from}: ${d.fromName.slice(0, 20)} | → | ${d.to}: ${d.toName.slice(0, 20)} | API: \`${d.reason}\` |\n`;
|
|
@@ -3829,6 +3951,7 @@ subagent, contextType) {
|
|
|
3829
3951
|
p += `[\n {\n`;
|
|
3830
3952
|
p += ` "id": "Task-001",\n`;
|
|
3831
3953
|
p += ` "functionalUnit": "所属功能单元/影响域(必填!见下方类型规则)",\n`;
|
|
3954
|
+
p += ` "moduleTopic": "受影响模块的英文 slug(bugfix 建议提供,如 login-flow、payment-callback,目录名拼为 模块名-bug内容名)",\n`;
|
|
3832
3955
|
p += ` "name": "任务名称(中文)",\n`;
|
|
3833
3956
|
p += ` "topic": "english-slug-for-directory",\n`;
|
|
3834
3957
|
p += ` "type": "feature|bugfix|refactor|research|security|performance",\n`;
|
|
@@ -3847,7 +3970,8 @@ subagent, contextType) {
|
|
|
3847
3970
|
p += '```\n\n';
|
|
3848
3971
|
p += `> **functionalUnit 必须填写**:根据任务类型语义不同:\n`;
|
|
3849
3972
|
p += `> - feature → 功能模块名(如:用户管理、订单系统、支付模块)\n`;
|
|
3850
|
-
p += `> - bugfix →
|
|
3973
|
+
p += `> - bugfix → 受影响组件/流程(如:登录流程、支付回调、数据同步);目录名将拼为「模块英文-bug内容英文」,\n`;
|
|
3974
|
+
p += `> 建议同时提供 moduleTopic(模块英文 slug),未提供时用拼音兜底\n`;
|
|
3851
3975
|
p += `> - refactor → 重构目标范围(如:数据库层、API网关、状态管理)\n`;
|
|
3852
3976
|
p += `> - security → 安全修复范围(如:SQL注入防护、XSS修复、鉴权加固)\n`;
|
|
3853
3977
|
p += `> - performance → 性能优化目标(如:查询优化、缓存策略、并发提升)\n`;
|
|
@@ -4185,7 +4309,8 @@ async function generateTaskSummary(iterationDir, tasks, createdSections) {
|
|
|
4185
4309
|
const aiHours = Math.round(estimatedHours * 0.7); // 预估 70% 可由 AI 完成
|
|
4186
4310
|
const humanHours = estimatedHours - aiHours;
|
|
4187
4311
|
const priority = task.priority || sec._complexity?.priority || 'medium';
|
|
4188
|
-
|
|
4312
|
+
// v8.3.291: 依赖从解析后的 _dependsOn 读取(AI 的 dependencies 字段已映射为实际 taskId)
|
|
4313
|
+
const deps = (sec._dependsOn || []).join(', ') || '-';
|
|
4189
4314
|
const risk = task.risk || 'medium';
|
|
4190
4315
|
totalHumanHours += humanHours;
|
|
4191
4316
|
totalAiHours += aiHours;
|