speccore 8.3.181 → 8.3.188
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-analyze/SKILL.md +2 -169
- package/.agents/skills/spec-ask/SKILL.md +2 -177
- package/.agents/skills/spec-change/SKILL.md +2 -214
- package/.agents/skills/spec-dashboard/SKILL.md +1 -76
- package/.agents/skills/spec-deploy/SKILL.md +2 -298
- package/.agents/skills/spec-doc2spec/SKILL.md +2 -116
- package/.agents/skills/spec-done/SKILL.md +2 -203
- package/.agents/skills/spec-execute/SKILL.md +2 -178
- package/.agents/skills/spec-help/SKILL.md +1 -75
- package/.agents/skills/spec-iteration-create/SKILL.md +2 -123
- package/.agents/skills/spec-plan/SKILL.md +2 -117
- package/.agents/skills/spec-pr/SKILL.md +2 -203
- package/.agents/skills/spec-run/SKILL.md +16 -0
- package/.agents/skills/spec-spec2doc/SKILL.md +2 -121
- package/.agents/skills/spec-split/SKILL.md +2 -208
- package/.agents/skills/spec-task-create/SKILL.md +2 -151
- package/.agents/skills/spec-verify/SKILL.md +2 -214
- package/.agents/skills/spec-welcome/SKILL.md +1 -67
- package/.agents/skills/speccore-router/SKILL.md +14 -2
- package/README.en.md +9 -9
- package/README.md +2 -1
- package/dist/cli.js +24 -25
- package/dist/cli.js.map +1 -1
- package/dist/commands/about.js +1 -1
- package/dist/commands/about.js.map +1 -1
- package/dist/commands/analyze.d.ts +1 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +94 -7
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/ask.js +6 -6
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/dev.d.ts +2 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +102 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.js +28 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/execute.js +3 -3
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +31 -52
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/iteration/split.d.ts.map +1 -1
- package/dist/commands/iteration/split.js +12 -39
- package/dist/commands/iteration/split.js.map +1 -1
- package/dist/commands/knowledge.d.ts +0 -12
- package/dist/commands/knowledge.d.ts.map +1 -1
- package/dist/commands/knowledge.js +0 -80
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/refresh.d.ts.map +1 -1
- package/dist/commands/refresh.js +10 -0
- package/dist/commands/refresh.js.map +1 -1
- package/dist/commands/search.d.ts +1 -0
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +38 -0
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +13 -3
- package/dist/commands/update.js.map +1 -1
- package/dist/core/agent-adapter.d.ts +6 -0
- package/dist/core/agent-adapter.d.ts.map +1 -1
- package/dist/core/agent-adapter.js +56 -172
- package/dist/core/agent-adapter.js.map +1 -1
- package/dist/core/agents/defaults/code-generator.md +64 -0
- package/dist/core/agents/defaults/code-reviewer.md +5 -0
- package/dist/core/agents/defaults/compiler.md +7 -0
- package/dist/core/agents/defaults/compliance-checker.md +2 -0
- package/dist/core/agents/defaults/dependency-analyst.md +5 -0
- package/dist/core/agents/defaults/doc-sync-agent.md +5 -0
- package/dist/core/agents/defaults/effort-estimator.md +28 -0
- package/dist/core/agents/defaults/global-analyzer.md +66 -0
- package/dist/core/agents/defaults/impact-analyst.md +5 -0
- package/dist/core/agents/defaults/interaction-designer.md +5 -0
- package/dist/core/agents/defaults/performance-expert.md +2 -0
- package/dist/core/agents/defaults/product-analyst-backend.md +6 -0
- package/dist/core/agents/defaults/product-analyst-frontend.md +6 -0
- package/dist/core/agents/defaults/product-analyst.md +5 -0
- package/dist/core/agents/defaults/regression-tester.md +5 -0
- package/dist/core/agents/defaults/requirement-analyzer.md +72 -0
- package/dist/core/agents/defaults/risk-assessor.md +5 -0
- package/dist/core/agents/defaults/schedule-planner.md +5 -0
- package/dist/core/agents/defaults/security-reviewer-finance.md +6 -0
- package/dist/core/agents/defaults/security-reviewer.md +7 -0
- package/dist/core/agents/defaults/task-decomposer.md +5 -0
- package/dist/core/agents/defaults/test-engineer.md +2 -0
- package/dist/core/agents/defaults/test-reviewer.md +5 -0
- package/dist/core/agents/engine/agent-loader.d.ts.map +1 -1
- package/dist/core/agents/engine/agent-loader.js +76 -6
- package/dist/core/agents/engine/agent-loader.js.map +1 -1
- package/dist/core/agents/engine/types.d.ts +5 -0
- package/dist/core/agents/engine/types.d.ts.map +1 -1
- package/dist/core/analyze-engine.d.ts.map +1 -1
- package/dist/core/analyze-engine.js +73 -82
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-engine.d.ts +0 -58
- package/dist/core/ask-engine.d.ts.map +1 -1
- package/dist/core/ask-engine.js +63 -361
- package/dist/core/ask-engine.js.map +1 -1
- package/dist/core/business-rules.d.ts +36 -0
- package/dist/core/business-rules.d.ts.map +1 -0
- package/dist/core/business-rules.js +109 -0
- package/dist/core/business-rules.js.map +1 -0
- package/dist/core/change-impact-global.d.ts.map +1 -1
- package/dist/core/change-impact-global.js +4 -3
- package/dist/core/change-impact-global.js.map +1 -1
- package/dist/core/code-scanner.d.ts +1 -0
- package/dist/core/code-scanner.d.ts.map +1 -1
- package/dist/core/code-scanner.js +32 -3
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/content-delivery.d.ts +59 -0
- package/dist/core/content-delivery.d.ts.map +1 -0
- package/dist/core/content-delivery.js +219 -0
- package/dist/core/content-delivery.js.map +1 -0
- package/dist/core/global-artifacts.d.ts.map +1 -1
- package/dist/core/global-artifacts.js +262 -19
- package/dist/core/global-artifacts.js.map +1 -1
- package/dist/core/global-retrieval.d.ts +38 -0
- package/dist/core/global-retrieval.d.ts.map +1 -0
- package/dist/core/global-retrieval.js +100 -0
- package/dist/core/global-retrieval.js.map +1 -0
- package/dist/core/html-prototype.d.ts +22 -0
- package/dist/core/html-prototype.d.ts.map +1 -0
- package/dist/core/html-prototype.js +103 -0
- package/dist/core/html-prototype.js.map +1 -0
- package/dist/core/multi-lang-parser.d.ts +43 -0
- package/dist/core/multi-lang-parser.d.ts.map +1 -0
- package/dist/core/multi-lang-parser.js +317 -0
- package/dist/core/multi-lang-parser.js.map +1 -0
- package/dist/core/pipeline-engine.js +16 -16
- package/dist/core/pipeline-engine.js.map +1 -1
- package/dist/core/platform-inference.d.ts +35 -0
- package/dist/core/platform-inference.d.ts.map +1 -0
- package/dist/core/platform-inference.js +205 -0
- package/dist/core/platform-inference.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +1 -1
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +101 -75
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/refresh-scheduler.d.ts +50 -0
- package/dist/core/refresh-scheduler.d.ts.map +1 -0
- package/dist/core/refresh-scheduler.js +139 -0
- package/dist/core/refresh-scheduler.js.map +1 -0
- package/dist/core/reverse-requirement.d.ts +54 -0
- package/dist/core/reverse-requirement.d.ts.map +1 -0
- package/dist/core/reverse-requirement.js +277 -0
- package/dist/core/reverse-requirement.js.map +1 -0
- package/dist/core/schemas/task.schema.d.ts +2 -2
- package/dist/core/spec-skeleton.d.ts.map +1 -1
- package/dist/core/spec-skeleton.js +123 -0
- package/dist/core/spec-skeleton.js.map +1 -1
- package/dist/core/unified-config.d.ts +14 -0
- package/dist/core/unified-config.d.ts.map +1 -1
- package/dist/core/unified-config.js +94 -10
- package/dist/core/unified-config.js.map +1 -1
- package/dist/core/unified-retrieval.d.ts.map +1 -1
- package/dist/core/unified-retrieval.js +34 -8
- package/dist/core/unified-retrieval.js.map +1 -1
- package/dist/utils/task-utils.d.ts +4 -0
- package/dist/utils/task-utils.d.ts.map +1 -1
- package/dist/utils/task-utils.js +18 -0
- package/dist/utils/task-utils.js.map +1 -1
- package/package.json +5 -3
- package/vendor/tree-sitter/tree-sitter-go.wasm +0 -0
- package/vendor/tree-sitter/tree-sitter-java.wasm +0 -0
- package/vendor/tree-sitter/tree-sitter-python.wasm +0 -0
- package/vendor/tree-sitter/tree-sitter-rust.wasm +0 -0
- package/.agents/agents/README.md +0 -79
- package/.agents/agents/spec-analyzer.md +0 -41
- package/.agents/agents/spec-architect.md +0 -57
- package/.agents/agents/spec-change-detector.md +0 -55
- package/.agents/agents/spec-clarifier.md +0 -83
- package/.agents/agents/spec-executor.md +0 -41
- package/.agents/agents/spec-gatekeeper.md +0 -84
- package/.agents/agents/spec-global-analyzer.md +0 -111
- package/.agents/agents/spec-knowledge-curator.md +0 -54
- package/.agents/agents/spec-reviewer.md +0 -46
- package/.agents/agents/spec-security-auditor.md +0 -56
- package/.agents/agents/spec-tester.md +0 -120
- package/.agents/skills/spec-analyze/references/analysis-report.md +0 -9
- package/.agents/skills/spec-execute/references/code-output.md +0 -13
- package/.agents/skills/spec-plan/references/plan-template.md +0 -29
- package/.agents/skills/spec-task-create/references/requirement-template.md +0 -23
- package/dist/commands/bugfix.d.ts +0 -17
- package/dist/commands/bugfix.d.ts.map +0 -1
- package/dist/commands/bugfix.js +0 -301
- package/dist/commands/bugfix.js.map +0 -1
- package/dist/commands/help-quick.d.ts +0 -3
- package/dist/commands/help-quick.d.ts.map +0 -1
- package/dist/commands/help-quick.js +0 -66
- package/dist/commands/help-quick.js.map +0 -1
- package/dist/commands/index-update.d.ts +0 -8
- package/dist/commands/index-update.d.ts.map +0 -1
- package/dist/commands/index-update.js +0 -180
- package/dist/commands/index-update.js.map +0 -1
- package/dist/commands/schedule.d.ts +0 -26
- package/dist/commands/schedule.d.ts.map +0 -1
- package/dist/commands/schedule.js +0 -182
- package/dist/commands/schedule.js.map +0 -1
- package/dist/commands/watch.d.ts +0 -11
- package/dist/commands/watch.d.ts.map +0 -1
- package/dist/commands/watch.js +0 -166
- package/dist/commands/watch.js.map +0 -1
- package/dist/core/ai-markdown.d.ts +0 -5
- package/dist/core/ai-markdown.d.ts.map +0 -1
- package/dist/core/ai-markdown.js +0 -29
- package/dist/core/ai-markdown.js.map +0 -1
- package/dist/core/schedule-engine.d.ts +0 -25
- package/dist/core/schedule-engine.d.ts.map +0 -1
- package/dist/core/schedule-engine.js +0 -281
- package/dist/core/schedule-engine.js.map +0 -1
- package/dist/core/schedule-store.d.ts +0 -119
- package/dist/core/schedule-store.d.ts.map +0 -1
- package/dist/core/schedule-store.js +0 -216
- package/dist/core/schedule-store.js.map +0 -1
|
@@ -58,7 +58,12 @@ const knowledge_graph_1 = require("./knowledge-graph");
|
|
|
58
58
|
const context_builder_1 = require("./context-builder");
|
|
59
59
|
const spec_paths_1 = require("./spec-paths");
|
|
60
60
|
const context_1 = require("./context");
|
|
61
|
+
const rag_engine_1 = require("./rag-engine");
|
|
61
62
|
const unified_retrieval_1 = require("./unified-retrieval");
|
|
63
|
+
// v8.3.183+: 统一内容供给管线(md 大纲摘要,替代链接全文内联)
|
|
64
|
+
const content_delivery_1 = require("./content-delivery");
|
|
65
|
+
// v8.3.183+: HTML 原型渲染(Playwright 截图 + accessibility tree,替代纯文本)
|
|
66
|
+
const html_prototype_1 = require("./html-prototype");
|
|
62
67
|
// v8.3.122+: execute 时深入读取关联源码
|
|
63
68
|
const code_scanner_1 = require("./code-scanner");
|
|
64
69
|
// v8.3.125+: 同义词扩展,解决中英文/缩写关键词匹配失败
|
|
@@ -415,7 +420,12 @@ async function loadExtraSpecs(cwd, taskDir, platform, iteration, options) {
|
|
|
415
420
|
const budget = getFileBudget(fileName);
|
|
416
421
|
if (content.length > budget.limit) {
|
|
417
422
|
if (budget.mode === 'error') {
|
|
418
|
-
logger_1.logger.error(`[prompt-builder] ${fileName} 超过预算上限 (${content.length} > ${budget.limit})
|
|
423
|
+
logger_1.logger.error(`[prompt-builder] ${fileName} 超过预算上限 (${content.length} > ${budget.limit})。`);
|
|
424
|
+
logger_1.logger.error(` 该文件属于"必须完整"类型,不会被截断。建议精简方式:`);
|
|
425
|
+
logger_1.logger.error(` - 删除过时的注释和示例代码`);
|
|
426
|
+
logger_1.logger.error(` - 将详细说明链接到外部文档`);
|
|
427
|
+
logger_1.logger.error(` - 使用表格代替冗长的列表`);
|
|
428
|
+
logger_1.logger.error(` - 精简后重新执行: speccore execute --resume`);
|
|
419
429
|
// 不截断,保留完整内容
|
|
420
430
|
}
|
|
421
431
|
else {
|
|
@@ -537,14 +547,28 @@ async function loadExtraSpecs(cwd, taskDir, platform, iteration, options) {
|
|
|
537
547
|
* 只加载 ALLOWED_EXTRA_FILES 白名单内的文件,防止上下文污染
|
|
538
548
|
* 白名单外文件将被忽略并输出提示
|
|
539
549
|
*/
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
'
|
|
550
|
+
// v8.3.182+: 白名单分两级(核心 + 条件)
|
|
551
|
+
// 核心白名单:所有任务都需要
|
|
552
|
+
const CORE_EXTRA_FILES = new Set([
|
|
553
|
+
'CONTEXT.md', // 任务上下文(来源追溯 + 关联任务)
|
|
554
|
+
'ERROR_CODES.md', // 错误码定义
|
|
544
555
|
]);
|
|
556
|
+
// 条件白名单:按平台类型加载
|
|
557
|
+
function getPlatformExtraFiles(platform) {
|
|
558
|
+
if (!platform)
|
|
559
|
+
return new Set();
|
|
560
|
+
const p = platform.toLowerCase();
|
|
561
|
+
if (p.includes('backend') || p.includes('service') || p.includes('api') || p.includes('server')) {
|
|
562
|
+
return new Set(['SCHEMA.md']);
|
|
563
|
+
}
|
|
564
|
+
if (p.includes('web') || p.includes('mobile') || p.includes('h5') || p.includes('frontend') || p.includes('admin')) {
|
|
565
|
+
return new Set(['COMPONENT_TREE.md', 'ROUTES.md', 'STATE.md']);
|
|
566
|
+
}
|
|
567
|
+
return new Set();
|
|
568
|
+
}
|
|
545
569
|
// v8.3.181+: 按文件类型细分预算(必须完整 vs 可以截断)
|
|
546
570
|
const FILE_BUDGETS = {
|
|
547
|
-
'CONSTITUTION.md': { limit:
|
|
571
|
+
'CONSTITUTION.md': { limit: 6000, mode: 'error' },
|
|
548
572
|
'REQ.md': { limit: 2000, mode: 'error' },
|
|
549
573
|
'API_CONTRACT.yaml': { limit: 2000, mode: 'error' },
|
|
550
574
|
'TASK.md': { limit: 1500, mode: 'truncate' },
|
|
@@ -560,6 +584,9 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
560
584
|
const validExts = ['.md', '.yaml', '.yml', '.json', '.html', '.htm'];
|
|
561
585
|
const skipDirs = new Set(['.meta', '.git', 'node_modules', 'tests', 'src', 'dist', 'build']);
|
|
562
586
|
const ignoredFiles = [];
|
|
587
|
+
// v8.3.182+: 合并核心白名单 + 条件白名单
|
|
588
|
+
const platformExtras = getPlatformExtraFiles(platform);
|
|
589
|
+
const allowedFiles = new Set([...CORE_EXTRA_FILES, ...platformExtras]);
|
|
563
590
|
// 1. 扫描 00-specs/ 下白名单内的文件
|
|
564
591
|
const specsDir = (0, path_1.join)(cwd, taskDir, '00-specs');
|
|
565
592
|
try {
|
|
@@ -571,7 +598,7 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
571
598
|
const ext = e.name.slice(e.name.lastIndexOf('.'));
|
|
572
599
|
if (!validExts.includes(ext))
|
|
573
600
|
continue;
|
|
574
|
-
if (!
|
|
601
|
+
if (!allowedFiles.has(e.name)) {
|
|
575
602
|
ignoredFiles.push(`00-specs/${e.name}`);
|
|
576
603
|
continue;
|
|
577
604
|
}
|
|
@@ -594,7 +621,7 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
594
621
|
if (!subE.isDirectory() || subE.name.startsWith('.'))
|
|
595
622
|
continue;
|
|
596
623
|
const subtaskDir = (0, path_1.join)(platformBase, subE.name);
|
|
597
|
-
await scanDirRecursive(subtaskDir, (0, path_1.join)(platform, subE.name), results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles);
|
|
624
|
+
await scanDirRecursive(subtaskDir, (0, path_1.join)(platform, subE.name), results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles, allowedFiles);
|
|
598
625
|
}
|
|
599
626
|
}
|
|
600
627
|
}
|
|
@@ -613,7 +640,7 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
613
640
|
return results;
|
|
614
641
|
}
|
|
615
642
|
/** 递归扫描目录,收集用户自定义文档(白名单模式) */
|
|
616
|
-
async function scanDirRecursive(dir, relPrefix, results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles) {
|
|
643
|
+
async function scanDirRecursive(dir, relPrefix, results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles, allowedFiles) {
|
|
617
644
|
try {
|
|
618
645
|
const entries = await (0, fs_extra_1.readdir)(dir, { withFileTypes: true });
|
|
619
646
|
for (const e of entries) {
|
|
@@ -622,13 +649,13 @@ async function scanDirRecursive(dir, relPrefix, results, seenPaths, skipDirs, va
|
|
|
622
649
|
if (e.isDirectory()) {
|
|
623
650
|
if (skipDirs.has(e.name) || e.name.startsWith('.'))
|
|
624
651
|
continue;
|
|
625
|
-
await scanDirRecursive((0, path_1.join)(dir, e.name), relPath, results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles);
|
|
652
|
+
await scanDirRecursive((0, path_1.join)(dir, e.name), relPath, results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles, allowedFiles);
|
|
626
653
|
}
|
|
627
654
|
else if (e.isFile()) {
|
|
628
655
|
const ext = e.name.slice(e.name.lastIndexOf('.'));
|
|
629
656
|
if (!validExts.includes(ext))
|
|
630
657
|
continue;
|
|
631
|
-
if (!
|
|
658
|
+
if (!allowedFiles.has(e.name)) {
|
|
632
659
|
ignoredFiles.push(relPath);
|
|
633
660
|
continue;
|
|
634
661
|
}
|
|
@@ -676,7 +703,12 @@ async function loadAllTaskContext(cwd, taskDir, platform, iteration, graph) {
|
|
|
676
703
|
const fallbackLimit = budget.limit * 2;
|
|
677
704
|
if (content.length > fallbackLimit) {
|
|
678
705
|
if (budget.mode === 'error') {
|
|
679
|
-
logger_1.logger.error(`[prompt-builder] ${fileName} 超过兜底预算上限 (${content.length} > ${fallbackLimit})
|
|
706
|
+
logger_1.logger.error(`[prompt-builder] ${fileName} 超过兜底预算上限 (${content.length} > ${fallbackLimit})。`);
|
|
707
|
+
logger_1.logger.error(` 该文件属于"必须完整"类型,不会被截断。建议精简方式:`);
|
|
708
|
+
logger_1.logger.error(` - 删除过时的注释和示例代码`);
|
|
709
|
+
logger_1.logger.error(` - 将详细说明链接到外部文档`);
|
|
710
|
+
logger_1.logger.error(` - 使用表格代替冗长的列表`);
|
|
711
|
+
logger_1.logger.error(` - 精简后重新执行: speccore execute --resume`);
|
|
680
712
|
// 不截断
|
|
681
713
|
}
|
|
682
714
|
else {
|
|
@@ -1059,7 +1091,7 @@ async function buildGlobalTOC(globalDir) {
|
|
|
1059
1091
|
* 加载全局上下文(带 TOC 缓存)
|
|
1060
1092
|
* 策略:必读的 INDEX.md 直接注入 + 其余文件只给目录,AI 自己 Read
|
|
1061
1093
|
*/
|
|
1062
|
-
async function loadGlobalContext(cwd, _command, platform) {
|
|
1094
|
+
async function loadGlobalContext(cwd, _command, platform, feature) {
|
|
1063
1095
|
const globalDir = (0, path_1.join)(cwd, '.speccore', 'GLOBAL');
|
|
1064
1096
|
const ctx = { toc: [] };
|
|
1065
1097
|
if (!await (0, fs_extra_1.pathExists)(globalDir))
|
|
@@ -1074,37 +1106,15 @@ async function loadGlobalContext(cwd, _command, platform) {
|
|
|
1074
1106
|
// 支持单文件(单文件模式)+ BUSINESS_RULES/ 目录(推荐,支持按 platform 过滤)
|
|
1075
1107
|
if (!ctx.keyFileSummaries)
|
|
1076
1108
|
ctx.keyFileSummaries = [];
|
|
1077
|
-
//
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
ctx.keyFileSummaries.push({ path:
|
|
1083
|
-
}
|
|
1084
|
-
catch { /* 忽略 */ }
|
|
1085
|
-
}
|
|
1086
|
-
// 2. 新路径:GLOBAL/BUSINESS_RULES/ 目录,按 platform 过滤加载
|
|
1087
|
-
const businessRulesDir = (0, path_1.join)(globalDir, 'BUSINESS_RULES');
|
|
1088
|
-
if (await (0, fs_extra_1.pathExists)(businessRulesDir)) {
|
|
1089
|
-
try {
|
|
1090
|
-
const files = (await (0, fs_extra_1.readdir)(businessRulesDir))
|
|
1091
|
-
.filter(f => f.endsWith('.md'))
|
|
1092
|
-
.sort();
|
|
1093
|
-
for (const file of files) {
|
|
1094
|
-
// platform 过滤:无 platform 时加载全部;有 platform 时加载 common + 匹配端
|
|
1095
|
-
if (platform) {
|
|
1096
|
-
const base = file.replace(/\.md$/, '');
|
|
1097
|
-
const isCommon = base.includes('-common');
|
|
1098
|
-
const isPlatformMatch = base === platform || base.endsWith(`-${platform}`) || base.includes(`-${platform}-`);
|
|
1099
|
-
if (!isCommon && !isPlatformMatch)
|
|
1100
|
-
continue;
|
|
1101
|
-
}
|
|
1102
|
-
const content = await (0, fs_extra_1.readFile)((0, path_1.join)(businessRulesDir, file), 'utf-8');
|
|
1103
|
-
ctx.keyFileSummaries.push({ path: `BUSINESS_RULES/${file}`, content: content.slice(0, 4000) });
|
|
1104
|
-
}
|
|
1109
|
+
// v8.3.184+: 业务规则三层统一加载(全局 BUSINESS_RULES/ + 端级 + 功能级)
|
|
1110
|
+
try {
|
|
1111
|
+
const { loadBusinessRules } = await Promise.resolve().then(() => __importStar(require('./business-rules')));
|
|
1112
|
+
const rules = await loadBusinessRules({ cwd, platform, feature });
|
|
1113
|
+
for (const item of rules) {
|
|
1114
|
+
ctx.keyFileSummaries.push({ path: item.path, content: item.content });
|
|
1105
1115
|
}
|
|
1106
|
-
catch { /* 忽略 */ }
|
|
1107
1116
|
}
|
|
1117
|
+
catch { /* 忽略 */ }
|
|
1108
1118
|
// 3. v8.3.134+: RULES/ 规则文件自动注入(四层架构第二层)
|
|
1109
1119
|
// 按 frontmatter priority 降序排序,优先加载高优先级规则;总量上限 8000 字符
|
|
1110
1120
|
const rulesDir = (0, path_1.join)(cwd, '.speccore', 'RULES');
|
|
@@ -1604,8 +1614,8 @@ function getInstruction(command, context) {
|
|
|
1604
1614
|
*/
|
|
1605
1615
|
// v8.3.160+: 命令 → 默认子 Agent 角色映射
|
|
1606
1616
|
const DEFAULT_SUBAGENT_MAP = {
|
|
1607
|
-
analyze: '
|
|
1608
|
-
execute: '
|
|
1617
|
+
analyze: 'requirement-analyzer',
|
|
1618
|
+
execute: 'code-generator',
|
|
1609
1619
|
split: 'task-decomposer',
|
|
1610
1620
|
plan: 'schedule-planner',
|
|
1611
1621
|
change: 'impact-analyst',
|
|
@@ -2404,6 +2414,23 @@ function formatPrompt(prompt, maxTokens) {
|
|
|
2404
2414
|
logger_1.logger?.info?.(` 🪶 Prompt 已极简模式:仅保留技术栈/API/核心指令`);
|
|
2405
2415
|
return result;
|
|
2406
2416
|
}
|
|
2417
|
+
// ═══════════════════════════════════════════════════════════
|
|
2418
|
+
// v8.3.187+ 通用行为准则(degrade to honesty 体系)
|
|
2419
|
+
// 融合业界最佳实践:
|
|
2420
|
+
// - Claude Code 官方系统提示词:Read before write / Minimal change / 不臆造 API
|
|
2421
|
+
// - Anthropic Prompt Library:avoid over-engineering / hallucination-free / 诚实标注
|
|
2422
|
+
// - Karpathy 12 规则:Think before coding / Precise edits / 主动澄清 / 明确失败报告
|
|
2423
|
+
// 原则:少而精(5–8 条为宜,过多会导致合规率骤降),每条可操作、正面指令 + 明确禁止结合。
|
|
2424
|
+
// ═══════════════════════════════════════════════════════════
|
|
2425
|
+
const UNIVERSAL_BEHAVIOR_RULES = [
|
|
2426
|
+
'- **Spec 优先(最高优先级)**:代码、口头要求与 Spec(REQ/TECH/API_CONTRACT)冲突时,一律以 Spec 为准,并明确指出冲突点与差异。',
|
|
2427
|
+
'- **先读后写**:动手改代码前,先读相关 Spec 与现有实现;禁止凭空臆造不存在的 API、字段、路径或库方法,不确定就查,查不到就如实说明。',
|
|
2428
|
+
'- **不迎合用户**:优先保证技术正确与真实,而非附和用户;需求有缺陷、自相矛盾或不合理处,直接指出并给建议,不为顺从而照做。',
|
|
2429
|
+
'- **最小改动**:只做当前任务要求或明确必要的改动;不顺手重构无关代码、不添加超出需求的「改进」、不过度设计;无用代码直接删除,不留兼容性 hack。',
|
|
2430
|
+
'- **主动澄清**:需求或 Spec 有歧义、缺关键信息时,先提出澄清问题或明确列出假设,不擅自猜测后闷头实现。',
|
|
2431
|
+
'- **降级到诚实**:区分「事实 / 推断 / 猜测」;不确定的信息标注置信度,不编造;做不到或没把握的方案,说明局限,不给自信的错误答案。',
|
|
2432
|
+
'- **破坏性操作先确认**:删除、覆盖、迁移文件或改动公共 API 等影响面大/不可逆的操作,先说明影响并确认后再执行。',
|
|
2433
|
+
];
|
|
2407
2434
|
/** 实际构建 prompt 文本(无裁剪逻辑) */
|
|
2408
2435
|
function buildPromptText(prompt) {
|
|
2409
2436
|
// v8.3.160+: analyze 命令使用 buildMultiDocPrompt 生成的原始 Prompt,直接返回
|
|
@@ -2413,6 +2440,11 @@ function buildPromptText(prompt) {
|
|
|
2413
2440
|
const lines = [];
|
|
2414
2441
|
lines.push('[SPECCORE_PROMPT]');
|
|
2415
2442
|
lines.push('');
|
|
2443
|
+
// v8.3.184+ 通用行为准则(v8.3.187+ 扩展并抽取为 UNIVERSAL_BEHAVIOR_RULES 常量)
|
|
2444
|
+
lines.push('## 通用行为准则');
|
|
2445
|
+
for (const rule of UNIVERSAL_BEHAVIOR_RULES)
|
|
2446
|
+
lines.push(rule);
|
|
2447
|
+
lines.push('');
|
|
2416
2448
|
// v8.3.160+: 注入子 Agent 角色定义和上下文裁剪策略
|
|
2417
2449
|
if (prompt.agentContext) {
|
|
2418
2450
|
lines.push(prompt.agentContext);
|
|
@@ -2774,32 +2806,22 @@ async function expandMarkdownLinks(content, baseDir, seenPaths, maxDepth = 3, cu
|
|
|
2774
2806
|
let linkContent = await (0, fs_extra_1.readFile)(resolved, 'utf-8');
|
|
2775
2807
|
if (linkContent.trim().length <= 30)
|
|
2776
2808
|
continue;
|
|
2777
|
-
// v8.3.138+: HTML/原型文件使用独立阈值(8KB),避免原型文件被过度截断。
|
|
2778
|
-
// 超过阈值不截断 inline(避免结构残缺误导 AI),而是提示宿主 AI 直接打开查看。
|
|
2779
2809
|
const isHtml = resolved.endsWith('.html') || resolved.endsWith('.htm');
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
`- 文件: ${resolved}\n` +
|
|
2785
|
-
`- 大小: ${(linkContent.length / 1024).toFixed(1)} KB\n` +
|
|
2786
|
-
`- 描述: ${link.text || '无描述'}\n` +
|
|
2787
|
-
`> ⚠️ **请打开此 HTML 文件查看完整内容**。此为页面原型/设计稿,与需求理解高度相关,CLI 因文件过大未完整展开,需要你直接打开文件查看。`);
|
|
2788
|
-
continue;
|
|
2789
|
-
}
|
|
2790
|
-
// v8.3.122+: HTML 原型文件保留完整内容,不再提取纯文本
|
|
2810
|
+
// v8.3.183+: 统一用结构化摘要替代全文内联
|
|
2811
|
+
// - html → Playwright accessibility tree(页面结构),失败降级 extractHtmlText
|
|
2812
|
+
// - md → 标题大纲
|
|
2813
|
+
let rawSummary;
|
|
2791
2814
|
if (isHtml) {
|
|
2792
|
-
|
|
2815
|
+
const proto = await (0, html_prototype_1.renderHtmlPrototype)(resolved);
|
|
2816
|
+
rawSummary = proto?.accessibilityTree || (0, rag_engine_1.extractHtmlText)(linkContent);
|
|
2793
2817
|
}
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
linkContent = linkContent.slice(0, maxChars) +
|
|
2797
|
-
`\n\n---\n📄 **文件内容已截断**(宿主 AI 请务必打开查看完整内容):\n` +
|
|
2798
|
-
`- 文件: ${resolved}\n` +
|
|
2799
|
-
`- 大小: ${(await (0, fs_extra_1.stat)(resolved)).size} 字节\n` +
|
|
2800
|
-
`> ⚠️ **请打开此文件查看完整内容**。此文件与需求理解高度相关,CLI 因长度限制已截断,需要你直接打开文件查看。`;
|
|
2818
|
+
else {
|
|
2819
|
+
rawSummary = (0, content_delivery_1.extractMdOutline)(linkContent);
|
|
2801
2820
|
}
|
|
2802
|
-
|
|
2821
|
+
const summary = rawSummary.length > maxChars
|
|
2822
|
+
? rawSummary.slice(0, maxChars) + '\n…(摘要截断)'
|
|
2823
|
+
: rawSummary;
|
|
2824
|
+
expansions.push(`\n\n**[链接] ${link.text}** (${link.path}):\n${summary}\n> 全文见 \`${resolved}\``);
|
|
2803
2825
|
}
|
|
2804
2826
|
catch { /* 忽略读取失败的链接文件 */ }
|
|
2805
2827
|
}
|
|
@@ -2873,17 +2895,21 @@ async function inlineMarkdownImages(content, baseDir, seenPaths, visionConfig, m
|
|
|
2873
2895
|
}
|
|
2874
2896
|
}
|
|
2875
2897
|
else {
|
|
2876
|
-
// v8.3.
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2898
|
+
// v8.3.183+: 无视觉模型时,用 alt 语义兜底(硬保证有描述),"请打开"降为补充
|
|
2899
|
+
const altDesc = img.alt && img.alt.trim() ? img.alt.trim() : '';
|
|
2900
|
+
if (altDesc) {
|
|
2901
|
+
inlines.push(`\n\n---\n🖼️ **图片** ${altDesc}:\`${resolved}\`\n> 图片细节需宿主 AI 打开查看(CLI 无视觉模型,仅能提供 alt 语义)`);
|
|
2902
|
+
}
|
|
2903
|
+
else {
|
|
2904
|
+
inlines.push(`\n\n---\n🖼️ **图片文件**(无 alt 描述,宿主 AI 请打开查看):\n- ${resolved}`);
|
|
2905
|
+
try {
|
|
2906
|
+
if (await (0, fs_extra_1.pathExists)(resolved)) {
|
|
2907
|
+
const st = await (0, fs_extra_1.stat)(resolved);
|
|
2908
|
+
inlines.push(`- 文件大小: ${(st.size / 1024).toFixed(1)} KB`);
|
|
2909
|
+
}
|
|
2883
2910
|
}
|
|
2911
|
+
catch { /* ignore */ }
|
|
2884
2912
|
}
|
|
2885
|
-
catch { /* ignore */ }
|
|
2886
|
-
inlines.push(`> ⚠️ **请打开此图片文件查看内容**。此图片与需求理解高度相关,CLI 无法自动解析图片内容,需要你直接打开文件查看。`);
|
|
2887
2913
|
}
|
|
2888
2914
|
}
|
|
2889
2915
|
// v8.3.125+: 在内容末尾附加外链图片清单,提示宿主 AI 按需查看
|