speccore 8.3.158 → 8.3.160

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 (85) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/analyze.d.ts.map +1 -1
  3. package/dist/commands/analyze.js +88 -96
  4. package/dist/commands/analyze.js.map +1 -1
  5. package/dist/commands/ask.d.ts.map +1 -1
  6. package/dist/commands/ask.js +0 -13
  7. package/dist/commands/ask.js.map +1 -1
  8. package/dist/commands/execute.d.ts.map +1 -1
  9. package/dist/commands/execute.js +67 -6
  10. package/dist/commands/execute.js.map +1 -1
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +71 -216
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/iteration/split.d.ts.map +1 -1
  15. package/dist/commands/iteration/split.js +73 -9
  16. package/dist/commands/iteration/split.js.map +1 -1
  17. package/dist/commands/migrate.d.ts.map +1 -1
  18. package/dist/commands/migrate.js +1 -2
  19. package/dist/commands/migrate.js.map +1 -1
  20. package/dist/commands/update.d.ts.map +1 -1
  21. package/dist/commands/update.js +1 -4
  22. package/dist/commands/update.js.map +1 -1
  23. package/dist/core/agent-adapter.d.ts +81 -0
  24. package/dist/core/agent-adapter.d.ts.map +1 -0
  25. package/dist/core/agent-adapter.js +425 -0
  26. package/dist/core/agent-adapter.js.map +1 -0
  27. package/dist/core/agents/defaults/_INDEX.md +15 -15
  28. package/dist/core/agents/defaults/code-reviewer.md +9 -0
  29. package/dist/core/agents/defaults/compiler.md +12 -3
  30. package/dist/core/agents/defaults/dependency-analyst.md +7 -0
  31. package/dist/core/agents/defaults/doc-sync-agent.md +7 -0
  32. package/dist/core/agents/defaults/impact-analyst.md +7 -0
  33. package/dist/core/agents/defaults/interaction-designer.md +17 -0
  34. package/dist/core/agents/defaults/performance-expert.md +9 -0
  35. package/dist/core/agents/defaults/regression-tester.md +7 -0
  36. package/dist/core/agents/defaults/security-reviewer.md +9 -0
  37. package/dist/core/agents/defaults/test-engineer.md +10 -0
  38. package/dist/core/agents/defaults/test-reviewer.md +10 -0
  39. package/dist/core/lock-manager.d.ts.map +1 -1
  40. package/dist/core/lock-manager.js +2 -0
  41. package/dist/core/lock-manager.js.map +1 -1
  42. package/dist/core/pipeline-engine.d.ts +49 -8
  43. package/dist/core/pipeline-engine.d.ts.map +1 -1
  44. package/dist/core/pipeline-engine.js +221 -34
  45. package/dist/core/pipeline-engine.js.map +1 -1
  46. package/dist/core/prompt-builder.d.ts +4 -0
  47. package/dist/core/prompt-builder.d.ts.map +1 -1
  48. package/dist/core/prompt-builder.js +83 -10
  49. package/dist/core/prompt-builder.js.map +1 -1
  50. package/dist/core/rules/defaults/ANALYSIS_QUALITY.md +73 -0
  51. package/dist/core/rules/defaults/EXECUTION.md +20 -0
  52. package/dist/core/rules/defaults/ITERATION_QUALITY.md +49 -0
  53. package/dist/core/rules/defaults/TASK_SPLIT.md +16 -0
  54. package/dist/core/spec-paths.d.ts.map +1 -1
  55. package/dist/core/spec-paths.js +2 -1
  56. package/dist/core/spec-paths.js.map +1 -1
  57. package/package.json +4 -6
  58. package/templates/api-design-example.md +0 -338
  59. package/templates/ci/github-actions.yml +0 -44
  60. package/templates/dashboard.html +0 -425
  61. package/templates/database-example.md +0 -223
  62. package/templates/deploy-docker/README.md +0 -284
  63. package/templates/deploy-docker/deploy-remote.sh +0 -79
  64. package/templates/deploy-docker/docker-compose.yml +0 -113
  65. package/templates/deploy-docker/frontend.Dockerfile +0 -43
  66. package/templates/deploy-docker/nginx.conf +0 -30
  67. package/templates/deploy-examples.yaml +0 -436
  68. package/templates/deploy-java/Dockerfile +0 -50
  69. package/templates/deploy-java/README.md +0 -212
  70. package/templates/deploy-java/deploy.sh +0 -120
  71. package/templates/deploy-java/spring-boot.service +0 -35
  72. package/templates/html/speccore-ask-explain.html +0 -10
  73. package/templates/html/speccore-ask-guide.html +0 -10
  74. package/templates/html/speccore-ask-match.html +0 -10
  75. package/templates/html/speccore-ask-pipeline.html +0 -1
  76. package/templates/html/speccore-ask-result.html +0 -10
  77. package/templates/html/speccore-demo.html +0 -449
  78. package/templates/html/speccore-dev.html +0 -202
  79. package/templates/html/speccore-help.html +0 -1
  80. package/templates/html/speccore-knowledge-graph.html +0 -656
  81. package/templates/html/speccore-retro-T-001.html +0 -1
  82. package/templates/html/speccore-setup-guide.html +0 -289
  83. package/templates/html/speccore-welcome.html +0 -1
  84. package/templates/security-example.md +0 -226
  85. package/templates/verify-spec-example.yaml +0 -982
@@ -37,6 +37,8 @@ const techStackCache = new Map();
37
37
  const constitutionCache = new Map();
38
38
  const reqContentCache = new Map();
39
39
  const tocCache = new Map();
40
+ // v8.3.160+: 关键约束缓存(解决上下文漂移)
41
+ const keyConstraintsCache = new Map();
40
42
  /** 通用文件缓存读取 */
41
43
  async function cachedRead(cache, filePath, loader) {
42
44
  try {
@@ -87,6 +89,51 @@ async function loadTechStack(cwd) {
87
89
  return stack;
88
90
  });
89
91
  }
92
+ /**
93
+ * v8.3.160+: 从 CONSTITUTION.md 提取关键约束(解决上下文漂移)
94
+ * 提取命名规范、Git 策略、错误码、核心禁令等不可遗忘的约束
95
+ */
96
+ async function loadKeyConstraints(cwd) {
97
+ const constitutionPath = (0, path_1.join)(cwd, '.speccore', 'CONSTITUTION.md');
98
+ if (!await (0, fs_extra_1.pathExists)(constitutionPath))
99
+ return [];
100
+ return cachedRead(keyConstraintsCache, constitutionPath, async () => {
101
+ const content = await (0, fs_extra_1.readFile)(constitutionPath, 'utf-8');
102
+ const constraints = [];
103
+ // 提取核心禁令(⛔ 标记)
104
+ const banMatches = content.matchAll(/⛔\s*(.+)/g);
105
+ for (const match of banMatches) {
106
+ constraints.push(`禁止: ${match[1].trim()}`);
107
+ }
108
+ // 提取命名规范
109
+ const namingSection = content.match(/##\s*命名规范[\s\S]*?(?=##\s|#{3,}\s|$)/i);
110
+ if (namingSection) {
111
+ const lines = namingSection[0].split('\n')
112
+ .filter(l => l.trim().startsWith('-') || l.trim().startsWith('*'))
113
+ .map(l => `命名: ${l.trim().replace(/^[-*]\s*/, '')}`)
114
+ .slice(0, 6);
115
+ constraints.push(...lines);
116
+ }
117
+ // 提取 Git 分支策略
118
+ const gitMatch = content.match(/Git\s*分支[策略]*[::]\s*(.+)/i) ||
119
+ content.match(/分支策略[::]\s*(.+)/i);
120
+ if (gitMatch) {
121
+ constraints.push(`Git: ${gitMatch[1].trim()}`);
122
+ }
123
+ // 提取错误码体系
124
+ const errorMatch = content.match(/错误码[体系]*[::]\s*(.+)/i);
125
+ if (errorMatch) {
126
+ constraints.push(`错误码: ${errorMatch[1].trim()}`);
127
+ }
128
+ // 提取端名规范
129
+ const platformMatch = content.match(/端名[列表]*[::]\s*(.+)/i) ||
130
+ content.match(/平台[列表]*[::]\s*(.+)/i);
131
+ if (platformMatch) {
132
+ constraints.push(`端名: ${platformMatch[1].trim()}`);
133
+ }
134
+ return constraints.slice(0, 20); // 最多 20 条,控制 Token 预算
135
+ });
136
+ }
90
137
  /**
91
138
  * 定位 REQ.md 实际路径(支持新旧结构)
92
139
  */
@@ -1442,11 +1489,23 @@ async function buildPrompt(command, options) {
1442
1489
  const cwd = options.cwd || (0, task_utils_1.findProjectRoot)() || process.cwd();
1443
1490
  const techStack = await loadTechStack(cwd);
1444
1491
  const taskDir = options.taskDir || '';
1445
- // P0-1: 统一读取 REQ.md,避免 loadApiSpecs/loadDataModels/loadBusinessRules 各读一次
1446
- const reqContent = taskDir ? await loadReqContent(cwd, taskDir) : null;
1447
- const apiSpecs = await loadApiSpecs(cwd, taskDir, reqContent || undefined);
1448
- const dataModels = await loadDataModels(cwd, taskDir, reqContent || undefined);
1449
- const businessRules = await loadBusinessRules(cwd, taskDir, reqContent || undefined);
1492
+ // v8.3.160+: 步骤级上下文预算(默认 12000)
1493
+ const contextBudget = options.contextBudget || 12000;
1494
+ // v8.3.160+: 根据 contextType 控制 REQ.md 加载深度
1495
+ // full: 加载全文 | incremental/platform-only/contract-only: 不加载(依赖前一步摘要或路径引用)
1496
+ const shouldLoadReqContent = !options.contextType || options.contextType === 'full';
1497
+ const reqContent = shouldLoadReqContent && taskDir ? await loadReqContent(cwd, taskDir) : null;
1498
+ // v8.3.160+: 规格加载策略与 REQ.md 保持一致
1499
+ const shouldLoadFullSpecs = shouldLoadReqContent;
1500
+ const apiSpecs = shouldLoadFullSpecs
1501
+ ? await loadApiSpecs(cwd, taskDir, reqContent || undefined)
1502
+ : [];
1503
+ const dataModels = shouldLoadFullSpecs
1504
+ ? await loadDataModels(cwd, taskDir, reqContent || undefined)
1505
+ : [];
1506
+ const businessRules = shouldLoadFullSpecs
1507
+ ? await loadBusinessRules(cwd, taskDir, reqContent || undefined)
1508
+ : [];
1450
1509
  // 统一检索层:同时查询文档 RAG + 代码切片 + 知识图谱
1451
1510
  let extraSpecs = [];
1452
1511
  // v8.3.123+: analyze/split 阶段也需要统一检索,从迭代需求提取查询词
@@ -1529,6 +1588,8 @@ async function buildPrompt(command, options) {
1529
1588
  }
1530
1589
  }
1531
1590
  }
1591
+ // v8.3.160+: 加载关键约束(每轮重注入,防止上下文漂移)
1592
+ const keyConstraints = await loadKeyConstraints(cwd);
1532
1593
  // v8.3.122+: execute / analyze 时深入读取关联源码(完整文件内容,不只是切片)
1533
1594
  // v8.3.122++: 同时注入知识图谱任务上下文,帮助 AI 理解代码关联关系
1534
1595
  if ((command === 'execute' || command === 'analyze') && searchQuery) {
@@ -1995,6 +2056,8 @@ async function buildPrompt(command, options) {
1995
2056
  projectPaths: projectPathsInfo,
1996
2057
  rulesContent,
1997
2058
  codeGraphSummary,
2059
+ keyConstraints,
2060
+ contextBudget,
1998
2061
  instruction,
1999
2062
  outputHint: command === 'execute'
2000
2063
  ? '请返回格式: {"files": [{"path": "工程标识/相对路径", "content": "代码内容"}]}'
@@ -2020,18 +2083,20 @@ function estimateTokens(text) {
2020
2083
  * 将 Prompt 序列化为 AI 可读的文本(输出到 stdout)
2021
2084
  * 带动态裁剪:超出预算时按优先级逐级简化
2022
2085
  */
2023
- function formatPrompt(prompt, maxTokens = 12000) {
2086
+ function formatPrompt(prompt, maxTokens) {
2087
+ // v8.3.160+: 使用步骤级上下文预算
2088
+ const budget = maxTokens ?? prompt.contextBudget ?? 12000;
2024
2089
  // 尝试完整构建
2025
2090
  let result = buildPromptText(prompt);
2026
2091
  let tokens = estimateTokens(result);
2027
- if (tokens <= maxTokens)
2092
+ if (tokens <= budget)
2028
2093
  return result;
2029
2094
  // Level 1: 简化全局上下文(只保留 INDEX.md,去掉 TOC 目录)
2030
2095
  if (prompt.globalContext) {
2031
2096
  const slimGlobal = { ...prompt.globalContext, toc: [] };
2032
2097
  result = buildPromptText({ ...prompt, globalContext: slimGlobal });
2033
2098
  tokens = estimateTokens(result);
2034
- if (tokens <= maxTokens) {
2099
+ if (tokens <= budget) {
2035
2100
  logger_1.logger?.info?.(` 🪶 Prompt 已简化:隐藏全局目录(-${estimateTokens(formatGlobalContext(prompt.globalContext, prompt.platform))} tokens)`);
2036
2101
  return result;
2037
2102
  }
@@ -2102,7 +2167,7 @@ function formatPrompt(prompt, maxTokens = 12000) {
2102
2167
  }
2103
2168
  result = buildPromptText({ ...prompt, extraSpecs: budgeted });
2104
2169
  tokens = estimateTokens(result);
2105
- if (tokens <= maxTokens) {
2170
+ if (tokens <= budget) {
2106
2171
  const removed = prompt.extraSpecs.length - budgeted.length;
2107
2172
  logger_1.logger?.info?.(` 🪶 Prompt 已简化:分层预算控制 (P1:${usedP1}/${BUDGET_P1} P2:${usedP2}/${BUDGET_P2} P3:${usedP3}/${BUDGET_P3}${removed > 0 ? ` 移除${removed}项` : ''})`);
2108
2173
  return result;
@@ -2112,7 +2177,7 @@ function formatPrompt(prompt, maxTokens = 12000) {
2112
2177
  if (prompt.taskContext) {
2113
2178
  result = buildPromptText({ ...prompt, taskContext: undefined });
2114
2179
  tokens = estimateTokens(result);
2115
- if (tokens <= maxTokens) {
2180
+ if (tokens <= budget) {
2116
2181
  logger_1.logger?.info?.(` 🪶 Prompt 已简化:隐藏任务关联链`);
2117
2182
  return result;
2118
2183
  }
@@ -2137,6 +2202,14 @@ function buildPromptText(prompt) {
2137
2202
  lines.push('');
2138
2203
  lines.push(`# 任务: ${prompt.command} — ${prompt.task || prompt.iteration}`);
2139
2204
  lines.push('');
2205
+ // v8.3.160+: 关键约束重注入(必须放在最前面,防止上下文漂移)
2206
+ if (prompt.keyConstraints && prompt.keyConstraints.length > 0) {
2207
+ lines.push('## ⚠️ 核心约束(每轮必达)');
2208
+ for (const constraint of prompt.keyConstraints) {
2209
+ lines.push(`- ${constraint}`);
2210
+ }
2211
+ lines.push('');
2212
+ }
2140
2213
  // 技术栈
2141
2214
  if (Object.keys(prompt.techStack).length > 0) {
2142
2215
  lines.push('## 技术栈');