flatbread-cli 0.3.1 → 0.3.2

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 (2) hide show
  1. package/dist/flatbread.mjs +75 -65
  2. package/package.json +1 -1
@@ -4307,6 +4307,73 @@ function tallyFailures(loops) {
4307
4307
  };
4308
4308
  }
4309
4309
 
4310
+ // ../schema/src/harness.ts
4311
+ var HARNESS_INFO = {
4312
+ "claude-code": {
4313
+ id: "claude-code",
4314
+ label: "Claude Code",
4315
+ formatLabel: "session JSONL (~/.claude/projects)",
4316
+ confidence: "observed",
4317
+ implemented: true,
4318
+ humanTest: "A1",
4319
+ toolResults: "measured",
4320
+ note: "Built from real observed logs. Anthropic publishes no format guarantee, so watch the unknown-type counter."
4321
+ },
4322
+ cursor: {
4323
+ id: "cursor",
4324
+ label: "Cursor",
4325
+ formatLabel: "state.vscdb SQLite (cursorDiskKV + ItemTable)",
4326
+ confidence: "documented",
4327
+ implemented: true,
4328
+ humanTest: "A5",
4329
+ toolResults: "unavailable",
4330
+ note: "Reads composerData:/bubbleId: from cursorDiskKV (modern) and aiService.prompts from ItemTable (legacy). Cursor publishes no schema and has moved these keys between releases."
4331
+ },
4332
+ opencode: {
4333
+ id: "opencode",
4334
+ label: "OpenCode",
4335
+ formatLabel: "SQLite opencode.db (1.3+) or storage/ JSON tree (1.0.x)",
4336
+ confidence: "documented",
4337
+ implemented: true,
4338
+ humanTest: "A4",
4339
+ toolResults: "measured",
4340
+ note: "Two layouts. 1.3+ keeps sessions in an SQLite opencode.db (schema read off a real 1.3.17 install); 1.0.x kept a session/message/part JSON tree. OpenCode publishes no schema and its migrations have moved this once already, so a version bump can move it again."
4341
+ },
4342
+ antigravity: {
4343
+ id: "antigravity",
4344
+ label: "Google Antigravity",
4345
+ formatLabel: "app brain/<id>/.system_generated/logs/transcript.jsonl, or IDE conversations/<id>.pb",
4346
+ confidence: "documented",
4347
+ implemented: true,
4348
+ humanTest: "A6",
4349
+ toolResults: "unavailable",
4350
+ note: "Both stores measured on one machine. The app's transcript is read the way deja-vu reads it: prompts, replies and the planner's tool calls, not tool output. The IDE's .pb is read the way deja-vu reads Windsurf: prompts and replies only."
4351
+ },
4352
+ terminal: {
4353
+ id: "terminal",
4354
+ label: "Terminal / PTY recording",
4355
+ formatLabel: "asciinema cast v2, or a plain text transcript",
4356
+ confidence: "spec",
4357
+ implemented: true,
4358
+ humanTest: "A3",
4359
+ toolResults: "unavailable",
4360
+ note: "Cast format is specified. Segmenting a raw terminal stream into prompts and replies is heuristic and will misread unfamiliar prompts."
4361
+ },
4362
+ otel: {
4363
+ id: "otel",
4364
+ label: "OpenTelemetry",
4365
+ formatLabel: "OTLP/JSON spans with GenAI semantic conventions",
4366
+ confidence: "spec",
4367
+ implemented: true,
4368
+ humanTest: "A2",
4369
+ toolResults: "measured",
4370
+ note: "Both the wire format and the gen_ai.* attribute names are specified. Unproven: that real instrumentation populates them."
4371
+ }
4372
+ };
4373
+ function failuresRecorded(harness) {
4374
+ return HARNESS_INFO[harness].toolResults === "measured";
4375
+ }
4376
+
4310
4377
  // ../schema/src/brief.ts
4311
4378
  var MUTATING_TOOL_NAMES = /* @__PURE__ */ new Set([
4312
4379
  "write",
@@ -4642,14 +4709,15 @@ function runDiagnostics(trace) {
4642
4709
  if (hit) waste.push({ kind: "repeated-search", label, steps: hit, windowMinutes: WASTE_RULES.repeatedSearch.windowMinutes });
4643
4710
  }
4644
4711
  const stats = trace.stats;
4712
+ const recorded = failuresRecorded(trace.source.harness);
4645
4713
  return {
4646
4714
  counts: {
4647
4715
  steps: steps.length,
4648
4716
  agentSteps: steps.length - prompts.length,
4649
4717
  humanPrompts: prompts.length,
4650
4718
  toolCalls: stats.toolCallCount,
4651
- failures: steps.filter((step) => step.type === "error_recovery").length,
4652
- recoveries: loops.filter((loop) => loop.outcome === "recovered").length
4719
+ failures: recorded ? steps.filter((step) => step.type === "error_recovery").length : null,
4720
+ recoveries: recorded ? loops.filter((loop) => loop.outcome === "recovered").length : null
4653
4721
  },
4654
4722
  tokens: {
4655
4723
  input: stats.inputTokens,
@@ -4778,64 +4846,6 @@ function buildExecutionBrief(trace) {
4778
4846
  };
4779
4847
  }
4780
4848
 
4781
- // ../schema/src/harness.ts
4782
- var HARNESS_INFO = {
4783
- "claude-code": {
4784
- id: "claude-code",
4785
- label: "Claude Code",
4786
- formatLabel: "session JSONL (~/.claude/projects)",
4787
- confidence: "observed",
4788
- implemented: true,
4789
- humanTest: "A1",
4790
- note: "Built from real observed logs. Anthropic publishes no format guarantee, so watch the unknown-type counter."
4791
- },
4792
- cursor: {
4793
- id: "cursor",
4794
- label: "Cursor",
4795
- formatLabel: "state.vscdb SQLite (cursorDiskKV + ItemTable)",
4796
- confidence: "documented",
4797
- implemented: true,
4798
- humanTest: "A5",
4799
- note: "Reads composerData:/bubbleId: from cursorDiskKV (modern) and aiService.prompts from ItemTable (legacy). Cursor publishes no schema and has moved these keys between releases."
4800
- },
4801
- opencode: {
4802
- id: "opencode",
4803
- label: "OpenCode",
4804
- formatLabel: "SQLite opencode.db (1.3+) or storage/ JSON tree (1.0.x)",
4805
- confidence: "documented",
4806
- implemented: true,
4807
- humanTest: "A4",
4808
- note: "Two layouts. 1.3+ keeps sessions in an SQLite opencode.db (schema read off a real 1.3.17 install); 1.0.x kept a session/message/part JSON tree. OpenCode publishes no schema and its migrations have moved this once already, so a version bump can move it again."
4809
- },
4810
- antigravity: {
4811
- id: "antigravity",
4812
- label: "Google Antigravity",
4813
- formatLabel: "app brain/<id>/.system_generated/logs/transcript.jsonl, or IDE conversations/<id>.pb",
4814
- confidence: "documented",
4815
- implemented: true,
4816
- humanTest: "A6",
4817
- note: "Both stores measured on one machine. The app's transcript is read the way deja-vu reads it: prompts, replies and the planner's tool calls, not tool output. The IDE's .pb is read the way deja-vu reads Windsurf: prompts and replies only."
4818
- },
4819
- terminal: {
4820
- id: "terminal",
4821
- label: "Terminal / PTY recording",
4822
- formatLabel: "asciinema cast v2, or a plain text transcript",
4823
- confidence: "spec",
4824
- implemented: true,
4825
- humanTest: "A3",
4826
- note: "Cast format is specified. Segmenting a raw terminal stream into prompts and replies is heuristic and will misread unfamiliar prompts."
4827
- },
4828
- otel: {
4829
- id: "otel",
4830
- label: "OpenTelemetry",
4831
- formatLabel: "OTLP/JSON spans with GenAI semantic conventions",
4832
- confidence: "spec",
4833
- implemented: true,
4834
- humanTest: "A2",
4835
- note: "Both the wire format and the gen_ai.* attribute names are specified. Unproven: that real instrumentation populates them."
4836
- }
4837
- };
4838
-
4839
4849
  // ../schema/src/capsule.ts
4840
4850
  var CAPSULE_LIMITS = {
4841
4851
  /** Diff lines across every patch. Past it the rest is counted, never silently dropped. */
@@ -6000,7 +6010,7 @@ function buildTrace(input) {
6000
6010
  const title = titleFromPrompt(firstPrompt?.content ?? "");
6001
6011
  const filesChanged = input.capabilities.filesChanged === "measured" ? changedFiles.size : null;
6002
6012
  const filesPhrase = filesChanged === null ? "an unrecorded number of files changed" : `${plural2(filesChanged, "file")} changed`;
6003
- const summary = `${plural2(steps.length, "step")}, ${plural2(toolCallCount, "tool call")}, ${filesPhrase}, ${plural2(errorCount, "tool error")} over ${Math.round(durationSeconds)}s.`;
6013
+ const summary = `${plural2(steps.length, "step")}, ${plural2(toolCallCount, "tool call")}, ${filesPhrase}, ${failuresRecorded(input.harness) ? plural2(errorCount, "tool error") : "tool errors not recorded"} over ${Math.round(durationSeconds)}s.`;
6004
6014
  const tokensMeasured = input.capabilities.tokens === "measured";
6005
6015
  const provenance = {
6006
6016
  id: input.harness,
@@ -10204,7 +10214,7 @@ function renderReviewPage(input) {
10204
10214
  <h1>${marked("title", trace.title)}</h1>
10205
10215
  <div class="meta">
10206
10216
  <b>${escapeHtml(trace.model)}</b> &middot; ${plural2(trace.steps.length, "step")} &middot; ${plural2(toolCalls, "tool call")} &middot;
10207
- ${trace.stats.filesChanged === null ? `${formatCount(null)} files` : plural2(trace.stats.filesChanged, "file")} changed &middot; ${plural2(trace.stats.errorCount, "error")} &middot;
10217
+ ${trace.stats.filesChanged === null ? `${formatCount(null)} files` : plural2(trace.stats.filesChanged, "file")} changed &middot; ${failuresRecorded(trace.source.harness) ? plural2(trace.stats.errorCount, "error") : `${formatCount(null)} errors`} &middot;
10208
10218
  ${Math.round(trace.stats.durationSeconds)}s &middot; <b>${matches.length}</b> redaction match${matches.length === 1 ? "" : "es"}
10209
10219
  </div>
10210
10220
  <div class="meta path">${escapeHtml(sessionPath)}</div>
@@ -10786,7 +10796,7 @@ function diagnosticsLines(diagnostics) {
10786
10796
  const { counts, tokens } = diagnostics;
10787
10797
  const out = [
10788
10798
  `${plural3(counts.steps, "step")}: ${counts.agentSteps.toLocaleString("en-US")} by the agent, ${plural3(counts.humanPrompts, "prompt")} from a person`,
10789
- `${plural3(counts.toolCalls, "tool call")}, ${plural3(counts.failures, "failure")}, ${plural3(counts.recoveries, "recovery", "recoveries")} by the agent`
10799
+ counts.failures === null || counts.recoveries === null ? `${plural3(counts.toolCalls, "tool call")}; failures not recorded by this harness` : `${plural3(counts.toolCalls, "tool call")}, ${plural3(counts.failures, "failure")}, ${plural3(counts.recoveries, "recovery", "recoveries")} by the agent`
10790
10800
  ];
10791
10801
  const recorded = [];
10792
10802
  if (tokens.input !== null) recorded.push(["in", tokens.input]);
@@ -11069,7 +11079,7 @@ function logCapture(dir, line, now = (/* @__PURE__ */ new Date()).toISOString())
11069
11079
 
11070
11080
  // src/mcp.ts
11071
11081
  var MCP_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
11072
- var MCP_SERVER_VERSION = "0.3.1";
11082
+ var MCP_SERVER_VERSION = "0.3.2";
11073
11083
  function defaultMcpDeps(storeDir2, bucketDir2) {
11074
11084
  return {
11075
11085
  storeDir: storeDir2,
@@ -12732,7 +12742,7 @@ function report(result, outputPath) {
12732
12742
  lines2.push(` tool calls ${formatInt(trace.stats.toolCallCount)}`);
12733
12743
  lines2.push(` tools used ${result.toolNames.length > 0 ? result.toolNames.join(", ") : "(none)"}`);
12734
12744
  lines2.push(` files changed ${formatCount(trace.stats.filesChanged)}`);
12735
- lines2.push(` tool errors ${formatInt(trace.stats.errorCount)}`);
12745
+ lines2.push(` tool errors ${failuresRecorded(trace.source.harness) ? formatInt(trace.stats.errorCount) : formatCount(null)}`);
12736
12746
  lines2.push("");
12737
12747
  lines2.push(
12738
12748
  ` tokens in ${formatCount(trace.stats.inputTokens)} / out ${formatCount(trace.stats.outputTokens)} / cache read ${formatCount(trace.stats.cacheReadTokens)} / cache write ${formatCount(trace.stats.cacheCreationTokens)}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flatbread-cli",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Flatbread: read a coding agent's session off disk, redact it, share it, and pull a run's Context Capsule into another agent.",
5
5
  "type": "module",
6
6
  "bin": {