speccore 8.3.22 → 8.3.26

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.
Files changed (114) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +19 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/analyze.d.ts.map +1 -1
  5. package/dist/commands/analyze.js +24 -8
  6. package/dist/commands/analyze.js.map +1 -1
  7. package/dist/commands/config.d.ts +3 -1
  8. package/dist/commands/config.d.ts.map +1 -1
  9. package/dist/commands/config.js +206 -90
  10. package/dist/commands/config.js.map +1 -1
  11. package/dist/commands/context-output.d.ts.map +1 -1
  12. package/dist/commands/context-output.js +0 -10
  13. package/dist/commands/context-output.js.map +1 -1
  14. package/dist/commands/dev.js +2 -2
  15. package/dist/commands/dev.js.map +1 -1
  16. package/dist/commands/doctor.d.ts.map +1 -1
  17. package/dist/commands/doctor.js +140 -0
  18. package/dist/commands/doctor.js.map +1 -1
  19. package/dist/commands/done.js +51 -20
  20. package/dist/commands/done.js.map +1 -1
  21. package/dist/commands/execute.d.ts.map +1 -1
  22. package/dist/commands/execute.js +145 -37
  23. package/dist/commands/execute.js.map +1 -1
  24. package/dist/commands/help.js +5 -0
  25. package/dist/commands/help.js.map +1 -1
  26. package/dist/commands/init.d.ts +0 -2
  27. package/dist/commands/init.d.ts.map +1 -1
  28. package/dist/commands/init.js +9 -51
  29. package/dist/commands/init.js.map +1 -1
  30. package/dist/commands/iteration/split.js +29 -17
  31. package/dist/commands/iteration/split.js.map +1 -1
  32. package/dist/commands/status-panel.d.ts.map +1 -1
  33. package/dist/commands/status-panel.js +7 -6
  34. package/dist/commands/status-panel.js.map +1 -1
  35. package/dist/commands/status.d.ts.map +1 -1
  36. package/dist/commands/status.js +32 -0
  37. package/dist/commands/status.js.map +1 -1
  38. package/dist/commands/update.d.ts.map +1 -1
  39. package/dist/commands/update.js +206 -8
  40. package/dist/commands/update.js.map +1 -1
  41. package/dist/commands/verdict.d.ts +16 -0
  42. package/dist/commands/verdict.d.ts.map +1 -0
  43. package/dist/commands/verdict.js +189 -0
  44. package/dist/commands/verdict.js.map +1 -0
  45. package/dist/commands/verify.d.ts.map +1 -1
  46. package/dist/commands/verify.js +3 -2
  47. package/dist/commands/verify.js.map +1 -1
  48. package/dist/core/arbitration/arbitration-engine.d.ts +36 -0
  49. package/dist/core/arbitration/arbitration-engine.d.ts.map +1 -0
  50. package/dist/core/arbitration/arbitration-engine.js +142 -0
  51. package/dist/core/arbitration/arbitration-engine.js.map +1 -0
  52. package/dist/core/arbitration/conflict-detector.d.ts +15 -0
  53. package/dist/core/arbitration/conflict-detector.d.ts.map +1 -0
  54. package/dist/core/arbitration/conflict-detector.js +78 -0
  55. package/dist/core/arbitration/conflict-detector.js.map +1 -0
  56. package/dist/core/arbitration/conflict-types.d.ts +34 -0
  57. package/dist/core/arbitration/conflict-types.d.ts.map +1 -0
  58. package/dist/core/arbitration/conflict-types.js +8 -0
  59. package/dist/core/arbitration/conflict-types.js.map +1 -0
  60. package/dist/core/arbitration/contract-registry.d.ts +15 -0
  61. package/dist/core/arbitration/contract-registry.d.ts.map +1 -0
  62. package/dist/core/arbitration/contract-registry.js +185 -0
  63. package/dist/core/arbitration/contract-registry.js.map +1 -0
  64. package/dist/core/arbitration/contract-types.d.ts +33 -0
  65. package/dist/core/arbitration/contract-types.d.ts.map +1 -0
  66. package/dist/core/arbitration/contract-types.js +8 -0
  67. package/dist/core/arbitration/contract-types.js.map +1 -0
  68. package/dist/core/arbitration/index.d.ts +16 -0
  69. package/dist/core/arbitration/index.d.ts.map +1 -0
  70. package/dist/core/arbitration/index.js +32 -0
  71. package/dist/core/arbitration/index.js.map +1 -0
  72. package/dist/core/arbitration/l1-auto-arbiter.d.ts +19 -0
  73. package/dist/core/arbitration/l1-auto-arbiter.d.ts.map +1 -0
  74. package/dist/core/arbitration/l1-auto-arbiter.js +41 -0
  75. package/dist/core/arbitration/l1-auto-arbiter.js.map +1 -0
  76. package/dist/core/arbitration/l2-ai-arbiter.d.ts +19 -0
  77. package/dist/core/arbitration/l2-ai-arbiter.d.ts.map +1 -0
  78. package/dist/core/arbitration/l2-ai-arbiter.js +57 -0
  79. package/dist/core/arbitration/l2-ai-arbiter.js.map +1 -0
  80. package/dist/core/arbitration/l3-human-arbiter.d.ts +24 -0
  81. package/dist/core/arbitration/l3-human-arbiter.d.ts.map +1 -0
  82. package/dist/core/arbitration/l3-human-arbiter.js +65 -0
  83. package/dist/core/arbitration/l3-human-arbiter.js.map +1 -0
  84. package/dist/core/arbitration/verdict-generator.d.ts +16 -0
  85. package/dist/core/arbitration/verdict-generator.d.ts.map +1 -0
  86. package/dist/core/arbitration/verdict-generator.js +166 -0
  87. package/dist/core/arbitration/verdict-generator.js.map +1 -0
  88. package/dist/core/arbitration/verdict-types.d.ts +49 -0
  89. package/dist/core/arbitration/verdict-types.d.ts.map +1 -0
  90. package/dist/core/arbitration/verdict-types.js +8 -0
  91. package/dist/core/arbitration/verdict-types.js.map +1 -0
  92. package/dist/core/ask-config.d.ts +4 -3
  93. package/dist/core/ask-config.d.ts.map +1 -1
  94. package/dist/core/ask-config.js +79 -1
  95. package/dist/core/ask-config.js.map +1 -1
  96. package/dist/core/ask-engine.d.ts.map +1 -1
  97. package/dist/core/ask-engine.js +7 -0
  98. package/dist/core/ask-engine.js.map +1 -1
  99. package/dist/core/intent-recognition.d.ts +1 -1
  100. package/dist/core/intent-recognition.d.ts.map +1 -1
  101. package/dist/core/intent-recognition.js +10 -0
  102. package/dist/core/intent-recognition.js.map +1 -1
  103. package/dist/core/pattern-detector.d.ts +24 -0
  104. package/dist/core/pattern-detector.d.ts.map +1 -1
  105. package/dist/core/pattern-detector.js +172 -3
  106. package/dist/core/pattern-detector.js.map +1 -1
  107. package/dist/core/spec-skeleton.d.ts.map +1 -1
  108. package/dist/core/spec-skeleton.js +35 -12
  109. package/dist/core/spec-skeleton.js.map +1 -1
  110. package/dist/core/unified-config.d.ts +161 -27
  111. package/dist/core/unified-config.d.ts.map +1 -1
  112. package/dist/core/unified-config.js +856 -82
  113. package/dist/core/unified-config.js.map +1 -1
  114. package/package.json +1 -1
@@ -63,6 +63,8 @@ const execution_state_1 = require("../core/execution-state");
63
63
  const git_integration_1 = require("../core/git-integration");
64
64
  const prompt_builder_1 = require("../core/prompt-builder");
65
65
  const verify_engine_1 = require("../core/verify-engine");
66
+ const arbitration_engine_1 = require("../core/arbitration/arbitration-engine");
67
+ const verdict_generator_1 = require("../core/arbitration/verdict-generator");
66
68
  const unified_config_1 = require("../core/unified-config");
67
69
  const pipeline_engine_1 = require("../core/pipeline-engine");
68
70
  const index_guard_1 = require("../core/index-guard");
@@ -1527,7 +1529,8 @@ async function executionVerifyLoop(tasks, iteration, options) {
1527
1529
  const maxRounds = 3;
1528
1530
  const iterDir = await (0, context_1.getIterationDir)(iteration);
1529
1531
  const config = await (0, unified_config_1.loadConfig)();
1530
- const codePath = config.code_scope?.[0] || process.cwd();
1532
+ const projectConfig = await (0, unified_config_1.loadProjectConfig)();
1533
+ const codePath = projectConfig.code_scope?.[0] || process.cwd();
1531
1534
  const absCodePath = codePath.startsWith('/') ? codePath : (0, path_1.join)(process.cwd(), codePath);
1532
1535
  for (const task of tasks) {
1533
1536
  logger_1.logger.info(`\n🔍 验证 ${task.id}...`);
@@ -1538,27 +1541,100 @@ async function executionVerifyLoop(tasks, iteration, options) {
1538
1541
  if (round > 1)
1539
1542
  logger_1.logger.info(` 🔄 第 ${round} 轮修复...`);
1540
1543
  allPassed = true;
1541
- // ── Step 1: 质量门禁(编译→Lint→测试→依赖→安全→Spec一致性)──
1542
- const gate = await (0, verify_engine_1.runQualityGate)(task.id, taskCodePath, taskDir);
1543
- if (!gate.passed) {
1544
- allPassed = false;
1545
- logger_1.logger.warn(` ❌ 质量门禁未通过`);
1546
- for (const f of gate.blockingFailed) {
1547
- logger_1.logger.warn(` ❌ ${f.name}: ${f.details}`);
1548
- await (0, issue_tracker_1.logIssue)(taskDir, {
1549
- type: f.name.includes('编译') || f.name.includes('测试') ? 'error' : 'technical',
1550
- severity: 'critical',
1551
- summary: `${f.name}: ${f.details}`,
1552
- detail: `任务: ${task.id},轮次: ${round}/3`,
1553
- });
1544
+ // ── Step 1: 契约冲突裁决 / 传统质量门禁 ──
1545
+ const arbConfig = await (0, arbitration_engine_1.getArbitrationConfig)();
1546
+ let testPassed = true;
1547
+ if (!arbConfig.enabled) {
1548
+ // 仲裁已禁用:回退到传统质量门禁
1549
+ const gate = await (0, verify_engine_1.runQualityGate)(task.id, taskCodePath, taskDir);
1550
+ await (0, verify_engine_1.writeVerifyReport)(gate.report, taskDir);
1551
+ if (options.auto) {
1552
+ logger_1.logger.info(` 🚧 质量门禁: ${gate.passed ? '✅ 通过' : '❌ 失败'} (arbitration=off)`);
1554
1553
  }
1554
+ else {
1555
+ logger_1.logger.info('');
1556
+ logger_1.logger.info(`🚧 传统质量门禁 — ${task.id}`);
1557
+ logger_1.logger.info(` ${gate.passed ? '✅ 全部通过' : `❌ ${gate.blockingFailed.length} 项阻塞性检查失败`}`);
1558
+ }
1559
+ if (!gate.passed) {
1560
+ allPassed = false;
1561
+ }
1562
+ const testCheck = gate.report.checks.find(c => c.name === '单元测试');
1563
+ testPassed = !testCheck || testCheck.status !== 'fail';
1555
1564
  }
1556
1565
  else {
1557
- logger_1.logger.info(` ✅ 质量门禁通过`);
1566
+ // 仲裁已启用:执行三级裁决
1567
+ const arbResult = await (0, arbitration_engine_1.runArbitration)(task.id, taskCodePath, taskDir, { mode: arbConfig.mode });
1568
+ await (0, verdict_generator_1.writeArbitrationReport)(arbResult.report, taskDir);
1569
+ if (options.auto) {
1570
+ // auto 模式:极简输出
1571
+ const totalFailed = arbResult.report.L1.failed + arbResult.report.L2.failed + arbResult.report.L3.failed;
1572
+ const modeLabel = arbConfig.mode === 'full' ? '' : ` [${arbConfig.mode}]`;
1573
+ if (totalFailed === 0) {
1574
+ logger_1.logger.info(` ⚖️ 契约裁决${modeLabel}: ✅ 全部通过`);
1575
+ }
1576
+ else {
1577
+ logger_1.logger.info(` ⚖️ 契约裁决${modeLabel}: ❌ L1=${arbResult.report.L1.failed} L2=${arbResult.report.L2.pending} L3=${arbResult.report.L3.pending}`);
1578
+ }
1579
+ }
1580
+ else {
1581
+ // 正常模式:完整输出
1582
+ logger_1.logger.info('');
1583
+ logger_1.logger.info(`⚖️ 契约冲突裁决 — ${task.id}${arbConfig.mode !== 'full' ? ` [mode=${arbConfig.mode}]` : ''}`);
1584
+ // L1 机器契约
1585
+ if (arbResult.report.L1.total > 0) {
1586
+ logger_1.logger.info(` ⚙️ L1 机器契约: ${arbResult.report.L1.passed}/${arbResult.report.L1.total} 通过`);
1587
+ if (arbResult.report.L1.failed > 0) {
1588
+ logger_1.logger.warn(` ❌ ${arbResult.report.L1.failed} 项致命错误,已自动裁决驳回`);
1589
+ allPassed = false;
1590
+ }
1591
+ }
1592
+ else {
1593
+ logger_1.logger.info(` ⚙️ L1 机器契约: ✅ 全部通过`);
1594
+ }
1595
+ // L2 规范契约
1596
+ if (arbResult.report.L2.total > 0) {
1597
+ logger_1.logger.info(` 🤖 L2 规范契约: ${arbResult.report.L2.passed}/${arbResult.report.L2.total} 通过, ${arbResult.report.L2.pending} 待确认`);
1598
+ if (arbResult.report.L2.pending > 0) {
1599
+ logger_1.logger.info(` 💡 ${arbResult.report.L2.pending} 项需确认修复方案(见 ARBITRATION_REPORT.md)`);
1600
+ }
1601
+ if (arbResult.report.L2.failed > 0) {
1602
+ allPassed = false;
1603
+ }
1604
+ }
1605
+ else {
1606
+ logger_1.logger.info(` 🤖 L2 规范契约: ✅ 全部通过`);
1607
+ }
1608
+ // L3 架构契约
1609
+ if (arbResult.report.L3.total > 0) {
1610
+ logger_1.logger.info(` 👤 L3 架构契约: ${arbResult.report.L3.passed}/${arbResult.report.L3.total} 通过, ${arbResult.report.L3.pending} 待裁决`);
1611
+ if (arbResult.report.L3.pending > 0) {
1612
+ logger_1.logger.warn(` ⚠️ ${arbResult.report.L3.pending} 项需人工裁决`);
1613
+ logger_1.logger.info(` 执行: speccore verdict --list --task ${task.id}`);
1614
+ allPassed = false;
1615
+ }
1616
+ }
1617
+ else {
1618
+ logger_1.logger.info(` 👤 L3 架构契约: ✅ 全部通过`);
1619
+ }
1620
+ }
1621
+ if (!arbResult.canProceed) {
1622
+ allPassed = false;
1623
+ if (!options.auto) {
1624
+ for (const c of arbResult.report.conflicts.filter(c => c.level === 'L1' && c.status === 'resolved')) {
1625
+ await (0, issue_tracker_1.logIssue)(taskDir, {
1626
+ type: 'error',
1627
+ severity: 'critical',
1628
+ summary: `L1 契约违反: ${c.contractName}`,
1629
+ detail: `任务: ${task.id},轮次: ${round}/3,${c.message}`,
1630
+ });
1631
+ }
1632
+ }
1633
+ }
1634
+ const testConflict = arbResult.report.conflicts.find(c => c.contractName === '单元测试通过');
1635
+ testPassed = !testConflict || testConflict.status !== 'resolved';
1558
1636
  }
1559
1637
  // ── Step 2: 文档同步 — 根据单元测试结果更新 TEST.md ──
1560
- const testCheck = gate.report.checks.find(c => c.name === '单元测试');
1561
- const testPassed = testCheck?.status === 'pass';
1562
1638
  await (0, verify_engine_1.syncTestDocFromResults)(taskDir, testPassed);
1563
1639
  // ── Step 3: 检查 REVIEW.md(人工审查清单)──
1564
1640
  const platDirsRound = await getPlatformSubtaskDirs(taskDir);
@@ -1619,7 +1695,8 @@ async function executionVerifyLoop(tasks, iteration, options) {
1619
1695
  if (round < maxRounds) {
1620
1696
  logger_1.logger.info(` 💡 AI 将修复未通过项。使用 speccore execute --task=${task.id} --force 重新执行代码生成`);
1621
1697
  await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.needs-retry'), String(round));
1622
- // 输出 [SPECCORE_EXEC] 让 AI 修复
1698
+ // 输出 [SPECCORE_EXEC] 让 AI 修复(回退到质量门禁报告)
1699
+ const gate = await (0, verify_engine_1.runQualityGate)(task.id, taskCodePath, taskDir);
1623
1700
  if (!gate.passed) {
1624
1701
  await (0, verify_engine_1.outputFixTag)(gate.report, taskDir, round);
1625
1702
  }
@@ -1629,29 +1706,60 @@ async function executionVerifyLoop(tasks, iteration, options) {
1629
1706
  if (allPassed) {
1630
1707
  await (0, fs_extra_1.writeFile)((0, path_1.join)(taskDir, '.verification'), 'passed');
1631
1708
  logger_1.logger.info(` ✅ ${task.id} 全部检查通过,可以 speccore done`);
1632
- // v8.2.0+: 执行通过后检测可复用模式候选
1709
+ // v8.3.23+: 执行通过后检测可复用模式候选(适配端平铺结构 + 自动写入)
1633
1710
  try {
1634
- const codeDirs = [
1635
- (0, path_1.join)(taskDir, '10-backend'),
1636
- (0, path_1.join)(taskDir, '20-frontend'),
1637
- (0, path_1.join)(taskDir, 'src'),
1638
- ];
1711
+ const codeDirs = await (0, pattern_detector_1.resolveCodeDirsFromTask)(taskDir);
1712
+ if (codeDirs.length === 0) {
1713
+ // 无代码目录时静默跳过(代码可能在外部工程)
1714
+ return;
1715
+ }
1639
1716
  const candidates = await (0, pattern_detector_1.detectPatternCandidates)(codeDirs, `task:${task.id}`);
1640
- if (candidates.length > 0) {
1717
+ if (candidates.length === 0)
1718
+ return;
1719
+ const mode = await (0, pattern_detector_1.getPatternAutoSaveMode)();
1720
+ const autoSaved = [];
1721
+ const manual = [];
1722
+ for (const c of candidates) {
1723
+ const result = await (0, pattern_detector_1.autoSavePattern)(c, `task:${task.id}`, mode);
1724
+ if (result.saved && result.path) {
1725
+ autoSaved.push(`${c.name} [${result.confidence}]`);
1726
+ }
1727
+ else if (!(0, pattern_detector_1.isHighConfidenceCandidate)(c) && mode === 'smart') {
1728
+ manual.push(`${c.name} [${c.category}]`);
1729
+ }
1730
+ }
1731
+ logger_1.logger.info('');
1732
+ logger_1.logger.info('🧩 执行完成,检测到以下可复用模式候选:');
1733
+ const byPlatform = (0, pattern_detector_1.groupCandidatesByPlatform)(candidates);
1734
+ for (const [plat, list] of Object.entries(byPlatform)) {
1735
+ const platLabel = plat === 'shared' ? '🌐 跨端共享' : plat === 'backend' ? '⚙️ 后端' : plat === 'frontend' ? '🎨 前端' : '📦 其他';
1736
+ logger_1.logger.info(` ${platLabel}:`);
1737
+ for (const c of list.slice(0, 2)) {
1738
+ logger_1.logger.info(` • ${c.name} [${c.category}] — ${c.reason}`);
1739
+ }
1740
+ if (list.length > 2) {
1741
+ logger_1.logger.info(` ... 还有 ${list.length - 2} 个`);
1742
+ }
1743
+ }
1744
+ if (autoSaved.length > 0) {
1641
1745
  logger_1.logger.info('');
1642
- logger_1.logger.info('🧩 执行完成,检测到以下可复用模式候选:');
1643
- const byPlatform = (0, pattern_detector_1.groupCandidatesByPlatform)(candidates);
1644
- for (const [plat, list] of Object.entries(byPlatform)) {
1645
- const platLabel = plat === 'shared' ? '🌐 跨端共享' : plat === 'backend' ? '⚙️ 后端' : plat === 'frontend' ? '🎨 前端' : '📦 其他';
1646
- logger_1.logger.info(` ${platLabel}:`);
1647
- for (const c of list.slice(0, 2)) {
1648
- logger_1.logger.info(` • ${c.name} [${c.category}] — ${c.reason}`);
1649
- }
1650
- if (list.length > 2) {
1651
- logger_1.logger.info(` ... 还有 ${list.length - 2} 个`);
1652
- }
1746
+ logger_1.logger.info(` ✅ 已自动保存 ${autoSaved.length} 个高置信度模式到 .speccore/PATTERNS/`);
1747
+ for (const s of autoSaved.slice(0, 3)) {
1748
+ logger_1.logger.info(` • ${s}`);
1653
1749
  }
1654
- logger_1.logger.info(` 💡 有价值?执行 speccore pattern save --name=<模式名> --file=<文件路径>`);
1750
+ }
1751
+ if (manual.length > 0 && mode === 'smart') {
1752
+ logger_1.logger.info('');
1753
+ logger_1.logger.info(` 💡 以下 ${manual.length} 个候选置信度较低,建议手动确认后保存:`);
1754
+ for (const m of manual.slice(0, 3)) {
1755
+ logger_1.logger.info(` • ${m}`);
1756
+ }
1757
+ logger_1.logger.info(' 命令: speccore pattern save --name=<模式名> --file=<文件路径>');
1758
+ }
1759
+ if (mode === 'off') {
1760
+ logger_1.logger.info('');
1761
+ logger_1.logger.info(' 💡 检测到可复用模式,自动保存已关闭。如需保存请执行:');
1762
+ logger_1.logger.info(' speccore pattern save --name=<模式名> --file=<文件路径>');
1655
1763
  }
1656
1764
  }
1657
1765
  catch { /* 静默失败 */ }