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.
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"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"}
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
- if (content.length > MAX_PER_FILE) {
415
- content = content.slice(0, MAX_PER_FILE) + `\n\n> ... (已截断,原文件 ${rawContent.length} 字,完整内容请 Read: ${fullPath})`;
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
- if (content.length > MAX_PER_FILE) {
453
- content = content.slice(0, MAX_PER_FILE) + `\n\n> ... (已截断,原文件 ${content.length} 字)`;
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.15+: 扫描用户自定义文档
527
- * 扫描 00-specs/ 和子任务目录下所有 .md/.yaml/.yml/.json 文件
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
- // 1. 扫描 00-specs/ 下所有文件(排除已在白名单中的)
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
- if (content.length > MAX_PER_FILE) {
627
- content = content.slice(0, MAX_PER_FILE) + `\n\n> ... (已截断,原文件 ${rawContent.length} 字,完整内容请 Read: ${fullPath})`;
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;