speccore 8.3.180 → 8.3.181
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/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +49 -17
- package/dist/commands/analyze.js.map +1 -1
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +73 -16
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/requirement-clarifier.d.ts +8 -1
- package/dist/core/requirement-clarifier.d.ts.map +1 -1
- package/dist/core/requirement-clarifier.js +53 -18
- package/dist/core/requirement-clarifier.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAoD,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAgDtG,gBAAgB;AAChB,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAErE,YAAY;AACZ,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAe;AACf,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,WAAW;AACX,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/D;AAED,WAAW;AACX,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gBAAgB;AAChB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gBAAgB;AAChB,MAAM,WAAW,QAAQ;IACvB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,0BAA0B;AAC1B,MAAM,WAAW,aAAa;IAC5B,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,0BAA0B;IAC1B,GAAG,EAAE,QAAQ,EAAE,CAAC;CACjB;AAED,0BAA0B;AAC1B,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -410,9 +410,17 @@ async function loadExtraSpecs(cwd, taskDir, platform, iteration, options) {
|
|
|
410
410
|
if (content.trim().length <= 50 || content.trim().match(/^#+\s*待填充|^<!--\s*AI-FILL\s*-->$/m)) {
|
|
411
411
|
continue;
|
|
412
412
|
}
|
|
413
|
-
//
|
|
414
|
-
|
|
415
|
-
|
|
413
|
+
// v8.3.181+: 按文件类型细分预算
|
|
414
|
+
const fileName = (0, path_1.basename)(f.path);
|
|
415
|
+
const budget = getFileBudget(fileName);
|
|
416
|
+
if (content.length > budget.limit) {
|
|
417
|
+
if (budget.mode === 'error') {
|
|
418
|
+
logger_1.logger.error(`[prompt-builder] ${fileName} 超过预算上限 (${content.length} > ${budget.limit})。该文件必须完整,请精简源文件内容。`);
|
|
419
|
+
// 不截断,保留完整内容
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
content = content.slice(0, budget.limit) + `\n\n> ... (已截断,原文件 ${rawContent.length} 字,预算上限 ${budget.limit},完整内容请 Read: ${fullPath})`;
|
|
423
|
+
}
|
|
416
424
|
}
|
|
417
425
|
// 总大小限制
|
|
418
426
|
if (totalChars + content.length > MAX_TOTAL) {
|
|
@@ -449,8 +457,10 @@ async function loadExtraSpecs(cwd, taskDir, platform, iteration, options) {
|
|
|
449
457
|
if (content.trim().length <= 50 || content.trim().match(/^#+\s*待填充|^<!--\s*AI-FILL\s*-->$/m)) {
|
|
450
458
|
continue;
|
|
451
459
|
}
|
|
452
|
-
|
|
453
|
-
|
|
460
|
+
// v8.3.181+: 自定义文件使用默认预算
|
|
461
|
+
const customBudget = getFileBudget((0, path_1.basename)(uf.path));
|
|
462
|
+
if (content.length > customBudget.limit) {
|
|
463
|
+
content = content.slice(0, customBudget.limit) + `\n\n> ... (已截断,原文件 ${content.length} 字,预算上限 ${customBudget.limit})`;
|
|
454
464
|
}
|
|
455
465
|
if (totalChars + content.length > MAX_TOTAL) {
|
|
456
466
|
const remain = MAX_TOTAL - totalChars;
|
|
@@ -523,15 +533,34 @@ async function loadExtraSpecs(cwd, taskDir, platform, iteration, options) {
|
|
|
523
533
|
return extras;
|
|
524
534
|
}
|
|
525
535
|
/**
|
|
526
|
-
* v8.3.
|
|
527
|
-
*
|
|
528
|
-
*
|
|
536
|
+
* v8.3.181+: 扫描用户自定义文档(白名单模式)
|
|
537
|
+
* 只加载 ALLOWED_EXTRA_FILES 白名单内的文件,防止上下文污染
|
|
538
|
+
* 白名单外文件将被忽略并输出提示
|
|
529
539
|
*/
|
|
540
|
+
const ALLOWED_EXTRA_FILES = new Set([
|
|
541
|
+
'SCHEMA.md', 'TEST.md', 'REVIEW.md', 'DEPLOY.md', 'MONITOR.md',
|
|
542
|
+
'RISK.md', 'DEPS.md', 'ERROR_CODES.md', 'COMPONENT_TREE.md',
|
|
543
|
+
'ROUTES.md', 'STATE.md',
|
|
544
|
+
]);
|
|
545
|
+
// v8.3.181+: 按文件类型细分预算(必须完整 vs 可以截断)
|
|
546
|
+
const FILE_BUDGETS = {
|
|
547
|
+
'CONSTITUTION.md': { limit: 4000, mode: 'error' },
|
|
548
|
+
'REQ.md': { limit: 2000, mode: 'error' },
|
|
549
|
+
'API_CONTRACT.yaml': { limit: 2000, mode: 'error' },
|
|
550
|
+
'TASK.md': { limit: 1500, mode: 'truncate' },
|
|
551
|
+
'TECH.md': { limit: 3000, mode: 'truncate' },
|
|
552
|
+
'DEV_GUIDE.md': { limit: 2000, mode: 'truncate' },
|
|
553
|
+
};
|
|
554
|
+
const DEFAULT_BUDGET = { limit: 1000, mode: 'truncate' };
|
|
555
|
+
function getFileBudget(fileName) {
|
|
556
|
+
return FILE_BUDGETS[fileName] ?? DEFAULT_BUDGET;
|
|
557
|
+
}
|
|
530
558
|
async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
531
559
|
const results = [];
|
|
532
560
|
const validExts = ['.md', '.yaml', '.yml', '.json', '.html', '.htm'];
|
|
533
561
|
const skipDirs = new Set(['.meta', '.git', 'node_modules', 'tests', 'src', 'dist', 'build']);
|
|
534
|
-
|
|
562
|
+
const ignoredFiles = [];
|
|
563
|
+
// 1. 扫描 00-specs/ 下白名单内的文件
|
|
535
564
|
const specsDir = (0, path_1.join)(cwd, taskDir, '00-specs');
|
|
536
565
|
try {
|
|
537
566
|
if (await (0, fs_extra_1.pathExists)(specsDir)) {
|
|
@@ -542,6 +571,10 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
542
571
|
const ext = e.name.slice(e.name.lastIndexOf('.'));
|
|
543
572
|
if (!validExts.includes(ext))
|
|
544
573
|
continue;
|
|
574
|
+
if (!ALLOWED_EXTRA_FILES.has(e.name)) {
|
|
575
|
+
ignoredFiles.push(`00-specs/${e.name}`);
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
545
578
|
const relPath = (0, path_1.join)('00-specs', e.name);
|
|
546
579
|
const fullPath = (0, path_1.join)(cwd, taskDir, relPath);
|
|
547
580
|
if (!seenPaths.has(fullPath)) {
|
|
@@ -551,7 +584,7 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
551
584
|
}
|
|
552
585
|
}
|
|
553
586
|
catch { /* 忽略 */ }
|
|
554
|
-
// 2.
|
|
587
|
+
// 2. 扫描子任务目录下白名单内的文件(递归)
|
|
555
588
|
if (platform) {
|
|
556
589
|
const platformBase = (0, path_1.join)(cwd, taskDir, platform);
|
|
557
590
|
try {
|
|
@@ -561,16 +594,26 @@ async function scanUserCustomFiles(cwd, taskDir, platform, seenPaths) {
|
|
|
561
594
|
if (!subE.isDirectory() || subE.name.startsWith('.'))
|
|
562
595
|
continue;
|
|
563
596
|
const subtaskDir = (0, path_1.join)(platformBase, subE.name);
|
|
564
|
-
await scanDirRecursive(subtaskDir, (0, path_1.join)(platform, subE.name), results, seenPaths, skipDirs, validExts, cwd, taskDir);
|
|
597
|
+
await scanDirRecursive(subtaskDir, (0, path_1.join)(platform, subE.name), results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles);
|
|
565
598
|
}
|
|
566
599
|
}
|
|
567
600
|
}
|
|
568
601
|
catch { /* 忽略 */ }
|
|
569
602
|
}
|
|
603
|
+
// 输出被忽略的文件提示
|
|
604
|
+
if (ignoredFiles.length > 0) {
|
|
605
|
+
console.warn(`[prompt-builder] 以下文件不在白名单中,已忽略(如需加载请在 TASK.md 中声明):`);
|
|
606
|
+
for (const f of ignoredFiles.slice(0, 10)) {
|
|
607
|
+
console.warn(` - ${f}`);
|
|
608
|
+
}
|
|
609
|
+
if (ignoredFiles.length > 10) {
|
|
610
|
+
console.warn(` ... 还有 ${ignoredFiles.length - 10} 个文件被忽略`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
570
613
|
return results;
|
|
571
614
|
}
|
|
572
|
-
/**
|
|
573
|
-
async function scanDirRecursive(dir, relPrefix, results, seenPaths, skipDirs, validExts, cwd, taskDir) {
|
|
615
|
+
/** 递归扫描目录,收集用户自定义文档(白名单模式) */
|
|
616
|
+
async function scanDirRecursive(dir, relPrefix, results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles) {
|
|
574
617
|
try {
|
|
575
618
|
const entries = await (0, fs_extra_1.readdir)(dir, { withFileTypes: true });
|
|
576
619
|
for (const e of entries) {
|
|
@@ -579,12 +622,16 @@ async function scanDirRecursive(dir, relPrefix, results, seenPaths, skipDirs, va
|
|
|
579
622
|
if (e.isDirectory()) {
|
|
580
623
|
if (skipDirs.has(e.name) || e.name.startsWith('.'))
|
|
581
624
|
continue;
|
|
582
|
-
await scanDirRecursive((0, path_1.join)(dir, e.name), relPath, results, seenPaths, skipDirs, validExts, cwd, taskDir);
|
|
625
|
+
await scanDirRecursive((0, path_1.join)(dir, e.name), relPath, results, seenPaths, skipDirs, validExts, cwd, taskDir, ignoredFiles);
|
|
583
626
|
}
|
|
584
627
|
else if (e.isFile()) {
|
|
585
628
|
const ext = e.name.slice(e.name.lastIndexOf('.'));
|
|
586
629
|
if (!validExts.includes(ext))
|
|
587
630
|
continue;
|
|
631
|
+
if (!ALLOWED_EXTRA_FILES.has(e.name)) {
|
|
632
|
+
ignoredFiles.push(relPath);
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
588
635
|
if (!seenPaths.has(fullPath)) {
|
|
589
636
|
results.push({ name: `用户补充/${relPath}`, path: relPath });
|
|
590
637
|
}
|
|
@@ -623,8 +670,18 @@ async function loadAllTaskContext(cwd, taskDir, platform, iteration, graph) {
|
|
|
623
670
|
}
|
|
624
671
|
if (content.trim().length <= 50 || content.trim().match(/^#+\s*待填充|^<!--\s*AI-FILL\s*-->$/m))
|
|
625
672
|
return;
|
|
626
|
-
|
|
627
|
-
|
|
673
|
+
// v8.3.181+: 兜底模式也按文件类型检查预算(放宽到 2 倍)
|
|
674
|
+
const fileName = (0, path_1.basename)(fullPath);
|
|
675
|
+
const budget = getFileBudget(fileName);
|
|
676
|
+
const fallbackLimit = budget.limit * 2;
|
|
677
|
+
if (content.length > fallbackLimit) {
|
|
678
|
+
if (budget.mode === 'error') {
|
|
679
|
+
logger_1.logger.error(`[prompt-builder] ${fileName} 超过兜底预算上限 (${content.length} > ${fallbackLimit})。该文件必须完整,请精简源文件内容。`);
|
|
680
|
+
// 不截断
|
|
681
|
+
}
|
|
682
|
+
else {
|
|
683
|
+
content = content.slice(0, fallbackLimit) + `\n\n> ... (已截断,原文件 ${rawContent.length} 字,兜底预算上限 ${fallbackLimit})`;
|
|
684
|
+
}
|
|
628
685
|
}
|
|
629
686
|
if (totalChars + content.length > MAX_TOTAL)
|
|
630
687
|
return;
|