speccore 8.3.250 → 8.3.252

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.
@@ -25,7 +25,8 @@ disable-model-invocation: false
25
25
  先识别用户给了什么,按入口执行预处理,再统一做范围确认:
26
26
 
27
27
  **入口 A:已切分好的功能单元**(用户指定了单元名或说「全部」)
28
- - 直接进入下方「范围确认」,无需预处理
28
+ - 无需预处理,直接进入下方「范围确认」
29
+ - 用户只给单元名(如「features/ 下的 v3-service-01-门禁授权同步」)时:先 `speccore status` 探测活跃迭代(.speccore/local/context.json 的 currentIteration);探不到或单元不在该迭代,向用户确认迭代名,不要猜
29
30
 
30
31
  **入口 B:一个文档地址**(.md / .docx / .pdf,多个文档可批量)
31
32
  - `.md` → 执行 `speccore unitize -f "<路径>"`(多文档可 `--files "a.md=端1,b.md"`,端名须与 CONSTITUTION.md 一致)
@@ -44,7 +45,7 @@ disable-model-invocation: false
44
45
  5. 目录/任务命名由 CLI 确定性生成(单元目录 {文档slug}-{序号}-{标题}、Task-{编号}-{slug}、子任务 Task-{父任务}-{端名}),不要自己改
45
46
 
46
47
  ### Step 1 澄清与分析
47
- 1. 执行 `speccore analyze --prompt -I <迭代> --with-code`(--with-code 使 Prompt 携带各端工程路径表与源码上下文;指定范围用 `--unit M-01,M-03`,不要用 --feature——那是确定性局部分析,不出 Prompt)
48
+ 1. 执行 `speccore analyze --prompt -I <迭代> --with-code`(--with-code 使 Prompt 携带各端工程路径表与源码上下文;指定范围用 `--unit`,直接写切分出的目录名即可——如 `--unit "v3-service-01-门禁授权同步"` 或 `--unit M-01,M-03` 均可(v8.3.250+ 目录名与 M-ID 双匹配);不要用 --feature——那是确定性局部分析,不出 Prompt)
48
49
  2. stdout 出现 `[SPECCORE_PROMPT]` → 将 Prompt 内容作为你的工作指令执行(不要改写、不要略过);多单元时按 Prompt 内的「逐个单元」指示处理,每个单元用 `analyze --unit <id> --apply '<内容>'` 提交
49
50
  3. 分析中发现需求模糊点 → **向用户提问澄清**,不要自行脑补
50
51
  4. 分析完成后按 Prompt 中的写入格式执行 `speccore analyze --apply '{json}' -I <迭代>` 落盘
@@ -5,7 +5,7 @@ description: >
5
5
  或明确要求通过 speccore 命令行工具执行操作,且意图涉及以下概念时使用:
6
6
  迭代管理、需求文档导入(doc2spec)、需求切分(unitize)、Spec 分析生成(analyze --prompt)、
7
7
  任务拆分(taskify)、执行计划(plan --prompt)、代码执行(execute --prompt)、
8
- 任务归档(done)、PR 提交(pr)、状态查看(status/dashboard/doctor)、智能级联(dev)。
8
+ 任务归档(done)、PR 提交(pr)、状态查看(status/dashboard/doctor)、智能级联/端到端流水线(run)。
9
9
  将用户意图映射为 speccore CLI 命令,通过 execute_command 执行。
10
10
  核心原则:必须直接执行,决不输出命令文本。唯一下例外:"只看不跑"。
11
11
  以下情况明确不处理:解释代码逻辑、审查代码片段、讨论需求合理性、
@@ -312,8 +312,8 @@ allowed-tools: ["Bash", "Read", "Write", "Edit"]
312
312
  ### 智能级联 / 端到端流水线
313
313
  | 用户说法 | 提取参数 | CLI 命令 |
314
314
  | :--- | :--- | :--- |
315
- | 智能级联/全流程推进 | - | `speccore dev` |
316
- | 推进项目/继续开发 | - | `speccore dev` |
315
+ | 智能级联/全流程推进 | - | `speccore run` |
316
+ | 推进项目/继续开发 | - | `speccore run --auto` |
317
317
  | 全自动推进/跑流水线 | - | `speccore run` |
318
318
  | 端到端/一键开发/自动开发 | demand? | `speccore run "{demand}"` |
319
319
  | {一句话需求描述}(如"做积分功能") | demand | `speccore run "{demand}"` |
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -83,6 +83,7 @@ const unit_context_assembler_1 = require("../core/unit-context-assembler");
83
83
  const dispatch_loop_1 = require("../core/dispatch-loop");
84
84
  const pipeline_engine_1 = require("../core/pipeline-engine");
85
85
  const change_detection_1 = require("../core/change-detection");
86
+ const ai_trace_1 = require("../utils/ai-trace");
86
87
  const streaming_analyzer_1 = require("../core/streaming-analyzer");
87
88
  const requirement_clarifier_1 = require("../core/requirement-clarifier");
88
89
  const agents_1 = require("../core/agents");
@@ -242,6 +243,14 @@ async function applyDocContent(content, iter) {
242
243
  const iterDir = await (0, context_1.getIterationDir)(iter);
243
244
  const specDir = (0, path_1.join)(iterDir, '020-specs');
244
245
  let docs = {};
246
+ // v8.3.252+: 飞行记录仪——解析前原样留档(格式错误也留痕),
247
+ // 区分「AI 没给」与「给了但被解析丢弃」
248
+ await (0, ai_trace_1.recordAiTrace)(iter, 'apply-in', {
249
+ rawLength: content.length,
250
+ hasJson: trimmed.startsWith('{'),
251
+ hasDocMarkers: /\[DOC:[^\]]+\]/.test(trimmed),
252
+ rawPreview: trimmed.slice(0, 500),
253
+ });
245
254
  // 格式 1:JSON 对象
246
255
  if (trimmed.startsWith('{')) {
247
256
  try {
@@ -258,6 +267,11 @@ async function applyDocContent(content, iter) {
258
267
  for (const [name, c] of blocks)
259
268
  docs[name] = c;
260
269
  }
270
+ if (Object.keys(docs).length === 0) {
271
+ await (0, ai_trace_1.recordAiTrace)(iter, 'apply-fail', { reason: 'no-parsable-content', rawInput: content });
272
+ logger_1.logger.warn('⚠️ 已收到 AI 回传内容,但 JSON 与 [DOC:] 两种格式均未解析出文档,请检查回传格式');
273
+ return 0;
274
+ }
261
275
  let applied = 0;
262
276
  // v8.3.237+: 与 --apply 主通道一致——有功能模块的项目才拦截(内容类归 {feature}/overview/,
263
277
  // 全局 overview/REQUIREMENT.md 由 split 聚合),无功能模块的老项目放行
@@ -273,6 +287,11 @@ async function applyDocContent(content, iter) {
273
287
  await (0, fs_extra_1.writeFile)(fp, docContent);
274
288
  applied++;
275
289
  }
290
+ await (0, ai_trace_1.recordAiTrace)(iter, 'apply-done', {
291
+ applied,
292
+ files: Object.keys(docs),
293
+ totalChars: Object.values(docs).reduce((s, c) => s + (typeof c === 'string' ? c.length : 0), 0),
294
+ });
276
295
  return applied;
277
296
  }
278
297
  /**
@@ -784,6 +803,7 @@ async function analyzeCommand(options) {
784
803
  const targetUnit = targetUnits[0];
785
804
  if (options.prompt) {
786
805
  const prompt = await buildUnitAnalysisPrompt(iterDir, iter, targetUnit, units);
806
+ await (0, ai_trace_1.recordAiTrace)(iter, 'prompt-out', { mode: 'unit', unit: targetUnit.id, promptLength: prompt.length, prompt });
787
807
  process.stdout.write(`[SPECCORE_PROMPT]\n${prompt}`);
788
808
  process.exitCode = 10;
789
809
  return;
@@ -791,14 +811,22 @@ async function analyzeCommand(options) {
791
811
  if (options.apply) {
792
812
  // v8.3.249+: 此前为“空实现”——只打印「已接收」但 [DOC:xxx] 内容从不落盘,
793
813
  // AI 认真提交后产物丢失,taskify 拿不到分析结果。现在真正解析写入。
814
+ await (0, ai_trace_1.recordAiTrace)(iter, 'apply-in', {
815
+ unit: targetUnit.id,
816
+ rawLength: options.apply.length,
817
+ hasDocMarkers: /\[DOC:[^\]]+\]/.test(options.apply),
818
+ rawPreview: options.apply.trim().slice(0, 500),
819
+ });
794
820
  const docBlocks = parseDocMarkers(options.apply);
795
821
  if (docBlocks.size === 0) {
822
+ await (0, ai_trace_1.recordAiTrace)(iter, 'apply-fail', { unit: targetUnit.id, reason: 'no-doc-markers', rawInput: options.apply });
796
823
  logger_1.logger.warn('⚠️ 未检测到 [DOC:xxx] 标记,请按 prompt 格式输出');
797
824
  return;
798
825
  }
799
826
  const specDir = getUnitSpecDir(iterDir, targetUnit);
800
827
  await (0, fs_extra_1.ensureDir)(specDir);
801
828
  let written = 0;
829
+ const writtenFiles = [];
802
830
  for (const [docName, content] of docBlocks) {
803
831
  const safeName = (0, path_1.basename)(docName);
804
832
  if (!/^[A-Za-z_][A-Za-z0-9_-]*\.(md|yaml)$/.test(safeName))
@@ -809,7 +837,9 @@ async function analyzeCommand(options) {
809
837
  }
810
838
  await (0, fs_extra_1.writeFile)((0, path_1.join)(specDir, safeName), content.trim());
811
839
  written++;
840
+ writtenFiles.push(safeName);
812
841
  }
842
+ await (0, ai_trace_1.recordAiTrace)(iter, 'apply-done', { unit: targetUnit.id, applied: written, files: writtenFiles });
813
843
  logger_1.logger.success(`✅ 功能单元 ${targetUnit.id} 分析结果已写入 ${written} 个文档`);
814
844
  logger_1.logger.info(` 📂 020-specs/${sanitizeUnitDirName(targetUnit.name)}/overview/`);
815
845
  return;
@@ -2738,6 +2768,7 @@ ${singlePrompt}`);
2738
2768
  catch { /* ignore */ }
2739
2769
  }
2740
2770
  const prompt = await buildMultiDocPrompt('analyze', { iteration: iter, task: options.task, type: options.type, scope: options.scope, withCode: options.withCode, platform: options.platform, phase: options.phase, autoMode: options.auto }, options, needsClarify ? { needsClarify, clarifyTargets } : undefined);
2771
+ await (0, ai_trace_1.recordAiTrace)(iter, 'prompt-out', { mode: 'analyze-main', scope: options.scope, promptLength: prompt.length, prompt });
2741
2772
  process.stdout.write(`[SPECCORE_PROMPT]\n${prompt}`);
2742
2773
  // v7.2.0+: 全局分析完成后输出下一步引导
2743
2774
  if (options.scope === 'global') {