speccore 8.3.333 → 8.3.341
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-ask/SKILL.md +4 -0
- package/.agents/skills/spec-unitize/SKILL.md +9 -1
- package/.agents/skills/speccore-router/SKILL.md +12 -11
- package/README.en.md +3 -11
- package/README.md +3 -13
- package/dist/cli.js +64 -206
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +530 -481
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +6 -0
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +9 -7
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/doc2spec.d.ts +44 -1
- package/dist/commands/doc2spec.d.ts.map +1 -1
- package/dist/commands/doc2spec.js +257 -5
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/doctor.js +3 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/done.js +1 -5
- package/dist/commands/done.js.map +1 -1
- package/dist/commands/execute.js +118 -66
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/help.js +6 -54
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +71 -47
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/iteration/create.d.ts.map +1 -1
- package/dist/commands/iteration/create.js +72 -10
- package/dist/commands/iteration/create.js.map +1 -1
- package/dist/commands/iteration/taskify.d.ts.map +1 -1
- package/dist/commands/iteration/taskify.js +133 -35
- package/dist/commands/iteration/taskify.js.map +1 -1
- package/dist/commands/pr.d.ts.map +1 -1
- package/dist/commands/pr.js +24 -2
- package/dist/commands/pr.js.map +1 -1
- package/dist/commands/prompts.d.ts +6 -0
- package/dist/commands/prompts.d.ts.map +1 -1
- package/dist/commands/prompts.js +19 -10
- package/dist/commands/prompts.js.map +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/status-panel.d.ts.map +1 -1
- package/dist/commands/status-panel.js +23 -34
- package/dist/commands/status-panel.js.map +1 -1
- package/dist/commands/unitize.d.ts +3 -0
- package/dist/commands/unitize.d.ts.map +1 -1
- package/dist/commands/unitize.js +32 -9
- package/dist/commands/unitize.js.map +1 -1
- package/dist/commands/update-env-configs.d.ts.map +1 -1
- package/dist/commands/update-env-configs.js +2 -1
- package/dist/commands/update-env-configs.js.map +1 -1
- package/dist/commands/update.d.ts +4 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +41 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/welcome.d.ts.map +1 -1
- package/dist/commands/welcome.js +41 -0
- package/dist/commands/welcome.js.map +1 -1
- package/dist/core/analyze-engine.js +3 -3
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/arbitration/l3-human-arbiter.js +1 -1
- package/dist/core/arbitration/l3-human-arbiter.js.map +1 -1
- package/dist/core/arbitration/verdict-generator.js +1 -1
- package/dist/core/arbitration/verdict-generator.js.map +1 -1
- package/dist/core/ask-context.d.ts.map +1 -1
- package/dist/core/ask-context.js +14 -3
- package/dist/core/ask-context.js.map +1 -1
- package/dist/core/ask-engine.d.ts.map +1 -1
- package/dist/core/ask-engine.js +55 -49
- package/dist/core/ask-engine.js.map +1 -1
- package/dist/core/code-graph/reporter.d.ts.map +1 -1
- package/dist/core/code-graph/reporter.js +3 -12
- package/dist/core/code-graph/reporter.js.map +1 -1
- package/dist/core/code-graph/requirement-linker.js +1 -1
- package/dist/core/code-graph/requirement-linker.js.map +1 -1
- package/dist/core/code-scanner.js +1 -1
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/deploy/engine.d.ts.map +1 -1
- package/dist/core/deploy/engine.js +58 -44
- package/dist/core/deploy/engine.js.map +1 -1
- package/dist/core/environment-config.d.ts +13 -0
- package/dist/core/environment-config.d.ts.map +1 -1
- package/dist/core/environment-config.js +28 -1
- package/dist/core/environment-config.js.map +1 -1
- package/dist/core/error-diagnosis.js +2 -2
- package/dist/core/error-diagnosis.js.map +1 -1
- package/dist/core/git-integration.d.ts +5 -7
- package/dist/core/git-integration.d.ts.map +1 -1
- package/dist/core/git-integration.js +137 -12
- package/dist/core/git-integration.js.map +1 -1
- package/dist/core/global-knowledge.d.ts.map +1 -1
- package/dist/core/global-knowledge.js +25 -11
- package/dist/core/global-knowledge.js.map +1 -1
- package/dist/core/handoff-generator.d.ts.map +1 -1
- package/dist/core/handoff-generator.js +3 -1
- package/dist/core/handoff-generator.js.map +1 -1
- package/dist/core/index-guard.d.ts.map +1 -1
- package/dist/core/index-guard.js +4 -26
- package/dist/core/index-guard.js.map +1 -1
- package/dist/core/intent-recognition.d.ts +1 -1
- package/dist/core/intent-recognition.d.ts.map +1 -1
- package/dist/core/intent-recognition.js +68 -68
- package/dist/core/intent-recognition.js.map +1 -1
- package/dist/core/knowledge-graph.d.ts.map +1 -1
- package/dist/core/knowledge-graph.js +6 -4
- package/dist/core/knowledge-graph.js.map +1 -1
- package/dist/core/name-validator.d.ts.map +1 -1
- package/dist/core/name-validator.js +41 -20
- package/dist/core/name-validator.js.map +1 -1
- package/dist/core/pinyin-initials.d.ts +10 -0
- package/dist/core/pinyin-initials.d.ts.map +1 -0
- package/dist/core/pinyin-initials.js +44 -0
- package/dist/core/pinyin-initials.js.map +1 -0
- package/dist/core/prompt-builder.js +1 -1
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/prompt-plugins/analyze-graph-plugin.js +1 -1
- package/dist/core/prompt-plugins/analyze-graph-plugin.js.map +1 -1
- package/dist/core/reindex-engine.js +4 -4
- package/dist/core/reindex-engine.js.map +1 -1
- package/dist/core/skeleton-residue.d.ts +13 -0
- package/dist/core/skeleton-residue.d.ts.map +1 -1
- package/dist/core/skeleton-residue.js +83 -14
- package/dist/core/skeleton-residue.js.map +1 -1
- package/dist/core/spec-merger.d.ts.map +1 -1
- package/dist/core/spec-merger.js +3 -2
- package/dist/core/spec-merger.js.map +1 -1
- package/dist/core/state.d.ts +10 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/state.js +20 -1
- package/dist/core/state.js.map +1 -1
- package/dist/core/structured-extractor.d.ts +6 -0
- package/dist/core/structured-extractor.d.ts.map +1 -1
- package/dist/core/structured-extractor.js +6 -0
- package/dist/core/structured-extractor.js.map +1 -1
- package/dist/core/task-paths.d.ts +12 -0
- package/dist/core/task-paths.d.ts.map +1 -1
- package/dist/core/task-paths.js +33 -1
- package/dist/core/task-paths.js.map +1 -1
- package/dist/core/unified-config.d.ts +7 -1
- package/dist/core/unified-config.d.ts.map +1 -1
- package/dist/core/unified-config.js +70 -21
- package/dist/core/unified-config.js.map +1 -1
- package/dist/core/unit-staffing.d.ts +21 -4
- package/dist/core/unit-staffing.d.ts.map +1 -1
- package/dist/core/unit-staffing.js +59 -12
- package/dist/core/unit-staffing.js.map +1 -1
- package/dist/core/usage-analytics.js +1 -1
- package/dist/core/usage-analytics.js.map +1 -1
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +45 -5
- package/dist/core/validator.js.map +1 -1
- package/dist/core/verify-report-aggregator.d.ts.map +1 -1
- package/dist/core/verify-report-aggregator.js +19 -2
- package/dist/core/verify-report-aggregator.js.map +1 -1
- package/dist/utils/task-utils.d.ts +4 -1
- package/dist/utils/task-utils.d.ts.map +1 -1
- package/dist/utils/task-utils.js +30 -4
- package/dist/utils/task-utils.js.map +1 -1
- package/package.json +4 -3
- package/templates/deploy-examples.yaml +33 -5
- package/templates/html/speccore-ask-explain.html +1 -1
- package/templates/html/speccore-ask-guide.html +1 -1
- package/templates/html/speccore-ask-match.html +1 -1
- package/templates/html/speccore-ask-pipeline.html +1 -1
- package/templates/html/speccore-ask-result.html +1 -1
- package/templates/html/speccore-help.html +2 -2
- package/templates/speccore-yml-example.yml +174 -54
- package/templates/verify-spec-example.yaml +66 -1
- package/dist/commands/audit.d.ts +0 -12
- package/dist/commands/audit.d.ts.map +0 -1
- package/dist/commands/audit.js +0 -540
- package/dist/commands/audit.js.map +0 -1
- package/dist/commands/backup.d.ts +0 -18
- package/dist/commands/backup.d.ts.map +0 -1
- package/dist/commands/backup.js +0 -102
- package/dist/commands/backup.js.map +0 -1
- package/dist/commands/baseline.d.ts +0 -13
- package/dist/commands/baseline.d.ts.map +0 -1
- package/dist/commands/baseline.js +0 -227
- package/dist/commands/baseline.js.map +0 -1
- package/dist/commands/chain.d.ts +0 -55
- package/dist/commands/chain.d.ts.map +0 -1
- package/dist/commands/chain.js +0 -501
- package/dist/commands/chain.js.map +0 -1
- package/dist/commands/clarify.d.ts +0 -17
- package/dist/commands/clarify.d.ts.map +0 -1
- package/dist/commands/clarify.js +0 -351
- package/dist/commands/clarify.js.map +0 -1
- package/dist/commands/code-index.d.ts +0 -21
- package/dist/commands/code-index.d.ts.map +0 -1
- package/dist/commands/code-index.js +0 -193
- package/dist/commands/code-index.js.map +0 -1
- package/dist/commands/context.d.ts +0 -10
- package/dist/commands/context.d.ts.map +0 -1
- package/dist/commands/context.js +0 -213
- package/dist/commands/context.js.map +0 -1
- package/dist/commands/current.d.ts +0 -10
- package/dist/commands/current.d.ts.map +0 -1
- package/dist/commands/current.js +0 -53
- package/dist/commands/current.js.map +0 -1
- package/dist/commands/dev.d.ts +0 -18
- package/dist/commands/dev.d.ts.map +0 -1
- package/dist/commands/dev.js +0 -854
- package/dist/commands/dev.js.map +0 -1
- package/dist/commands/diff.d.ts +0 -10
- package/dist/commands/diff.d.ts.map +0 -1
- package/dist/commands/diff.js +0 -160
- package/dist/commands/diff.js.map +0 -1
- package/dist/commands/global-status.d.ts +0 -9
- package/dist/commands/global-status.d.ts.map +0 -1
- package/dist/commands/global-status.js +0 -135
- package/dist/commands/global-status.js.map +0 -1
- package/dist/commands/graph.d.ts +0 -25
- package/dist/commands/graph.d.ts.map +0 -1
- package/dist/commands/graph.js +0 -523
- package/dist/commands/graph.js.map +0 -1
- package/dist/commands/handover.d.ts +0 -11
- package/dist/commands/handover.d.ts.map +0 -1
- package/dist/commands/handover.js +0 -170
- package/dist/commands/handover.js.map +0 -1
- package/dist/commands/health.d.ts +0 -7
- package/dist/commands/health.d.ts.map +0 -1
- package/dist/commands/health.js +0 -80
- package/dist/commands/health.js.map +0 -1
- package/dist/commands/history.d.ts +0 -9
- package/dist/commands/history.d.ts.map +0 -1
- package/dist/commands/history.js +0 -117
- package/dist/commands/history.js.map +0 -1
- package/dist/commands/impact.d.ts +0 -12
- package/dist/commands/impact.d.ts.map +0 -1
- package/dist/commands/impact.js +0 -238
- package/dist/commands/impact.js.map +0 -1
- package/dist/commands/import.d.ts +0 -19
- package/dist/commands/import.d.ts.map +0 -1
- package/dist/commands/import.js +0 -673
- package/dist/commands/import.js.map +0 -1
- package/dist/commands/knowledge.d.ts +0 -6
- package/dist/commands/knowledge.d.ts.map +0 -1
- package/dist/commands/knowledge.js +0 -94
- package/dist/commands/knowledge.js.map +0 -1
- package/dist/commands/lifecycle.d.ts +0 -9
- package/dist/commands/lifecycle.d.ts.map +0 -1
- package/dist/commands/lifecycle.js +0 -288
- package/dist/commands/lifecycle.js.map +0 -1
- package/dist/commands/merge-check.d.ts +0 -10
- package/dist/commands/merge-check.d.ts.map +0 -1
- package/dist/commands/merge-check.js +0 -183
- package/dist/commands/merge-check.js.map +0 -1
- package/dist/commands/notify.d.ts +0 -13
- package/dist/commands/notify.d.ts.map +0 -1
- package/dist/commands/notify.js +0 -63
- package/dist/commands/notify.js.map +0 -1
- package/dist/commands/rag-index.d.ts +0 -19
- package/dist/commands/rag-index.d.ts.map +0 -1
- package/dist/commands/rag-index.js +0 -286
- package/dist/commands/rag-index.js.map +0 -1
- package/dist/commands/recommend.d.ts +0 -13
- package/dist/commands/recommend.d.ts.map +0 -1
- package/dist/commands/recommend.js +0 -37
- package/dist/commands/recommend.js.map +0 -1
- package/dist/commands/refresh.d.ts +0 -21
- package/dist/commands/refresh.d.ts.map +0 -1
- package/dist/commands/refresh.js +0 -211
- package/dist/commands/refresh.js.map +0 -1
- package/dist/commands/rollback.d.ts +0 -8
- package/dist/commands/rollback.d.ts.map +0 -1
- package/dist/commands/rollback.js +0 -113
- package/dist/commands/rollback.js.map +0 -1
- package/dist/commands/status.d.ts +0 -7
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/trace.d.ts +0 -12
- package/dist/commands/trace.d.ts.map +0 -1
- package/dist/commands/trace.js +0 -163
- package/dist/commands/trace.js.map +0 -1
- package/dist/commands/tracker.d.ts +0 -2
- package/dist/commands/tracker.d.ts.map +0 -1
- package/dist/commands/tracker.js +0 -28
- package/dist/commands/tracker.js.map +0 -1
- package/dist/commands/verdict.d.ts +0 -16
- package/dist/commands/verdict.d.ts.map +0 -1
- package/dist/commands/verdict.js +0 -189
- package/dist/commands/verdict.js.map +0 -1
- package/dist/commands/workspace.d.ts +0 -20
- package/dist/commands/workspace.d.ts.map +0 -1
- package/dist/commands/workspace.js +0 -142
- package/dist/commands/workspace.js.map +0 -1
- package/dist/core/constraint-set.d.ts +0 -67
- package/dist/core/constraint-set.d.ts.map +0 -1
- package/dist/core/constraint-set.js +0 -151
- package/dist/core/constraint-set.js.map +0 -1
- package/dist/core/smart-recommend.d.ts +0 -16
- package/dist/core/smart-recommend.d.ts.map +0 -1
- package/dist/core/smart-recommend.js +0 -149
- package/dist/core/smart-recommend.js.map +0 -1
- package/dist/core/task-type-registry.d.ts +0 -110
- package/dist/core/task-type-registry.d.ts.map +0 -1
- package/dist/core/task-type-registry.js +0 -334
- package/dist/core/task-type-registry.js.map +0 -1
- package/dist/utils/mermaid-render.d.ts +0 -39
- package/dist/utils/mermaid-render.d.ts.map +0 -1
- package/dist/utils/mermaid-render.js +0 -284
- package/dist/utils/mermaid-render.js.map +0 -1
package/dist/commands/execute.js
CHANGED
|
@@ -272,10 +272,10 @@ async function executeCommand(options) {
|
|
|
272
272
|
tasks = tasks.filter(t => t.status === options.status);
|
|
273
273
|
if (options.assignee)
|
|
274
274
|
tasks = tasks.filter(t => t.assignee === options.assignee);
|
|
275
|
-
// v8.3.288+:
|
|
275
|
+
// v8.3.288+ / v8.3.339+: 按所属功能模块筛选(逗号分隔多值,模糊匹配单元名/模块目录名)
|
|
276
276
|
if (options.module) {
|
|
277
277
|
const before = tasks.length;
|
|
278
|
-
tasks =
|
|
278
|
+
tasks = (0, state_1.filterTasksByModule)(tasks, options.module);
|
|
279
279
|
logger_1.logger.info(`🎯 模块筛选「${options.module}」: ${before} → ${tasks.length} 个任务`);
|
|
280
280
|
}
|
|
281
281
|
// v8.3.145+: 使用项目实际端名过滤,不再硬编码 backend/frontend
|
|
@@ -593,6 +593,12 @@ async function executeWithProgress(tasks, iteration, base, skip, options) {
|
|
|
593
593
|
logger_1.logger.info(` 🌿 ${task.id}: ${branchName}`);
|
|
594
594
|
}
|
|
595
595
|
await generateTaskSkeleton(task, iteration);
|
|
596
|
+
// v8.3.337+: 直接执行路径同样跑完成收尾(标记 completed + 骨架体检兑底)
|
|
597
|
+
try {
|
|
598
|
+
const tDir = await resolveTaskDir(await (0, context_1.getIterationDir)(iteration), task.id);
|
|
599
|
+
await finalizeTaskCompletion(iteration, task.id, tDir);
|
|
600
|
+
}
|
|
601
|
+
catch { /* 收尾失败不阻断 */ }
|
|
596
602
|
completed.push(`${task.id} - ${task.name || ''}`);
|
|
597
603
|
logger_1.logger.info(` ✅ ${task.id} completed`);
|
|
598
604
|
logger_1.logger.info('');
|
|
@@ -832,6 +838,12 @@ async function processBatch(tasks, state, iteration) {
|
|
|
832
838
|
}
|
|
833
839
|
logger_1.logger.info(` 🔄 执行中...`);
|
|
834
840
|
await generateTaskSkeleton(task, iteration);
|
|
841
|
+
// v8.3.337+: 批次路径同样跑完成收尾(标记 completed + 骨架体检兑底)
|
|
842
|
+
try {
|
|
843
|
+
const tDir = await resolveTaskDir(await (0, context_1.getIterationDir)(iteration), task.id);
|
|
844
|
+
await finalizeTaskCompletion(iteration, task.id, tDir);
|
|
845
|
+
}
|
|
846
|
+
catch { /* 收尾失败不阻断 */ }
|
|
835
847
|
completed.push(task.id);
|
|
836
848
|
// 写入任务摘要到 execution-state(文件即记忆)
|
|
837
849
|
// v8.3.166+: 包含 agent 角色,供跨 Agent 状态共享
|
|
@@ -1945,7 +1957,7 @@ async function executionVerifyLoop(tasks, iteration, options) {
|
|
|
1945
1957
|
logger_1.logger.info(` 👤 L3 架构契约: ${arbResult.report.L3.passed}/${arbResult.report.L3.total} 通过, ${arbResult.report.L3.pending} 待裁决`);
|
|
1946
1958
|
if (arbResult.report.L3.pending > 0) {
|
|
1947
1959
|
logger_1.logger.warn(` ⚠️ ${arbResult.report.L3.pending} 项需人工裁决`);
|
|
1948
|
-
logger_1.logger.info(`
|
|
1960
|
+
logger_1.logger.info(` 裁决入口: 任务目录 ARBITRATION_REPORT.md`);
|
|
1949
1961
|
allPassed = false;
|
|
1950
1962
|
}
|
|
1951
1963
|
}
|
|
@@ -2171,10 +2183,10 @@ async function listPendingTasks(iteration, options) {
|
|
|
2171
2183
|
}
|
|
2172
2184
|
// 过滤已完成的任务
|
|
2173
2185
|
let pending = tasks.filter(t => t.status !== 'completed' && t.status !== 'archived');
|
|
2174
|
-
// v8.3.288+: 按所属功能模块筛选(--module
|
|
2186
|
+
// v8.3.288+ / v8.3.339+: 按所属功能模块筛选(--module 逗号分隔多值,模糊匹配单元名/模块目录名)
|
|
2175
2187
|
if (options.module) {
|
|
2176
2188
|
const before = pending.length;
|
|
2177
|
-
pending =
|
|
2189
|
+
pending = (0, state_1.filterTasksByModule)(pending, options.module);
|
|
2178
2190
|
logger_1.logger.info(`🎯 模块筛选「${options.module}」: ${before} → ${pending.length} 个任务`);
|
|
2179
2191
|
}
|
|
2180
2192
|
if (pending.length === 0) {
|
|
@@ -2215,8 +2227,22 @@ async function runPromptMode(iteration, options) {
|
|
|
2215
2227
|
const taskDir = (await (0, fs_extra_1.pathExists)(tasksDir30)) ? tasksDir30 : iterDir;
|
|
2216
2228
|
let availableTasks = [];
|
|
2217
2229
|
try {
|
|
2218
|
-
|
|
2219
|
-
|
|
2230
|
+
// v8.3.337+: 兼容 030-tasks 新旧布局(新布局模块目录=功能单元名,位于类型子目录层)
|
|
2231
|
+
const { isTaskModuleDirName } = await Promise.resolve().then(() => __importStar(require('../core/task-paths')));
|
|
2232
|
+
const collect = async (dir, depth) => {
|
|
2233
|
+
const entries = await (0, fs_extra_1.readdir)(dir, { withFileTypes: true });
|
|
2234
|
+
for (const e of entries) {
|
|
2235
|
+
if (!e.isDirectory())
|
|
2236
|
+
continue;
|
|
2237
|
+
if (e.name.startsWith('Task-') || (depth <= 1 && isTaskModuleDirName(e.name))) {
|
|
2238
|
+
availableTasks.push(e.name);
|
|
2239
|
+
}
|
|
2240
|
+
else if (!e.name.startsWith('.')) {
|
|
2241
|
+
await collect((0, path_1.join)(dir, e.name), depth + 1);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
await collect(taskDir, 0);
|
|
2220
2246
|
}
|
|
2221
2247
|
catch { }
|
|
2222
2248
|
(0, prompt_builder_1.outputNeedsInfo)({
|
|
@@ -2543,6 +2569,14 @@ async function runPromptMode(iteration, options) {
|
|
|
2543
2569
|
process.stdout.write(`✅ 代码已由子 Agent 直接写入 ${dispatchResult.filesChanged.length} 个文件:\n`);
|
|
2544
2570
|
for (const f of dispatchResult.filesChanged)
|
|
2545
2571
|
process.stdout.write(` 📄 ${f}\n`);
|
|
2572
|
+
// v8.3.337+: SDK 直连路径同样跑完成收尾(标记 completed + 骨架体检兑底),
|
|
2573
|
+
// 修复子 Agent 只写代码不覆盖端级骨架时文档保持空模板的问题
|
|
2574
|
+
try {
|
|
2575
|
+
await finalizeTaskCompletion(iteration, task, taskDir);
|
|
2576
|
+
}
|
|
2577
|
+
catch (e) {
|
|
2578
|
+
logger_1.logger.debug(`[execute] SDK 直连完成收尾失败(不阻断): ${e.message}`);
|
|
2579
|
+
}
|
|
2546
2580
|
process.exitCode = 0;
|
|
2547
2581
|
return;
|
|
2548
2582
|
}
|
|
@@ -2609,6 +2643,80 @@ async function runPromptMode(iteration, options) {
|
|
|
2609
2643
|
process.exitCode = 10;
|
|
2610
2644
|
}
|
|
2611
2645
|
// ═══════════════════════════════════════════════════════════
|
|
2646
|
+
// 任务完成收尾(v8.3.337+)——标记 completed + 联动 TASK.md + 完成骨架体检 + 组级聚合
|
|
2647
|
+
// 从 runApplyMode 尾部抽出为公共函数:SDK 直连(filesChanged)、--all、批次等
|
|
2648
|
+
// 所有执行路径共用,确保任何路径任务完成后端级骨架都有兜底体检。
|
|
2649
|
+
// ═══════════════════════════════════════════════════════════
|
|
2650
|
+
async function finalizeTaskCompletion(iteration, task, taskDir) {
|
|
2651
|
+
// 更新 PROJECT_GRAPH
|
|
2652
|
+
await updateProjectGraphStatus(iteration, task);
|
|
2653
|
+
// ── 标记任务状态为 completed ──
|
|
2654
|
+
try {
|
|
2655
|
+
const metaDir = (0, path_1.join)(taskDir, '.meta');
|
|
2656
|
+
await (0, fs_extra_1.ensureDir)(metaDir);
|
|
2657
|
+
await (0, fs_extra_1.writeFile)((0, path_1.join)(metaDir, 'status'), 'completed');
|
|
2658
|
+
}
|
|
2659
|
+
catch { }
|
|
2660
|
+
// v8.3.273+: 联动 TASK.md——状态行改「已完成」+ 工作清单全勾选(修复状态与 checklist 脱节)
|
|
2661
|
+
try {
|
|
2662
|
+
const taskMdPath = (0, path_1.join)(taskDir, 'TASK.md');
|
|
2663
|
+
if (await (0, fs_extra_1.pathExists)(taskMdPath)) {
|
|
2664
|
+
let md = await (0, fs_extra_1.readFile)(taskMdPath, 'utf-8');
|
|
2665
|
+
md = md.replace(/^(- \*\*状态\*\*: ).*$/m, '$1已完成');
|
|
2666
|
+
md = md.replace(/^- \[ \]/gm, '- [x]');
|
|
2667
|
+
await (0, fs_extra_1.writeFile)(taskMdPath, md);
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
catch { /* TASK.md 联动失败不阻断 */ }
|
|
2671
|
+
// v8.3.313+: 完成骨架体检——端级文档仍含骨架占位时,先尝试 CLI 自动降级填充
|
|
2672
|
+
// (REQ/TECH 从模块级 00-specs 真实规格派生端级快照),填不了的继续挂「骨架待补」待办(TASK.md + .issues.md 双账本)
|
|
2673
|
+
try {
|
|
2674
|
+
const residues = await (0, skeleton_residue_1.collectSkeletonResidues)(taskDir);
|
|
2675
|
+
if (residues.length > 0) {
|
|
2676
|
+
const filled = await (0, skeleton_residue_1.autoFillSkeletonFallback)(taskDir, residues);
|
|
2677
|
+
const remain = residues.filter(r => !filled.has(r.rel));
|
|
2678
|
+
if (filled.size > 0) {
|
|
2679
|
+
logger_1.logger.info(` 📄 完成骨架体检:${filled.size} 份端级骨架已由 CLI 自动降级填充(模块级规格快照,可在此基础上补充端级细节)`);
|
|
2680
|
+
}
|
|
2681
|
+
if (remain.length > 0) {
|
|
2682
|
+
logger_1.logger.warn(` ⚠️ 完成骨架体检:${remain.length} 份端级文档仍含骨架占位(无模块级规格可降级),已挂「骨架待补」待办(状态保持 completed,建议尽快补写规格)`);
|
|
2683
|
+
}
|
|
2684
|
+
await (0, skeleton_residue_1.appendSkeletonTodos)(taskDir, remain);
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
catch { /* 完成骨架体检失败不阻断 */ }
|
|
2688
|
+
// v8.3.273+: 组级状态聚合——所属 Task 组全部子任务完成后,组级 .meta/status 同步 completed
|
|
2689
|
+
// v8.3.337+: 组目录定位改用 isTaskModuleDirName(兼容新命名链 admin-web-01-xxx 与旧 Task-NNN)
|
|
2690
|
+
try {
|
|
2691
|
+
const parts = taskDir.split('/');
|
|
2692
|
+
const taskIdx = parts.findIndex(p => (0, task_paths_1.isTaskModuleDirName)(p));
|
|
2693
|
+
if (taskIdx >= 0) {
|
|
2694
|
+
const groupDir = parts.slice(0, taskIdx + 1).join('/');
|
|
2695
|
+
const statuses = [];
|
|
2696
|
+
const collect = async (dir) => {
|
|
2697
|
+
for (const e of await (0, fs_extra_1.readdir)(dir, { withFileTypes: true })) {
|
|
2698
|
+
if (!e.isDirectory())
|
|
2699
|
+
continue;
|
|
2700
|
+
const stPath = (0, path_1.join)(dir, e.name, '.meta', 'status');
|
|
2701
|
+
if (await (0, fs_extra_1.pathExists)(stPath)) {
|
|
2702
|
+
statuses.push((await (0, fs_extra_1.readFile)(stPath, 'utf-8')).trim());
|
|
2703
|
+
}
|
|
2704
|
+
else {
|
|
2705
|
+
await collect((0, path_1.join)(dir, e.name));
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
};
|
|
2709
|
+
await collect(groupDir);
|
|
2710
|
+
const subtaskStatuses = statuses.filter((_, i) => i !== 0); // 排除组级自身
|
|
2711
|
+
if (subtaskStatuses.length > 0 && subtaskStatuses.every(s => s === 'completed')) {
|
|
2712
|
+
await (0, fs_extra_1.writeFile)((0, path_1.join)(groupDir, '.meta', 'status'), 'completed');
|
|
2713
|
+
logger_1.logger.info(` 📊 组级状态已同步: ${(0, path_1.basename)(groupDir)} → completed(${subtaskStatuses.length} 个子任务全部完成)`);
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
catch { /* 组级聚合失败不阻断 */ }
|
|
2718
|
+
}
|
|
2719
|
+
// ═══════════════════════════════════════════════════════════
|
|
2612
2720
|
// Response 模式 — 接收 AI 返回内容,写入文件
|
|
2613
2721
|
// ═══════════════════════════════════════════════════════════
|
|
2614
2722
|
async function runApplyMode(iteration, options) {
|
|
@@ -2880,65 +2988,9 @@ async function runApplyMode(iteration, options) {
|
|
|
2880
2988
|
// 写入 .issues.md 失败不阻断
|
|
2881
2989
|
}
|
|
2882
2990
|
}
|
|
2883
|
-
//
|
|
2884
|
-
await updateProjectGraphStatus(iteration, task);
|
|
2885
|
-
// ── 标记任务状态为 completed ──
|
|
2991
|
+
// v8.3.337+: 任务完成收尾(标记 completed + TASK.md 联动 + 骨架体检 + 组级聚合)抽为公共函数
|
|
2886
2992
|
const taskDirForStatus = await resolveTaskDir(iterDir, task);
|
|
2887
|
-
|
|
2888
|
-
const metaDir = (0, path_1.join)(taskDirForStatus, '.meta');
|
|
2889
|
-
await (0, fs_extra_1.ensureDir)(metaDir);
|
|
2890
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(metaDir, 'status'), 'completed');
|
|
2891
|
-
}
|
|
2892
|
-
catch { }
|
|
2893
|
-
// v8.3.273+: 联动 TASK.md——状态行改「已完成」+ 工作清单全勾选(修复状态与 checklist 脱节)
|
|
2894
|
-
try {
|
|
2895
|
-
const taskMdPath = (0, path_1.join)(taskDirForStatus, 'TASK.md');
|
|
2896
|
-
if (await (0, fs_extra_1.pathExists)(taskMdPath)) {
|
|
2897
|
-
let md = await (0, fs_extra_1.readFile)(taskMdPath, 'utf-8');
|
|
2898
|
-
md = md.replace(/^(- \*\*状态\*\*: ).*$/m, '$1已完成');
|
|
2899
|
-
md = md.replace(/^- \[ \]/gm, '- [x]');
|
|
2900
|
-
await (0, fs_extra_1.writeFile)(taskMdPath, md);
|
|
2901
|
-
}
|
|
2902
|
-
}
|
|
2903
|
-
catch { /* TASK.md 联动失败不阻断 */ }
|
|
2904
|
-
// v8.3.313+: 完成骨架体检——端级文档仍含骨架占位时 completed 照常,但挂「骨架待补」待办(TASK.md + .issues.md 双账本)
|
|
2905
|
-
try {
|
|
2906
|
-
const residues = await (0, skeleton_residue_1.collectSkeletonResidues)(taskDirForStatus);
|
|
2907
|
-
if (residues.length > 0) {
|
|
2908
|
-
logger_1.logger.warn(` ⚠️ 完成骨架体检:${residues.length} 份端级文档仍含骨架占位,已挂「骨架待补」待办(状态保持 completed,建议尽快补写规格)`);
|
|
2909
|
-
await (0, skeleton_residue_1.appendSkeletonTodos)(taskDirForStatus, residues);
|
|
2910
|
-
}
|
|
2911
|
-
}
|
|
2912
|
-
catch { /* 完成骨架体检失败不阻断 */ }
|
|
2913
|
-
// v8.3.273+: 组级状态聚合——所属 Task 组全部子任务完成后,组级 .meta/status 同步 completed
|
|
2914
|
-
try {
|
|
2915
|
-
const parts = taskDirForStatus.split('/');
|
|
2916
|
-
const taskIdx = parts.findIndex(p => /^Task-\d+/.test(p));
|
|
2917
|
-
if (taskIdx >= 0) {
|
|
2918
|
-
const groupDir = parts.slice(0, taskIdx + 1).join('/');
|
|
2919
|
-
const statuses = [];
|
|
2920
|
-
const collect = async (dir) => {
|
|
2921
|
-
for (const e of await (0, fs_extra_1.readdir)(dir, { withFileTypes: true })) {
|
|
2922
|
-
if (!e.isDirectory())
|
|
2923
|
-
continue;
|
|
2924
|
-
const stPath = (0, path_1.join)(dir, e.name, '.meta', 'status');
|
|
2925
|
-
if (await (0, fs_extra_1.pathExists)(stPath)) {
|
|
2926
|
-
statuses.push((await (0, fs_extra_1.readFile)(stPath, 'utf-8')).trim());
|
|
2927
|
-
}
|
|
2928
|
-
else {
|
|
2929
|
-
await collect((0, path_1.join)(dir, e.name));
|
|
2930
|
-
}
|
|
2931
|
-
}
|
|
2932
|
-
};
|
|
2933
|
-
await collect(groupDir);
|
|
2934
|
-
const subtaskStatuses = statuses.filter((_, i) => i !== 0); // 排除组级自身
|
|
2935
|
-
if (subtaskStatuses.length > 0 && subtaskStatuses.every(s => s === 'completed')) {
|
|
2936
|
-
await (0, fs_extra_1.writeFile)((0, path_1.join)(groupDir, '.meta', 'status'), 'completed');
|
|
2937
|
-
logger_1.logger.info(` 📊 组级状态已同步: ${(0, path_1.basename)(groupDir)} → completed(${subtaskStatuses.length} 个子任务全部完成)`);
|
|
2938
|
-
}
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
catch { /* 组级聚合失败不阻断 */ }
|
|
2993
|
+
await finalizeTaskCompletion(iteration, task, taskDirForStatus);
|
|
2942
2994
|
logger_1.logger.success(`\n📁 完成: ${writtenCount} 个文件已写入`);
|
|
2943
2995
|
logger_1.logger.info(` 📂 位置: ${iterDir}/`);
|
|
2944
2996
|
// v6.69.1: 记录任务执行快照,支持下次增量检测
|
|
@@ -2984,7 +3036,7 @@ function outputPostSummary(iteration, task, fileCount, filePaths) {
|
|
|
2984
3036
|
logger_1.logger.info('');
|
|
2985
3037
|
logger_1.logger.warn('🔄 检测到接口/实体变更,建议刷新全局层:');
|
|
2986
3038
|
logger_1.logger.info(` → speccore global analyze --with-code # 刷新全局 FUNCTION_MAP.md / API_CONTRACT.yaml`);
|
|
2987
|
-
logger_1.logger.info(` → speccore
|
|
3039
|
+
logger_1.logger.info(` → speccore reindex # 重建检索索引`);
|
|
2988
3040
|
}
|
|
2989
3041
|
logger_1.logger.info('━'.repeat(40));
|
|
2990
3042
|
}
|