codesesh 0.14.0 → 0.15.0

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.
@@ -1059,18 +1059,11 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1059
1059
  }
1060
1060
  const content = readFileSync2(meta.sourcePath, "utf-8");
1061
1061
  const builder = new TranscriptBuilder();
1062
- const ignoredToolCallIds = /* @__PURE__ */ new Set();
1063
1062
  const assistantUuidToToolCalls = /* @__PURE__ */ new Map();
1064
1063
  const countedUsageKeys = /* @__PURE__ */ new Set();
1065
1064
  for (const record of parseJsonlLines(content)) {
1066
1065
  try {
1067
- this.convertRecord(
1068
- record,
1069
- builder,
1070
- ignoredToolCallIds,
1071
- assistantUuidToToolCalls,
1072
- countedUsageKeys
1073
- );
1066
+ this.convertRecord(record, builder, assistantUuidToToolCalls, countedUsageKeys);
1074
1067
  } catch {
1075
1068
  }
1076
1069
  }
@@ -1295,25 +1288,19 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1295
1288
  return null;
1296
1289
  }
1297
1290
  // --- Record conversion ---
1298
- convertRecord(data, builder, ignoredToolCallIds, assistantUuidToToolCalls, countedUsageKeys) {
1291
+ convertRecord(data, builder, assistantUuidToToolCalls, countedUsageKeys) {
1299
1292
  if (data["isMeta"] === true) return;
1300
1293
  const msgType = String(data["type"] ?? "");
1301
1294
  if (isInternalEventType(msgType)) return;
1302
1295
  if (msgType === "assistant") {
1303
- this.convertAssistantRecord(
1304
- data,
1305
- builder,
1306
- ignoredToolCallIds,
1307
- assistantUuidToToolCalls,
1308
- countedUsageKeys
1309
- );
1296
+ this.convertAssistantRecord(data, builder, assistantUuidToToolCalls, countedUsageKeys);
1310
1297
  } else if (msgType === "user") {
1311
- this.convertUserRecord(data, builder, ignoredToolCallIds, assistantUuidToToolCalls);
1298
+ this.convertUserRecord(data, builder, assistantUuidToToolCalls);
1312
1299
  } else if (msgType === "tool_result") {
1313
1300
  this.convertToolResultRecord(data, builder);
1314
1301
  }
1315
1302
  }
1316
- convertAssistantRecord(data, builder, ignoredToolCallIds, assistantUuidToToolCalls, countedUsageKeys) {
1303
+ convertAssistantRecord(data, builder, assistantUuidToToolCalls, countedUsageKeys) {
1317
1304
  const msg = data["message"] ?? {};
1318
1305
  const timestampMs = parseTimestampMs(data);
1319
1306
  const rawContent = msg["content"] ?? [];
@@ -1353,12 +1340,7 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1353
1340
  continue;
1354
1341
  }
1355
1342
  if (partType !== "tool_use") continue;
1356
- const toolName = String(part["name"] ?? "").trim();
1357
1343
  const toolCallId = String(part["id"] ?? "").trim();
1358
- if (toolName && toolCallId && this.shouldIgnoreTool(toolName)) {
1359
- ignoredToolCallIds.add(toolCallId);
1360
- continue;
1361
- }
1362
1344
  const toolPart = this.buildToolPart(part, timestampMs);
1363
1345
  const message = builder.appendToolCall(
1364
1346
  toolPart,
@@ -1375,7 +1357,7 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1375
1357
  assistantUuidToToolCalls.set(uuid, toolCallIds);
1376
1358
  }
1377
1359
  }
1378
- convertUserRecord(data, builder, ignoredToolCallIds, assistantUuidToToolCalls) {
1360
+ convertUserRecord(data, builder, assistantUuidToToolCalls) {
1379
1361
  const msg = data["message"] ?? {};
1380
1362
  const timestampMs = parseTimestampMs(data);
1381
1363
  const content = msg["content"] ?? "";
@@ -1400,7 +1382,6 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1400
1382
  const ci = item;
1401
1383
  if (ci["type"] !== "tool_result") continue;
1402
1384
  const toolCallId = this.resolveToolCallId(data, ci, assistantUuidToToolCalls);
1403
- if (toolCallId && ignoredToolCallIds.has(toolCallId)) continue;
1404
1385
  const outputParts = this.normalizeClaudeToolOutput(ci["content"], timestampMs);
1405
1386
  if (this.backfillToolOutput(builder, toolCallId, outputParts, toolStateUpdates)) {
1406
1387
  continue;
@@ -1504,9 +1485,17 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1504
1485
  const parts = [];
1505
1486
  for (const item of content) {
1506
1487
  if (typeof item === "object" && item !== null) {
1507
- const text2 = String(
1508
- item["text"] ?? item["content"] ?? ""
1509
- );
1488
+ const itemRecord = item;
1489
+ const source = itemRecord["source"];
1490
+ if (itemRecord["type"] === "image" && source) {
1491
+ const data = typeof source["data"] === "string" ? source["data"] : "";
1492
+ const mimeType = typeof source["media_type"] === "string" ? source["media_type"] : "";
1493
+ if (data && mimeType.startsWith("image/")) {
1494
+ parts.push({ type: "image", data, mime_type: mimeType, time_created: timestampMs });
1495
+ }
1496
+ continue;
1497
+ }
1498
+ const text2 = String(itemRecord["text"] ?? itemRecord["content"] ?? "");
1510
1499
  const cleaned = cleanInternalText(text2);
1511
1500
  if (cleaned) parts.push(this.buildTextPart(cleaned, timestampMs));
1512
1501
  } else if (typeof item === "string") {
@@ -1567,10 +1556,6 @@ var ClaudeCodeAgent = class extends FileSystemSessionSource {
1567
1556
  parts: opts.outputParts
1568
1557
  };
1569
1558
  }
1570
- // --- Utilities ---
1571
- shouldIgnoreTool(toolName) {
1572
- return toolName === "TodoWrite";
1573
- }
1574
1559
  };
1575
1560
  var DatabaseConstructor = null;
1576
1561
  try {
@@ -2628,11 +2613,268 @@ var KimiAgent = class extends FileSystemSessionSource {
2628
2613
  };
2629
2614
  }
2630
2615
  };
2616
+ var PARSE_FAIL = /* @__PURE__ */ Symbol("parse-fail");
2617
+ var EXEC_OUTPUT_ENVELOPE_RE = /^Script completed\nWall time [^\n]*\nOutput:\n?/;
2618
+ function stripExecOutputEnvelope(text) {
2619
+ return text.replace(EXEC_OUTPUT_ENVELOPE_RE, "");
2620
+ }
2621
+ function splitExecToolName(name) {
2622
+ if (name.startsWith("mcp__")) {
2623
+ const separator = name.lastIndexOf("__");
2624
+ if (separator > 0 && separator + 2 < name.length) {
2625
+ return { name: name.slice(separator + 2), namespace: name.slice(0, separator + 2) };
2626
+ }
2627
+ }
2628
+ return { name };
2629
+ }
2630
+ function pickExecOutputTarget(calls) {
2631
+ for (let index = calls.length - 1; index >= 0; index -= 1) {
2632
+ const { name } = splitExecToolName(calls[index].name);
2633
+ if (name !== "apply_patch" && name !== "update_plan") return index;
2634
+ }
2635
+ return calls.length - 1;
2636
+ }
2637
+ function getExecPatchText(args) {
2638
+ if (typeof args === "string") return args;
2639
+ if (args && typeof args === "object") {
2640
+ const patch = args["patch"];
2641
+ if (typeof patch === "string") return patch;
2642
+ }
2643
+ return "";
2644
+ }
2645
+ function decodeExecCalls(input) {
2646
+ if (typeof input !== "string" || !input.includes("tools.")) return [];
2647
+ const scope = collectStringVars(input);
2648
+ const calls = [];
2649
+ const callRe = /tools\.([A-Za-z_$][\w$]*)\s*\(/g;
2650
+ let match;
2651
+ while ((match = callRe.exec(input)) !== null) {
2652
+ const reader = new JsValueReader(input, callRe.lastIndex, scope);
2653
+ const args = reader.parseValue();
2654
+ if (args !== PARSE_FAIL) {
2655
+ calls.push({ name: match[1], args });
2656
+ callRe.lastIndex = reader.pos;
2657
+ }
2658
+ }
2659
+ return calls;
2660
+ }
2661
+ function collectStringVars(input) {
2662
+ const scope = /* @__PURE__ */ new Map();
2663
+ const assignRe = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*/g;
2664
+ let match;
2665
+ while ((match = assignRe.exec(input)) !== null) {
2666
+ const reader = new JsValueReader(input, assignRe.lastIndex, scope);
2667
+ const value = reader.parseValue();
2668
+ if (value !== PARSE_FAIL) {
2669
+ if (typeof value === "string") scope.set(match[1], value);
2670
+ assignRe.lastIndex = reader.pos;
2671
+ }
2672
+ }
2673
+ return scope;
2674
+ }
2675
+ var IDENT_START_RE = /[A-Za-z_$]/;
2676
+ var IDENT_PART_RE = /[\w$]/;
2677
+ var JsValueReader = class {
2678
+ pos;
2679
+ src;
2680
+ scope;
2681
+ constructor(src, start, scope) {
2682
+ this.src = src;
2683
+ this.pos = start;
2684
+ this.scope = scope;
2685
+ }
2686
+ parseValue() {
2687
+ this.skipTrivia();
2688
+ const char = this.src[this.pos];
2689
+ if (char === void 0) return PARSE_FAIL;
2690
+ if (char === "{") return this.parseObject();
2691
+ if (char === "[") return this.parseArray();
2692
+ if (char === '"' || char === "'" || char === "`") return this.parseString(char);
2693
+ if (char === "-" || char === "+" || char >= "0" && char <= "9") return this.parseNumber();
2694
+ if (IDENT_START_RE.test(char)) return this.parseIdentifierValue();
2695
+ return PARSE_FAIL;
2696
+ }
2697
+ parseObject() {
2698
+ this.pos++;
2699
+ const result = {};
2700
+ this.skipTrivia();
2701
+ if (this.src[this.pos] === "}") {
2702
+ this.pos++;
2703
+ return result;
2704
+ }
2705
+ while (this.pos < this.src.length) {
2706
+ this.skipTrivia();
2707
+ const key = this.parseKey();
2708
+ if (key === PARSE_FAIL) return PARSE_FAIL;
2709
+ this.skipTrivia();
2710
+ if (this.src[this.pos] === ":") {
2711
+ this.pos++;
2712
+ const value = this.parseValue();
2713
+ if (value === PARSE_FAIL) return PARSE_FAIL;
2714
+ result[key] = value;
2715
+ } else {
2716
+ result[key] = this.resolveIdentifier(key);
2717
+ }
2718
+ this.skipTrivia();
2719
+ const next = this.src[this.pos];
2720
+ if (next === ",") {
2721
+ this.pos++;
2722
+ this.skipTrivia();
2723
+ if (this.src[this.pos] === "}") {
2724
+ this.pos++;
2725
+ return result;
2726
+ }
2727
+ continue;
2728
+ }
2729
+ if (next === "}") {
2730
+ this.pos++;
2731
+ return result;
2732
+ }
2733
+ return PARSE_FAIL;
2734
+ }
2735
+ return PARSE_FAIL;
2736
+ }
2737
+ parseArray() {
2738
+ this.pos++;
2739
+ const result = [];
2740
+ this.skipTrivia();
2741
+ if (this.src[this.pos] === "]") {
2742
+ this.pos++;
2743
+ return result;
2744
+ }
2745
+ while (this.pos < this.src.length) {
2746
+ const value = this.parseValue();
2747
+ if (value === PARSE_FAIL) return PARSE_FAIL;
2748
+ result.push(value);
2749
+ this.skipTrivia();
2750
+ const next = this.src[this.pos];
2751
+ if (next === ",") {
2752
+ this.pos++;
2753
+ this.skipTrivia();
2754
+ if (this.src[this.pos] === "]") {
2755
+ this.pos++;
2756
+ return result;
2757
+ }
2758
+ continue;
2759
+ }
2760
+ if (next === "]") {
2761
+ this.pos++;
2762
+ return result;
2763
+ }
2764
+ return PARSE_FAIL;
2765
+ }
2766
+ return PARSE_FAIL;
2767
+ }
2768
+ parseKey() {
2769
+ const char = this.src[this.pos];
2770
+ if (char === '"' || char === "'" || char === "`") {
2771
+ const value = this.parseString(char);
2772
+ return typeof value === "string" ? value : PARSE_FAIL;
2773
+ }
2774
+ if (char !== void 0 && IDENT_START_RE.test(char)) return this.readIdentifier();
2775
+ return PARSE_FAIL;
2776
+ }
2777
+ parseString(quote) {
2778
+ this.pos++;
2779
+ let out = "";
2780
+ while (this.pos < this.src.length) {
2781
+ const char = this.src[this.pos++];
2782
+ if (char === "\\") {
2783
+ out += this.readEscape();
2784
+ continue;
2785
+ }
2786
+ if (char === quote) break;
2787
+ out += char;
2788
+ }
2789
+ return out;
2790
+ }
2791
+ readEscape() {
2792
+ const char = this.src[this.pos++];
2793
+ switch (char) {
2794
+ case "n":
2795
+ return "\n";
2796
+ case "t":
2797
+ return " ";
2798
+ case "r":
2799
+ return "\r";
2800
+ case "b":
2801
+ return "\b";
2802
+ case "f":
2803
+ return "\f";
2804
+ case "v":
2805
+ return "\v";
2806
+ case "0":
2807
+ return "\0";
2808
+ case "u": {
2809
+ const hex = this.src.slice(this.pos, this.pos + 4);
2810
+ if (/^[0-9a-fA-F]{4}$/.test(hex)) {
2811
+ this.pos += 4;
2812
+ return String.fromCharCode(parseInt(hex, 16));
2813
+ }
2814
+ return "u";
2815
+ }
2816
+ case "x": {
2817
+ const hex = this.src.slice(this.pos, this.pos + 2);
2818
+ if (/^[0-9a-fA-F]{2}$/.test(hex)) {
2819
+ this.pos += 2;
2820
+ return String.fromCharCode(parseInt(hex, 16));
2821
+ }
2822
+ return "x";
2823
+ }
2824
+ default:
2825
+ return char ?? "";
2826
+ }
2827
+ }
2828
+ parseNumber() {
2829
+ const numberRe = /[-+]?(?:0[xX][0-9a-fA-F]+|(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?)/y;
2830
+ numberRe.lastIndex = this.pos;
2831
+ const match = numberRe.exec(this.src);
2832
+ if (!match) return PARSE_FAIL;
2833
+ this.pos += match[0].length;
2834
+ return Number(match[0]);
2835
+ }
2836
+ parseIdentifierValue() {
2837
+ const name = this.readIdentifier();
2838
+ if (name === "true") return true;
2839
+ if (name === "false") return false;
2840
+ if (name === "null") return null;
2841
+ if (name === "undefined") return void 0;
2842
+ return this.resolveIdentifier(name);
2843
+ }
2844
+ resolveIdentifier(name) {
2845
+ return this.scope.has(name) ? this.scope.get(name) : void 0;
2846
+ }
2847
+ readIdentifier() {
2848
+ const start = this.pos;
2849
+ while (this.pos < this.src.length && IDENT_PART_RE.test(this.src[this.pos])) this.pos++;
2850
+ return this.src.slice(start, this.pos);
2851
+ }
2852
+ skipTrivia() {
2853
+ while (this.pos < this.src.length) {
2854
+ const char = this.src[this.pos];
2855
+ if (char === " " || char === " " || char === "\n" || char === "\r") {
2856
+ this.pos++;
2857
+ continue;
2858
+ }
2859
+ if (char === "/" && this.src[this.pos + 1] === "/") {
2860
+ const newline = this.src.indexOf("\n", this.pos + 2);
2861
+ this.pos = newline === -1 ? this.src.length : newline + 1;
2862
+ continue;
2863
+ }
2864
+ if (char === "/" && this.src[this.pos + 1] === "*") {
2865
+ const close = this.src.indexOf("*/", this.pos + 2);
2866
+ this.pos = close === -1 ? this.src.length : close + 2;
2867
+ continue;
2868
+ }
2869
+ break;
2870
+ }
2871
+ }
2872
+ };
2631
2873
  var PROPOSED_PLAN_PATTERN = /<proposed_plan>\s*([\s\S]*?)\s*<\/proposed_plan>/;
2632
2874
  var PLAN_APPROVAL_PREFIX = "PLEASE IMPLEMENT THIS PLAN";
2633
2875
  var SUBAGENT_NOTIFICATION_PATTERN = /<subagent_notification>\s*([\s\S]*?)\s*<\/subagent_notification>/;
2634
2876
  var HEAD_INDEX_VERSION2 = "codex-head-v1";
2635
- var PARSER_VERSION = "codex-parser-v3";
2877
+ var PARSER_VERSION = "codex-parser-v4";
2636
2878
  var DEVELOPER_LIKE_USER_MARKERS = [
2637
2879
  "agents.md instructions for",
2638
2880
  "<instructions>",
@@ -2709,6 +2951,20 @@ function normalizeCustomToolArguments(toolName, input) {
2709
2951
  }
2710
2952
  return input;
2711
2953
  }
2954
+ function flattenOutputText(output) {
2955
+ if (typeof output === "string") return output;
2956
+ if (Array.isArray(output)) {
2957
+ return output.map((item) => {
2958
+ if (typeof item === "string") return item;
2959
+ if (item && typeof item === "object") {
2960
+ const text = item["text"];
2961
+ if (typeof text === "string") return text;
2962
+ }
2963
+ return "";
2964
+ }).join("");
2965
+ }
2966
+ return "";
2967
+ }
2712
2968
  var PATCH_BEGIN_RE = /\*\*\* Begin Patch/;
2713
2969
  var PATCH_END_RE = /\*\*\* End Patch/;
2714
2970
  var PATCH_HEADER_RE = /\*\*\*\s+(Add|Delete|Update|Move)\s+File:\s*(.+)/;
@@ -3437,7 +3693,9 @@ var CodexAgent = class extends FileSystemSessionSource {
3437
3693
  convertToolCallOutput(payload, transcript, timestampMs) {
3438
3694
  const callId = String(payload["call_id"] ?? "").trim();
3439
3695
  if (!callId) return;
3440
- const outputText = cleanInternalText(String(payload["output"] ?? ""));
3696
+ const outputText = cleanInternalText(
3697
+ stripExecOutputEnvelope(flattenOutputText(payload["output"]))
3698
+ );
3441
3699
  const outputParts = outputText ? [{ type: "text", text: outputText, time_created: timestampMs }] : [];
3442
3700
  if (outputParts.length > 0) {
3443
3701
  transcript.resolveToolCall(callId, { output: outputParts, status: "completed" });
@@ -3448,6 +3706,13 @@ var CodexAgent = class extends FileSystemSessionSource {
3448
3706
  const callId = String(payload["call_id"] ?? "").trim();
3449
3707
  const name = String(payload["name"] ?? "").trim();
3450
3708
  if (!name) return;
3709
+ if (name === "exec") {
3710
+ const decoded = decodeExecCalls(payload["input"]);
3711
+ if (decoded.length > 0) {
3712
+ this.appendDecodedExecCalls(decoded, callId, transcript, timestampMs, activeModel);
3713
+ return;
3714
+ }
3715
+ }
3451
3716
  const toolIdentity = resolveToolIdentity(name, payload["namespace"]);
3452
3717
  const rawInput = payload["input"];
3453
3718
  const normalizedInput = normalizeCustomToolArguments(name, rawInput);
@@ -3469,6 +3734,36 @@ var CodexAgent = class extends FileSystemSessionSource {
3469
3734
  { markModeAsTool: true }
3470
3735
  );
3471
3736
  }
3737
+ // ---- Decoded code-mode exec calls ----
3738
+ appendDecodedExecCalls(calls, callId, transcript, timestampMs, activeModel) {
3739
+ const outputIndex = pickExecOutputTarget(calls);
3740
+ calls.forEach((call, index) => {
3741
+ const partCallId = index === outputIndex ? callId : `${callId}#${index}`;
3742
+ this.appendDecodedExecCall(call, partCallId, transcript, timestampMs, activeModel);
3743
+ });
3744
+ }
3745
+ appendDecodedExecCall(call, callId, transcript, timestampMs, activeModel) {
3746
+ const { name, namespace } = splitExecToolName(call.name);
3747
+ const toolIdentity = resolveToolIdentity(name, namespace);
3748
+ const arguments_ = name === "apply_patch" ? parseApplyPatchInput(getExecPatchText(call.args)) : call.args;
3749
+ const toolPart = {
3750
+ type: "tool",
3751
+ tool: toolIdentity.tool,
3752
+ callID: callId,
3753
+ title: `Tool: ${toolIdentity.tool}`,
3754
+ state: {
3755
+ arguments: arguments_,
3756
+ output: null,
3757
+ metadata: toolIdentity.metadata
3758
+ },
3759
+ time_created: timestampMs
3760
+ };
3761
+ transcript.appendToolCall(
3762
+ toolPart,
3763
+ { id: "", timestampMs, agent: "codex", model: activeModel },
3764
+ { markModeAsTool: true }
3765
+ );
3766
+ }
3472
3767
  };
3473
3768
  var PerfTracer = class {
3474
3769
  rootMarkers = [];
@@ -5711,6 +6006,12 @@ function createCacheTables(db) {
5711
6006
  index_version TEXT NOT NULL,
5712
6007
  last_sync_at INTEGER NOT NULL
5713
6008
  );
6009
+
6010
+ CREATE TABLE IF NOT EXISTS pending_reindex (
6011
+ agent_name TEXT NOT NULL,
6012
+ session_id TEXT NOT NULL,
6013
+ PRIMARY KEY (agent_name, session_id)
6014
+ );
5714
6015
  `);
5715
6016
  }
5716
6017
  function createSessionTables(db) {
@@ -6408,6 +6709,20 @@ function invalidateSearchContentHashes(db) {
6408
6709
  db.exec("UPDATE session_documents SET content_hash = ''");
6409
6710
  }
6410
6711
  }
6712
+ var CODEX_EXEC_DECODE_MIGRATION_KEY = "codex_exec_decode_migrated_v3";
6713
+ function migrateCodexExecDecode(db) {
6714
+ if (!tableExists(db, "cache_meta")) return;
6715
+ const done = db.prepare("SELECT value FROM cache_meta WHERE key = ?").get(CODEX_EXEC_DECODE_MIGRATION_KEY);
6716
+ if (done) return;
6717
+ if (tableExists(db, "sessions") && tableExists(db, "pending_reindex")) {
6718
+ db.exec(
6719
+ "INSERT OR IGNORE INTO pending_reindex(agent_name, session_id) SELECT agent_name, session_id FROM sessions WHERE agent_name = 'codex'"
6720
+ );
6721
+ }
6722
+ db.prepare(
6723
+ "INSERT INTO cache_meta(key, value) VALUES (?, '1') ON CONFLICT(key) DO UPDATE SET value = '1'"
6724
+ ).run(CODEX_EXEC_DECODE_MIGRATION_KEY);
6725
+ }
6411
6726
  function rebuildSearchIndex(db) {
6412
6727
  if (!tableExists(db, "session_documents_fts")) {
6413
6728
  return;
@@ -6465,6 +6780,7 @@ function ensureSchema(db, dbPath) {
6465
6780
  if (currentVersion === 0 && !hasAnyCacheSchema(db)) {
6466
6781
  createLatestCacheSchema(db);
6467
6782
  setCacheSchemaVersion(db);
6783
+ migrateCodexExecDecode(db);
6468
6784
  return;
6469
6785
  }
6470
6786
  runSchemaMigrations(db, {
@@ -6532,6 +6848,7 @@ function ensureSchema(db, dbPath) {
6532
6848
  if (getUserVersion(db) <= CACHE_SCHEMA_VERSION) {
6533
6849
  setCacheSchemaVersion(db);
6534
6850
  }
6851
+ migrateCodexExecDecode(db);
6535
6852
  }
6536
6853
  function escapeFtsTerm(value) {
6537
6854
  return value.replaceAll('"', '""');
@@ -6657,6 +6974,10 @@ function toFtsQuery(input) {
6657
6974
  (token, index, values) => token !== "OR" || index > 0 && index < values.length - 1 && values[index - 1] !== "OR" && values[index + 1] !== "OR"
6658
6975
  ).join(" ");
6659
6976
  }
6977
+ function readPendingReindexIds(db, agentName) {
6978
+ const rows = db.prepare("SELECT session_id FROM pending_reindex WHERE agent_name = ?").all(agentName);
6979
+ return new Set(rows.map((row) => String(row.session_id)));
6980
+ }
6660
6981
  var SEARCH_INDEX_STATE_BATCH_SIZE = 900;
6661
6982
  function shouldBulkSyncSearchIndex(options, changedCount) {
6662
6983
  if (options.isBulk != null) {
@@ -6682,7 +7003,7 @@ function sessionContentHash(session) {
6682
7003
  session.stats.total_tokens ?? 0
6683
7004
  ]);
6684
7005
  }
6685
- function searchIndexStateFromRows(indexedRows, messageCountRows) {
7006
+ function searchIndexStateFromRows(indexedRows, messageCountRows, pendingReindexSessionIds = /* @__PURE__ */ new Set()) {
6686
7007
  return {
6687
7008
  contentHashBySessionId: new Map(
6688
7009
  indexedRows.map((row) => [String(row.session_id), String(row.content_hash ?? "")])
@@ -6692,7 +7013,8 @@ function searchIndexStateFromRows(indexedRows, messageCountRows) {
6692
7013
  ),
6693
7014
  messageCountBySessionId: new Map(
6694
7015
  messageCountRows.map((row) => [String(row.session_id), Number(row.value ?? 0)])
6695
- )
7016
+ ),
7017
+ pendingReindexSessionIds
6696
7018
  };
6697
7019
  }
6698
7020
  function readSearchIndexState(db, agentName, sessionIds) {
@@ -6722,11 +7044,11 @@ function readSearchIndexState(db, agentName, sessionIds) {
6722
7044
  ).all(...batch, agentName, agentName);
6723
7045
  rows.push(...batchRows);
6724
7046
  }
6725
- return searchIndexStateFromRows(rows, rows);
7047
+ return searchIndexStateFromRows(rows, rows, readPendingReindexIds(db, agentName));
6726
7048
  }
6727
7049
  function searchIndexEntryNeedsUpdate(state, session) {
6728
7050
  const sessionId = session.id;
6729
- return state.contentHashBySessionId.get(sessionId) !== sessionContentHash(session) || state.indexedMessageCountBySessionId.get(sessionId) !== (state.messageCountBySessionId.get(sessionId) ?? 0);
7051
+ return state.pendingReindexSessionIds.has(sessionId) || state.contentHashBySessionId.get(sessionId) !== sessionContentHash(session) || state.indexedMessageCountBySessionId.get(sessionId) !== (state.messageCountBySessionId.get(sessionId) ?? 0);
6730
7052
  }
6731
7053
  function loadSearchIndexEntry(agentName, change, loadSessionData) {
6732
7054
  try {
@@ -6846,11 +7168,15 @@ function writeSearchIndexRows(db, agentName, removedSessionIds, entries) {
6846
7168
  indexed_message_count = excluded.indexed_message_count,
6847
7169
  indexed_at = excluded.indexed_at
6848
7170
  `);
7171
+ const clearPendingReindex = db.prepare(
7172
+ "DELETE FROM pending_reindex WHERE agent_name = ? AND session_id = ?"
7173
+ );
6849
7174
  for (const sessionId of new Set(removedSessionIds)) {
6850
7175
  deleteRow.run(agentName, sessionId);
6851
7176
  deleteFileActivity.run(agentName, sessionId);
6852
7177
  deleteMessageTools.run(agentName, sessionId, 0);
6853
7178
  deleteMessages.run(agentName, sessionId, 0);
7179
+ clearPendingReindex.run(agentName, sessionId);
6854
7180
  }
6855
7181
  let indexed = 0;
6856
7182
  for (const entry of entries) {
@@ -6858,6 +7184,7 @@ function writeSearchIndexRows(db, agentName, removedSessionIds, entries) {
6858
7184
  upsertSessionRow(upsertIndexedSession, agentName, entry.session, null, entry.sortIndex, null);
6859
7185
  deleteFileActivity.run(agentName, entry.session.id);
6860
7186
  deleteMessageTools.run(agentName, entry.session.id, 0);
7187
+ clearPendingReindex.run(agentName, entry.session.id);
6861
7188
  writeFileActivityRows(insertFileActivity, entry.fileActivity);
6862
7189
  for (const message of entry.messages) {
6863
7190
  upsertMessage.run(
@@ -6918,7 +7245,11 @@ function syncSessionSearchIndex(agentName, sessions, loadSessionData, options =
6918
7245
  const messageCountRows = db.prepare(
6919
7246
  "SELECT session_id, COUNT(*) AS value FROM messages WHERE agent_name = ? GROUP BY session_id"
6920
7247
  ).all(agentName);
6921
- const searchIndexState = searchIndexStateFromRows(existingRows, messageCountRows);
7248
+ const searchIndexState = searchIndexStateFromRows(
7249
+ existingRows,
7250
+ messageCountRows,
7251
+ readPendingReindexIds(db, agentName)
7252
+ );
6922
7253
  const sessionMap = new Map(sessions.map((session) => [session.id, session]));
6923
7254
  const toDelete = existingRows.map((row) => String(row.session_id)).filter((sessionId) => !sessionMap.has(sessionId));
6924
7255
  const toUpsert = sessions.filter(
@@ -7679,7 +8010,8 @@ function loadCachedSessionData(agentName, sessionId) {
7679
8010
  if (!row) {
7680
8011
  return null;
7681
8012
  }
7682
- const messageRows = db.prepare(
8013
+ const pendingReindex = db.prepare("SELECT 1 FROM pending_reindex WHERE agent_name = ? AND session_id = ?").get(agentName, sessionId) != null;
8014
+ const messageRows = pendingReindex ? [] : db.prepare(
7683
8015
  `
7684
8016
  SELECT
7685
8017
  message_id,
@@ -9070,4 +9402,4 @@ export {
9070
9402
  buildDashboard,
9071
9403
  executeSessionSearch
9072
9404
  };
9073
- //# sourceMappingURL=chunk-VRVZJDNL.js.map
9405
+ //# sourceMappingURL=chunk-NBCLV4CX.js.map