chat-recall 0.6.1 → 0.6.3

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.
@@ -2040,7 +2040,7 @@ var require_thread_stream = __commonJS({
2040
2040
  var { version } = require_package();
2041
2041
  var { EventEmitter } = __require("events");
2042
2042
  var { Worker } = __require("worker_threads");
2043
- var { join: join15 } = __require("path");
2043
+ var { join: join14 } = __require("path");
2044
2044
  var { pathToFileURL } = __require("url");
2045
2045
  var { wait } = require_wait();
2046
2046
  var {
@@ -2083,7 +2083,7 @@ var require_thread_stream = __commonJS({
2083
2083
  function createWorker(stream, opts) {
2084
2084
  const { filename, workerData } = opts;
2085
2085
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
2086
- const toExecute = bundlerOverrides["thread-stream-worker"] || join15(__dirname, "lib", "worker.js");
2086
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join14(__dirname, "lib", "worker.js");
2087
2087
  const worker = new Worker(toExecute, {
2088
2088
  ...opts.workerOpts,
2089
2089
  trackUnmanagedFds: false,
@@ -2486,7 +2486,7 @@ var require_transport = __commonJS({
2486
2486
  "use strict";
2487
2487
  var { createRequire: createRequire3 } = __require("module");
2488
2488
  var getCallers = require_caller();
2489
- var { join: join15, isAbsolute, sep } = __require("node:path");
2489
+ var { join: join14, isAbsolute, sep } = __require("node:path");
2490
2490
  var sleep = require_atomic_sleep();
2491
2491
  var onExit = require_on_exit_leak_free();
2492
2492
  var ThreadStream = require_thread_stream();
@@ -2549,7 +2549,7 @@ var require_transport = __commonJS({
2549
2549
  throw new Error("only one of target or targets can be specified");
2550
2550
  }
2551
2551
  if (targets) {
2552
- target = bundlerOverrides["pino-worker"] || join15(__dirname, "worker.js");
2552
+ target = bundlerOverrides["pino-worker"] || join14(__dirname, "worker.js");
2553
2553
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
2554
2554
  return {
2555
2555
  ...dest,
@@ -2567,7 +2567,7 @@ var require_transport = __commonJS({
2567
2567
  });
2568
2568
  });
2569
2569
  } else if (pipeline) {
2570
- target = bundlerOverrides["pino-worker"] || join15(__dirname, "worker.js");
2570
+ target = bundlerOverrides["pino-worker"] || join14(__dirname, "worker.js");
2571
2571
  options.pipelines = [pipeline.map((dest) => {
2572
2572
  return {
2573
2573
  ...dest,
@@ -2589,7 +2589,7 @@ var require_transport = __commonJS({
2589
2589
  return origin;
2590
2590
  }
2591
2591
  if (origin === "pino/file") {
2592
- return join15(__dirname, "..", "file.js");
2592
+ return join14(__dirname, "..", "file.js");
2593
2593
  }
2594
2594
  let fixTarget2;
2595
2595
  for (const filePath of callers) {
@@ -3578,7 +3578,7 @@ var require_safe_stable_stringify = __commonJS({
3578
3578
  return circularValue;
3579
3579
  }
3580
3580
  let res = "";
3581
- let join15 = ",";
3581
+ let join14 = ",";
3582
3582
  const originalIndentation = indentation;
3583
3583
  if (Array.isArray(value)) {
3584
3584
  if (value.length === 0) {
@@ -3592,7 +3592,7 @@ var require_safe_stable_stringify = __commonJS({
3592
3592
  indentation += spacer;
3593
3593
  res += `
3594
3594
  ${indentation}`;
3595
- join15 = `,
3595
+ join14 = `,
3596
3596
  ${indentation}`;
3597
3597
  }
3598
3598
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3600,13 +3600,13 @@ ${indentation}`;
3600
3600
  for (; i < maximumValuesToStringify - 1; i++) {
3601
3601
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3602
3602
  res += tmp2 !== void 0 ? tmp2 : "null";
3603
- res += join15;
3603
+ res += join14;
3604
3604
  }
3605
3605
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3606
3606
  res += tmp !== void 0 ? tmp : "null";
3607
3607
  if (value.length - 1 > maximumBreadth) {
3608
3608
  const removedKeys = value.length - maximumBreadth - 1;
3609
- res += `${join15}"... ${getItemCount(removedKeys)} not stringified"`;
3609
+ res += `${join14}"... ${getItemCount(removedKeys)} not stringified"`;
3610
3610
  }
3611
3611
  if (spacer !== "") {
3612
3612
  res += `
@@ -3627,7 +3627,7 @@ ${originalIndentation}`;
3627
3627
  let separator = "";
3628
3628
  if (spacer !== "") {
3629
3629
  indentation += spacer;
3630
- join15 = `,
3630
+ join14 = `,
3631
3631
  ${indentation}`;
3632
3632
  whitespace = " ";
3633
3633
  }
@@ -3641,13 +3641,13 @@ ${indentation}`;
3641
3641
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
3642
3642
  if (tmp !== void 0) {
3643
3643
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
3644
- separator = join15;
3644
+ separator = join14;
3645
3645
  }
3646
3646
  }
3647
3647
  if (keyLength > maximumBreadth) {
3648
3648
  const removedKeys = keyLength - maximumBreadth;
3649
3649
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
3650
- separator = join15;
3650
+ separator = join14;
3651
3651
  }
3652
3652
  if (spacer !== "" && separator.length > 1) {
3653
3653
  res = `
@@ -3688,7 +3688,7 @@ ${originalIndentation}`;
3688
3688
  }
3689
3689
  const originalIndentation = indentation;
3690
3690
  let res = "";
3691
- let join15 = ",";
3691
+ let join14 = ",";
3692
3692
  if (Array.isArray(value)) {
3693
3693
  if (value.length === 0) {
3694
3694
  return "[]";
@@ -3701,7 +3701,7 @@ ${originalIndentation}`;
3701
3701
  indentation += spacer;
3702
3702
  res += `
3703
3703
  ${indentation}`;
3704
- join15 = `,
3704
+ join14 = `,
3705
3705
  ${indentation}`;
3706
3706
  }
3707
3707
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3709,13 +3709,13 @@ ${indentation}`;
3709
3709
  for (; i < maximumValuesToStringify - 1; i++) {
3710
3710
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3711
3711
  res += tmp2 !== void 0 ? tmp2 : "null";
3712
- res += join15;
3712
+ res += join14;
3713
3713
  }
3714
3714
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3715
3715
  res += tmp !== void 0 ? tmp : "null";
3716
3716
  if (value.length - 1 > maximumBreadth) {
3717
3717
  const removedKeys = value.length - maximumBreadth - 1;
3718
- res += `${join15}"... ${getItemCount(removedKeys)} not stringified"`;
3718
+ res += `${join14}"... ${getItemCount(removedKeys)} not stringified"`;
3719
3719
  }
3720
3720
  if (spacer !== "") {
3721
3721
  res += `
@@ -3728,7 +3728,7 @@ ${originalIndentation}`;
3728
3728
  let whitespace = "";
3729
3729
  if (spacer !== "") {
3730
3730
  indentation += spacer;
3731
- join15 = `,
3731
+ join14 = `,
3732
3732
  ${indentation}`;
3733
3733
  whitespace = " ";
3734
3734
  }
@@ -3737,7 +3737,7 @@ ${indentation}`;
3737
3737
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
3738
3738
  if (tmp !== void 0) {
3739
3739
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
3740
- separator = join15;
3740
+ separator = join14;
3741
3741
  }
3742
3742
  }
3743
3743
  if (spacer !== "" && separator.length > 1) {
@@ -3795,20 +3795,20 @@ ${originalIndentation}`;
3795
3795
  indentation += spacer;
3796
3796
  let res2 = `
3797
3797
  ${indentation}`;
3798
- const join16 = `,
3798
+ const join15 = `,
3799
3799
  ${indentation}`;
3800
3800
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
3801
3801
  let i = 0;
3802
3802
  for (; i < maximumValuesToStringify - 1; i++) {
3803
3803
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3804
3804
  res2 += tmp2 !== void 0 ? tmp2 : "null";
3805
- res2 += join16;
3805
+ res2 += join15;
3806
3806
  }
3807
3807
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3808
3808
  res2 += tmp !== void 0 ? tmp : "null";
3809
3809
  if (value.length - 1 > maximumBreadth) {
3810
3810
  const removedKeys = value.length - maximumBreadth - 1;
3811
- res2 += `${join16}"... ${getItemCount(removedKeys)} not stringified"`;
3811
+ res2 += `${join15}"... ${getItemCount(removedKeys)} not stringified"`;
3812
3812
  }
3813
3813
  res2 += `
3814
3814
  ${originalIndentation}`;
@@ -3824,16 +3824,16 @@ ${originalIndentation}`;
3824
3824
  return '"[Object]"';
3825
3825
  }
3826
3826
  indentation += spacer;
3827
- const join15 = `,
3827
+ const join14 = `,
3828
3828
  ${indentation}`;
3829
3829
  let res = "";
3830
3830
  let separator = "";
3831
3831
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
3832
3832
  if (isTypedArrayWithEntries(value)) {
3833
- res += stringifyTypedArray(value, join15, maximumBreadth);
3833
+ res += stringifyTypedArray(value, join14, maximumBreadth);
3834
3834
  keys = keys.slice(value.length);
3835
3835
  maximumPropertiesToStringify -= value.length;
3836
- separator = join15;
3836
+ separator = join14;
3837
3837
  }
3838
3838
  if (deterministic) {
3839
3839
  keys = sort(keys, comparator);
@@ -3844,13 +3844,13 @@ ${indentation}`;
3844
3844
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
3845
3845
  if (tmp !== void 0) {
3846
3846
  res += `${separator}${strEscape(key2)}: ${tmp}`;
3847
- separator = join15;
3847
+ separator = join14;
3848
3848
  }
3849
3849
  }
3850
3850
  if (keyLength > maximumBreadth) {
3851
3851
  const removedKeys = keyLength - maximumBreadth;
3852
3852
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
3853
- separator = join15;
3853
+ separator = join14;
3854
3854
  }
3855
3855
  if (separator !== "") {
3856
3856
  res = `
@@ -4499,31 +4499,30 @@ function defaultSourcesEnabled() {
4499
4499
  plugins: true,
4500
4500
  agentMemory: true
4501
4501
  },
4502
- gemini: {
4502
+ opencode: {
4503
4503
  sessions: true,
4504
4504
  plans: true,
4505
- brain: true,
4506
- extensions: true,
4505
+ todos: true,
4507
4506
  skills: true,
4508
4507
  agents: true,
4509
4508
  commands: true
4510
4509
  },
4511
- opencode: {
4510
+ codex: {
4512
4511
  sessions: true,
4513
- plans: true,
4514
- todos: true,
4512
+ plugins: true,
4515
4513
  skills: true,
4516
4514
  agents: true,
4517
4515
  commands: true
4518
4516
  },
4519
- codex: {
4517
+ agy: {
4520
4518
  sessions: true,
4521
- plugins: true,
4519
+ plans: true,
4520
+ brain: true,
4521
+ extensions: true,
4522
4522
  skills: true,
4523
4523
  agents: true,
4524
4524
  commands: true
4525
4525
  },
4526
- agy: { sessions: true, plans: true },
4527
4526
  cursor: { sessions: true, skills: true, agents: true, commands: true },
4528
4527
  shared: { skills: true },
4529
4528
  common: { mcps: true, agentMd: true }
@@ -4568,7 +4567,7 @@ function defaultTeam() {
4568
4567
  },
4569
4568
  vault: {
4570
4569
  enabled: false,
4571
- syncTools: ["claude", "gemini", "codex", "opencode", "agy", "cursor"],
4570
+ syncTools: ["claude", "codex", "opencode", "agy", "cursor"],
4572
4571
  excludeProjects: []
4573
4572
  }
4574
4573
  };
@@ -4587,12 +4586,13 @@ function freshDefaults() {
4587
4586
  function mergeSources(base, partial) {
4588
4587
  if (!partial)
4589
4588
  return base;
4589
+ const legacyGemini = partial.enabled?.gemini;
4590
+ const inherited = legacyGemini && typeof legacyGemini === "object" ? (({ sessions: _s, plans: _p, ...rest }) => rest)(legacyGemini) : {};
4590
4591
  const enabled = {
4591
4592
  claude: { ...base.enabled.claude, ...partial.enabled?.claude ?? {} },
4592
- gemini: { ...base.enabled.gemini, ...partial.enabled?.gemini ?? {} },
4593
4593
  opencode: { ...base.enabled.opencode, ...partial.enabled?.opencode ?? {} },
4594
4594
  codex: { ...base.enabled.codex, ...partial.enabled?.codex ?? {} },
4595
- agy: { ...base.enabled.agy, ...partial.enabled?.agy ?? {} },
4595
+ agy: { ...base.enabled.agy, ...inherited, ...partial.enabled?.agy ?? {} },
4596
4596
  cursor: { ...base.enabled.cursor, ...partial.enabled?.cursor ?? {} },
4597
4597
  shared: { ...base.enabled.shared, ...partial.enabled?.shared ?? {} },
4598
4598
  common: { ...base.enabled.common, ...partial.enabled?.common ?? {} }
@@ -4785,14 +4785,13 @@ var init_settings = __esm({
4785
4785
  init_project_path_match();
4786
4786
  init_paths();
4787
4787
  CLI_DETECTION_ORDER = [
4788
- { preset: "gemini", bin: "gemini", cmd: 'gemini -p " "' },
4789
4788
  { preset: "claude-cli", bin: "claude", cmd: 'claude -p " "' },
4790
4789
  { preset: "opencode", bin: "opencode", cmd: 'opencode run "$(cat {prompt_file})"' },
4791
4790
  { preset: "kilocode", bin: "kilocode", cmd: 'kilocode run "$(cat {prompt_file})"' },
4792
4791
  { preset: "llm", bin: "llm", cmd: "llm --no-stream" },
4793
4792
  { preset: "aichat", bin: "aichat", cmd: "aichat --no-stream" }
4794
4793
  ];
4795
- SCHEMA_VERSION = 3;
4794
+ SCHEMA_VERSION = 4;
4796
4795
  PERSONAL_DIR_NAMES = [
4797
4796
  "Pictures",
4798
4797
  "Music",
@@ -5436,10 +5435,6 @@ function applyDecisions(roots, includeExcluded) {
5436
5435
  function applyExclusions(roots, includeExcluded) {
5437
5436
  return applyDecisions(roots, includeExcluded);
5438
5437
  }
5439
- function geminiTmpDirs(opts = {}) {
5440
- const overridden = !!(process.env.CHAT_RECALL_GEMINI_HOME || sources().geminiHome);
5441
- return applyExclusions(siblingHomes(geminiHomeDir(), overridden, "tmp"), opts.includeExcluded);
5442
- }
5443
5438
  function codexSessionDirs(opts = {}) {
5444
5439
  const overridden = !!(process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome);
5445
5440
  return applyExclusions(siblingHomes(codexHomeDir(), overridden, "sessions"), opts.includeExcluded);
@@ -5805,6 +5800,50 @@ var init_tool_backend = __esm({
5805
5800
  }
5806
5801
  });
5807
5802
 
5803
+ // ../engine/dist/core/sqlite-reader.js
5804
+ import { createRequire as createRequire2 } from "node:module";
5805
+ function filterExperimentalWarning() {
5806
+ if (_filtered)
5807
+ return;
5808
+ _filtered = true;
5809
+ const existing = process.listeners("warning");
5810
+ process.removeAllListeners("warning");
5811
+ process.on("warning", (w) => {
5812
+ if (w?.name === "ExperimentalWarning" && /SQLite/i.test(w.message))
5813
+ return;
5814
+ if (existing.length === 0)
5815
+ console.error(w?.stack || String(w));
5816
+ else
5817
+ for (const l of existing)
5818
+ l(w);
5819
+ });
5820
+ }
5821
+ function sqlite() {
5822
+ if (!_sqlite) {
5823
+ filterExperimentalWarning();
5824
+ _sqlite = require2("node:sqlite");
5825
+ }
5826
+ return _sqlite;
5827
+ }
5828
+ function openSqliteReadonly(path) {
5829
+ try {
5830
+ return new (sqlite()).DatabaseSync(path, { readOnly: true });
5831
+ } catch {
5832
+ return null;
5833
+ }
5834
+ }
5835
+ function openSqliteReadonlyOrThrow(path) {
5836
+ return new (sqlite()).DatabaseSync(path, { readOnly: true });
5837
+ }
5838
+ var require2, _sqlite, _filtered;
5839
+ var init_sqlite_reader = __esm({
5840
+ "../engine/dist/core/sqlite-reader.js"() {
5841
+ "use strict";
5842
+ require2 = createRequire2(import.meta.url);
5843
+ _filtered = false;
5844
+ }
5845
+ });
5846
+
5808
5847
  // ../engine/dist/core/generic-engine.js
5809
5848
  import { basename as basename3 } from "path";
5810
5849
  import { createPatch } from "diff";
@@ -6023,628 +6062,82 @@ function editToolNameFor(op) {
6023
6062
  case "edit":
6024
6063
  return "Edit";
6025
6064
  case "multi_edit":
6026
- return "MultiEdit";
6027
- case "notebook_edit":
6028
- return "NotebookEdit";
6029
- case "write":
6030
- return "Write";
6031
- case "read":
6032
- return "Edit";
6033
- }
6034
- }
6035
- function makeFileResult(acc) {
6036
- let diff = "";
6037
- let linesAdded = 0;
6038
- let linesRemoved = 0;
6039
- let initialKnown = acc.before !== null;
6040
- let reverted = false;
6041
- if (acc.before !== null && acc.after !== null) {
6042
- if (acc.before === acc.after) {
6043
- reverted = true;
6044
- } else {
6045
- diff = createPatch(acc.file, acc.before, acc.after);
6046
- for (const line of diff.split("\n")) {
6047
- if (line.startsWith("+") && !line.startsWith("+++"))
6048
- linesAdded++;
6049
- else if (line.startsWith("-") && !line.startsWith("---"))
6050
- linesRemoved++;
6051
- }
6052
- }
6053
- }
6054
- return {
6055
- file: acc.file,
6056
- initialContent: acc.before,
6057
- initialKnown,
6058
- finalContent: acc.after,
6059
- diff,
6060
- linesAdded,
6061
- linesRemoved,
6062
- events: acc.events,
6063
- succeededEvents: acc.succeeded,
6064
- failedEvents: acc.failed,
6065
- reverted
6066
- };
6067
- }
6068
- var DEFAULT_USER_MAX, DEFAULT_ASSISTANT_MAX, DEFAULT_TOOL_RESULT_MAX, DEFAULT_MAX_TURNS;
6069
- var init_generic_engine = __esm({
6070
- "../engine/dist/core/generic-engine.js"() {
6071
- "use strict";
6072
- init_tool_backend();
6073
- DEFAULT_USER_MAX = 1200;
6074
- DEFAULT_ASSISTANT_MAX = 1500;
6075
- DEFAULT_TOOL_RESULT_MAX = 800;
6076
- DEFAULT_MAX_TURNS = 5e3;
6077
- }
6078
- });
6079
-
6080
- // ../engine/dist/core/backends/tail-read.js
6081
- import { openSync, readSync, closeSync, statSync as statSync3 } from "node:fs";
6082
- function readTailFromOffset(path, offset) {
6083
- let size = 0;
6084
- try {
6085
- size = statSync3(path).size;
6086
- } catch {
6087
- return { text: "", newOffset: offset };
6088
- }
6089
- if (size <= offset)
6090
- return { text: "", newOffset: offset };
6091
- const len = Math.min(size - offset, 16 * 1024 * 1024);
6092
- const buf = Buffer.allocUnsafe(len);
6093
- let fd = null;
6094
- try {
6095
- fd = openSync(path, "r");
6096
- let got = 0;
6097
- while (got < len) {
6098
- const n = readSync(fd, buf, got, len - got, offset + got);
6099
- if (n <= 0)
6100
- break;
6101
- got += n;
6102
- }
6103
- if (got === 0)
6104
- return { text: "", newOffset: offset };
6105
- const slice = got < len ? buf.subarray(0, got) : buf;
6106
- const lastNl = slice.lastIndexOf(10);
6107
- if (lastNl < 0) {
6108
- return { text: "", newOffset: offset };
6109
- }
6110
- const text = slice.subarray(0, lastNl + 1).toString("utf-8");
6111
- return { text, newOffset: offset + lastNl + 1 };
6112
- } catch {
6113
- return { text: "", newOffset: offset };
6114
- } finally {
6115
- if (fd !== null) {
6116
- try {
6117
- closeSync(fd);
6118
- } catch {
6119
- }
6120
- }
6121
- }
6122
- }
6123
- var init_tail_read = __esm({
6124
- "../engine/dist/core/backends/tail-read.js"() {
6125
- "use strict";
6126
- }
6127
- });
6128
-
6129
- // ../engine/dist/core/flat-string.js
6130
- function flatString(s) {
6131
- if (!s)
6132
- return "";
6133
- if (s.length < 13)
6134
- return s;
6135
- return Buffer.from(s, "utf8").toString("utf8");
6136
- }
6137
- var init_flat_string = __esm({
6138
- "../engine/dist/core/flat-string.js"() {
6139
- "use strict";
6140
- }
6141
- });
6142
-
6143
- // ../engine/dist/core/backends/gemini.js
6144
- import { createHash } from "crypto";
6145
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync2, statSync as statSync4 } from "fs";
6146
- import { basename as basename4, join as join5 } from "path";
6147
- function readSessionId(path, format) {
6148
- try {
6149
- if (format === "json") {
6150
- const json = JSON.parse(readFileSync2(path, "utf-8"));
6151
- return typeof json?.sessionId === "string" ? json.sessionId : null;
6152
- }
6153
- const head = readHeadSync(path).split("\n", 1)[0] || "";
6154
- const meta = JSON.parse(head);
6155
- return typeof meta?.sessionId === "string" ? meta.sessionId : null;
6156
- } catch {
6157
- return null;
6158
- }
6159
- }
6160
- function flatten(content) {
6161
- if (typeof content === "string")
6162
- return content;
6163
- if (!Array.isArray(content))
6164
- return "";
6165
- return content.map((seg) => {
6166
- if (typeof seg === "string")
6167
- return seg;
6168
- if (seg && typeof seg === "object" && typeof seg.text === "string") {
6169
- return seg.text;
6170
- }
6171
- return "";
6172
- }).filter(Boolean).join("\n");
6173
- }
6174
- var PREFIX, FULL_PARSE_MAX, GeminiBackend, geminiBackend;
6175
- var init_gemini = __esm({
6176
- "../engine/dist/core/backends/gemini.js"() {
6177
- "use strict";
6178
- init_tool_paths();
6179
- init_live_session_scan();
6180
- init_session_outcome();
6181
- init_session_git();
6182
- init_generic_engine();
6183
- init_tail_read();
6184
- init_flat_string();
6185
- PREFIX = "gemini_";
6186
- FULL_PARSE_MAX = 4 * 1024 * 1024;
6187
- GeminiBackend = class {
6188
- id = "gemini";
6189
- idPrefix = PREFIX;
6190
- displayName = "Gemini";
6191
- homeDir() {
6192
- return geminiHomeDir();
6193
- }
6194
- // ── Subpath helpers ────────────────────────────────────────────
6195
- tmpDir() {
6196
- return join5(this.homeDir(), "tmp");
6197
- }
6198
- projectsJson() {
6199
- return join5(this.homeDir(), "projects.json");
6200
- }
6201
- settingsFile() {
6202
- return join5(this.homeDir(), "settings.json");
6203
- }
6204
- extensionsDir() {
6205
- return join5(this.homeDir(), "extensions");
6206
- }
6207
- antigravityBrainDir() {
6208
- return join5(this.homeDir(), "antigravity", "brain");
6209
- }
6210
- // Toolkit-artifact dirs. Gemini gained first-class Skills + Agents + (TOML)
6211
- // Commands; all live directly under the home dir, mirroring Claude's layout.
6212
- skillsDir() {
6213
- return join5(this.homeDir(), "skills");
6214
- }
6215
- commandsDir() {
6216
- return join5(this.homeDir(), "commands");
6217
- }
6218
- agentsDir() {
6219
- return join5(this.homeDir(), "agents");
6220
- }
6221
- isAvailable() {
6222
- return geminiTmpDirs().length > 0;
6223
- }
6224
- // ── ID handling ────────────────────────────────────────────────
6225
- matchesId(id) {
6226
- return id.startsWith(PREFIX);
6227
- }
6228
- toRawId(id) {
6229
- return id.startsWith(PREFIX) ? id.slice(PREFIX.length) : id;
6230
- }
6231
- toPrefixedId(rawId) {
6232
- return rawId.startsWith(PREFIX) ? rawId : PREFIX + rawId;
6233
- }
6234
- // ── Location ───────────────────────────────────────────────────
6235
- findSession(id) {
6236
- const located = findGeminiSessionFile(this.toRawId(id));
6237
- if (!located)
6238
- return null;
6239
- let mtime = 0;
6240
- try {
6241
- mtime = statSync4(located.path).mtimeMs;
6242
- } catch {
6243
- }
6244
- return {
6245
- path: located.path,
6246
- format: located.format,
6247
- projectDir: located.projectDir,
6248
- projectPath: located.projectPath,
6249
- mtime
6250
- };
6251
- }
6252
- listSessions(opts = {}) {
6253
- const projMap = this.loadProjectMap();
6254
- const cutoff = opts.sinceMs ?? 0;
6255
- const filter = opts.projectFilter?.toLowerCase();
6256
- const out = [];
6257
- const seen = /* @__PURE__ */ new Map();
6258
- for (const root of geminiTmpDirs()) {
6259
- for (const projDir of readdirSync3(root, { withFileTypes: true })) {
6260
- if (!projDir.isDirectory())
6261
- continue;
6262
- const projectPath = projMap.get(projDir.name) || "";
6263
- if (filter && !projectPath.toLowerCase().includes(filter))
6264
- continue;
6265
- const chatsDir = join5(root, projDir.name, "chats");
6266
- if (!existsSync5(chatsDir))
6267
- continue;
6268
- let files;
6269
- try {
6270
- files = readdirSync3(chatsDir);
6271
- } catch {
6272
- continue;
6273
- }
6274
- for (const f of files) {
6275
- if (!f.startsWith("session-") || !f.endsWith(".json") && !f.endsWith(".jsonl"))
6276
- continue;
6277
- const fullPath = join5(chatsDir, f);
6278
- let stat;
6279
- try {
6280
- stat = statSync4(fullPath);
6281
- } catch {
6282
- continue;
6283
- }
6284
- if (stat.mtimeMs < cutoff)
6285
- continue;
6286
- const format = f.endsWith(".jsonl") ? "jsonl" : "json";
6287
- let sessionId = null;
6288
- let firstPrompt = "";
6289
- let messageCount = 0;
6290
- if (stat.size <= FULL_PARSE_MAX) {
6291
- sessionId = readSessionId(fullPath, format);
6292
- const messages = readGeminiMessages(fullPath, format);
6293
- const firstUser = messages.find((m) => m.type === "user");
6294
- firstPrompt = flatString((typeof firstUser?.text === "string" ? firstUser.text : flatten(firstUser?.content)).slice(0, 200));
6295
- messageCount = messages.length;
6296
- } else if (format === "jsonl") {
6297
- const lines = readHeadSync(fullPath, 1048576).split("\n");
6298
- try {
6299
- const meta = JSON.parse(lines[0] || "");
6300
- if (typeof meta?.sessionId === "string")
6301
- sessionId = meta.sessionId;
6302
- } catch {
6303
- }
6304
- for (const line of lines.slice(1, -1)) {
6305
- const s = line.trim();
6306
- if (!s)
6307
- continue;
6308
- let m;
6309
- try {
6310
- m = JSON.parse(s);
6311
- } catch {
6312
- continue;
6313
- }
6314
- if (m?.type !== "user")
6315
- continue;
6316
- firstPrompt = flatString((typeof m.text === "string" ? m.text : flatten(m.content)).slice(0, 200));
6317
- break;
6318
- }
6319
- }
6320
- const innerId = sessionId || basename4(f).replace(/\.jsonl?$/, "");
6321
- const prior = seen.get(innerId);
6322
- if (prior) {
6323
- if (stat.mtimeMs > prior.mtime) {
6324
- prior.mtime = stat.mtimeMs;
6325
- prior.modified = stat.mtime.toISOString();
6326
- prior.fullPath = fullPath;
6327
- }
6328
- continue;
6329
- }
6330
- const ref = {
6331
- toolId: "gemini",
6332
- rawId: innerId,
6333
- prefixedId: this.toPrefixedId(innerId),
6334
- projectPath,
6335
- projectDir: projDir.name,
6336
- fullPath,
6337
- created: stat.birthtime.toISOString(),
6338
- modified: stat.mtime.toISOString(),
6339
- mtime: stat.mtimeMs,
6340
- firstPrompt,
6341
- messageCount
6342
- };
6343
- seen.set(innerId, ref);
6344
- out.push(ref);
6345
- }
6346
- }
6347
- }
6348
- out.sort((a, b) => b.mtime - a.mtime);
6349
- return opts.limit ? out.slice(0, opts.limit) : out;
6350
- }
6351
- // ── Generic-engine inputs ───────────────────────────────────────
6352
- fileToolMap = {
6353
- write_file: "write",
6354
- replace: "edit",
6355
- read_file: "read",
6356
- read_many_files: "read"
6357
- };
6358
- /**
6359
- * For Gemini, the diff lives inline:
6360
- * - replace: { file_path, old_string, new_string }
6361
- * - write_file: { file_path, content }
6362
- */
6363
- extractEditDelta(toolName, input) {
6364
- if (input == null || typeof input !== "object")
6365
- return null;
6366
- const inp = input;
6367
- if (toolName === "replace") {
6368
- const before = typeof inp.old_string === "string" ? inp.old_string : typeof inp.oldString === "string" ? inp.oldString : null;
6369
- const after = typeof inp.new_string === "string" ? inp.new_string : typeof inp.newString === "string" ? inp.newString : null;
6370
- if (before === null && after === null)
6371
- return null;
6372
- return { before, after };
6373
- }
6374
- if (toolName === "write_file") {
6375
- const after = typeof inp.content === "string" ? inp.content : null;
6376
- return { before: "", after };
6377
- }
6378
- return null;
6379
- }
6380
- /**
6381
- * Read every gemini message into canonical events. Handles both the
6382
- * legacy `.json` (single blob with `messages: []`) and the current
6383
- * `.jsonl` (one event per line) — `readGeminiMessages` normalizes
6384
- * both.
6385
- */
6386
- readEvents(rawId) {
6387
- const located = findGeminiSessionFile(rawId);
6388
- if (!located)
6389
- return [];
6390
- let mtime = 0;
6391
- try {
6392
- mtime = statSync4(located.path).mtimeMs;
6393
- } catch {
6394
- }
6395
- const messages = readGeminiMessages(located.path, located.format);
6396
- const events = [];
6397
- let lineNum = 0;
6398
- for (const m of messages) {
6399
- lineNum++;
6400
- const tsIso = typeof m?.timestamp === "string" ? m.timestamp : void 0;
6401
- const ts = tsIso ? Date.parse(tsIso) || mtime : mtime;
6402
- if (m?.type === "user") {
6403
- const text = (typeof m.text === "string" ? m.text : Array.isArray(m.content) ? flatten(m.content) : typeof m.content === "string" ? m.content : "").trim();
6404
- if (text)
6405
- events.push({ kind: "user", ts, tsIso, line: lineNum, text });
6406
- } else if (m?.type === "gemini") {
6407
- const text = (typeof m.text === "string" ? m.text : flatten(m.content)).trim();
6408
- if (text)
6409
- events.push({ kind: "assistant_text", ts, tsIso, line: lineNum, text });
6410
- const tcs = Array.isArray(m.toolCalls) ? m.toolCalls : [];
6411
- for (const tc of tcs) {
6412
- const toolName = String(tc?.name || "");
6413
- if (!toolName)
6414
- continue;
6415
- const id = String(tc?.id || "");
6416
- events.push({
6417
- kind: "tool_use",
6418
- ts,
6419
- tsIso,
6420
- line: lineNum,
6421
- toolName,
6422
- toolUseId: id,
6423
- toolInput: tc?.args
6424
- });
6425
- if (tc?.result !== void 0) {
6426
- const body = typeof tc.result === "string" ? tc.result : JSON.stringify(tc.result);
6427
- events.push({
6428
- kind: "tool_result",
6429
- ts,
6430
- tsIso,
6431
- line: lineNum,
6432
- toolUseId: id,
6433
- toolName,
6434
- resultBody: body,
6435
- resultIsError: tc?.status === "error",
6436
- resultBytes: body.length
6437
- });
6438
- }
6439
- }
6440
- }
6441
- }
6442
- return events;
6443
- }
6444
- // ── Per-session operations — all delegate to the generic engine ─
6445
- extractTurns(id, opts = {}) {
6446
- const events = this.readEvents(this.toRawId(id));
6447
- return extractTurnsFromEvents(this.toPrefixedId(id), events, opts);
6448
- }
6449
- liveScanEdits(id) {
6450
- const located = findGeminiSessionFile(this.toRawId(id));
6451
- if (!located) {
6452
- return { found: false, projectPath: "", projectDir: "", edits: [], fileMtime: 0, tool: "gemini" };
6453
- }
6454
- let fileMtime = 0;
6455
- try {
6456
- fileMtime = statSync4(located.path).mtimeMs;
6457
- } catch {
6458
- }
6459
- const events = this.readEvents(this.toRawId(id));
6460
- return liveScanEditsFromEvents(events, this.fileToolMap, {
6461
- sessionId: this.toPrefixedId(id),
6462
- tool: "gemini",
6463
- projectPath: located.projectPath,
6464
- projectDir: located.projectDir,
6465
- fileMtime,
6466
- found: true
6467
- });
6468
- }
6469
- replay(id) {
6470
- const located = findGeminiSessionFile(this.toRawId(id));
6471
- if (!located) {
6472
- return { sessionId: this.toPrefixedId(id), found: false, projectPath: "", files: [], totalLinesAdded: 0, totalLinesRemoved: 0 };
6473
- }
6474
- const events = this.readEvents(this.toRawId(id));
6475
- return replayFromEvents(this.toPrefixedId(id), events, this.fileToolMap, this.extractEditDelta.bind(this), {
6476
- projectPath: located.projectPath,
6477
- found: true
6478
- });
6479
- }
6480
- computeOutcome(id, opts) {
6481
- return computeOutcome(this.toPrefixedId(id), opts);
6482
- }
6483
- /**
6484
- * Walk the gemini chats tree (both .json + .jsonl formats) and run
6485
- * liveScanEdits on each transcript modified since `sinceMs`.
6486
- */
6487
- collectRecentEdits(opts) {
6488
- const tmpRoot = this.tmpDir();
6489
- if (!existsSync5(tmpRoot))
6490
- return [];
6491
- const projMap = this.loadProjectMap();
6492
- const candidates = [];
6493
- for (const proj of readdirSync3(tmpRoot, { withFileTypes: true })) {
6494
- if (!proj.isDirectory())
6495
- continue;
6496
- const projectPath = projMap.get(proj.name) || "";
6497
- if (opts.projectFilter) {
6498
- const haystack = (projectPath + " " + proj.name).toLowerCase();
6499
- if (!haystack.includes(opts.projectFilter.toLowerCase()))
6500
- continue;
6501
- }
6502
- const chats = join5(tmpRoot, proj.name, "chats");
6503
- if (!existsSync5(chats))
6504
- continue;
6505
- let files;
6506
- try {
6507
- files = readdirSync3(chats);
6508
- } catch {
6509
- continue;
6510
- }
6511
- for (const f of files) {
6512
- if (!f.startsWith("session-"))
6513
- continue;
6514
- const isJsonl = f.endsWith(".jsonl");
6515
- const isJson = !isJsonl && f.endsWith(".json");
6516
- if (!isJsonl && !isJson)
6517
- continue;
6518
- try {
6519
- const st = statSync4(join5(chats, f));
6520
- if (st.mtimeMs < opts.sinceMs)
6521
- continue;
6522
- const trimLen = isJsonl ? 6 : 5;
6523
- candidates.push({ rawIdHint: f.slice(0, -trimLen), mtime: st.mtimeMs });
6524
- } catch {
6525
- }
6526
- }
6527
- }
6528
- candidates.sort((a, b) => b.mtime - a.mtime);
6529
- const limited = opts.limitSessions ? candidates.slice(0, opts.limitSessions) : candidates;
6530
- const edits = [];
6531
- for (const c of limited) {
6532
- const scan = this.liveScanEdits(c.rawIdHint);
6533
- edits.push(...scan.edits);
6534
- }
6535
- return edits;
6536
- }
6537
- getCommits(id, files, startMs, endMs, bufferMinutes) {
6538
- return getSessionCommits(this.toPrefixedId(id), files, startMs, endMs, bufferMinutes);
6539
- }
6540
- // ── Internals ──────────────────────────────────────────────────
6541
- /** Map sha256(projectPath) → projectPath using ~/.gemini/projects.json. */
6542
- loadProjectMap() {
6543
- const map = /* @__PURE__ */ new Map();
6544
- const path = this.projectsJson();
6545
- if (!existsSync5(path))
6546
- return map;
6547
- try {
6548
- const json = JSON.parse(readFileSync2(path, "utf-8"));
6549
- const projects = json?.projects ?? {};
6550
- for (const projectPath of Object.keys(projects)) {
6551
- const hash = createHash("sha256").update(projectPath).digest("hex");
6552
- map.set(hash, projectPath);
6553
- }
6554
- } catch {
6555
- }
6556
- return map;
6557
- }
6558
- exportRawSession(id) {
6559
- const loc = this.findSession(id);
6560
- if (!loc)
6561
- return null;
6562
- try {
6563
- return {
6564
- tool: "gemini",
6565
- mtime: statSync4(loc.path).mtimeMs,
6566
- files: [{ name: basename4(loc.path), bytes: readFileSync2(loc.path) }]
6567
- };
6568
- } catch {
6569
- return null;
6570
- }
6571
- }
6572
- isAppendOnly() {
6573
- return true;
6574
- }
6575
- fileSize(prefixedId) {
6576
- const loc = this.findSession(prefixedId);
6577
- if (!loc)
6578
- return 0;
6579
- try {
6580
- return statSync4(loc.path).size;
6581
- } catch {
6582
- return 0;
6583
- }
6584
- }
6585
- async readFromOffset(prefixedId, offset) {
6586
- const loc = this.findSession(prefixedId);
6587
- if (!loc)
6588
- return { text: "", newOffset: offset };
6589
- return readTailFromOffset(loc.path, offset);
6590
- }
6591
- };
6592
- geminiBackend = new GeminiBackend();
6593
- }
6594
- });
6595
-
6596
- // ../engine/dist/core/sqlite-reader.js
6597
- import { createRequire as createRequire2 } from "node:module";
6598
- function filterExperimentalWarning() {
6599
- if (_filtered)
6600
- return;
6601
- _filtered = true;
6602
- const existing = process.listeners("warning");
6603
- process.removeAllListeners("warning");
6604
- process.on("warning", (w) => {
6605
- if (w?.name === "ExperimentalWarning" && /SQLite/i.test(w.message))
6606
- return;
6607
- if (existing.length === 0)
6608
- console.error(w?.stack || String(w));
6609
- else
6610
- for (const l of existing)
6611
- l(w);
6612
- });
6613
- }
6614
- function sqlite() {
6615
- if (!_sqlite) {
6616
- filterExperimentalWarning();
6617
- _sqlite = require2("node:sqlite");
6065
+ return "MultiEdit";
6066
+ case "notebook_edit":
6067
+ return "NotebookEdit";
6068
+ case "write":
6069
+ return "Write";
6070
+ case "read":
6071
+ return "Edit";
6618
6072
  }
6619
- return _sqlite;
6620
6073
  }
6621
- function openSqliteReadonly(path) {
6622
- try {
6623
- return new (sqlite()).DatabaseSync(path, { readOnly: true });
6624
- } catch {
6625
- return null;
6074
+ function makeFileResult(acc) {
6075
+ let diff = "";
6076
+ let linesAdded = 0;
6077
+ let linesRemoved = 0;
6078
+ let initialKnown = acc.before !== null;
6079
+ let reverted = false;
6080
+ if (acc.before !== null && acc.after !== null) {
6081
+ if (acc.before === acc.after) {
6082
+ reverted = true;
6083
+ } else {
6084
+ diff = createPatch(acc.file, acc.before, acc.after);
6085
+ for (const line of diff.split("\n")) {
6086
+ if (line.startsWith("+") && !line.startsWith("+++"))
6087
+ linesAdded++;
6088
+ else if (line.startsWith("-") && !line.startsWith("---"))
6089
+ linesRemoved++;
6090
+ }
6091
+ }
6626
6092
  }
6093
+ return {
6094
+ file: acc.file,
6095
+ initialContent: acc.before,
6096
+ initialKnown,
6097
+ finalContent: acc.after,
6098
+ diff,
6099
+ linesAdded,
6100
+ linesRemoved,
6101
+ events: acc.events,
6102
+ succeededEvents: acc.succeeded,
6103
+ failedEvents: acc.failed,
6104
+ reverted
6105
+ };
6627
6106
  }
6628
- function openSqliteReadonlyOrThrow(path) {
6629
- return new (sqlite()).DatabaseSync(path, { readOnly: true });
6107
+ var DEFAULT_USER_MAX, DEFAULT_ASSISTANT_MAX, DEFAULT_TOOL_RESULT_MAX, DEFAULT_MAX_TURNS;
6108
+ var init_generic_engine = __esm({
6109
+ "../engine/dist/core/generic-engine.js"() {
6110
+ "use strict";
6111
+ init_tool_backend();
6112
+ DEFAULT_USER_MAX = 1200;
6113
+ DEFAULT_ASSISTANT_MAX = 1500;
6114
+ DEFAULT_TOOL_RESULT_MAX = 800;
6115
+ DEFAULT_MAX_TURNS = 5e3;
6116
+ }
6117
+ });
6118
+
6119
+ // ../engine/dist/core/flat-string.js
6120
+ function flatString(s) {
6121
+ if (!s)
6122
+ return "";
6123
+ if (s.length < 13)
6124
+ return s;
6125
+ return Buffer.from(s, "utf8").toString("utf8");
6630
6126
  }
6631
- var require2, _sqlite, _filtered;
6632
- var init_sqlite_reader = __esm({
6633
- "../engine/dist/core/sqlite-reader.js"() {
6127
+ var init_flat_string = __esm({
6128
+ "../engine/dist/core/flat-string.js"() {
6634
6129
  "use strict";
6635
- require2 = createRequire2(import.meta.url);
6636
- _filtered = false;
6637
6130
  }
6638
6131
  });
6639
6132
 
6640
6133
  // ../engine/dist/core/backends/opencode.js
6641
- import { existsSync as existsSync6 } from "fs";
6134
+ import { existsSync as existsSync5 } from "fs";
6642
6135
  import { homedir as homedir4 } from "os";
6643
- import { dirname as dirname6, join as join6 } from "path";
6136
+ import { dirname as dirname6, join as join5 } from "path";
6644
6137
  function openReadonly(path) {
6645
6138
  return openSqliteReadonly(path);
6646
6139
  }
6647
- var PREFIX2, OpencodeBackend, opencodeBackend;
6140
+ var PREFIX, OpencodeBackend, opencodeBackend;
6648
6141
  var init_opencode = __esm({
6649
6142
  "../engine/dist/core/backends/opencode.js"() {
6650
6143
  "use strict";
@@ -6654,10 +6147,10 @@ var init_opencode = __esm({
6654
6147
  init_session_git();
6655
6148
  init_generic_engine();
6656
6149
  init_flat_string();
6657
- PREFIX2 = "opencode_";
6150
+ PREFIX = "opencode_";
6658
6151
  OpencodeBackend = class {
6659
6152
  id = "opencode";
6660
- idPrefix = PREFIX2;
6153
+ idPrefix = PREFIX;
6661
6154
  displayName = "OpenCode";
6662
6155
  /**
6663
6156
  * Path to the SQLite db. Env override is the *full path*, not a directory,
@@ -6671,11 +6164,11 @@ var init_opencode = __esm({
6671
6164
  }
6672
6165
  // ── Subpath helpers ────────────────────────────────────────────
6673
6166
  plansDir() {
6674
- return join6(this.homeDir(), "plans");
6167
+ return join5(this.homeDir(), "plans");
6675
6168
  }
6676
6169
  /** Root that holds OpenCode's global config dir (~/.config/opencode). */
6677
6170
  configRoot() {
6678
- return join6(process.env.HOME || homedir4(), ".config", "opencode");
6171
+ return join5(process.env.HOME || homedir4(), ".config", "opencode");
6679
6172
  }
6680
6173
  /**
6681
6174
  * Canonical OpenCode skills location. The current docs use the plural
@@ -6684,15 +6177,15 @@ var init_opencode = __esm({
6684
6177
  * plural canonical dir for "promote skill to OpenCode" actions.
6685
6178
  */
6686
6179
  skillsDir() {
6687
- return join6(this.configRoot(), "skills");
6180
+ return join5(this.configRoot(), "skills");
6688
6181
  }
6689
6182
  /** Custom slash commands — markdown with frontmatter, plural canonical dir. */
6690
6183
  commandsDir() {
6691
- return join6(this.configRoot(), "commands");
6184
+ return join5(this.configRoot(), "commands");
6692
6185
  }
6693
6186
  /** Agent/subagent definitions — markdown with frontmatter. */
6694
6187
  agentsDir() {
6695
- return join6(this.configRoot(), "agents");
6188
+ return join5(this.configRoot(), "agents");
6696
6189
  }
6697
6190
  /** Every configured OpenCode database, primary first. Unlike the other tools
6698
6191
  * OpenCode stores sessions in a FILE, so a second profile means a second db
@@ -6701,7 +6194,7 @@ var init_opencode = __esm({
6701
6194
  return opencodeDbPaths();
6702
6195
  }
6703
6196
  isAvailable() {
6704
- return this.dbPaths().some((p) => existsSync6(p));
6197
+ return this.dbPaths().some((p) => existsSync5(p));
6705
6198
  }
6706
6199
  /**
6707
6200
  * Which database holds this session. Sessions are keyed by id inside a db, so
@@ -6714,7 +6207,7 @@ var init_opencode = __esm({
6714
6207
  if (cached)
6715
6208
  return cached;
6716
6209
  for (const path of this.dbPaths()) {
6717
- if (!existsSync6(path))
6210
+ if (!existsSync5(path))
6718
6211
  continue;
6719
6212
  const db = openReadonly(path);
6720
6213
  if (!db)
@@ -6739,13 +6232,13 @@ var init_opencode = __esm({
6739
6232
  }
6740
6233
  // ── ID handling ────────────────────────────────────────────────
6741
6234
  matchesId(id) {
6742
- return id.startsWith(PREFIX2);
6235
+ return id.startsWith(PREFIX);
6743
6236
  }
6744
6237
  toRawId(id) {
6745
- return id.startsWith(PREFIX2) ? id.slice(PREFIX2.length) : id;
6238
+ return id.startsWith(PREFIX) ? id.slice(PREFIX.length) : id;
6746
6239
  }
6747
6240
  toPrefixedId(rawId) {
6748
- return rawId.startsWith(PREFIX2) ? rawId : PREFIX2 + rawId;
6241
+ return rawId.startsWith(PREFIX) ? rawId : PREFIX + rawId;
6749
6242
  }
6750
6243
  // ── Location ───────────────────────────────────────────────────
6751
6244
  findSession(id) {
@@ -7130,7 +6623,7 @@ var init_opencode = __esm({
7130
6623
  }
7131
6624
  exportRawSession(id) {
7132
6625
  const dbPath = this.dbPath();
7133
- if (!existsSync6(dbPath))
6626
+ if (!existsSync5(dbPath))
7134
6627
  return null;
7135
6628
  const realId = this.toRawId(id);
7136
6629
  const db = openSqliteReadonlyOrThrow(dbPath);
@@ -7164,9 +6657,58 @@ var init_opencode = __esm({
7164
6657
  }
7165
6658
  });
7166
6659
 
6660
+ // ../engine/dist/core/backends/tail-read.js
6661
+ import { openSync, readSync, closeSync, statSync as statSync3 } from "node:fs";
6662
+ function readTailFromOffset(path, offset) {
6663
+ let size = 0;
6664
+ try {
6665
+ size = statSync3(path).size;
6666
+ } catch {
6667
+ return { text: "", newOffset: offset };
6668
+ }
6669
+ if (size <= offset)
6670
+ return { text: "", newOffset: offset };
6671
+ const len = Math.min(size - offset, 16 * 1024 * 1024);
6672
+ const buf = Buffer.allocUnsafe(len);
6673
+ let fd = null;
6674
+ try {
6675
+ fd = openSync(path, "r");
6676
+ let got = 0;
6677
+ while (got < len) {
6678
+ const n = readSync(fd, buf, got, len - got, offset + got);
6679
+ if (n <= 0)
6680
+ break;
6681
+ got += n;
6682
+ }
6683
+ if (got === 0)
6684
+ return { text: "", newOffset: offset };
6685
+ const slice = got < len ? buf.subarray(0, got) : buf;
6686
+ const lastNl = slice.lastIndexOf(10);
6687
+ if (lastNl < 0) {
6688
+ return { text: "", newOffset: offset };
6689
+ }
6690
+ const text = slice.subarray(0, lastNl + 1).toString("utf-8");
6691
+ return { text, newOffset: offset + lastNl + 1 };
6692
+ } catch {
6693
+ return { text: "", newOffset: offset };
6694
+ } finally {
6695
+ if (fd !== null) {
6696
+ try {
6697
+ closeSync(fd);
6698
+ } catch {
6699
+ }
6700
+ }
6701
+ }
6702
+ }
6703
+ var init_tail_read = __esm({
6704
+ "../engine/dist/core/backends/tail-read.js"() {
6705
+ "use strict";
6706
+ }
6707
+ });
6708
+
7167
6709
  // ../engine/dist/core/backends/codex.js
7168
- import { readdirSync as readdirSync4, readFileSync as readFileSync3, statSync as statSync5, openSync as openSync2, readSync as readSync2, closeSync as closeSync2 } from "fs";
7169
- import { basename as basename5, dirname as dirname7, join as join7 } from "path";
6710
+ import { readdirSync as readdirSync3, readFileSync as readFileSync2, statSync as statSync4, openSync as openSync2, readSync as readSync2, closeSync as closeSync2 } from "fs";
6711
+ import { basename as basename4, dirname as dirname7, join as join6 } from "path";
7170
6712
  function parseShellWrites(cmd) {
7171
6713
  const out = [];
7172
6714
  const firstLine = cmd.split("\n", 1)[0].trim();
@@ -7261,12 +6803,12 @@ function parseCodexPatch(input) {
7261
6803
  function* walkRollouts(root) {
7262
6804
  let entries;
7263
6805
  try {
7264
- entries = readdirSync4(root, { withFileTypes: true });
6806
+ entries = readdirSync3(root, { withFileTypes: true });
7265
6807
  } catch {
7266
6808
  return;
7267
6809
  }
7268
6810
  for (const e of entries) {
7269
- const full = join7(root, e.name);
6811
+ const full = join6(root, e.name);
7270
6812
  if (e.isDirectory()) {
7271
6813
  yield* walkRollouts(full);
7272
6814
  } else if (e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")) {
@@ -7294,7 +6836,7 @@ function flattenContent(content) {
7294
6836
  }
7295
6837
  function readFirstLine(path) {
7296
6838
  try {
7297
- const head = readFileSync3(path, "utf-8").split("\n", 1)[0] || "";
6839
+ const head = readFileSync2(path, "utf-8").split("\n", 1)[0] || "";
7298
6840
  if (!head)
7299
6841
  return null;
7300
6842
  return JSON.parse(head);
@@ -7302,7 +6844,7 @@ function readFirstLine(path) {
7302
6844
  return null;
7303
6845
  }
7304
6846
  }
7305
- var PREFIX3, CodexBackend, codexBackend;
6847
+ var PREFIX2, CodexBackend, codexBackend;
7306
6848
  var init_codex = __esm({
7307
6849
  "../engine/dist/core/backends/codex.js"() {
7308
6850
  "use strict";
@@ -7313,39 +6855,39 @@ var init_codex = __esm({
7313
6855
  init_generic_engine();
7314
6856
  init_tail_read();
7315
6857
  init_flat_string();
7316
- PREFIX3 = "codex_";
6858
+ PREFIX2 = "codex_";
7317
6859
  CodexBackend = class {
7318
6860
  id = "codex";
7319
- idPrefix = PREFIX3;
6861
+ idPrefix = PREFIX2;
7320
6862
  displayName = "Codex";
7321
6863
  homeDir() {
7322
6864
  return codexHomeDir();
7323
6865
  }
7324
6866
  // ── Subpath helpers ────────────────────────────────────────────
7325
6867
  sessionsDir() {
7326
- return join7(this.homeDir(), "sessions");
6868
+ return join6(this.homeDir(), "sessions");
7327
6869
  }
7328
6870
  configToml() {
7329
- return join7(this.homeDir(), "config.toml");
6871
+ return join6(this.homeDir(), "config.toml");
7330
6872
  }
7331
6873
  pluginsDir() {
7332
- return join7(this.homeDir(), ".tmp", "plugins", "plugins");
6874
+ return join6(this.homeDir(), ".tmp", "plugins", "plugins");
7333
6875
  }
7334
6876
  /** OpenAI-bundled, read-only system skills (imagegen, skill-creator, …). */
7335
6877
  skillsSystemDir() {
7336
- return join7(this.homeDir(), "skills", ".system");
6878
+ return join6(this.homeDir(), "skills", ".system");
7337
6879
  }
7338
6880
  /** User skills root. Direct children (excluding `.system`) are user-authored. */
7339
6881
  skillsDir() {
7340
- return join7(this.homeDir(), "skills");
6882
+ return join6(this.homeDir(), "skills");
7341
6883
  }
7342
6884
  /** Custom prompts (deprecated upstream in favor of skills) — flat *.md. */
7343
6885
  promptsDir() {
7344
- return join7(this.homeDir(), "prompts");
6886
+ return join6(this.homeDir(), "prompts");
7345
6887
  }
7346
6888
  /** Subagent definitions — one TOML file per agent. */
7347
6889
  agentsDir() {
7348
- return join7(this.homeDir(), "agents");
6890
+ return join6(this.homeDir(), "agents");
7349
6891
  }
7350
6892
  /** Any configured home having a sessions/ tree makes Codex available — a
7351
6893
  * machine whose only Codex profile is a secondary one still counts. */
@@ -7358,13 +6900,13 @@ var init_codex = __esm({
7358
6900
  }
7359
6901
  // ── ID handling ────────────────────────────────────────────────
7360
6902
  matchesId(id) {
7361
- return id.startsWith(PREFIX3);
6903
+ return id.startsWith(PREFIX2);
7362
6904
  }
7363
6905
  toRawId(id) {
7364
- return id.startsWith(PREFIX3) ? id.slice(PREFIX3.length) : id;
6906
+ return id.startsWith(PREFIX2) ? id.slice(PREFIX2.length) : id;
7365
6907
  }
7366
6908
  toPrefixedId(rawId) {
7367
- return rawId.startsWith(PREFIX3) ? rawId : PREFIX3 + rawId;
6909
+ return rawId.startsWith(PREFIX2) ? rawId : PREFIX2 + rawId;
7368
6910
  }
7369
6911
  // ── Location ───────────────────────────────────────────────────
7370
6912
  findSession(id) {
@@ -7373,7 +6915,7 @@ var init_codex = __esm({
7373
6915
  return null;
7374
6916
  let mtime = 0;
7375
6917
  try {
7376
- mtime = statSync5(located.path).mtimeMs;
6918
+ mtime = statSync4(located.path).mtimeMs;
7377
6919
  } catch {
7378
6920
  }
7379
6921
  return {
@@ -7393,7 +6935,7 @@ var init_codex = __esm({
7393
6935
  for (const filePath of walkRollouts(root)) {
7394
6936
  let stat;
7395
6937
  try {
7396
- stat = statSync5(filePath);
6938
+ stat = statSync4(filePath);
7397
6939
  } catch {
7398
6940
  continue;
7399
6941
  }
@@ -7405,14 +6947,14 @@ var init_codex = __esm({
7405
6947
  const payload = meta.payload;
7406
6948
  if (payload.agent_role || payload.agent_nickname)
7407
6949
  continue;
7408
- const rawId = payload.id || basename5(filePath).replace(/^rollout-/, "").replace(/\.jsonl$/, "");
6950
+ const rawId = payload.id || basename4(filePath).replace(/^rollout-/, "").replace(/\.jsonl$/, "");
7409
6951
  const projectPath = payload.cwd || "";
7410
6952
  if (filter && !projectPath.toLowerCase().includes(filter))
7411
6953
  continue;
7412
6954
  let firstPrompt = "";
7413
6955
  let messageCount = 0;
7414
6956
  try {
7415
- const lines = readFileSync3(filePath, "utf-8").split("\n");
6957
+ const lines = readFileSync2(filePath, "utf-8").split("\n");
7416
6958
  for (const line of lines) {
7417
6959
  if (!line.trim())
7418
6960
  continue;
@@ -7553,7 +7095,7 @@ var init_codex = __esm({
7553
7095
  const dayDir = located.path.substring(0, located.path.lastIndexOf("/"));
7554
7096
  let entries = [];
7555
7097
  try {
7556
- entries = readdirSync4(dayDir);
7098
+ entries = readdirSync3(dayDir);
7557
7099
  } catch {
7558
7100
  }
7559
7101
  for (const entry of entries) {
@@ -7564,7 +7106,7 @@ var init_codex = __esm({
7564
7106
  continue;
7565
7107
  let firstLine = "";
7566
7108
  try {
7567
- firstLine = readFileSync3(path, "utf-8").split("\n", 1)[0] || "";
7109
+ firstLine = readFileSync2(path, "utf-8").split("\n", 1)[0] || "";
7568
7110
  } catch {
7569
7111
  continue;
7570
7112
  }
@@ -7588,8 +7130,8 @@ var init_codex = __esm({
7588
7130
  let raw = "";
7589
7131
  let mtime = 0;
7590
7132
  try {
7591
- raw = readFileSync3(path, "utf-8");
7592
- mtime = statSync5(path).mtimeMs;
7133
+ raw = readFileSync2(path, "utf-8");
7134
+ mtime = statSync4(path).mtimeMs;
7593
7135
  } catch {
7594
7136
  return [];
7595
7137
  }
@@ -7689,7 +7231,7 @@ var init_codex = __esm({
7689
7231
  const events = this.readEvents(this.toRawId(id));
7690
7232
  let fileMtime = 0;
7691
7233
  try {
7692
- fileMtime = statSync5(located.path).mtimeMs;
7234
+ fileMtime = statSync4(located.path).mtimeMs;
7693
7235
  } catch {
7694
7236
  }
7695
7237
  return liveScanEditsFromEvents(events, this.fileToolMap, {
@@ -7739,21 +7281,21 @@ var init_codex = __esm({
7739
7281
  const scanDir = (dir) => {
7740
7282
  let entries;
7741
7283
  try {
7742
- entries = readdirSync4(dir, { withFileTypes: true });
7284
+ entries = readdirSync3(dir, { withFileTypes: true });
7743
7285
  } catch {
7744
7286
  return;
7745
7287
  }
7746
7288
  for (const entry of entries) {
7747
7289
  if (entry.isDirectory()) {
7748
- scanDir(join7(dir, entry.name));
7290
+ scanDir(join6(dir, entry.name));
7749
7291
  continue;
7750
7292
  }
7751
7293
  if (!entry.name.endsWith(".jsonl"))
7752
7294
  continue;
7753
- const p = join7(dir, entry.name);
7295
+ const p = join6(dir, entry.name);
7754
7296
  let st;
7755
7297
  try {
7756
- st = statSync5(p);
7298
+ st = statSync4(p);
7757
7299
  } catch {
7758
7300
  continue;
7759
7301
  }
@@ -7765,7 +7307,7 @@ var init_codex = __esm({
7765
7307
  let parentId = null;
7766
7308
  let isSubagent = false;
7767
7309
  try {
7768
- const first = readFileSync3(p, "utf-8").split("\n")[0];
7310
+ const first = readFileSync2(p, "utf-8").split("\n")[0];
7769
7311
  if (first) {
7770
7312
  const meta = JSON.parse(first);
7771
7313
  const payload = meta?.payload || {};
@@ -7820,22 +7362,22 @@ var init_codex = __esm({
7820
7362
  let mtime = 0;
7821
7363
  const push = (path, name) => {
7822
7364
  try {
7823
- const st = statSync5(path);
7824
- files.push({ name, bytes: readFileSync3(path) });
7365
+ const st = statSync4(path);
7366
+ files.push({ name, bytes: readFileSync2(path) });
7825
7367
  if (st.mtimeMs > mtime)
7826
7368
  mtime = st.mtimeMs;
7827
7369
  } catch {
7828
7370
  }
7829
7371
  };
7830
- push(loc.path, basename5(loc.path));
7831
- const parentId = basename5(loc.path).match(/([a-f0-9-]{36})\.jsonl$/i)?.[1];
7372
+ push(loc.path, basename4(loc.path));
7373
+ const parentId = basename4(loc.path).match(/([a-f0-9-]{36})\.jsonl$/i)?.[1];
7832
7374
  if (parentId) {
7833
7375
  const dayDir = dirname7(loc.path);
7834
7376
  try {
7835
- for (const f of readdirSync4(dayDir)) {
7377
+ for (const f of readdirSync3(dayDir)) {
7836
7378
  if (!f.endsWith(".jsonl") || !f.startsWith("rollout-"))
7837
7379
  continue;
7838
- const p = join7(dayDir, f);
7380
+ const p = join6(dayDir, f);
7839
7381
  if (p === loc.path)
7840
7382
  continue;
7841
7383
  try {
@@ -7862,7 +7404,7 @@ var init_codex = __esm({
7862
7404
  if (!loc)
7863
7405
  return 0;
7864
7406
  try {
7865
- return statSync5(loc.path).size;
7407
+ return statSync4(loc.path).size;
7866
7408
  } catch {
7867
7409
  return 0;
7868
7410
  }
@@ -7879,14 +7421,14 @@ var init_codex = __esm({
7879
7421
  });
7880
7422
 
7881
7423
  // ../engine/dist/core/backends/agy.js
7882
- import { existsSync as existsSync7, readdirSync as readdirSync5, readFileSync as readFileSync4, statSync as statSync6 } from "fs";
7883
- import { basename as basename6, dirname as dirname8, join as join8 } from "path";
7424
+ import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync3, statSync as statSync5 } from "fs";
7425
+ import { basename as basename5, dirname as dirname8, join as join7 } from "path";
7884
7426
  function agyTranscriptPath(logsDir) {
7885
- const full = join8(logsDir, "transcript_full.jsonl");
7886
- if (existsSync7(full))
7427
+ const full = join7(logsDir, "transcript_full.jsonl");
7428
+ if (existsSync6(full))
7887
7429
  return full;
7888
- const primary = join8(logsDir, "transcript.jsonl");
7889
- if (existsSync7(primary))
7430
+ const primary = join7(logsDir, "transcript.jsonl");
7431
+ if (existsSync6(primary))
7890
7432
  return primary;
7891
7433
  return "";
7892
7434
  }
@@ -7899,7 +7441,7 @@ function resolveAgyProject(logsDir, homeDir) {
7899
7441
  function extractProjectPathFromTranscript(path, homeDir) {
7900
7442
  let content;
7901
7443
  try {
7902
- content = readFileSync4(path, "utf-8");
7444
+ content = readFileSync3(path, "utf-8");
7903
7445
  } catch {
7904
7446
  return "";
7905
7447
  }
@@ -7975,7 +7517,7 @@ function matchesTool(resultType, toolName) {
7975
7517
  const normTool = toolName.toLowerCase().replace(/_/g, "");
7976
7518
  return normResult.includes(normTool) || normTool.includes(normResult) || normResult === "codeaction" && ["writetofile", "replacefilecontent", "multireplacefilecontent"].includes(normTool) || normResult === "generic" && ["askpermission"].includes(normTool);
7977
7519
  }
7978
- var PREFIX4, AgyBackend, agyBackend;
7520
+ var PREFIX3, AgyBackend, agyBackend;
7979
7521
  var init_agy = __esm({
7980
7522
  "../engine/dist/core/backends/agy.js"() {
7981
7523
  "use strict";
@@ -7986,26 +7528,71 @@ var init_agy = __esm({
7986
7528
  init_session_git();
7987
7529
  init_generic_engine();
7988
7530
  init_flat_string();
7989
- PREFIX4 = "agy_";
7531
+ PREFIX3 = "agy_";
7990
7532
  AgyBackend = class {
7991
7533
  id = "agy";
7992
- idPrefix = PREFIX4;
7534
+ idPrefix = PREFIX3;
7993
7535
  displayName = "Antigravity";
7994
7536
  homeDir() {
7995
7537
  return agyHomeDir();
7996
7538
  }
7539
+ /**
7540
+ * THE SHARED ROOT ANTIGRAVITY INHERITED: `~/.gemini`.
7541
+ *
7542
+ * Google put Antigravity inside Gemini CLI's directory, so `~/.gemini` now
7543
+ * holds three things at once: Antigravity CLI (`antigravity-cli/`), the
7544
+ * Antigravity desktop app (`antigravity/`), and the user-level
7545
+ * `skills/ commands/ agents/ extensions/ settings.json` that Gemini CLI
7546
+ * created and Antigravity still reads.
7547
+ *
7548
+ * These `shared*` helpers are READ roots for that third group. They used to
7549
+ * hang off the Gemini CLI backend, which was switched off on 2026-06-18;
7550
+ * Antigravity is the only tool left reading them, so they live here.
7551
+ *
7552
+ * WRITES DO NOT GO HERE. An install goes to Antigravity's own directory —
7553
+ * `homeDir()/skills` and friends, which is what `toolkit-sync.ts` and
7554
+ * `artifact-codec.ts` target. Verified on a real install: both
7555
+ * `~/.gemini/skills` and `~/.gemini/antigravity-cli/skills` exist, and only
7556
+ * the second is Antigravity's own.
7557
+ */
7558
+ sharedRootDir() {
7559
+ return geminiHomeDir();
7560
+ }
7561
+ sharedSkillsDir() {
7562
+ return join7(this.sharedRootDir(), "skills");
7563
+ }
7564
+ sharedCommandsDir() {
7565
+ return join7(this.sharedRootDir(), "commands");
7566
+ }
7567
+ sharedAgentsDir() {
7568
+ return join7(this.sharedRootDir(), "agents");
7569
+ }
7570
+ sharedExtensionsDir() {
7571
+ return join7(this.sharedRootDir(), "extensions");
7572
+ }
7573
+ sharedSettingsFile() {
7574
+ return join7(this.sharedRootDir(), "settings.json");
7575
+ }
7576
+ sharedProjectsJson() {
7577
+ return join7(this.sharedRootDir(), "projects.json");
7578
+ }
7579
+ /** The DESKTOP app's brain, `~/.gemini/antigravity/brain`. The CLI's own is
7580
+ * `homeDir()/brain`, reached through `agyBrainDirs()`. Both exist. */
7581
+ desktopBrainDir() {
7582
+ return join7(this.sharedRootDir(), "antigravity", "brain");
7583
+ }
7997
7584
  isAvailable() {
7998
7585
  return agyBrainDirs().length > 0;
7999
7586
  }
8000
7587
  // ── ID handling ────────────────────────────────────────────────
8001
7588
  matchesId(id) {
8002
- return id.startsWith(PREFIX4);
7589
+ return id.startsWith(PREFIX3);
8003
7590
  }
8004
7591
  toRawId(id) {
8005
- return id.startsWith(PREFIX4) ? id.slice(PREFIX4.length) : id;
7592
+ return id.startsWith(PREFIX3) ? id.slice(PREFIX3.length) : id;
8006
7593
  }
8007
7594
  toPrefixedId(rawId) {
8008
- return rawId.startsWith(PREFIX4) ? rawId : PREFIX4 + rawId;
7595
+ return rawId.startsWith(PREFIX3) ? rawId : PREFIX3 + rawId;
8009
7596
  }
8010
7597
  // ── Location ───────────────────────────────────────────────────
8011
7598
  findSession(id) {
@@ -8019,19 +7606,19 @@ var init_agy = __esm({
8019
7606
  }
8020
7607
  /** Resolve a session inside ONE brain root. */
8021
7608
  findSessionIn(brainDir, rawId) {
8022
- const sessionDir = join8(brainDir, rawId);
8023
- if (!existsSync7(sessionDir))
7609
+ const sessionDir = join7(brainDir, rawId);
7610
+ if (!existsSync6(sessionDir))
8024
7611
  return null;
8025
- const path = agyTranscriptPath(join8(sessionDir, ".system_generated", "logs"));
7612
+ const path = agyTranscriptPath(join7(sessionDir, ".system_generated", "logs"));
8026
7613
  if (!path)
8027
7614
  return null;
8028
7615
  let mtime = 0;
8029
7616
  try {
8030
- mtime = statSync6(path).mtimeMs;
7617
+ mtime = statSync5(path).mtimeMs;
8031
7618
  } catch {
8032
7619
  }
8033
7620
  const projectPath = resolveAgyProject(dirname8(path), this.homeDir());
8034
- const projectDir = projectPath ? basename6(projectPath) : "";
7621
+ const projectDir = projectPath ? basename5(projectPath) : "";
8035
7622
  return {
8036
7623
  path,
8037
7624
  format: "jsonl",
@@ -8048,24 +7635,24 @@ var init_agy = __esm({
8048
7635
  for (const brainDir of agyBrainDirs()) {
8049
7636
  let sessionDirs;
8050
7637
  try {
8051
- sessionDirs = readdirSync5(brainDir);
7638
+ sessionDirs = readdirSync4(brainDir);
8052
7639
  } catch {
8053
7640
  continue;
8054
7641
  }
8055
7642
  for (const rawId of sessionDirs) {
8056
- const sessionPath = join8(brainDir, rawId);
7643
+ const sessionPath = join7(brainDir, rawId);
8057
7644
  try {
8058
- if (!statSync6(sessionPath).isDirectory())
7645
+ if (!statSync5(sessionPath).isDirectory())
8059
7646
  continue;
8060
7647
  } catch {
8061
7648
  continue;
8062
7649
  }
8063
- const filePath = agyTranscriptPath(join8(sessionPath, ".system_generated", "logs"));
7650
+ const filePath = agyTranscriptPath(join7(sessionPath, ".system_generated", "logs"));
8064
7651
  if (!filePath)
8065
7652
  continue;
8066
7653
  let stat;
8067
7654
  try {
8068
- stat = statSync6(filePath);
7655
+ stat = statSync5(filePath);
8069
7656
  } catch {
8070
7657
  continue;
8071
7658
  }
@@ -8074,11 +7661,11 @@ var init_agy = __esm({
8074
7661
  const projectPath = resolveAgyProject(dirname8(filePath), this.homeDir());
8075
7662
  if (filter && (!projectPath || !projectPath.toLowerCase().includes(filter)))
8076
7663
  continue;
8077
- const projectDir = projectPath ? basename6(projectPath) : "";
7664
+ const projectDir = projectPath ? basename5(projectPath) : "";
8078
7665
  let firstPrompt = "";
8079
7666
  let messageCount = 0;
8080
7667
  try {
8081
- const lines = readFileSync4(filePath, "utf-8").split("\n").filter(Boolean);
7668
+ const lines = readFileSync3(filePath, "utf-8").split("\n").filter(Boolean);
8082
7669
  messageCount = lines.length;
8083
7670
  for (const line of lines) {
8084
7671
  const obj = JSON.parse(line);
@@ -8168,7 +7755,7 @@ var init_agy = __esm({
8168
7755
  return [];
8169
7756
  let rawText;
8170
7757
  try {
8171
- rawText = readFileSync4(located.path, "utf-8");
7758
+ rawText = readFileSync3(located.path, "utf-8");
8172
7759
  } catch {
8173
7760
  return [];
8174
7761
  }
@@ -8323,23 +7910,23 @@ var init_agy = __esm({
8323
7910
  const candidates = [];
8324
7911
  let sessionDirs;
8325
7912
  try {
8326
- sessionDirs = readdirSync5(brainDir);
7913
+ sessionDirs = readdirSync4(brainDir);
8327
7914
  } catch {
8328
7915
  return [];
8329
7916
  }
8330
7917
  for (const rawId of sessionDirs) {
8331
- const sessionPath = join8(brainDir, rawId);
7918
+ const sessionPath = join7(brainDir, rawId);
8332
7919
  try {
8333
- if (!statSync6(sessionPath).isDirectory())
7920
+ if (!statSync5(sessionPath).isDirectory())
8334
7921
  continue;
8335
7922
  } catch {
8336
7923
  continue;
8337
7924
  }
8338
- const filePath = agyTranscriptPath(join8(sessionPath, ".system_generated", "logs"));
7925
+ const filePath = agyTranscriptPath(join7(sessionPath, ".system_generated", "logs"));
8339
7926
  if (!filePath)
8340
7927
  continue;
8341
7928
  try {
8342
- const st = statSync6(filePath);
7929
+ const st = statSync5(filePath);
8343
7930
  if (st.mtimeMs < opts.sinceMs)
8344
7931
  continue;
8345
7932
  candidates.push({ rawId, mtime: st.mtimeMs });
@@ -8367,8 +7954,8 @@ var init_agy = __esm({
8367
7954
  try {
8368
7955
  return {
8369
7956
  tool: "agy",
8370
- mtime: statSync6(loc.path).mtimeMs,
8371
- files: [{ name: basename6(loc.path), bytes: readFileSync4(loc.path) }]
7957
+ mtime: statSync5(loc.path).mtimeMs,
7958
+ files: [{ name: basename5(loc.path), bytes: readFileSync3(loc.path) }]
8372
7959
  };
8373
7960
  } catch {
8374
7961
  return null;
@@ -8382,7 +7969,7 @@ var init_agy = __esm({
8382
7969
  if (!loc)
8383
7970
  return 0;
8384
7971
  try {
8385
- return statSync6(loc.path).size;
7972
+ return statSync5(loc.path).size;
8386
7973
  } catch {
8387
7974
  return 0;
8388
7975
  }
@@ -8399,8 +7986,8 @@ var init_agy = __esm({
8399
7986
  });
8400
7987
 
8401
7988
  // ../engine/dist/core/backends/cursor-store.js
8402
- import { existsSync as existsSync8, readdirSync as readdirSync6, readFileSync as readFileSync5, statSync as statSync7 } from "fs";
8403
- import { join as join9 } from "path";
7989
+ import { existsSync as existsSync7, readdirSync as readdirSync5, readFileSync as readFileSync4, statSync as statSync6 } from "fs";
7990
+ import { join as join8 } from "path";
8404
7991
  function cursorProjectSlug(absPath) {
8405
7992
  return absPath.replace(/[^a-zA-Z0-9]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
8406
7993
  }
@@ -8408,28 +7995,28 @@ function listChatsIn(chatsRoot) {
8408
7995
  const out = [];
8409
7996
  let hashDirs;
8410
7997
  try {
8411
- hashDirs = readdirSync6(chatsRoot);
7998
+ hashDirs = readdirSync5(chatsRoot);
8412
7999
  } catch {
8413
8000
  return out;
8414
8001
  }
8415
8002
  for (const workspaceHash of hashDirs) {
8416
- const hashPath = join9(chatsRoot, workspaceHash);
8003
+ const hashPath = join8(chatsRoot, workspaceHash);
8417
8004
  let chatIds;
8418
8005
  try {
8419
- if (!statSync7(hashPath).isDirectory())
8006
+ if (!statSync6(hashPath).isDirectory())
8420
8007
  continue;
8421
- chatIds = readdirSync6(hashPath);
8008
+ chatIds = readdirSync5(hashPath);
8422
8009
  } catch {
8423
8010
  continue;
8424
8011
  }
8425
8012
  for (const chatId of chatIds) {
8426
- const dir = join9(hashPath, chatId);
8427
- const dbPath = join9(dir, "store.db");
8428
- if (!existsSync8(dbPath))
8013
+ const dir = join8(hashPath, chatId);
8014
+ const dbPath = join8(dir, "store.db");
8015
+ if (!existsSync7(dbPath))
8429
8016
  continue;
8430
8017
  let meta = {};
8431
8018
  try {
8432
- meta = JSON.parse(readFileSync5(join9(dir, "meta.json"), "utf-8"));
8019
+ meta = JSON.parse(readFileSync4(join8(dir, "meta.json"), "utf-8"));
8433
8020
  } catch {
8434
8021
  }
8435
8022
  if (meta.hasConversation === false)
@@ -8438,7 +8025,7 @@ function listChatsIn(chatsRoot) {
8438
8025
  let created = meta.createdAtMs ?? 0;
8439
8026
  if (!mtime || !created) {
8440
8027
  try {
8441
- const st = statSync7(dbPath);
8028
+ const st = statSync6(dbPath);
8442
8029
  mtime = mtime || st.mtimeMs;
8443
8030
  created = created || st.birthtimeMs || st.mtimeMs;
8444
8031
  } catch {
@@ -8463,25 +8050,25 @@ function findChat(chatsRoots, chatId) {
8463
8050
  for (const root of chatsRoots) {
8464
8051
  let hashDirs;
8465
8052
  try {
8466
- hashDirs = readdirSync6(root);
8053
+ hashDirs = readdirSync5(root);
8467
8054
  } catch {
8468
8055
  continue;
8469
8056
  }
8470
8057
  for (const workspaceHash of hashDirs) {
8471
- const dir = join9(root, workspaceHash, chatId);
8472
- const dbPath = join9(dir, "store.db");
8473
- if (!existsSync8(dbPath))
8058
+ const dir = join8(root, workspaceHash, chatId);
8059
+ const dbPath = join8(dir, "store.db");
8060
+ if (!existsSync7(dbPath))
8474
8061
  continue;
8475
8062
  let meta = {};
8476
8063
  try {
8477
- meta = JSON.parse(readFileSync5(join9(dir, "meta.json"), "utf-8"));
8064
+ meta = JSON.parse(readFileSync4(join8(dir, "meta.json"), "utf-8"));
8478
8065
  } catch {
8479
8066
  }
8480
8067
  let mtime = meta.updatedAtMs ?? 0;
8481
8068
  let created = meta.createdAtMs ?? 0;
8482
8069
  if (!mtime || !created) {
8483
8070
  try {
8484
- const st = statSync7(dbPath);
8071
+ const st = statSync6(dbPath);
8485
8072
  mtime = mtime || st.mtimeMs;
8486
8073
  created = created || st.birthtimeMs || st.mtimeMs;
8487
8074
  } catch {
@@ -8722,8 +8309,8 @@ function readStoreEvents(chat) {
8722
8309
  function transcriptPath(cursorHome, projectPath, chatId) {
8723
8310
  if (!projectPath)
8724
8311
  return null;
8725
- const p = join9(cursorHome, "projects", cursorProjectSlug(projectPath), "agent-transcripts", chatId, `${chatId}.jsonl`);
8726
- return existsSync8(p) ? p : null;
8312
+ const p = join8(cursorHome, "projects", cursorProjectSlug(projectPath), "agent-transcripts", chatId, `${chatId}.jsonl`);
8313
+ return existsSync7(p) ? p : null;
8727
8314
  }
8728
8315
  function readTranscriptEvents(rawText, mtimeFallback = 0) {
8729
8316
  const events = [];
@@ -8784,8 +8371,8 @@ var init_cursor_store = __esm({
8784
8371
  });
8785
8372
 
8786
8373
  // ../engine/dist/core/backends/cursor-ide.js
8787
- import { existsSync as existsSync9, readFileSync as readFileSync6, readdirSync as readdirSync7, statSync as statSync8 } from "fs";
8788
- import { dirname as dirname9, join as join10 } from "path";
8374
+ import { existsSync as existsSync8, readFileSync as readFileSync5, readdirSync as readdirSync6, statSync as statSync7 } from "fs";
8375
+ import { dirname as dirname9, join as join9 } from "path";
8789
8376
  function jsonOf(value) {
8790
8377
  if (value == null)
8791
8378
  return null;
@@ -8829,7 +8416,7 @@ function pathFromUri(uri) {
8829
8416
  return uri.startsWith("/") ? uri : "";
8830
8417
  }
8831
8418
  function projectPathForWorkspace(workspaceDir) {
8832
- const meta = jsonOf(safeRead(join10(workspaceDir, "workspace.json")));
8419
+ const meta = jsonOf(safeRead(join9(workspaceDir, "workspace.json")));
8833
8420
  if (!meta)
8834
8421
  return "";
8835
8422
  const uri = typeof meta.workspace === "string" && meta.workspace || typeof meta.folder === "string" && meta.folder || "";
@@ -8837,7 +8424,7 @@ function projectPathForWorkspace(workspaceDir) {
8837
8424
  }
8838
8425
  function safeRead(path) {
8839
8426
  try {
8840
- return readFileSync6(path, "utf-8");
8427
+ return readFileSync5(path, "utf-8");
8841
8428
  } catch {
8842
8429
  return null;
8843
8430
  }
@@ -8847,14 +8434,14 @@ function workspaceIndex(workspaceRoots) {
8847
8434
  for (const root of workspaceRoots) {
8848
8435
  let entries;
8849
8436
  try {
8850
- entries = readdirSync7(root);
8437
+ entries = readdirSync6(root);
8851
8438
  } catch {
8852
8439
  continue;
8853
8440
  }
8854
8441
  for (const id of entries) {
8855
- const dir = join10(root, id);
8442
+ const dir = join9(root, id);
8856
8443
  try {
8857
- if (!statSync8(dir).isDirectory())
8444
+ if (!statSync7(dir).isDirectory())
8858
8445
  continue;
8859
8446
  } catch {
8860
8447
  continue;
@@ -8934,13 +8521,13 @@ function listComposers(globalDbPath, workspaceRoots) {
8934
8521
  for (const root of workspaceRoots) {
8935
8522
  let entries;
8936
8523
  try {
8937
- entries = readdirSync7(root);
8524
+ entries = readdirSync6(root);
8938
8525
  } catch {
8939
8526
  continue;
8940
8527
  }
8941
8528
  for (const workspaceId of entries) {
8942
- const wsDb = join10(root, workspaceId, "state.vscdb");
8943
- if (!existsSync9(wsDb))
8529
+ const wsDb = join9(root, workspaceId, "state.vscdb");
8530
+ if (!existsSync8(wsDb))
8944
8531
  continue;
8945
8532
  const projectPath = wsIndex.get(workspaceId) || "";
8946
8533
  const w = openSqliteReadonly(wsDb);
@@ -9200,9 +8787,9 @@ var init_cursor_ide = __esm({
9200
8787
  });
9201
8788
 
9202
8789
  // ../engine/dist/core/backends/cursor.js
9203
- import { existsSync as existsSync10, readFileSync as readFileSync7, statSync as statSync9 } from "fs";
9204
- import { join as join11 } from "path";
9205
- var PREFIX5, CursorBackend, cursorBackend;
8790
+ import { existsSync as existsSync9, readFileSync as readFileSync6, statSync as statSync8 } from "fs";
8791
+ import { join as join10 } from "path";
8792
+ var PREFIX4, CursorBackend, cursorBackend;
9206
8793
  var init_cursor = __esm({
9207
8794
  "../engine/dist/core/backends/cursor.js"() {
9208
8795
  "use strict";
@@ -9213,10 +8800,10 @@ var init_cursor = __esm({
9213
8800
  init_flat_string();
9214
8801
  init_cursor_store();
9215
8802
  init_cursor_ide();
9216
- PREFIX5 = "cursor_";
8803
+ PREFIX4 = "cursor_";
9217
8804
  CursorBackend = class {
9218
8805
  id = "cursor";
9219
- idPrefix = PREFIX5;
8806
+ idPrefix = PREFIX4;
9220
8807
  displayName = "Cursor";
9221
8808
  homeDir() {
9222
8809
  return cursorHomeDir();
@@ -9226,13 +8813,13 @@ var init_cursor = __esm({
9226
8813
  }
9227
8814
  // ── ID handling ────────────────────────────────────────────────
9228
8815
  matchesId(id) {
9229
- return id.startsWith(PREFIX5);
8816
+ return id.startsWith(PREFIX4);
9230
8817
  }
9231
8818
  toRawId(id) {
9232
- return id.startsWith(PREFIX5) ? id.slice(PREFIX5.length) : id;
8819
+ return id.startsWith(PREFIX4) ? id.slice(PREFIX4.length) : id;
9233
8820
  }
9234
8821
  toPrefixedId(rawId) {
9235
- return rawId.startsWith(PREFIX5) ? rawId : PREFIX5 + rawId;
8822
+ return rawId.startsWith(PREFIX4) ? rawId : PREFIX4 + rawId;
9236
8823
  }
9237
8824
  // ── Location ───────────────────────────────────────────────────
9238
8825
  /** CLI first: it is the cheaper lookup and the more common surface. */
@@ -9253,7 +8840,7 @@ var init_cursor = __esm({
9253
8840
  if (r.surface === "cli") {
9254
8841
  let mtime2 = r.chat.updatedAtMs;
9255
8842
  try {
9256
- mtime2 = statSync9(r.chat.dbPath).mtimeMs || mtime2;
8843
+ mtime2 = statSync8(r.chat.dbPath).mtimeMs || mtime2;
9257
8844
  } catch {
9258
8845
  }
9259
8846
  return {
@@ -9266,7 +8853,7 @@ var init_cursor = __esm({
9266
8853
  }
9267
8854
  let mtime = r.composer.updatedAtMs;
9268
8855
  try {
9269
- mtime = statSync9(r.composer.globalDbPath).mtimeMs || mtime;
8856
+ mtime = statSync8(r.composer.globalDbPath).mtimeMs || mtime;
9270
8857
  } catch {
9271
8858
  }
9272
8859
  return {
@@ -9424,7 +9011,7 @@ var init_cursor = __esm({
9424
9011
  if (!jsonl)
9425
9012
  return [];
9426
9013
  try {
9427
- return readTranscriptEvents(readFileSync7(jsonl, "utf-8"), chat.updatedAtMs);
9014
+ return readTranscriptEvents(readFileSync6(jsonl, "utf-8"), chat.updatedAtMs);
9428
9015
  } catch {
9429
9016
  return [];
9430
9017
  }
@@ -9508,11 +9095,11 @@ var init_cursor = __esm({
9508
9095
  if (!lines)
9509
9096
  return null;
9510
9097
  const files = [{ name: `${r.chat.chatId}.jsonl`, bytes: Buffer.from(lines, "utf8") }];
9511
- const metaPath = join11(r.chat.dir, "meta.json");
9512
- if (existsSync10(metaPath)) {
9513
- files.push({ name: "meta.json", bytes: readFileSync7(metaPath) });
9098
+ const metaPath = join10(r.chat.dir, "meta.json");
9099
+ if (existsSync9(metaPath)) {
9100
+ files.push({ name: "meta.json", bytes: readFileSync6(metaPath) });
9514
9101
  }
9515
- return { tool: "cursor", mtime: statSync9(r.chat.dbPath).mtimeMs, files };
9102
+ return { tool: "cursor", mtime: statSync8(r.chat.dbPath).mtimeMs, files };
9516
9103
  }
9517
9104
  const events = readComposerEvents(r.composer);
9518
9105
  if (events.length === 0)
@@ -9520,7 +9107,7 @@ var init_cursor = __esm({
9520
9107
  const body = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
9521
9108
  return {
9522
9109
  tool: "cursor",
9523
- mtime: statSync9(r.composer.globalDbPath).mtimeMs,
9110
+ mtime: statSync8(r.composer.globalDbPath).mtimeMs,
9524
9111
  files: [{ name: `${r.composer.composerId}.jsonl`, bytes: Buffer.from(body, "utf8") }]
9525
9112
  };
9526
9113
  } catch {
@@ -9532,7 +9119,7 @@ var init_cursor = __esm({
9532
9119
  if (!p)
9533
9120
  return "";
9534
9121
  try {
9535
- return readFileSync7(p, "utf-8");
9122
+ return readFileSync6(p, "utf-8");
9536
9123
  } catch {
9537
9124
  return "";
9538
9125
  }
@@ -9545,7 +9132,6 @@ var init_cursor = __esm({
9545
9132
  // ../engine/dist/core/backends/index.js
9546
9133
  function bootstrapBackends() {
9547
9134
  registerBackend(claudeBackend);
9548
- registerBackend(geminiBackend);
9549
9135
  registerBackend(opencodeBackend);
9550
9136
  registerBackend(codexBackend);
9551
9137
  registerBackend(agyBackend);
@@ -9556,7 +9142,6 @@ var init_backends = __esm({
9556
9142
  "use strict";
9557
9143
  init_tool_backend();
9558
9144
  init_claude();
9559
- init_gemini();
9560
9145
  init_opencode();
9561
9146
  init_codex();
9562
9147
  init_agy();
@@ -9750,7 +9335,7 @@ var init_session_outcome = __esm({
9750
9335
  });
9751
9336
 
9752
9337
  // ../engine/dist/core/first-prompt.js
9753
- import { createReadStream, existsSync as existsSync11, openSync as openSync3, readSync as readSync3, closeSync as closeSync3 } from "fs";
9338
+ import { createReadStream, existsSync as existsSync10, openSync as openSync3, readSync as readSync3, closeSync as closeSync3 } from "fs";
9754
9339
  import { StringDecoder } from "string_decoder";
9755
9340
  function stripBanners(s) {
9756
9341
  let out = s;
@@ -9861,7 +9446,7 @@ var init_first_prompt = __esm({
9861
9446
  });
9862
9447
 
9863
9448
  // ../engine/dist/core/project-dir-name.js
9864
- import { readdirSync as readdirSync8 } from "node:fs";
9449
+ import { readdirSync as readdirSync7 } from "node:fs";
9865
9450
  function looksWindowsEncoded(dirName) {
9866
9451
  return /^[A-Za-z]--/.test(dirName);
9867
9452
  }
@@ -9881,7 +9466,7 @@ function resolveProjectDirName(dirName, deps = {}) {
9881
9466
  return structural;
9882
9467
  if (looksWindowsEncoded(dirName))
9883
9468
  return structural;
9884
- const readdir = deps.readdir ?? ((p) => readdirSync8(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name));
9469
+ const readdir = deps.readdir ?? ((p) => readdirSync7(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name));
9885
9470
  const encodeName = (name) => name.replace(/[-_.]/g, "-");
9886
9471
  let remaining = dirName.replace(/^-/, "");
9887
9472
  let current = "/";
@@ -9919,8 +9504,8 @@ var init_project_dir_name = __esm({
9919
9504
  });
9920
9505
 
9921
9506
  // ../engine/dist/core/backends/claude.js
9922
- import { existsSync as existsSync12, readdirSync as readdirSync9, readFileSync as readFileSync8, statSync as statSync10, openSync as openSync4, readSync as readSync4, closeSync as closeSync4 } from "fs";
9923
- import { join as join12, basename as basename7 } from "path";
9507
+ import { existsSync as existsSync11, readdirSync as readdirSync8, readFileSync as readFileSync7, statSync as statSync9, openSync as openSync4, readSync as readSync4, closeSync as closeSync4 } from "fs";
9508
+ import { join as join11, basename as basename6 } from "path";
9924
9509
  function stripReminders(text) {
9925
9510
  return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
9926
9511
  }
@@ -9950,44 +9535,44 @@ var init_claude = __esm({
9950
9535
  }
9951
9536
  // ── Subpath helpers used by the parser/source layer ─────────────
9952
9537
  projectsDir() {
9953
- return join12(this.homeDir(), "projects");
9538
+ return join11(this.homeDir(), "projects");
9954
9539
  }
9955
9540
  plansDir() {
9956
- return join12(this.homeDir(), "plans");
9541
+ return join11(this.homeDir(), "plans");
9957
9542
  }
9958
9543
  todosDir() {
9959
- return join12(this.homeDir(), "todos");
9544
+ return join11(this.homeDir(), "todos");
9960
9545
  }
9961
9546
  /** Legacy task-list directory still used by older Claude Code releases. */
9962
9547
  tasksDir() {
9963
- return join12(this.homeDir(), "tasks");
9548
+ return join11(this.homeDir(), "tasks");
9964
9549
  }
9965
9550
  pasteCacheDir() {
9966
- return join12(this.homeDir(), "paste-cache");
9551
+ return join11(this.homeDir(), "paste-cache");
9967
9552
  }
9968
9553
  skillsDir() {
9969
- return join12(this.homeDir(), "skills");
9554
+ return join11(this.homeDir(), "skills");
9970
9555
  }
9971
9556
  agentsDir() {
9972
- return join12(this.homeDir(), "agents");
9557
+ return join11(this.homeDir(), "agents");
9973
9558
  }
9974
9559
  commandsDir() {
9975
- return join12(this.homeDir(), "commands");
9560
+ return join11(this.homeDir(), "commands");
9976
9561
  }
9977
9562
  pluginsManifestPath() {
9978
- return join12(this.homeDir(), "plugins", "installed_plugins.json");
9563
+ return join11(this.homeDir(), "plugins", "installed_plugins.json");
9979
9564
  }
9980
9565
  hooksFile() {
9981
- return join12(this.homeDir(), "hooks.json");
9566
+ return join11(this.homeDir(), "hooks.json");
9982
9567
  }
9983
9568
  settingsFile() {
9984
- return join12(this.homeDir(), "settings.json");
9569
+ return join11(this.homeDir(), "settings.json");
9985
9570
  }
9986
9571
  historyFile() {
9987
- return join12(this.homeDir(), "history.jsonl");
9572
+ return join11(this.homeDir(), "history.jsonl");
9988
9573
  }
9989
9574
  isAvailable() {
9990
- return existsSync12(this.projectsDir());
9575
+ return existsSync11(this.projectsDir());
9991
9576
  }
9992
9577
  // ── ID handling ────────────────────────────────────────────────
9993
9578
  /**
@@ -10048,7 +9633,7 @@ var init_claude = __esm({
10048
9633
  let mtime = 0;
10049
9634
  for (const c of copies) {
10050
9635
  try {
10051
- mtime = Math.max(mtime, statSync10(c.path).mtimeMs);
9636
+ mtime = Math.max(mtime, statSync9(c.path).mtimeMs);
10052
9637
  } catch {
10053
9638
  }
10054
9639
  }
@@ -10072,22 +9657,22 @@ var init_claude = __esm({
10072
9657
  return opts.limit ? out.slice(0, opts.limit) : out;
10073
9658
  }
10074
9659
  collectSessionsFromRoot(root, cutoff, filter, seen, out) {
10075
- if (!existsSync12(root))
9660
+ if (!existsSync11(root))
10076
9661
  return;
10077
- for (const proj of readdirSync9(root, { withFileTypes: true })) {
9662
+ for (const proj of readdirSync8(root, { withFileTypes: true })) {
10078
9663
  if (!proj.isDirectory())
10079
9664
  continue;
10080
9665
  if (filter && !proj.name.toLowerCase().includes(filter))
10081
9666
  continue;
10082
- const projPath = join12(root, proj.name);
9667
+ const projPath = join11(root, proj.name);
10083
9668
  const projectPath = resolveProjectDirName(proj.name);
10084
- const indexPath = join12(projPath, "sessions-index.json");
10085
- if (existsSync12(indexPath)) {
9669
+ const indexPath = join11(projPath, "sessions-index.json");
9670
+ if (existsSync11(indexPath)) {
10086
9671
  try {
10087
- const indexData = JSON.parse(readFileSync8(indexPath, "utf-8"));
9672
+ const indexData = JSON.parse(readFileSync7(indexPath, "utf-8"));
10088
9673
  const entries = indexData.entries || [];
10089
9674
  for (const entry of entries) {
10090
- if (!entry.fullPath || !existsSync12(entry.fullPath))
9675
+ if (!entry.fullPath || !existsSync11(entry.fullPath))
10091
9676
  continue;
10092
9677
  if ((entry.fileMtime ?? 0) < cutoff)
10093
9678
  continue;
@@ -10111,20 +9696,20 @@ var init_claude = __esm({
10111
9696
  }
10112
9697
  let files;
10113
9698
  try {
10114
- files = readdirSync9(projPath);
9699
+ files = readdirSync8(projPath);
10115
9700
  } catch {
10116
9701
  continue;
10117
9702
  }
10118
9703
  for (const f of files) {
10119
9704
  if (!f.endsWith(".jsonl") || f === "sessions-index.json")
10120
9705
  continue;
10121
- const sessionId = basename7(f, ".jsonl");
9706
+ const sessionId = basename6(f, ".jsonl");
10122
9707
  if (seen.has(sessionId))
10123
9708
  continue;
10124
- const fullPath = join12(projPath, f);
9709
+ const fullPath = join11(projPath, f);
10125
9710
  let stat;
10126
9711
  try {
10127
- stat = statSync10(fullPath);
9712
+ stat = statSync9(fullPath);
10128
9713
  } catch {
10129
9714
  continue;
10130
9715
  }
@@ -10342,7 +9927,7 @@ var init_claude = __esm({
10342
9927
  const events = this.readEvents(rawId);
10343
9928
  let fileMtime = 0;
10344
9929
  try {
10345
- fileMtime = statSync10(located.path).mtimeMs;
9930
+ fileMtime = statSync9(located.path).mtimeMs;
10346
9931
  } catch {
10347
9932
  }
10348
9933
  return liveScanEditsFromEvents(events, this.fileToolMap, {
@@ -10378,32 +9963,32 @@ var init_claude = __esm({
10378
9963
  collectRecentEdits(opts) {
10379
9964
  const candidates = [];
10380
9965
  for (const root of claudeProjectDirs()) {
10381
- if (!existsSync12(root))
9966
+ if (!existsSync11(root))
10382
9967
  continue;
10383
- for (const projEntry of readdirSync9(root, { withFileTypes: true })) {
9968
+ for (const projEntry of readdirSync8(root, { withFileTypes: true })) {
10384
9969
  if (!projEntry.isDirectory())
10385
9970
  continue;
10386
9971
  if (opts.projectFilter && !projEntry.name.toLowerCase().includes(opts.projectFilter.toLowerCase()))
10387
9972
  continue;
10388
- const projPath = join12(root, projEntry.name);
9973
+ const projPath = join11(root, projEntry.name);
10389
9974
  let files;
10390
9975
  try {
10391
- files = readdirSync9(projPath);
9976
+ files = readdirSync8(projPath);
10392
9977
  } catch {
10393
9978
  continue;
10394
9979
  }
10395
9980
  for (const f of files) {
10396
9981
  if (!f.endsWith(".jsonl") || f === "sessions-index.json")
10397
9982
  continue;
10398
- const fp = join12(projPath, f);
9983
+ const fp = join11(projPath, f);
10399
9984
  try {
10400
- const st = statSync10(fp);
9985
+ const st = statSync9(fp);
10401
9986
  let mtime = st.mtimeMs;
10402
- const subDir = join12(projPath, f.slice(0, -6), "subagents");
10403
- if (existsSync12(subDir)) {
10404
- for (const sub of readdirSync9(subDir)) {
9987
+ const subDir = join11(projPath, f.slice(0, -6), "subagents");
9988
+ if (existsSync11(subDir)) {
9989
+ for (const sub of readdirSync8(subDir)) {
10405
9990
  try {
10406
- const subSt = statSync10(join12(subDir, sub));
9991
+ const subSt = statSync9(join11(subDir, sub));
10407
9992
  if (subSt.mtimeMs > mtime)
10408
9993
  mtime = subSt.mtimeMs;
10409
9994
  } catch {
@@ -10412,7 +9997,7 @@ var init_claude = __esm({
10412
9997
  }
10413
9998
  if (mtime < opts.sinceMs)
10414
9999
  continue;
10415
- candidates.push({ rawId: basename7(f, ".jsonl"), mtime });
10000
+ candidates.push({ rawId: basename6(f, ".jsonl"), mtime });
10416
10001
  } catch {
10417
10002
  }
10418
10003
  }
@@ -10468,7 +10053,7 @@ var init_claude = __esm({
10468
10053
  let total = 0;
10469
10054
  for (const located of findSessionFiles(this.toRawId(prefixedId))) {
10470
10055
  try {
10471
- total += statSync10(located.path).size;
10056
+ total += statSync9(located.path).size;
10472
10057
  } catch {
10473
10058
  }
10474
10059
  }
@@ -10512,11 +10097,11 @@ var init_model_pricing = __esm({
10512
10097
  });
10513
10098
 
10514
10099
  // ../engine/dist/parsers/session.js
10515
- import { createReadStream as createReadStream2, existsSync as existsSync13, readdirSync as readdirSync10, readFileSync as readFileSync9, statSync as statSync11, openSync as openSync5, readSync as readSync5, closeSync as closeSync5 } from "fs";
10516
- import { join as join13, basename as basename8 } from "path";
10100
+ import { createReadStream as createReadStream2, existsSync as existsSync12, readdirSync as readdirSync9, readFileSync as readFileSync8, statSync as statSync10, openSync as openSync5, readSync as readSync5, closeSync as closeSync5 } from "fs";
10101
+ import { join as join12, basename as basename7 } from "path";
10517
10102
  function hasSubagentsDir(sessionPath) {
10518
10103
  const dir = sessionPath.slice(0, -6);
10519
- return existsSync13(join13(dir, "subagents"));
10104
+ return existsSync12(join12(dir, "subagents"));
10520
10105
  }
10521
10106
  var init_session = __esm({
10522
10107
  "../engine/dist/parsers/session.js"() {
@@ -10539,13 +10124,6 @@ var init_claude2 = __esm({
10539
10124
  }
10540
10125
  });
10541
10126
 
10542
- // ../engine/dist/transcript/gemini.js
10543
- var init_gemini2 = __esm({
10544
- "../engine/dist/transcript/gemini.js"() {
10545
- "use strict";
10546
- }
10547
- });
10548
-
10549
10127
  // ../engine/dist/transcript/codex.js
10550
10128
  var log3;
10551
10129
  var init_codex2 = __esm({
@@ -10569,16 +10147,15 @@ var init_raw = __esm({
10569
10147
  "use strict";
10570
10148
  init_tool_backend();
10571
10149
  init_claude2();
10572
- init_gemini2();
10573
10150
  init_codex2();
10574
10151
  init_from_events();
10575
10152
  }
10576
10153
  });
10577
10154
 
10578
10155
  // ../engine/dist/transcript/shadow.js
10579
- import { createHash as createHash2 } from "crypto";
10156
+ import { createHash } from "crypto";
10580
10157
  function sha1(s) {
10581
- return createHash2("sha1").update(s).digest("hex");
10158
+ return createHash("sha1").update(s).digest("hex");
10582
10159
  }
10583
10160
  function lineKey(line) {
10584
10161
  try {
@@ -10638,12 +10215,8 @@ var init_shadow = __esm({
10638
10215
  });
10639
10216
 
10640
10217
  // ../engine/dist/core/live-session-scan.js
10641
- import { existsSync as existsSync14, readdirSync as readdirSync11, readFileSync as readFileSync10, statSync as statSync12, openSync as openSync6, readSync as readSync6, closeSync as closeSync6 } from "fs";
10642
- import { join as join14, basename as basename9 } from "path";
10643
- import { createHash as createHash3 } from "crypto";
10644
- function lazyGeminiProjectsJson() {
10645
- return join14(geminiHomeDir(), "projects.json");
10646
- }
10218
+ import { existsSync as existsSync13, readdirSync as readdirSync10, readFileSync as readFileSync9, statSync as statSync11, openSync as openSync6, readSync as readSync6, closeSync as closeSync6 } from "fs";
10219
+ import { join as join13, basename as basename8 } from "path";
10647
10220
  function findSessionFile(sessionId) {
10648
10221
  return sessionFileIndex().get(sessionId)?.[0] ?? null;
10649
10222
  }
@@ -10653,22 +10226,22 @@ function sessionFileIndex() {
10653
10226
  const byId = /* @__PURE__ */ new Map();
10654
10227
  const seenRoots = /* @__PURE__ */ new Set();
10655
10228
  for (const root of claudeProjectDirs()) {
10656
- if (seenRoots.has(root) || !existsSync14(root))
10229
+ if (seenRoots.has(root) || !existsSync13(root))
10657
10230
  continue;
10658
10231
  seenRoots.add(root);
10659
10232
  let entries;
10660
10233
  try {
10661
- entries = readdirSync11(root, { withFileTypes: true });
10234
+ entries = readdirSync10(root, { withFileTypes: true });
10662
10235
  } catch {
10663
10236
  continue;
10664
10237
  }
10665
10238
  for (const entry of entries) {
10666
10239
  if (!entry.isDirectory())
10667
10240
  continue;
10668
- const dir = join14(root, entry.name);
10241
+ const dir = join13(root, entry.name);
10669
10242
  let names;
10670
10243
  try {
10671
- names = readdirSync11(dir);
10244
+ names = readdirSync10(dir);
10672
10245
  } catch {
10673
10246
  continue;
10674
10247
  }
@@ -10677,7 +10250,7 @@ function sessionFileIndex() {
10677
10250
  continue;
10678
10251
  const id = name.slice(0, -".jsonl".length);
10679
10252
  const located = {
10680
- path: join14(dir, name),
10253
+ path: join13(dir, name),
10681
10254
  projectDir: entry.name,
10682
10255
  projectPath: resolveProjectDirName(entry.name)
10683
10256
  };
@@ -10709,7 +10282,7 @@ function resolveSessionContentGroups(sessionId) {
10709
10282
  };
10710
10283
  for (const located of findSessionFiles(sessionId)) {
10711
10284
  for (const p of resolveSessionContentPaths(located.path)) {
10712
- add(p === located.path ? "main" : `subagents/${basename9(p)}`, p);
10285
+ add(p === located.path ? "main" : `subagents/${basename8(p)}`, p);
10713
10286
  }
10714
10287
  }
10715
10288
  const names = [...groups.keys()].sort((a, b) => a === "main" ? -1 : b === "main" ? 1 : a.localeCompare(b));
@@ -10730,7 +10303,7 @@ function readSessionGroupText(group) {
10730
10303
  const parts = [];
10731
10304
  for (const p of group.paths) {
10732
10305
  try {
10733
- const st = statSync12(p);
10306
+ const st = statSync11(p);
10734
10307
  parts.push(`${p}:${st.mtimeMs}:${st.size}`);
10735
10308
  } catch {
10736
10309
  parts.push(`${p}:missing`);
@@ -10745,12 +10318,12 @@ function readSessionGroupText(group) {
10745
10318
  for (const p of group.paths) {
10746
10319
  let raw;
10747
10320
  try {
10748
- raw = readFileSync10(p, "utf-8");
10321
+ raw = readFileSync9(p, "utf-8");
10749
10322
  } catch {
10750
10323
  continue;
10751
10324
  }
10752
10325
  try {
10753
- mtime = Math.max(mtime, statSync12(p).mtimeMs);
10326
+ mtime = Math.max(mtime, statSync11(p).mtimeMs);
10754
10327
  } catch {
10755
10328
  }
10756
10329
  text = text ? mergeLineText(text, raw).text : raw;
@@ -10763,174 +10336,12 @@ function readSessionGroupText(group) {
10763
10336
  function resolveSessionContentPaths(sessionFile) {
10764
10337
  if (!hasSubagentsDir(sessionFile))
10765
10338
  return [sessionFile];
10766
- const subDir = join14(sessionFile.slice(0, -6), "subagents");
10767
- if (!existsSync14(subDir))
10339
+ const subDir = join13(sessionFile.slice(0, -6), "subagents");
10340
+ if (!existsSync13(subDir))
10768
10341
  return [sessionFile];
10769
- const subPaths = readdirSync11(subDir).filter((f) => f.endsWith(".jsonl")).sort().map((f) => join14(subDir, f));
10342
+ const subPaths = readdirSync10(subDir).filter((f) => f.endsWith(".jsonl")).sort().map((f) => join13(subDir, f));
10770
10343
  return [sessionFile, ...subPaths];
10771
10344
  }
10772
- function loadGeminiProjectMap() {
10773
- if (geminiProjectMapCache)
10774
- return geminiProjectMapCache;
10775
- const map = /* @__PURE__ */ new Map();
10776
- const projectsPath = lazyGeminiProjectsJson();
10777
- if (existsSync14(projectsPath)) {
10778
- try {
10779
- const data = JSON.parse(readFileSync10(projectsPath, "utf-8"));
10780
- for (const path of Object.keys(data.projects || {})) {
10781
- map.set(createHash3("sha256").update(path).digest("hex"), path);
10782
- }
10783
- } catch {
10784
- }
10785
- }
10786
- geminiProjectMapCache = map;
10787
- return map;
10788
- }
10789
- function findGeminiSessionFile(sessionIdOrFileBase) {
10790
- const idx = geminiIndex();
10791
- const exact = idx.byBase.get(sessionIdOrFileBase);
10792
- if (exact)
10793
- return exact;
10794
- for (let len = Math.min(sessionIdOrFileBase.length, 64); len >= 4; len--) {
10795
- const hit = idx.byTail.get(sessionIdOrFileBase.slice(0, len));
10796
- if (hit)
10797
- return hit;
10798
- }
10799
- return geminiInnerIdIndex(idx).get(sessionIdOrFileBase) ?? null;
10800
- }
10801
- function geminiIndex() {
10802
- if (geminiCache)
10803
- return geminiCache;
10804
- const byBase = /* @__PURE__ */ new Map();
10805
- const byTail = /* @__PURE__ */ new Map();
10806
- const all = [];
10807
- const projMap = loadGeminiProjectMap();
10808
- const isGeminiChat = (f) => f.startsWith("session-") && (f.endsWith(".json") || f.endsWith(".jsonl"));
10809
- for (const tmpRoot of geminiTmpDirs()) {
10810
- if (!existsSync14(tmpRoot))
10811
- continue;
10812
- let projs;
10813
- try {
10814
- projs = readdirSync11(tmpRoot, { withFileTypes: true });
10815
- } catch {
10816
- continue;
10817
- }
10818
- for (const proj of projs) {
10819
- if (!proj.isDirectory())
10820
- continue;
10821
- const chats = join14(tmpRoot, proj.name, "chats");
10822
- if (!existsSync14(chats))
10823
- continue;
10824
- let files;
10825
- try {
10826
- files = readdirSync11(chats);
10827
- } catch {
10828
- continue;
10829
- }
10830
- for (const f of files) {
10831
- if (!isGeminiChat(f))
10832
- continue;
10833
- const base = f.replace(/\.jsonl?$/, "");
10834
- const located = {
10835
- path: join14(chats, f),
10836
- projectDir: proj.name,
10837
- projectPath: projMap.get(proj.name) || "",
10838
- format: f.endsWith(".jsonl") ? "jsonl" : "json"
10839
- };
10840
- all.push(located);
10841
- if (!byBase.has(base))
10842
- byBase.set(base, located);
10843
- const tail = base.split("-").pop() || "";
10844
- if (tail.length >= 4 && !byTail.has(tail))
10845
- byTail.set(tail, located);
10846
- }
10847
- }
10848
- }
10849
- const built = { byBase, byTail, all, byInnerId: null };
10850
- if (scanScopeDepth > 0)
10851
- geminiCache = built;
10852
- return built;
10853
- }
10854
- function geminiInnerIdIndex(idx) {
10855
- if (idx.byInnerId)
10856
- return idx.byInnerId;
10857
- const byInnerId = /* @__PURE__ */ new Map();
10858
- for (const located of idx.all) {
10859
- try {
10860
- const innerId = readGeminiSessionIdFromFile(located.path, located.format);
10861
- if (innerId && !byInnerId.has(innerId))
10862
- byInnerId.set(innerId, located);
10863
- } catch {
10864
- }
10865
- }
10866
- idx.byInnerId = byInnerId;
10867
- return byInnerId;
10868
- }
10869
- function readHeadSync(path, bytes = 65536) {
10870
- const fd = openSync6(path, "r");
10871
- try {
10872
- const buf = Buffer.alloc(bytes);
10873
- const n = readSync6(fd, buf, 0, buf.length, 0);
10874
- return buf.toString("utf-8", 0, n);
10875
- } finally {
10876
- closeSync6(fd);
10877
- }
10878
- }
10879
- function readGeminiSessionIdFromFile(path, format) {
10880
- if (format === "json") {
10881
- try {
10882
- return JSON.parse(readFileSync10(path, "utf-8"))?.sessionId ?? null;
10883
- } catch {
10884
- return null;
10885
- }
10886
- }
10887
- try {
10888
- const head = readHeadSync(path).split("\n", 1)[0] || "";
10889
- return JSON.parse(head)?.sessionId ?? null;
10890
- } catch {
10891
- return null;
10892
- }
10893
- }
10894
- function readGeminiMessages(path, format) {
10895
- if (format === "json") {
10896
- try {
10897
- const json = JSON.parse(readFileSync10(path, "utf-8"));
10898
- return Array.isArray(json.messages) ? json.messages : [];
10899
- } catch {
10900
- return [];
10901
- }
10902
- }
10903
- const out = [];
10904
- let raw;
10905
- try {
10906
- raw = readFileSync10(path, "utf-8");
10907
- } catch {
10908
- return out;
10909
- }
10910
- let isFirst = true;
10911
- for (const line of raw.split("\n")) {
10912
- if (!line.trim())
10913
- continue;
10914
- if (isFirst) {
10915
- isFirst = false;
10916
- continue;
10917
- }
10918
- if (line.length > MAX_EVENT_LINE_BYTES)
10919
- continue;
10920
- let obj;
10921
- try {
10922
- obj = JSON.parse(line);
10923
- } catch {
10924
- continue;
10925
- }
10926
- if (!obj || typeof obj !== "object")
10927
- continue;
10928
- if (!obj.type)
10929
- continue;
10930
- out.push(obj);
10931
- }
10932
- return out;
10933
- }
10934
10345
  function findCodexSessionFile(sessionId) {
10935
10346
  for (const root of codexSessionDirs()) {
10936
10347
  const found = findCodexSessionFileIn(root, sessionId);
@@ -10940,23 +10351,23 @@ function findCodexSessionFile(sessionId) {
10940
10351
  return null;
10941
10352
  }
10942
10353
  function findCodexSessionFileIn(root, sessionId) {
10943
- if (!existsSync14(root))
10354
+ if (!existsSync13(root))
10944
10355
  return null;
10945
- for (const year of readdirSync11(root, { withFileTypes: true })) {
10356
+ for (const year of readdirSync10(root, { withFileTypes: true })) {
10946
10357
  if (!year.isDirectory())
10947
10358
  continue;
10948
- const yearPath = join14(root, year.name);
10949
- for (const month of readdirSync11(yearPath, { withFileTypes: true })) {
10359
+ const yearPath = join13(root, year.name);
10360
+ for (const month of readdirSync10(yearPath, { withFileTypes: true })) {
10950
10361
  if (!month.isDirectory())
10951
10362
  continue;
10952
- const monthPath = join14(yearPath, month.name);
10953
- for (const day of readdirSync11(monthPath, { withFileTypes: true })) {
10363
+ const monthPath = join13(yearPath, month.name);
10364
+ for (const day of readdirSync10(monthPath, { withFileTypes: true })) {
10954
10365
  if (!day.isDirectory())
10955
10366
  continue;
10956
- const dayPath = join14(monthPath, day.name);
10367
+ const dayPath = join13(monthPath, day.name);
10957
10368
  let files;
10958
10369
  try {
10959
- files = readdirSync11(dayPath);
10370
+ files = readdirSync10(dayPath);
10960
10371
  } catch {
10961
10372
  continue;
10962
10373
  }
@@ -10964,22 +10375,22 @@ function findCodexSessionFileIn(root, sessionId) {
10964
10375
  if (!f.endsWith(".jsonl"))
10965
10376
  continue;
10966
10377
  if (f.includes(sessionId)) {
10967
- return { path: join14(dayPath, f), projectPath: "" };
10378
+ return { path: join13(dayPath, f), projectPath: "" };
10968
10379
  }
10969
10380
  }
10970
10381
  }
10971
10382
  }
10972
10383
  }
10973
10384
  function scanDir(dir) {
10974
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
10385
+ for (const entry of readdirSync10(dir, { withFileTypes: true })) {
10975
10386
  if (entry.isDirectory()) {
10976
- const found = scanDir(join14(dir, entry.name));
10387
+ const found = scanDir(join13(dir, entry.name));
10977
10388
  if (found)
10978
10389
  return found;
10979
10390
  } else if (entry.name.endsWith(".jsonl")) {
10980
- const p = join14(dir, entry.name);
10391
+ const p = join13(dir, entry.name);
10981
10392
  try {
10982
- const first = readFileSync10(p, "utf-8").split("\n")[0];
10393
+ const first = readFileSync9(p, "utf-8").split("\n")[0];
10983
10394
  if (!first)
10984
10395
  continue;
10985
10396
  const meta = JSON.parse(first);
@@ -10994,7 +10405,7 @@ function findCodexSessionFileIn(root, sessionId) {
10994
10405
  }
10995
10406
  return scanDir(root);
10996
10407
  }
10997
- var scanScopeDepth, indexCache, readScope, readScopeDepth, geminiProjectMapCache, geminiCache, MAX_EVENT_LINE_BYTES;
10408
+ var scanScopeDepth, indexCache, readScope, readScopeDepth, MAX_EVENT_LINE_BYTES;
10998
10409
  var init_live_session_scan = __esm({
10999
10410
  "../engine/dist/core/live-session-scan.js"() {
11000
10411
  "use strict";
@@ -11008,8 +10419,6 @@ var init_live_session_scan = __esm({
11008
10419
  indexCache = null;
11009
10420
  readScope = null;
11010
10421
  readScopeDepth = 0;
11011
- geminiProjectMapCache = null;
11012
- geminiCache = null;
11013
10422
  MAX_EVENT_LINE_BYTES = 8 * 1024 * 1024;
11014
10423
  }
11015
10424
  });