flatbread-cli 0.3.0 → 0.3.1
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.
- package/THIRD-PARTY-NOTICES.md +5 -3
- package/dist/flatbread.mjs +157 -22
- package/package.json +1 -1
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## deja-vu
|
|
4
4
|
|
|
5
|
-
`src/adapters/antigravity.ts` reads conversations the way deja-vu reads Windsurf trajectories
|
|
6
|
-
(`internal/sources/windsurf.go`)
|
|
7
|
-
(`
|
|
5
|
+
`src/adapters/antigravity.ts` reads `.pb` conversations the way deja-vu reads Windsurf trajectories
|
|
6
|
+
(`internal/sources/windsurf.go`) and transcripts the way it reads Antigravity's
|
|
7
|
+
(`internal/sources/antigravity.go`). `test/fixtures/antigravity/` holds its fixtures
|
|
8
|
+
(`fixtures/registry/windsurf/cascade/`, `fixtures/registry/antigravity/`) and transcripts from
|
|
9
|
+
`internal/sources/antigravity_toolcalls_test.go`.
|
|
8
10
|
|
|
9
11
|
```
|
|
10
12
|
MIT License
|
package/dist/flatbread.mjs
CHANGED
|
@@ -4810,11 +4810,11 @@ var HARNESS_INFO = {
|
|
|
4810
4810
|
antigravity: {
|
|
4811
4811
|
id: "antigravity",
|
|
4812
4812
|
label: "Google Antigravity",
|
|
4813
|
-
formatLabel: "IDE conversations/<id>.pb
|
|
4813
|
+
formatLabel: "app brain/<id>/.system_generated/logs/transcript.jsonl, or IDE conversations/<id>.pb",
|
|
4814
4814
|
confidence: "documented",
|
|
4815
4815
|
implemented: true,
|
|
4816
4816
|
humanTest: "A6",
|
|
4817
|
-
note: "
|
|
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
4818
|
},
|
|
4819
4819
|
terminal: {
|
|
4820
4820
|
id: "terminal",
|
|
@@ -6052,11 +6052,12 @@ import fs3 from "node:fs";
|
|
|
6052
6052
|
import os2 from "node:os";
|
|
6053
6053
|
import path3 from "node:path";
|
|
6054
6054
|
import { fileURLToPath } from "node:url";
|
|
6055
|
-
var ANTIGRAVITY_ADAPTER_VERSION =
|
|
6055
|
+
var ANTIGRAVITY_ADAPTER_VERSION = 2;
|
|
6056
6056
|
var KEY = Buffer.from("safeCodeiumworldKeYsecretBalloon");
|
|
6057
6057
|
var NONCE = 12;
|
|
6058
6058
|
var TAG = 16;
|
|
6059
6059
|
var CONVERSATION = /[\\/]\.gemini[\\/]antigravity[^\\/]*[\\/]conversations[\\/][^\\/]+\.pb$/i;
|
|
6060
|
+
var TRANSCRIPT = /[\\/]\.gemini[\\/]antigravity[^\\/]*[\\/]brain[\\/][^\\/]+[\\/]\.system_generated[\\/]logs[\\/]transcript\.jsonl$/i;
|
|
6060
6061
|
var PB_VARINT = 0;
|
|
6061
6062
|
var PB_FIXED64 = 1;
|
|
6062
6063
|
var PB_BYTES = 2;
|
|
@@ -6214,6 +6215,82 @@ function decodeTrajectory2(plain) {
|
|
|
6214
6215
|
function homeOf(env) {
|
|
6215
6216
|
return (process.platform === "win32" ? env.USERPROFILE : env.HOME) || os2.homedir();
|
|
6216
6217
|
}
|
|
6218
|
+
var USER_BLOCKS = [/<ADDITIONAL_METADATA>[\s\S]*?<\/ADDITIONAL_METADATA>/g, /<USER_SETTINGS_CHANGE>[\s\S]*?<\/USER_SETTINGS_CHANGE>/g];
|
|
6219
|
+
var ARTIFACT_COMMENT = /^Comments on artifact URI:.*$|^The user has (?:approved|rejected) this document\.$/gm;
|
|
6220
|
+
var REQUEST_TAG = /[ \t]*\n?\s*<\/?USER_REQUEST>\s*/g;
|
|
6221
|
+
function cleanUserContent(text2) {
|
|
6222
|
+
let out = text2;
|
|
6223
|
+
for (const block of USER_BLOCKS) out = out.replace(block, "");
|
|
6224
|
+
out = out.replace(ARTIFACT_COMMENT, "");
|
|
6225
|
+
return out.replace(REQUEST_TAG, "\n").trim();
|
|
6226
|
+
}
|
|
6227
|
+
function decodeArg(value) {
|
|
6228
|
+
if (typeof value !== "string" || !value.startsWith('"')) return value;
|
|
6229
|
+
try {
|
|
6230
|
+
return JSON.parse(value);
|
|
6231
|
+
} catch {
|
|
6232
|
+
return value;
|
|
6233
|
+
}
|
|
6234
|
+
}
|
|
6235
|
+
function isRecord(value) {
|
|
6236
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6237
|
+
}
|
|
6238
|
+
function decodeTranscript(text2) {
|
|
6239
|
+
const events = [];
|
|
6240
|
+
const unread = /* @__PURE__ */ new Map();
|
|
6241
|
+
let cwd;
|
|
6242
|
+
let steps = 0;
|
|
6243
|
+
let line = 0;
|
|
6244
|
+
for (const raw of text2.replace(/\r\n/g, "\n").split("\n")) {
|
|
6245
|
+
line++;
|
|
6246
|
+
if (raw.trim() === "") continue;
|
|
6247
|
+
let record;
|
|
6248
|
+
try {
|
|
6249
|
+
record = JSON.parse(raw);
|
|
6250
|
+
} catch {
|
|
6251
|
+
tally(unread, "malformed line");
|
|
6252
|
+
continue;
|
|
6253
|
+
}
|
|
6254
|
+
if (!isRecord(record)) {
|
|
6255
|
+
tally(unread, "malformed line");
|
|
6256
|
+
continue;
|
|
6257
|
+
}
|
|
6258
|
+
steps++;
|
|
6259
|
+
const source = typeof record["source"] === "string" ? record["source"] : "";
|
|
6260
|
+
const type = typeof record["type"] === "string" ? record["type"] : "";
|
|
6261
|
+
const content = typeof record["content"] === "string" ? record["content"] : "";
|
|
6262
|
+
const created = typeof record["created_at"] === "string" && !Number.isNaN(Date.parse(record["created_at"])) ? record["created_at"] : void 0;
|
|
6263
|
+
const at = created ? { timestamp: created } : {};
|
|
6264
|
+
if (source === "USER_EXPLICIT") {
|
|
6265
|
+
const prompt2 = cleanUserContent(content);
|
|
6266
|
+
if (prompt2) events.push({ kind: "prompt", ...at, text: prompt2 });
|
|
6267
|
+
continue;
|
|
6268
|
+
}
|
|
6269
|
+
if (source !== "MODEL") {
|
|
6270
|
+
tally(unread, type ? `${source || "no"} source, type ${type}` : `${source || "no"} source`);
|
|
6271
|
+
continue;
|
|
6272
|
+
}
|
|
6273
|
+
if (type !== "" && type !== "PLANNER_RESPONSE") {
|
|
6274
|
+
tally(unread, `tool step ${type}`);
|
|
6275
|
+
continue;
|
|
6276
|
+
}
|
|
6277
|
+
if (content.trim()) events.push({ kind: "text", ...at, text: content.trim() });
|
|
6278
|
+
const calls = Array.isArray(record["tool_calls"]) ? record["tool_calls"] : [];
|
|
6279
|
+
calls.forEach((call, k) => {
|
|
6280
|
+
if (!isRecord(call) || typeof call["name"] !== "string") return;
|
|
6281
|
+
const args = {};
|
|
6282
|
+
if (isRecord(call["args"])) for (const [key, value] of Object.entries(call["args"])) args[key] = decodeArg(value);
|
|
6283
|
+
if (cwd === void 0 && call["name"] === "run_command" && typeof args["Cwd"] === "string" && args["Cwd"]) cwd = args["Cwd"];
|
|
6284
|
+
const step = typeof record["step_index"] === "number" ? record["step_index"] : `line${line}`;
|
|
6285
|
+
events.push({ kind: "tool_call", ...at, id: `${step}.${k}`, name: call["name"], input: args });
|
|
6286
|
+
});
|
|
6287
|
+
}
|
|
6288
|
+
if (cwd !== void 0) events.unshift({ kind: "meta", cwd });
|
|
6289
|
+
return { events, steps, unread };
|
|
6290
|
+
}
|
|
6291
|
+
function transcriptId(file) {
|
|
6292
|
+
return path3.basename(path3.dirname(path3.dirname(path3.dirname(file))));
|
|
6293
|
+
}
|
|
6217
6294
|
function listConversations(env = process.env) {
|
|
6218
6295
|
const gemini = path3.join(homeOf(env), ".gemini");
|
|
6219
6296
|
let roots;
|
|
@@ -6222,29 +6299,71 @@ function listConversations(env = process.env) {
|
|
|
6222
6299
|
} catch {
|
|
6223
6300
|
return [];
|
|
6224
6301
|
}
|
|
6225
|
-
const
|
|
6226
|
-
for (const root of roots) {
|
|
6227
|
-
const dir = path3.join(gemini, root, "conversations");
|
|
6228
|
-
let names;
|
|
6302
|
+
const statFile = (file) => {
|
|
6229
6303
|
try {
|
|
6230
|
-
|
|
6304
|
+
const stat = fs3.statSync(file);
|
|
6305
|
+
return stat.isFile() ? stat : null;
|
|
6231
6306
|
} catch {
|
|
6232
|
-
|
|
6307
|
+
return null;
|
|
6233
6308
|
}
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
} catch {
|
|
6241
|
-
continue;
|
|
6242
|
-
}
|
|
6309
|
+
};
|
|
6310
|
+
const readNames = (dir) => {
|
|
6311
|
+
try {
|
|
6312
|
+
return fs3.readdirSync(dir);
|
|
6313
|
+
} catch {
|
|
6314
|
+
return [];
|
|
6243
6315
|
}
|
|
6244
|
-
}
|
|
6245
|
-
|
|
6316
|
+
};
|
|
6317
|
+
const pb = /* @__PURE__ */ new Map();
|
|
6318
|
+
const transcripts = /* @__PURE__ */ new Map();
|
|
6319
|
+
for (const root of roots) {
|
|
6320
|
+
const conversations = path3.join(gemini, root, "conversations");
|
|
6321
|
+
for (const name of readNames(conversations)) {
|
|
6322
|
+
if (!name.toLowerCase().endsWith(".pb")) continue;
|
|
6323
|
+
const file = path3.join(conversations, name);
|
|
6324
|
+
const stat = statFile(file);
|
|
6325
|
+
if (stat === null) continue;
|
|
6326
|
+
const id = name.slice(0, -".pb".length).toLowerCase();
|
|
6327
|
+
const kept = pb.get(id);
|
|
6328
|
+
if (kept === void 0 || stat.size > kept.size) pb.set(id, { file, mtime: stat.mtimeMs, size: stat.size });
|
|
6329
|
+
}
|
|
6330
|
+
const brain = path3.join(gemini, root, "brain");
|
|
6331
|
+
for (const name of readNames(brain)) {
|
|
6332
|
+
const file = path3.join(brain, name, ".system_generated", "logs", "transcript.jsonl");
|
|
6333
|
+
const stat = statFile(file);
|
|
6334
|
+
if (stat === null) continue;
|
|
6335
|
+
const id = name.toLowerCase();
|
|
6336
|
+
const kept = transcripts.get(id);
|
|
6337
|
+
if (kept === void 0 || stat.size > kept.size) transcripts.set(id, { file, mtime: stat.mtimeMs, size: stat.size });
|
|
6338
|
+
}
|
|
6339
|
+
}
|
|
6340
|
+
for (const id of transcripts.keys()) pb.delete(id);
|
|
6341
|
+
return [...pb.values(), ...transcripts.values()].sort((a, b) => b.mtime - a.mtime).map((entry) => entry.file);
|
|
6246
6342
|
}
|
|
6247
6343
|
var REFUSAL_TEST = "A6";
|
|
6344
|
+
async function readTranscript(file) {
|
|
6345
|
+
const trajectory = decodeTranscript(await fs3.promises.readFile(file, "utf8"));
|
|
6346
|
+
const id = transcriptId(file);
|
|
6347
|
+
const said = trajectory.events.filter((e) => e.kind === "prompt" || e.kind === "text").length;
|
|
6348
|
+
if (said === 0) {
|
|
6349
|
+
return {
|
|
6350
|
+
refused: true,
|
|
6351
|
+
reason: `${id}'s transcript has ${trajectory.steps} record(s) and no prompt or reply this reader knows.`,
|
|
6352
|
+
humanTest: REFUSAL_TEST
|
|
6353
|
+
};
|
|
6354
|
+
}
|
|
6355
|
+
return {
|
|
6356
|
+
events: trajectory.events,
|
|
6357
|
+
capabilities: { tokens: "unavailable", filesChanged: "unavailable" },
|
|
6358
|
+
sessionId: id,
|
|
6359
|
+
unreadFields: [...trajectory.unread].sort((a, b) => b[1] - a[1]).map(([field, count]) => `${field} x${count}`),
|
|
6360
|
+
notes: [
|
|
6361
|
+
`${trajectory.steps} record(s), ${said} prompt/reply event(s)`,
|
|
6362
|
+
"tool steps' bodies and checkpoints are not read; tool calls come from the planner's tool_calls",
|
|
6363
|
+
"CONFIDENCE: documented (deja-vu's transcript reader, measured on app 2.24.0). See HUMAN-TESTS.md A6."
|
|
6364
|
+
]
|
|
6365
|
+
};
|
|
6366
|
+
}
|
|
6248
6367
|
var antigravityAdapter = {
|
|
6249
6368
|
id: "antigravity",
|
|
6250
6369
|
version: ANTIGRAVITY_ADAPTER_VERSION,
|
|
@@ -6252,9 +6371,13 @@ var antigravityAdapter = {
|
|
|
6252
6371
|
if (CONVERSATION.test(input.path)) {
|
|
6253
6372
|
return { score: 85, reason: "a conversations/<id>.pb under ~/.gemini/antigravity" };
|
|
6254
6373
|
}
|
|
6255
|
-
|
|
6374
|
+
if (TRANSCRIPT.test(input.path)) {
|
|
6375
|
+
return { score: 85, reason: "a brain/<id>/.system_generated/logs/transcript.jsonl under ~/.gemini/antigravity" };
|
|
6376
|
+
}
|
|
6377
|
+
return { score: 0, reason: "not an Antigravity conversations/<id>.pb or brain transcript" };
|
|
6256
6378
|
},
|
|
6257
6379
|
async read(input) {
|
|
6380
|
+
if (input.path.toLowerCase().endsWith(".jsonl")) return readTranscript(input.path);
|
|
6258
6381
|
const plain = openConversation(await fs3.promises.readFile(input.path));
|
|
6259
6382
|
if (plain === null) {
|
|
6260
6383
|
return {
|
|
@@ -6305,6 +6428,18 @@ var antigravityAdapter = {
|
|
|
6305
6428
|
const target = files[0];
|
|
6306
6429
|
if (target === void 0) return lines2;
|
|
6307
6430
|
lines2.push("", `inspecting ${target}`);
|
|
6431
|
+
if (target.toLowerCase().endsWith(".jsonl")) {
|
|
6432
|
+
try {
|
|
6433
|
+
const trajectory = decodeTranscript(await fs3.promises.readFile(target, "utf8"));
|
|
6434
|
+
lines2.push(` records: ${trajectory.steps}, events: ${trajectory.events.filter((e) => e.kind !== "meta").length}`);
|
|
6435
|
+
for (const [field, count] of [...trajectory.unread].sort((a, b) => b[1] - a[1]).slice(0, 15)) {
|
|
6436
|
+
lines2.push(` ${String(count).padStart(6)} ${field}`);
|
|
6437
|
+
}
|
|
6438
|
+
} catch (error) {
|
|
6439
|
+
lines2.push(` unreadable: ${error instanceof Error ? error.message : String(error)}`);
|
|
6440
|
+
}
|
|
6441
|
+
return lines2;
|
|
6442
|
+
}
|
|
6308
6443
|
let plain;
|
|
6309
6444
|
try {
|
|
6310
6445
|
plain = openConversation(await fs3.promises.readFile(target));
|
|
@@ -10934,7 +11069,7 @@ function logCapture(dir, line, now = (/* @__PURE__ */ new Date()).toISOString())
|
|
|
10934
11069
|
|
|
10935
11070
|
// src/mcp.ts
|
|
10936
11071
|
var MCP_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
|
|
10937
|
-
var MCP_SERVER_VERSION = "0.3.
|
|
11072
|
+
var MCP_SERVER_VERSION = "0.3.1";
|
|
10938
11073
|
function defaultMcpDeps(storeDir2, bucketDir2) {
|
|
10939
11074
|
return {
|
|
10940
11075
|
storeDir: storeDir2,
|
package/package.json
CHANGED