mcp-agents-memory 0.9.18 → 0.9.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -1675,15 +1675,15 @@ var require_pg_connection_string = __commonJS({
1675
1675
  if (config2.sslcert || config2.sslkey || config2.sslrootcert || config2.sslmode) {
1676
1676
  config2.ssl = {};
1677
1677
  }
1678
- const fs13 = config2.sslcert || config2.sslkey || config2.sslrootcert ? __require("fs") : null;
1678
+ const fs14 = config2.sslcert || config2.sslkey || config2.sslrootcert ? __require("fs") : null;
1679
1679
  if (config2.sslcert) {
1680
- config2.ssl.cert = fs13.readFileSync(config2.sslcert).toString();
1680
+ config2.ssl.cert = fs14.readFileSync(config2.sslcert).toString();
1681
1681
  }
1682
1682
  if (config2.sslkey) {
1683
- config2.ssl.key = fs13.readFileSync(config2.sslkey).toString();
1683
+ config2.ssl.key = fs14.readFileSync(config2.sslkey).toString();
1684
1684
  }
1685
1685
  if (config2.sslrootcert) {
1686
- config2.ssl.ca = fs13.readFileSync(config2.sslrootcert).toString();
1686
+ config2.ssl.ca = fs14.readFileSync(config2.sslrootcert).toString();
1687
1687
  }
1688
1688
  if (options.useLibpqCompat && config2.uselibpqcompat) {
1689
1689
  throw new Error("Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.");
@@ -3620,15 +3620,15 @@ var require_lib = __commonJS({
3620
3620
  "../mcp-agents-memory/node_modules/pgpass/lib/index.js"(exports, module) {
3621
3621
  "use strict";
3622
3622
  var path13 = __require("path");
3623
- var fs13 = __require("fs");
3623
+ var fs14 = __require("fs");
3624
3624
  var helper = require_helper();
3625
3625
  module.exports = function(connInfo, cb) {
3626
3626
  var file = helper.getFileName();
3627
- fs13.stat(file, function(err3, stat) {
3627
+ fs14.stat(file, function(err3, stat) {
3628
3628
  if (err3 || !helper.usePgPass(stat, file)) {
3629
3629
  return cb(void 0);
3630
3630
  }
3631
- var st = fs13.createReadStream(file);
3631
+ var st = fs14.createReadStream(file);
3632
3632
  helper.getPassword(connInfo, st, cb);
3633
3633
  });
3634
3634
  };
@@ -18203,8 +18203,8 @@ var require_SFTP = __commonJS({
18203
18203
  "../mcp-agents-memory/node_modules/ssh2/lib/protocol/SFTP.js"(exports, module) {
18204
18204
  "use strict";
18205
18205
  var EventEmitter = __require("events");
18206
- var fs13 = __require("fs");
18207
- var { constants } = fs13;
18206
+ var fs14 = __require("fs");
18207
+ var { constants } = fs14;
18208
18208
  var {
18209
18209
  Readable: ReadableStream2,
18210
18210
  Writable: WritableStream
@@ -18633,12 +18633,12 @@ var require_SFTP = __commonJS({
18633
18633
  fastGet(remotePath, localPath, opts, cb) {
18634
18634
  if (this.server)
18635
18635
  throw new Error("Client-only method called in server mode");
18636
- fastXfer(this, fs13, remotePath, localPath, opts, cb);
18636
+ fastXfer(this, fs14, remotePath, localPath, opts, cb);
18637
18637
  }
18638
18638
  fastPut(localPath, remotePath, opts, cb) {
18639
18639
  if (this.server)
18640
18640
  throw new Error("Client-only method called in server mode");
18641
- fastXfer(fs13, this, localPath, remotePath, opts, cb);
18641
+ fastXfer(fs14, this, localPath, remotePath, opts, cb);
18642
18642
  }
18643
18643
  readFile(path13, options, callback_) {
18644
18644
  if (this.server)
@@ -19899,13 +19899,13 @@ var require_SFTP = __commonJS({
19899
19899
  if (--left === 0)
19900
19900
  cb(err3);
19901
19901
  };
19902
- if (srcHandle && (src === fs13 || src.outgoing.state === "open"))
19902
+ if (srcHandle && (src === fs14 || src.outgoing.state === "open"))
19903
19903
  ++left;
19904
- if (dstHandle && (dst === fs13 || dst.outgoing.state === "open"))
19904
+ if (dstHandle && (dst === fs14 || dst.outgoing.state === "open"))
19905
19905
  ++left;
19906
- if (srcHandle && (src === fs13 || src.outgoing.state === "open"))
19906
+ if (srcHandle && (src === fs14 || src.outgoing.state === "open"))
19907
19907
  src.close(srcHandle, cbfinal);
19908
- if (dstHandle && (dst === fs13 || dst.outgoing.state === "open"))
19908
+ if (dstHandle && (dst === fs14 || dst.outgoing.state === "open"))
19909
19909
  dst.close(dstHandle, cbfinal);
19910
19910
  } else {
19911
19911
  cb(err3);
@@ -19921,7 +19921,7 @@ var require_SFTP = __commonJS({
19921
19921
  tryStat(null, { size: fileSize });
19922
19922
  function tryStat(err4, attrs) {
19923
19923
  if (err4) {
19924
- if (src !== fs13) {
19924
+ if (src !== fs14) {
19925
19925
  src.stat(srcPath, (err_, attrs_) => {
19926
19926
  if (err_)
19927
19927
  return onerror(err4);
@@ -25485,7 +25485,7 @@ var require_package2 = __commonJS({
25485
25485
  // ../mcp-agents-memory/node_modules/dotenv/lib/main.js
25486
25486
  var require_main = __commonJS({
25487
25487
  "../mcp-agents-memory/node_modules/dotenv/lib/main.js"(exports, module) {
25488
- var fs13 = __require("fs");
25488
+ var fs14 = __require("fs");
25489
25489
  var path13 = __require("path");
25490
25490
  var os14 = __require("os");
25491
25491
  var crypto3 = __require("crypto");
@@ -25594,7 +25594,7 @@ var require_main = __commonJS({
25594
25594
  if (options && options.path && options.path.length > 0) {
25595
25595
  if (Array.isArray(options.path)) {
25596
25596
  for (const filepath of options.path) {
25597
- if (fs13.existsSync(filepath)) {
25597
+ if (fs14.existsSync(filepath)) {
25598
25598
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
25599
25599
  }
25600
25600
  }
@@ -25604,7 +25604,7 @@ var require_main = __commonJS({
25604
25604
  } else {
25605
25605
  possibleVaultPath = path13.resolve(process.cwd(), ".env.vault");
25606
25606
  }
25607
- if (fs13.existsSync(possibleVaultPath)) {
25607
+ if (fs14.existsSync(possibleVaultPath)) {
25608
25608
  return possibleVaultPath;
25609
25609
  }
25610
25610
  return null;
@@ -25653,7 +25653,7 @@ var require_main = __commonJS({
25653
25653
  const parsedAll = {};
25654
25654
  for (const path14 of optionPaths) {
25655
25655
  try {
25656
- const parsed = DotenvModule.parse(fs13.readFileSync(path14, { encoding }));
25656
+ const parsed = DotenvModule.parse(fs14.readFileSync(path14, { encoding }));
25657
25657
  DotenvModule.populate(parsedAll, parsed, options);
25658
25658
  } catch (e) {
25659
25659
  if (debug) {
@@ -32726,12 +32726,12 @@ var require_dist2 = __commonJS({
32726
32726
  throw new Error(`Unknown format "${name}"`);
32727
32727
  return f;
32728
32728
  };
32729
- function addFormats(ajv, list, fs13, exportName) {
32729
+ function addFormats(ajv, list, fs14, exportName) {
32730
32730
  var _a3;
32731
32731
  var _b;
32732
32732
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
32733
32733
  for (const f of list)
32734
- ajv.addFormat(f, fs13[f]);
32734
+ ajv.addFormat(f, fs14[f]);
32735
32735
  }
32736
32736
  module.exports = exports = formatsPlugin;
32737
32737
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -32770,12 +32770,12 @@ __export(runner_exports, {
32770
32770
  runAllMigrations: () => runAllMigrations
32771
32771
  });
32772
32772
  import { spawn } from "child_process";
32773
- import fs11 from "fs";
32773
+ import fs12 from "fs";
32774
32774
  import path12 from "path";
32775
32775
  import { fileURLToPath as fileURLToPath4 } from "url";
32776
32776
  function listMigrationFiles() {
32777
- if (!fs11.existsSync(migrationsDir)) return [];
32778
- return fs11.readdirSync(migrationsDir).filter((f) => MIGRATION_FILE_RE.test(f)).sort();
32777
+ if (!fs12.existsSync(migrationsDir)) return [];
32778
+ return fs12.readdirSync(migrationsDir).filter((f) => MIGRATION_FILE_RE.test(f)).sort();
32779
32779
  }
32780
32780
  function runOne(file) {
32781
32781
  return new Promise((resolve, reject) => {
@@ -32808,7 +32808,7 @@ var init_runner = __esm({
32808
32808
  "src/migrations/runner.ts"() {
32809
32809
  "use strict";
32810
32810
  __dirname4 = path12.dirname(fileURLToPath4(import.meta.url));
32811
- migrationsDir = fs11.existsSync(path12.join(__dirname4, "migrations")) ? path12.join(__dirname4, "migrations") : __dirname4;
32811
+ migrationsDir = fs12.existsSync(path12.join(__dirname4, "migrations")) ? path12.join(__dirname4, "migrations") : __dirname4;
32812
32812
  MIGRATION_FILE_RE = /^\d{3}_.+\.js$/;
32813
32813
  }
32814
32814
  });
@@ -47049,22 +47049,28 @@ function skipWhitespace(s, i) {
47049
47049
  while (i < s.length && /\s/.test(s[i])) i++;
47050
47050
  return i;
47051
47051
  }
47052
+ function locateBuzzContext(text) {
47053
+ if (!text.startsWith("<base>")) return CONTEXT_OPEN.test(text.slice(0, 12)) ? { rest: text, pos: 0 } : null;
47054
+ const baseEnd = text.indexOf("</base>");
47055
+ if (baseEnd < 0) return null;
47056
+ const rest = text.slice(baseEnd + "</base>".length);
47057
+ let pos = skipWhitespace(rest, 0);
47058
+ for (; ; ) {
47059
+ const name = PREAMBLE_BLOCKS.find((b) => rest.startsWith(`<${b}>`, pos));
47060
+ if (!name) break;
47061
+ const close = rest.indexOf(`</${name}>`, pos);
47062
+ if (close < 0) return null;
47063
+ pos = skipWhitespace(rest, close + name.length + 3);
47064
+ }
47065
+ return CONTEXT_OPEN.test(rest.slice(pos, pos + 12)) ? { rest, pos } : null;
47066
+ }
47052
47067
  function cleanBuzzEnvelope(message) {
47053
47068
  try {
47054
47069
  const text = message.trimStart();
47055
47070
  if (!text.startsWith("<base>")) return null;
47056
- const baseEnd = text.indexOf("</base>");
47057
- if (baseEnd < 0) return null;
47058
- const rest = text.slice(baseEnd + "</base>".length);
47059
- let pos = skipWhitespace(rest, 0);
47060
- for (; ; ) {
47061
- const name = PREAMBLE_BLOCKS.find((b) => rest.startsWith(`<${b}>`, pos));
47062
- if (!name) break;
47063
- const close = rest.indexOf(`</${name}>`, pos);
47064
- if (close < 0) return null;
47065
- pos = skipWhitespace(rest, close + name.length + 3);
47066
- }
47067
- if (!CONTEXT_OPEN.test(rest.slice(pos, pos + 12))) return null;
47071
+ const loc = locateBuzzContext(text);
47072
+ if (!loc) return null;
47073
+ const { rest, pos } = loc;
47068
47074
  const bodyStart = rest.indexOf("\n", pos) + 1;
47069
47075
  const contextClose = rest.indexOf(CONTEXT_CLOSE, bodyStart - 1);
47070
47076
  if (contextClose < 0) return null;
@@ -47113,9 +47119,90 @@ function buzzEmbeddingText(message) {
47113
47119
  return message;
47114
47120
  }
47115
47121
  }
47122
+ function venueFromBuzzContext(message) {
47123
+ if (!CONTEXT_OPEN.test(message.slice(0, 12))) return null;
47124
+ const end = message.indexOf(CONTEXT_CLOSE);
47125
+ if (end < 0) return null;
47126
+ const lines = message.slice(0, end).split("\n").map((l) => l.replace(/\r$/, ""));
47127
+ const scope = lines.find((l) => l.startsWith("Scope: "))?.slice("Scope: ".length).trim();
47128
+ if (scope !== "thread" && scope !== "channel" && scope !== "dm") return null;
47129
+ if (scope === "dm") return "buzz:dm";
47130
+ const channel = lines.find((l) => l.startsWith("Channel: "))?.trimEnd();
47131
+ const m = channel ? /^Channel: (.+?) \(#[0-9a-f-]{36}\)$/.exec(channel) : null;
47132
+ return m ? `buzz:${m[1]}` : "buzz";
47133
+ }
47134
+ function looksLikeBuzzTurn(message) {
47135
+ const text = message.trimStart();
47136
+ if (text.startsWith("<base>")) return true;
47137
+ if (!CONTEXT_OPEN.test(text.slice(0, 12))) return false;
47138
+ const close = text.indexOf(CONTEXT_CLOSE);
47139
+ return close >= 0 && TURN_OPEN.test(text.slice(close + CONTEXT_CLOSE.length));
47140
+ }
47141
+ function venueFromBuzzMessage(message) {
47142
+ try {
47143
+ const loc = locateBuzzContext(message.trimStart());
47144
+ return loc ? venueFromBuzzContext(loc.rest.slice(loc.pos)) : null;
47145
+ } catch {
47146
+ return null;
47147
+ }
47148
+ }
47149
+
47150
+ // src/auto_save/venue.ts
47151
+ import fs2 from "fs";
47152
+ var INTERACTIVE_ENTRYPOINTS = /* @__PURE__ */ new Set(["cli", "claude-vscode"]);
47153
+ function classifySessionVenue(firstUserText, entrypoint) {
47154
+ if (buzzTurnVenue(firstUserText)) return "buzz";
47155
+ if (entrypoint && INTERACTIVE_ENTRYPOINTS.has(entrypoint)) return "terminal";
47156
+ if (/\bslack\b/i.test(firstUserText.slice(0, 500))) return "slack";
47157
+ if (entrypoint) return "auto";
47158
+ return null;
47159
+ }
47160
+ function buzzTurnVenue(message) {
47161
+ return venueFromBuzzMessage(message) ?? (looksLikeBuzzTurn(message) ? "buzz" : null);
47162
+ }
47163
+ var TAIL_CHUNK = 4 * 1024 * 1024;
47164
+ var TAIL_CAP = 64 * 1024 * 1024;
47165
+ var NEWLINE = 10;
47166
+ function lastBuzzVenueInFile(jsonlPath, uptoBytes, userText) {
47167
+ const fd = fs2.openSync(jsonlPath, "r");
47168
+ try {
47169
+ let end = uptoBytes;
47170
+ let carry = Buffer.alloc(0);
47171
+ while (end > 0 && uptoBytes - end < TAIL_CAP) {
47172
+ const start = Math.max(0, end - TAIL_CHUNK);
47173
+ const chunk = Buffer.allocUnsafe(end - start);
47174
+ fs2.readSync(fd, chunk, 0, chunk.length, start);
47175
+ const buf = carry.length ? Buffer.concat([chunk, carry]) : chunk;
47176
+ const firstNl = start > 0 ? buf.indexOf(NEWLINE) : -1;
47177
+ carry = firstNl >= 0 ? buf.subarray(0, firstNl) : start > 0 ? buf : Buffer.alloc(0);
47178
+ const whole = firstNl >= 0 ? buf.subarray(firstNl + 1) : start > 0 ? Buffer.alloc(0) : buf;
47179
+ const lines = whole.toString("utf-8").split("\n");
47180
+ for (let i = lines.length - 1; i >= 0; i--) {
47181
+ const text = lines[i] ? userText(lines[i]) : null;
47182
+ const venue = text ? buzzTurnVenue(text) : null;
47183
+ if (venue) return venue;
47184
+ }
47185
+ end = start;
47186
+ }
47187
+ return null;
47188
+ } finally {
47189
+ fs2.closeSync(fd);
47190
+ }
47191
+ }
47116
47192
 
47117
47193
  // src/hot_path.ts
47118
- var rawMessageColumnMissing = false;
47194
+ var missingColumns = /* @__PURE__ */ new Set();
47195
+ var MISSING_COLUMN_EFFECT = {
47196
+ raw_message: "Buzz \uBD09\uD22C \uC815\uB9AC\uAC00 \uC2DC\uC791\uB429\uB2C8\uB2E4. \uADF8 \uC804\uAE4C\uC9C0\uB294 \uC6D0\uBB38 \uADF8\uB300\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4.",
47197
+ venue: "\uB300\uD654 \uC790\uB9AC(venue) \uAE30\uB85D\uC774 \uC2DC\uC791\uB429\uB2C8\uB2E4. \uADF8 \uC804\uAE4C\uC9C0\uB294 venue \uC5C6\uC774 \uC800\uC7A5\uD569\uB2C8\uB2E4."
47198
+ };
47199
+ function missingOptionalColumn(err3, sql, cols) {
47200
+ const e = err3;
47201
+ if (e.code !== "42703") return void 0;
47202
+ const at = Number(e.position);
47203
+ const named = at > 0 ? /^[a-z_]+/.exec(sql.slice(at - 1))?.[0] : void 0;
47204
+ return cols.find(([c]) => named ? c === named : !!e.message?.includes(c))?.[0];
47205
+ }
47119
47206
  async function insertRawMemory(params) {
47120
47207
  const {
47121
47208
  user_id,
@@ -47136,26 +47223,31 @@ async function insertRawMemory(params) {
47136
47223
  const embeddingSql = embedding && embedding.length > 0 ? `[${embedding.join(",")}]` : null;
47137
47224
  const tagProcessed = p_tag_id !== null;
47138
47225
  const cleaned = role === "user" && !is_pinned && p_tag_id === null && embeddingSql === null ? cleanBuzzEnvelope(message) : null;
47139
- const insert = (text, raw) => db.query(
47140
- `INSERT INTO memory (
47226
+ const venue = params.venue ?? (role === "user" ? buzzTurnVenue(cleaned ?? message) : null);
47227
+ const optional2 = [];
47228
+ if (cleaned !== null) optional2.push(["raw_message", message]);
47229
+ if (venue) optional2.push(["venue", venue]);
47230
+ const buildInsert = (cols2) => {
47231
+ const text = cols2.some(([c]) => c === "raw_message") ? cleaned : message;
47232
+ const sql = `INSERT INTO memory (
47141
47233
  user_id, agent_platform, agent_model,
47142
47234
  subagent, subagent_model, subagent_role,
47143
47235
  role, message,
47144
47236
  p_tag_id, d_tag, embedding,
47145
47237
  is_pinned, tag_processed, external_uuid,
47146
- device_name${raw !== null ? ", raw_message" : ""}
47238
+ device_name${cols2.map(([c]) => `, ${c}`).join("")}
47147
47239
  ) VALUES (
47148
47240
  $1, $2, $3,
47149
47241
  $4, $5, $6,
47150
47242
  $7, $8,
47151
47243
  $9, $10::text[], $11::halfvec,
47152
47244
  $12, $13, $14,
47153
- $15${raw !== null ? ", $16" : ""}
47245
+ $15${cols2.map((_, i) => `, $${16 + i}`).join("")}
47154
47246
  )
47155
47247
  ON CONFLICT (external_uuid) WHERE external_uuid IS NOT NULL
47156
47248
  DO NOTHING
47157
- RETURNING id, created_at`,
47158
- [
47249
+ RETURNING id, created_at`;
47250
+ const values = [
47159
47251
  user_id,
47160
47252
  agent_platform,
47161
47253
  agent_model,
@@ -47171,24 +47263,26 @@ async function insertRawMemory(params) {
47171
47263
  tagProcessed,
47172
47264
  external_uuid,
47173
47265
  device_name,
47174
- ...raw !== null ? [raw] : []
47175
- ]
47176
- );
47266
+ ...cols2.map(([, v]) => v)
47267
+ ];
47268
+ return { sql, values };
47269
+ };
47270
+ let cols = optional2.filter(([c]) => !missingColumns.has(c));
47177
47271
  let result;
47178
- if (cleaned !== null && !rawMessageColumnMissing) {
47272
+ for (; ; ) {
47273
+ const { sql, values } = buildInsert(cols);
47179
47274
  try {
47180
- result = await insert(cleaned, message);
47275
+ result = await db.query(sql, values);
47276
+ break;
47181
47277
  } catch (err3) {
47182
- const e = err3;
47183
- if (e.code !== "42703" || !e.message?.includes("raw_message")) throw err3;
47184
- rawMessageColumnMissing = true;
47278
+ const missing = missingOptionalColumn(err3, sql, cols);
47279
+ if (!missing) throw err3;
47280
+ missingColumns.add(missing);
47185
47281
  console.error(
47186
- "\u26A0\uFE0F [HotPath] memory.raw_message \uCE78\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 `mcp-agents-memory migrate` \uC2E4\uD589 \uD6C4 \uC774 \uD504\uB85C\uC138\uC2A4\uB97C \uC7AC\uC2DC\uC791\uD574\uC57C Buzz \uBD09\uD22C \uC815\uB9AC\uAC00 \uC2DC\uC791\uB429\uB2C8\uB2E4. \uADF8 \uC804\uAE4C\uC9C0\uB294 \uC6D0\uBB38 \uADF8\uB300\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4."
47282
+ `\u26A0\uFE0F [HotPath] memory.${missing} \uCE78\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \`mcp-agents-memory migrate\` \uC2E4\uD589 \uD6C4 \uC774 \uD504\uB85C\uC138\uC2A4\uB97C \uC7AC\uC2DC\uC791\uD574\uC57C ${MISSING_COLUMN_EFFECT[missing]}`
47187
47283
  );
47188
- result = await insert(message, null);
47284
+ cols = cols.filter(([c]) => c !== missing);
47189
47285
  }
47190
- } else {
47191
- result = await insert(message, null);
47192
47286
  }
47193
47287
  if (result.rows.length === 0) {
47194
47288
  const existing = await db.query(
@@ -55635,7 +55729,7 @@ async function generateEmbedding(text) {
55635
55729
  init_db();
55636
55730
 
55637
55731
  // src/cold_path/jev_judge.ts
55638
- import fs2 from "fs";
55732
+ import fs3 from "fs";
55639
55733
  var API_URL = "https://api.typesafe.ai/v1/systemone";
55640
55734
  var MODEL = "jev-latest";
55641
55735
  var TYPESAFE_KEY_PATH = "/home/admin_3alab/.config/typesafe/api_key";
@@ -55661,7 +55755,7 @@ function loadJevApiKey() {
55661
55755
  const fromEnv = process.env.TYPESAFE_API_KEY?.trim();
55662
55756
  if (fromEnv) return fromEnv;
55663
55757
  try {
55664
- return fs2.readFileSync(TYPESAFE_KEY_PATH, "utf8").trim() || null;
55758
+ return fs3.readFileSync(TYPESAFE_KEY_PATH, "utf8").trim() || null;
55665
55759
  } catch {
55666
55760
  return null;
55667
55761
  }
@@ -55995,7 +56089,7 @@ async function tagMessage(input) {
55995
56089
  }
55996
56090
 
55997
56091
  // src/auto_save/opencode_capture.ts
55998
- import * as fs3 from "node:fs";
56092
+ import * as fs4 from "node:fs";
55999
56093
  import * as path4 from "node:path";
56000
56094
  import * as os2 from "node:os";
56001
56095
  var DEVICE_NAME = os2.hostname();
@@ -56191,7 +56285,7 @@ async function captureSessionStart(_cwd) {
56191
56285
  _state = null;
56192
56286
  _consecutiveFailures = 0;
56193
56287
  const dbPath = resolveDbPath();
56194
- if (!dbPath || !fs3.existsSync(dbPath)) return;
56288
+ if (!dbPath || !fs4.existsSync(dbPath)) return;
56195
56289
  const DatabaseSync = await loadSqlite();
56196
56290
  if (!DatabaseSync) {
56197
56291
  console.error(
@@ -56590,6 +56684,30 @@ function vectorToHalfvecSql(embedding) {
56590
56684
 
56591
56685
  // src/tools/search_memory.ts
56592
56686
  import os4 from "node:os";
56687
+
56688
+ // src/memory_columns.ts
56689
+ init_db();
56690
+ var cache2 = /* @__PURE__ */ new Map();
56691
+ async function hasMemoryColumn(column) {
56692
+ const c = cache2.get(column);
56693
+ if (c && (c.exists || Date.now() - c.checkedAt < 5 * 60 * 1e3)) return c.exists;
56694
+ let exists = false;
56695
+ try {
56696
+ const r = await db.query(
56697
+ // 쿼리가 search_path로 찾는 바로 그 memory 테이블 기준
56698
+ `SELECT 1 FROM pg_attribute
56699
+ WHERE attrelid = to_regclass('memory') AND attname = $1 AND NOT attisdropped LIMIT 1`,
56700
+ [column]
56701
+ );
56702
+ exists = r.rows.length > 0;
56703
+ } catch {
56704
+ exists = false;
56705
+ }
56706
+ cache2.set(column, { exists, checkedAt: Date.now() });
56707
+ return exists;
56708
+ }
56709
+
56710
+ // src/tools/search_memory.ts
56593
56711
  var DEFAULT_LIMIT = 10;
56594
56712
  var DEFAULT_FALLBACK_THRESHOLD = 0.3;
56595
56713
  function parseDateRange(s) {
@@ -56664,7 +56782,10 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56664
56782
  "\uAE30\uAE30 \uD55C\uC815. 'global'(\uAE30\uBCF8): \uC804 \uAE30\uAE30 \uAC80\uC0C9(\uB113\uAC8C). 'local': \uD604\uC7AC \uAE30\uAE30(hostname)\uB85C \uD55C\uC815(\uC774\uC5B4\uBC1B\uAE30\uC6A9, \uC881\uAC8C). zero-config \u2014 \uC11C\uBC84\uAC00 hostname \uC790\uB3D9 \uD574\uC11D."
56665
56783
  ),
56666
56784
  limit: external_exports.number().int().min(1).max(50).optional().describe(`\uCD5C\uB300 \uACB0\uACFC \uC218 (default ${DEFAULT_LIMIT})`),
56667
- include_archived: external_exports.boolean().optional().describe("archived \uBA54\uBAA8\uB9AC\uB3C4 \uD3EC\uD568 (default false)")
56785
+ include_archived: external_exports.boolean().optional().describe("archived \uBA54\uBAA8\uB9AC\uB3C4 \uD3EC\uD568 (default false)"),
56786
+ venue: external_exports.string().optional().describe(
56787
+ "\uB300\uD654\uAC00 \uC624\uAC04 \uC790\uB9AC\uB85C \uD55C\uC815. 'buzz'(\uBC84\uC988 \uC804\uCCB4) / 'buzz:<\uCC44\uB110>'(\uADF8 \uCC44\uB110, \uC608: buzz:DevRoom) / 'buzz:dm' / 'terminal'(\uC0AC\uB78C\uACFC 1:1) / 'slack' / 'auto'. \uACB0\uACFC\uB9C8\uB2E4 venue\uAC00 \uBD99\uC5B4 \uB098\uC628\uB2E4."
56788
+ )
56668
56789
  }
56669
56790
  },
56670
56791
  async (args) => {
@@ -56717,6 +56838,13 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56717
56838
  filters.push(`(m.device_name = $${p++} OR m.is_pinned = TRUE)`);
56718
56839
  params.push(localDevice);
56719
56840
  }
56841
+ const withVenue = await hasMemoryColumn("venue");
56842
+ const venueSel = withVenue ? ", m.venue" : "";
56843
+ const venueFilter = (n) => args.venue.includes(":") ? `lower(m.venue) = lower($${n})` : `(lower(m.venue) = lower($${n}) OR lower(m.venue) LIKE lower($${n}) || ':%')`;
56844
+ if (args.venue && withVenue) {
56845
+ filters.push(venueFilter(p++));
56846
+ params.push(args.venue);
56847
+ }
56720
56848
  const whereSql = filters.join(" AND ");
56721
56849
  let used = "recency";
56722
56850
  let topSimilarity = void 0;
@@ -56731,7 +56859,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56731
56859
  params.push(limit2);
56732
56860
  const r = await db.query(
56733
56861
  `SELECT m.id, m.role, m.message, m.agent_platform, m.agent_model, m.device_name,
56734
- pt.name AS p_tag_name, m.d_tag, m.is_pinned, m.created_at,
56862
+ pt.name AS p_tag_name, m.d_tag, m.is_pinned, m.created_at${venueSel},
56735
56863
  1 - (m.embedding <=> $${vecParam}::halfvec) AS similarity
56736
56864
  FROM memory m
56737
56865
  LEFT JOIN project_tags pt ON pt.id = canonical_project_tag_id(m.p_tag_id)
@@ -56752,6 +56880,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56752
56880
  d_tag: row.d_tag ?? [],
56753
56881
  is_pinned: row.is_pinned,
56754
56882
  created_at: row.created_at,
56883
+ venue: row.venue ?? null,
56755
56884
  similarity: Number(row.similarity)
56756
56885
  }));
56757
56886
  if (rows.length > 0) {
@@ -56787,12 +56916,16 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56787
56916
  ilikeFilters.push(`(m.device_name = $${q++} OR m.is_pinned = TRUE)`);
56788
56917
  ilikeParams.push(localDevice);
56789
56918
  }
56919
+ if (args.venue && withVenue) {
56920
+ ilikeFilters.push(venueFilter(q++));
56921
+ ilikeParams.push(args.venue);
56922
+ }
56790
56923
  ilikeFilters.push(`m.message ILIKE $${q++}`);
56791
56924
  ilikeParams.push(`%${args.query}%`);
56792
56925
  ilikeParams.push(limit2);
56793
56926
  const r = await db.query(
56794
56927
  `SELECT m.id, m.role, m.message, m.agent_platform, m.agent_model, m.device_name,
56795
- pt.name AS p_tag_name, m.d_tag, m.is_pinned, m.created_at
56928
+ pt.name AS p_tag_name, m.d_tag, m.is_pinned, m.created_at${venueSel}
56796
56929
  FROM memory m
56797
56930
  LEFT JOIN project_tags pt ON pt.id = canonical_project_tag_id(m.p_tag_id)
56798
56931
  WHERE ${ilikeFilters.join(" AND ")}
@@ -56811,7 +56944,8 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56811
56944
  p_tag_name: row.p_tag_name,
56812
56945
  d_tag: row.d_tag ?? [],
56813
56946
  is_pinned: row.is_pinned,
56814
- created_at: row.created_at
56947
+ created_at: row.created_at,
56948
+ venue: row.venue ?? null
56815
56949
  }));
56816
56950
  used = "ilike";
56817
56951
  topSimilarity = void 0;
@@ -56821,7 +56955,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56821
56955
  params.push(limit2);
56822
56956
  const r = await db.query(
56823
56957
  `SELECT m.id, m.role, m.message, m.agent_platform, m.agent_model, m.device_name,
56824
- pt.name AS p_tag_name, m.d_tag, m.is_pinned, m.created_at
56958
+ pt.name AS p_tag_name, m.d_tag, m.is_pinned, m.created_at${venueSel}
56825
56959
  FROM memory m
56826
56960
  LEFT JOIN project_tags pt ON pt.id = canonical_project_tag_id(m.p_tag_id)
56827
56961
  WHERE ${whereSql}
@@ -56839,7 +56973,8 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56839
56973
  p_tag_name: row.p_tag_name,
56840
56974
  d_tag: row.d_tag ?? [],
56841
56975
  is_pinned: row.is_pinned,
56842
- created_at: row.created_at
56976
+ created_at: row.created_at,
56977
+ venue: row.venue ?? null
56843
56978
  }));
56844
56979
  used = "recency";
56845
56980
  }
@@ -56851,6 +56986,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
56851
56986
  threshold: used === "ilike" ? threshold : void 0,
56852
56987
  top_similarity: topSimilarity,
56853
56988
  count: rows.length,
56989
+ ...args.venue && !withVenue ? { note: "\uC774 DB\uC5D4 \uC544\uC9C1 venue \uCE78\uC774 \uC5C6\uC5B4(migration 029 \uC804) venue \uD544\uD130\uB97C \uC801\uC6A9\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4." } : {},
56854
56990
  results: rows
56855
56991
  }, null, 2)
56856
56992
  }]
@@ -58192,6 +58328,7 @@ var PINNED_LIMIT = 10;
58192
58328
  var INJECT_PINNED_LIMIT = 5;
58193
58329
  var BRIEF_MAX_CHARS = Number(process.env.BRIEF_MAX_CHARS ?? 8e3);
58194
58330
  async function collectBrief(opts = {}) {
58331
+ const venueSel = await hasMemoryColumn("venue") ? ", venue" : "";
58195
58332
  const userId = opts.userId ?? await getDefaultUserId();
58196
58333
  const shortTermDays = opts.shortTermDays ?? Number(process.env.SHORT_TERM_DAYS ?? 3);
58197
58334
  const currentPlatform = opts.currentPlatform ?? null;
@@ -58202,7 +58339,7 @@ async function collectBrief(opts = {}) {
58202
58339
  );
58203
58340
  const user = u.rows[0] ?? { user_name: "unknown", core_profile: null, sub_profile: null };
58204
58341
  const pinnedMsgs = await db.query(
58205
- `SELECT role, agent_platform, device_name, message, created_at
58342
+ `SELECT role, agent_platform, device_name, message, created_at${venueSel}
58206
58343
  FROM memory
58207
58344
  WHERE user_id = $1
58208
58345
  AND is_active = TRUE
@@ -58230,7 +58367,7 @@ async function collectBrief(opts = {}) {
58230
58367
  let recentOthers = [];
58231
58368
  if (currentPlatform) {
58232
58369
  const currentMsgs = await db.query(
58233
- `SELECT role, agent_platform, device_name, message, created_at
58370
+ `SELECT role, agent_platform, device_name, message, created_at${venueSel}
58234
58371
  FROM memory
58235
58372
  WHERE user_id = $1
58236
58373
  AND is_active = TRUE
@@ -58245,7 +58382,7 @@ async function collectBrief(opts = {}) {
58245
58382
  );
58246
58383
  recentCurrent = currentMsgs.rows.reverse().map(rowToMsg);
58247
58384
  const othersMsgs = await db.query(
58248
- `SELECT role, agent_platform, device_name, message, created_at
58385
+ `SELECT role, agent_platform, device_name, message, created_at${venueSel}
58249
58386
  FROM memory
58250
58387
  WHERE user_id = $1
58251
58388
  AND is_active = TRUE
@@ -58260,7 +58397,7 @@ async function collectBrief(opts = {}) {
58260
58397
  recentOthers = othersMsgs.rows.reverse().map(rowToMsg);
58261
58398
  } else {
58262
58399
  const msgs = await db.query(
58263
- `SELECT role, agent_platform, device_name, message, created_at
58400
+ `SELECT role, agent_platform, device_name, message, created_at${venueSel}
58264
58401
  FROM memory
58265
58402
  WHERE user_id = $1
58266
58403
  AND is_active = TRUE
@@ -58307,11 +58444,15 @@ async function collectBrief(opts = {}) {
58307
58444
  };
58308
58445
  }
58309
58446
  function rowToMsg(r) {
58447
+ const raw = String(r.message ?? "");
58448
+ const buzz = buzzEmbeddingText(raw);
58449
+ const text = buzz === raw ? raw : buzz.split("\n").filter((l) => !/^<\/?[a-z-]+(\s[^>]*)?>\s*$/.test(l)).join(" ").replace(/\s+/g, " ").trim();
58310
58450
  return {
58311
58451
  role: r.role,
58312
58452
  agent_platform: r.agent_platform,
58313
58453
  device_name: r.device_name ?? null,
58314
- preview: String(r.message ?? "").slice(0, MAX_PREVIEW_STORE),
58454
+ venue: r.venue ?? null,
58455
+ preview: text.slice(0, MAX_PREVIEW_STORE),
58315
58456
  created_at: r.created_at
58316
58457
  };
58317
58458
  }
@@ -58441,7 +58582,8 @@ function fitSection(heading, lines, budget) {
58441
58582
  function formatMsgLine(m, showPlatform, maxPreview = PREVIEW_COMPACT) {
58442
58583
  const dt = m.created_at?.toISOString?.().slice(11, 16) ?? "";
58443
58584
  const device = m.device_name ? `@${m.device_name} ` : "";
58444
- const platformTag = showPlatform ? `${m.agent_platform} ${device}` : device;
58585
+ const venue = m.venue ? `${m.venue} ` : "";
58586
+ const platformTag = (showPlatform ? `${m.agent_platform} ${device}` : device) + venue;
58445
58587
  const truncated = m.preview.length > maxPreview;
58446
58588
  const text = truncated ? m.preview.slice(0, maxPreview) : m.preview;
58447
58589
  return `- [${dt} ${platformTag}${m.role}] ${text}${truncated ? "\u2026" : ""}`;
@@ -58494,7 +58636,7 @@ agent_platform_filter=false.`,
58494
58636
  import * as os10 from "node:os";
58495
58637
 
58496
58638
  // src/auto_save/gemini_capture.ts
58497
- import * as fs4 from "node:fs";
58639
+ import * as fs5 from "node:fs";
58498
58640
  import * as path5 from "node:path";
58499
58641
  import * as os6 from "node:os";
58500
58642
  import * as crypto2 from "node:crypto";
@@ -58520,12 +58662,12 @@ function deriveChatsDirCandidates(cwd) {
58520
58662
  path5.join(GEMINI_TMP_ROOT, cwdHash, "chats"),
58521
58663
  path5.join(GEMINI_TMP_ROOT, path5.basename(cwd), "chats")
58522
58664
  ];
58523
- return candidates.filter((d) => fs4.existsSync(d));
58665
+ return candidates.filter((d) => fs5.existsSync(d));
58524
58666
  }
58525
58667
  async function readSessionFile(filePath) {
58526
58668
  for (let attempt = 0; attempt < 2; attempt++) {
58527
58669
  try {
58528
- const raw = fs4.readFileSync(filePath, "utf-8");
58670
+ const raw = fs5.readFileSync(filePath, "utf-8");
58529
58671
  if (!raw.trim()) return null;
58530
58672
  return JSON.parse(raw);
58531
58673
  } catch {
@@ -58615,23 +58757,23 @@ async function flushJsonFile(filePath, fileState, contentSeen) {
58615
58757
  return { inserted, skipped, dedup };
58616
58758
  }
58617
58759
  async function flushJsonlFile(filePath, fileState, contentSeen) {
58618
- if (!fs4.existsSync(filePath)) return { inserted: 0, skipped: 0, dedup: 0 };
58760
+ if (!fs5.existsSync(filePath)) return { inserted: 0, skipped: 0, dedup: 0 };
58619
58761
  let stat;
58620
58762
  try {
58621
- stat = fs4.statSync(filePath);
58763
+ stat = fs5.statSync(filePath);
58622
58764
  } catch {
58623
58765
  return { inserted: 0, skipped: 0, dedup: 0 };
58624
58766
  }
58625
58767
  if (stat.size <= fileState.cursor) return { inserted: 0, skipped: 0, dedup: 0 };
58626
58768
  const length = stat.size - fileState.cursor;
58627
- const fd = fs4.openSync(filePath, "r");
58769
+ const fd = fs5.openSync(filePath, "r");
58628
58770
  let raw;
58629
58771
  try {
58630
58772
  const buf = Buffer.alloc(length);
58631
- fs4.readSync(fd, buf, 0, length, fileState.cursor);
58773
+ fs5.readSync(fd, buf, 0, length, fileState.cursor);
58632
58774
  raw = buf.toString("utf-8");
58633
58775
  } finally {
58634
- fs4.closeSync(fd);
58776
+ fs5.closeSync(fd);
58635
58777
  }
58636
58778
  const lastNl = raw.lastIndexOf("\n");
58637
58779
  if (lastNl === -1) return { inserted: 0, skipped: 0, dedup: 0 };
@@ -58702,10 +58844,10 @@ async function flushAllFiles() {
58702
58844
  let totalI = 0, totalS = 0, totalD = 0;
58703
58845
  const contentSeen = /* @__PURE__ */ new Set();
58704
58846
  for (const dir of _state2.chatsDirs) {
58705
- if (!fs4.existsSync(dir)) continue;
58847
+ if (!fs5.existsSync(dir)) continue;
58706
58848
  let entries;
58707
58849
  try {
58708
- entries = fs4.readdirSync(dir, { withFileTypes: true });
58850
+ entries = fs5.readdirSync(dir, { withFileTypes: true });
58709
58851
  } catch {
58710
58852
  continue;
58711
58853
  }
@@ -58770,7 +58912,7 @@ function captureSessionStart2(cwd) {
58770
58912
  for (const dir of chatsDirs) {
58771
58913
  let entries;
58772
58914
  try {
58773
- entries = fs4.readdirSync(dir, { withFileTypes: true });
58915
+ entries = fs5.readdirSync(dir, { withFileTypes: true });
58774
58916
  } catch {
58775
58917
  continue;
58776
58918
  }
@@ -58786,21 +58928,21 @@ function captureSessionStart2(cwd) {
58786
58928
  if (format === "json") {
58787
58929
  let session = null;
58788
58930
  try {
58789
- session = JSON.parse(fs4.readFileSync(filePath, "utf-8"));
58931
+ session = JSON.parse(fs5.readFileSync(filePath, "utf-8"));
58790
58932
  } catch {
58791
58933
  }
58792
58934
  cursor = session && Array.isArray(session.messages) ? session.messages.length : 0;
58793
58935
  if (session?.sessionId) realSessionId = session.sessionId;
58794
58936
  } else {
58795
58937
  try {
58796
- cursor = fs4.statSync(filePath).size;
58938
+ cursor = fs5.statSync(filePath).size;
58797
58939
  } catch {
58798
58940
  }
58799
58941
  try {
58800
- const fd = fs4.openSync(filePath, "r");
58942
+ const fd = fs5.openSync(filePath, "r");
58801
58943
  const buf = Buffer.alloc(512);
58802
- const n = fs4.readSync(fd, buf, 0, 512, 0);
58803
- fs4.closeSync(fd);
58944
+ const n = fs5.readSync(fd, buf, 0, 512, 0);
58945
+ fs5.closeSync(fd);
58804
58946
  const firstLine = buf.slice(0, n).toString("utf-8").split("\n")[0].trim();
58805
58947
  const header = JSON.parse(firstLine);
58806
58948
  if (typeof header.sessionId === "string" && header.sessionId) {
@@ -58823,7 +58965,7 @@ function armDirWatchers() {
58823
58965
  if (_watchers.length > 0) return;
58824
58966
  for (const dir of _state2.chatsDirs) {
58825
58967
  try {
58826
- const w = fs4.watch(dir, (_evt, filename) => {
58968
+ const w = fs5.watch(dir, (_evt, filename) => {
58827
58969
  if (filename && !filename.endsWith(".json") && !filename.endsWith(".jsonl")) return;
58828
58970
  scheduleFlush();
58829
58971
  });
@@ -58878,7 +59020,7 @@ async function captureSessionEnd2() {
58878
59020
  }
58879
59021
 
58880
59022
  // src/auto_save/grok_capture.ts
58881
- import * as fs5 from "node:fs";
59023
+ import * as fs6 from "node:fs";
58882
59024
  import * as path6 from "node:path";
58883
59025
  import * as os7 from "node:os";
58884
59026
  var DEVICE_NAME4 = os7.hostname();
@@ -58899,7 +59041,7 @@ function extractSessionId(filePath) {
58899
59041
  }
58900
59042
  function countCompleteLines(filePath) {
58901
59043
  try {
58902
- const content = fs5.readFileSync(filePath, "utf-8");
59044
+ const content = fs6.readFileSync(filePath, "utf-8");
58903
59045
  let n = 0;
58904
59046
  for (let i = 0; i < content.length; i++) if (content[i] === "\n") n++;
58905
59047
  return n;
@@ -58908,13 +59050,13 @@ function countCompleteLines(filePath) {
58908
59050
  }
58909
59051
  }
58910
59052
  function* walkChatHistories(root) {
58911
- if (!fs5.existsSync(root)) return;
59053
+ if (!fs6.existsSync(root)) return;
58912
59054
  const stack = [root];
58913
59055
  while (stack.length) {
58914
59056
  const dir = stack.pop();
58915
59057
  let entries;
58916
59058
  try {
58917
- entries = fs5.readdirSync(dir, { withFileTypes: true });
59059
+ entries = fs6.readdirSync(dir, { withFileTypes: true });
58918
59060
  } catch {
58919
59061
  continue;
58920
59062
  }
@@ -58929,7 +59071,7 @@ function* walkChatHistories(root) {
58929
59071
  }
58930
59072
  }
58931
59073
  function captureSessionStart3(_cwd) {
58932
- const rootExists = fs5.existsSync(SESSIONS_ROOT);
59074
+ const rootExists = fs6.existsSync(SESSIONS_ROOT);
58933
59075
  _state3 = {
58934
59076
  rootExists,
58935
59077
  files: /* @__PURE__ */ new Map()
@@ -58941,7 +59083,7 @@ function captureSessionStart3(_cwd) {
58941
59083
  for (const filePath of walkChatHistories(SESSIONS_ROOT)) {
58942
59084
  let stat;
58943
59085
  try {
58944
- stat = fs5.statSync(filePath);
59086
+ stat = fs6.statSync(filePath);
58945
59087
  } catch {
58946
59088
  continue;
58947
59089
  }
@@ -58992,14 +59134,14 @@ function parseEntry(line, lineIndex) {
58992
59134
  async function flushDeltaForFile2(filePath, fileState) {
58993
59135
  let stat;
58994
59136
  try {
58995
- stat = fs5.statSync(filePath);
59137
+ stat = fs6.statSync(filePath);
58996
59138
  } catch {
58997
59139
  return { inserted: 0, skipped: 0, dedup: 0 };
58998
59140
  }
58999
59141
  if (stat.size === fileState.lastSize) return { inserted: 0, skipped: 0, dedup: 0 };
59000
59142
  let content;
59001
59143
  try {
59002
- content = fs5.readFileSync(filePath, "utf-8");
59144
+ content = fs6.readFileSync(filePath, "utf-8");
59003
59145
  } catch {
59004
59146
  return { inserted: 0, skipped: 0, dedup: 0 };
59005
59147
  }
@@ -59046,7 +59188,7 @@ async function flushAllFiles2() {
59046
59188
  if (!fileState) {
59047
59189
  let stat = null;
59048
59190
  try {
59049
- stat = fs5.statSync(filePath);
59191
+ stat = fs6.statSync(filePath);
59050
59192
  } catch {
59051
59193
  }
59052
59194
  const fileBirthMs = stat ? stat.birthtimeMs || stat.ctimeMs : SERVER_START_MS;
@@ -59106,7 +59248,7 @@ function armDirWatcher() {
59106
59248
  if (!_state3 || !_state3.rootExists) return;
59107
59249
  if (_watcher) return;
59108
59250
  try {
59109
- _watcher = fs5.watch(SESSIONS_ROOT, { recursive: true }, (_evt, filename) => {
59251
+ _watcher = fs6.watch(SESSIONS_ROOT, { recursive: true }, (_evt, filename) => {
59110
59252
  if (!filename) return;
59111
59253
  if (path6.basename(filename) !== CHAT_FILE) return;
59112
59254
  scheduleFlush2();
@@ -59161,7 +59303,7 @@ function isCaptureArmed3() {
59161
59303
  }
59162
59304
 
59163
59305
  // src/auto_save/antigravity_capture.ts
59164
- import * as fs6 from "node:fs";
59306
+ import * as fs7 from "node:fs";
59165
59307
  import * as path7 from "node:path";
59166
59308
  import * as os8 from "node:os";
59167
59309
  var DEVICE_NAME5 = os8.hostname();
@@ -59186,7 +59328,7 @@ function extractSid(filePath) {
59186
59328
  }
59187
59329
  function countCompleteLines2(filePath) {
59188
59330
  try {
59189
- const content = fs6.readFileSync(filePath, "utf-8");
59331
+ const content = fs7.readFileSync(filePath, "utf-8");
59190
59332
  let n = 0;
59191
59333
  for (let i = 0; i < content.length; i++) if (content[i] === "\n") n++;
59192
59334
  return n;
@@ -59195,13 +59337,13 @@ function countCompleteLines2(filePath) {
59195
59337
  }
59196
59338
  }
59197
59339
  function* walkTranscripts(root) {
59198
- if (!fs6.existsSync(root)) return;
59340
+ if (!fs7.existsSync(root)) return;
59199
59341
  const stack = [root];
59200
59342
  while (stack.length) {
59201
59343
  const dir = stack.pop();
59202
59344
  let entries;
59203
59345
  try {
59204
- entries = fs6.readdirSync(dir, { withFileTypes: true });
59346
+ entries = fs7.readdirSync(dir, { withFileTypes: true });
59205
59347
  } catch {
59206
59348
  continue;
59207
59349
  }
@@ -59223,7 +59365,7 @@ function* walkAllTranscripts() {
59223
59365
  }
59224
59366
  }
59225
59367
  function captureSessionStart4(_cwd) {
59226
- const rootExists = ROOTS.some((r) => fs6.existsSync(r.dir));
59368
+ const rootExists = ROOTS.some((r) => fs7.existsSync(r.dir));
59227
59369
  _state4 = {
59228
59370
  rootExists,
59229
59371
  files: /* @__PURE__ */ new Map()
@@ -59235,7 +59377,7 @@ function captureSessionStart4(_cwd) {
59235
59377
  for (const { filePath, platform } of walkAllTranscripts()) {
59236
59378
  let stat;
59237
59379
  try {
59238
- stat = fs6.statSync(filePath);
59380
+ stat = fs7.statSync(filePath);
59239
59381
  } catch {
59240
59382
  continue;
59241
59383
  }
@@ -59248,7 +59390,7 @@ function captureSessionStart4(_cwd) {
59248
59390
  });
59249
59391
  count++;
59250
59392
  }
59251
- const liveRoots = ROOTS.filter((r) => fs6.existsSync(r.dir)).map((r) => r.platform);
59393
+ const liveRoots = ROOTS.filter((r) => fs7.existsSync(r.dir)).map((r) => r.platform);
59252
59394
  console.error(`\u{1F4DD} [Antigravity] capture armed: ${count} transcript(s) across [${liveRoots.join(", ")}]`);
59253
59395
  armDirWatcher2();
59254
59396
  }
@@ -59286,14 +59428,14 @@ function parseEntry2(line) {
59286
59428
  async function flushDeltaForFile3(filePath, fileState) {
59287
59429
  let stat;
59288
59430
  try {
59289
- stat = fs6.statSync(filePath);
59431
+ stat = fs7.statSync(filePath);
59290
59432
  } catch {
59291
59433
  return { inserted: 0, skipped: 0, dedup: 0 };
59292
59434
  }
59293
59435
  if (stat.size === fileState.lastSize) return { inserted: 0, skipped: 0, dedup: 0 };
59294
59436
  let content;
59295
59437
  try {
59296
- content = fs6.readFileSync(filePath, "utf-8");
59438
+ content = fs7.readFileSync(filePath, "utf-8");
59297
59439
  } catch {
59298
59440
  return { inserted: 0, skipped: 0, dedup: 0 };
59299
59441
  }
@@ -59342,7 +59484,7 @@ async function flushAllFiles3() {
59342
59484
  if (!fileState) {
59343
59485
  let stat = null;
59344
59486
  try {
59345
- stat = fs6.statSync(filePath);
59487
+ stat = fs7.statSync(filePath);
59346
59488
  } catch {
59347
59489
  }
59348
59490
  const fileBirthMs = stat ? stat.birthtimeMs || stat.ctimeMs : SERVER_START_MS2;
@@ -59404,9 +59546,9 @@ function armDirWatcher2() {
59404
59546
  if (!_state4 || !_state4.rootExists) return;
59405
59547
  if (_watchers2.length) return;
59406
59548
  for (const { dir } of ROOTS) {
59407
- if (!fs6.existsSync(dir)) continue;
59549
+ if (!fs7.existsSync(dir)) continue;
59408
59550
  try {
59409
- const w = fs6.watch(dir, { recursive: true }, (_evt, filename) => {
59551
+ const w = fs7.watch(dir, { recursive: true }, (_evt, filename) => {
59410
59552
  if (!filename) return;
59411
59553
  if (path7.basename(filename) !== CHAT_FILE2) return;
59412
59554
  scheduleFlush3();
@@ -59463,7 +59605,7 @@ function isCaptureArmed4() {
59463
59605
  }
59464
59606
 
59465
59607
  // src/auto_save/hermes_capture.ts
59466
- import * as fs7 from "node:fs";
59608
+ import * as fs8 from "node:fs";
59467
59609
  import * as path8 from "node:path";
59468
59610
  import * as os9 from "node:os";
59469
59611
  var DEVICE_NAME6 = os9.hostname();
@@ -59519,8 +59661,44 @@ function parseNewRows(db2, afterId) {
59519
59661
  }
59520
59662
  return { rows, maxId };
59521
59663
  }
59522
- function lookupModel(db2, sessionId, cache2) {
59523
- if (cache2.has(sessionId)) return cache2.get(sessionId);
59664
+ function lookupSource(db2, sessionId, cache3) {
59665
+ if (cache3.has(sessionId)) return cache3.get(sessionId);
59666
+ let source = null;
59667
+ try {
59668
+ const row = db2.prepare(`SELECT source FROM sessions WHERE id = ? LIMIT 1`).get(sessionId);
59669
+ source = row?.source ?? null;
59670
+ } catch {
59671
+ source = null;
59672
+ }
59673
+ cache3.set(sessionId, source);
59674
+ return source;
59675
+ }
59676
+ var SOURCE_VENUE = { slack: "slack", cli: "terminal", subagent: "subagent", cron: "auto" };
59677
+ function rowVenue(db2, row, state) {
59678
+ const source = lookupSource(db2, row.sessionId, state.sourceCache);
59679
+ if (source !== "acp") return source ? SOURCE_VENUE[source] ?? null : null;
59680
+ const own = row.role === "user" ? buzzTurnVenue(row.message) : null;
59681
+ if (own) {
59682
+ state.buzzVenue.set(row.sessionId, own);
59683
+ return own;
59684
+ }
59685
+ if (!state.buzzVenue.has(row.sessionId)) {
59686
+ let seeded = null;
59687
+ try {
59688
+ const prev = db2.prepare(`SELECT content FROM messages WHERE session_id = ? AND id < ? AND role = 'user' ORDER BY id DESC LIMIT 20`).all(row.sessionId, row.id);
59689
+ for (const p of prev) {
59690
+ seeded = p.content ? buzzTurnVenue(p.content) : null;
59691
+ if (seeded) break;
59692
+ }
59693
+ } catch {
59694
+ seeded = null;
59695
+ }
59696
+ state.buzzVenue.set(row.sessionId, seeded);
59697
+ }
59698
+ return state.buzzVenue.get(row.sessionId) ?? null;
59699
+ }
59700
+ function lookupModel(db2, sessionId, cache3) {
59701
+ if (cache3.has(sessionId)) return cache3.get(sessionId);
59524
59702
  let model = null;
59525
59703
  try {
59526
59704
  const row = db2.prepare(`SELECT model FROM sessions WHERE id = ? LIMIT 1`).get(sessionId);
@@ -59528,7 +59706,7 @@ function lookupModel(db2, sessionId, cache2) {
59528
59706
  } catch {
59529
59707
  model = null;
59530
59708
  }
59531
- cache2.set(sessionId, model);
59709
+ cache3.set(sessionId, model);
59532
59710
  return model;
59533
59711
  }
59534
59712
  function isCaptureArmed5() {
@@ -59541,7 +59719,7 @@ async function captureSessionStart5(_cwd) {
59541
59719
  }
59542
59720
  _state5 = null;
59543
59721
  _consecutiveOpenFailures = 0;
59544
- if (!fs7.existsSync(STATE_DB)) return;
59722
+ if (!fs8.existsSync(STATE_DB)) return;
59545
59723
  const DatabaseSync = await loadSqlite2();
59546
59724
  if (!DatabaseSync) {
59547
59725
  console.error(
@@ -59573,7 +59751,7 @@ async function captureSessionStart5(_cwd) {
59573
59751
  db2.close();
59574
59752
  } catch {
59575
59753
  }
59576
- _state5 = { cursor: maxId, modelCache: /* @__PURE__ */ new Map() };
59754
+ _state5 = { cursor: maxId, modelCache: /* @__PURE__ */ new Map(), sourceCache: /* @__PURE__ */ new Map(), buzzVenue: /* @__PURE__ */ new Map(), venueByRow: /* @__PURE__ */ new Map() };
59577
59755
  console.error(`\u{1F4DD} [Hermes] capture armed: cursor=${maxId} (live-from-now)`);
59578
59756
  if (_pollTimer5) clearInterval(_pollTimer5);
59579
59757
  _pollTimer5 = setInterval(() => {
@@ -59612,6 +59790,15 @@ async function flush2() {
59612
59790
  const userId = await getDefaultUserId();
59613
59791
  for (const r of rows) {
59614
59792
  const agentModel = r.role === "user" ? null : lookupModel(db2, r.sessionId, _state5.modelCache) ?? "unknown";
59793
+ let venue = _state5.venueByRow.get(r.id);
59794
+ if (venue === void 0) {
59795
+ try {
59796
+ venue = rowVenue(db2, r, _state5);
59797
+ } catch {
59798
+ venue = null;
59799
+ }
59800
+ _state5.venueByRow.set(r.id, venue);
59801
+ }
59615
59802
  try {
59616
59803
  const res = await insertRawMemory({
59617
59804
  user_id: userId,
@@ -59620,8 +59807,10 @@ async function flush2() {
59620
59807
  role: r.role,
59621
59808
  message: r.message,
59622
59809
  external_uuid: `hermes:${r.id}`,
59623
- device_name: DEVICE_NAME6
59810
+ device_name: DEVICE_NAME6,
59811
+ venue
59624
59812
  });
59813
+ _state5.venueByRow.delete(r.id);
59625
59814
  if (res.inserted) inserted++;
59626
59815
  else dedup++;
59627
59816
  } catch (err3) {
@@ -60704,7 +60893,7 @@ async function drainColdPath(maxTicks = 12) {
60704
60893
  }
60705
60894
 
60706
60895
  // src/auto_save/jsonl_capture.ts
60707
- import * as fs8 from "node:fs";
60896
+ import * as fs9 from "node:fs";
60708
60897
  import * as path9 from "node:path";
60709
60898
  import * as os12 from "node:os";
60710
60899
  var CLIENT_PLATFORM2 = "claude-code";
@@ -60723,12 +60912,12 @@ function findProjectDir(cwd) {
60723
60912
  const slug = cwdToSlug(cwd);
60724
60913
  const slugPath = path9.join(PROJECTS_ROOT, slug);
60725
60914
  try {
60726
- if (fs8.statSync(slugPath).isDirectory()) return slugPath;
60915
+ if (fs9.statSync(slugPath).isDirectory()) return slugPath;
60727
60916
  } catch {
60728
60917
  }
60729
60918
  let subdirs;
60730
60919
  try {
60731
- subdirs = fs8.readdirSync(PROJECTS_ROOT, { withFileTypes: true });
60920
+ subdirs = fs9.readdirSync(PROJECTS_ROOT, { withFileTypes: true });
60732
60921
  } catch {
60733
60922
  return null;
60734
60923
  }
@@ -60737,7 +60926,7 @@ function findProjectDir(cwd) {
60737
60926
  const dirPath = path9.join(PROJECTS_ROOT, subdir.name);
60738
60927
  let files;
60739
60928
  try {
60740
- files = fs8.readdirSync(dirPath, { withFileTypes: true });
60929
+ files = fs9.readdirSync(dirPath, { withFileTypes: true });
60741
60930
  } catch {
60742
60931
  continue;
60743
60932
  }
@@ -60752,13 +60941,13 @@ function findProjectDir(cwd) {
60752
60941
  function readCwdFromJsonl(jsonlPath) {
60753
60942
  let fd;
60754
60943
  try {
60755
- fd = fs8.openSync(jsonlPath, "r");
60944
+ fd = fs9.openSync(jsonlPath, "r");
60756
60945
  } catch {
60757
60946
  return null;
60758
60947
  }
60759
60948
  try {
60760
60949
  const buf = Buffer.alloc(2048);
60761
- const bytesRead = fs8.readSync(fd, buf, 0, 2048, 0);
60950
+ const bytesRead = fs9.readSync(fd, buf, 0, 2048, 0);
60762
60951
  const raw = buf.slice(0, bytesRead).toString("utf-8");
60763
60952
  for (const line of raw.split("\n")) {
60764
60953
  if (!line.trim()) continue;
@@ -60770,7 +60959,7 @@ function readCwdFromJsonl(jsonlPath) {
60770
60959
  }
60771
60960
  return null;
60772
60961
  } finally {
60773
- fs8.closeSync(fd);
60962
+ fs9.closeSync(fd);
60774
60963
  }
60775
60964
  }
60776
60965
  function captureSessionStart6(cwd) {
@@ -60800,7 +60989,7 @@ function _tryArm(cwd, attempt) {
60800
60989
  _state6.projectDir = projectDir;
60801
60990
  let entries;
60802
60991
  try {
60803
- entries = fs8.readdirSync(projectDir, { withFileTypes: true });
60992
+ entries = fs9.readdirSync(projectDir, { withFileTypes: true });
60804
60993
  } catch {
60805
60994
  return;
60806
60995
  }
@@ -60809,7 +60998,7 @@ function _tryArm(cwd, attempt) {
60809
60998
  const jsonlPath = path9.join(projectDir, entry.name);
60810
60999
  let stat;
60811
61000
  try {
60812
- stat = fs8.statSync(jsonlPath);
61001
+ stat = fs9.statSync(jsonlPath);
60813
61002
  } catch {
60814
61003
  continue;
60815
61004
  }
@@ -60855,27 +61044,48 @@ function parseEntry3(line) {
60855
61044
  uuid: entry.uuid ?? `${entry.timestamp ?? ""}-${Math.random()}`,
60856
61045
  role: entry.type,
60857
61046
  message: messageText,
60858
- agent_model
61047
+ agent_model,
61048
+ entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
60859
61049
  };
60860
61050
  }
61051
+ var HEAD_SCAN_BYTES = 2 * 1024 * 1024;
61052
+ function sessionVenueKind(jsonlPath) {
61053
+ const fd = fs9.openSync(jsonlPath, "r");
61054
+ try {
61055
+ const size = fs9.fstatSync(fd).size;
61056
+ const buf = Buffer.allocUnsafe(Math.min(HEAD_SCAN_BYTES, size));
61057
+ fs9.readSync(fd, buf, 0, buf.length, 0);
61058
+ for (const line of buf.toString("utf-8").split("\n")) {
61059
+ const parsed = line.trim() ? parseEntry3(line) : null;
61060
+ if (parsed?.role === "user") return classifySessionVenue(parsed.message, parsed.entrypoint);
61061
+ }
61062
+ return size >= HEAD_SCAN_BYTES ? null : void 0;
61063
+ } finally {
61064
+ fs9.closeSync(fd);
61065
+ }
61066
+ }
61067
+ var userTextOf = (line) => {
61068
+ const parsed = parseEntry3(line);
61069
+ return parsed?.role === "user" ? parsed.message : null;
61070
+ };
60861
61071
  async function flushDeltaForFile4(jsonlPath, fileState) {
60862
- if (!fs8.existsSync(jsonlPath)) return { inserted: 0, skipped: 0, dedup: 0 };
61072
+ if (!fs9.existsSync(jsonlPath)) return { inserted: 0, skipped: 0, dedup: 0 };
60863
61073
  let stat;
60864
61074
  try {
60865
- stat = fs8.statSync(jsonlPath);
61075
+ stat = fs9.statSync(jsonlPath);
60866
61076
  } catch {
60867
61077
  return { inserted: 0, skipped: 0, dedup: 0 };
60868
61078
  }
60869
61079
  if (stat.size <= fileState.cursorBytes) return { inserted: 0, skipped: 0, dedup: 0 };
60870
61080
  const length = stat.size - fileState.cursorBytes;
60871
- const fd = fs8.openSync(jsonlPath, "r");
61081
+ const fd = fs9.openSync(jsonlPath, "r");
60872
61082
  let raw;
60873
61083
  try {
60874
61084
  const buf = Buffer.alloc(length);
60875
- fs8.readSync(fd, buf, 0, length, fileState.cursorBytes);
61085
+ fs9.readSync(fd, buf, 0, length, fileState.cursorBytes);
60876
61086
  raw = buf.toString("utf-8");
60877
61087
  } finally {
60878
- fs8.closeSync(fd);
61088
+ fs9.closeSync(fd);
60879
61089
  }
60880
61090
  const lastNl = raw.lastIndexOf("\n");
60881
61091
  if (lastNl === -1) return { inserted: 0, skipped: 0, dedup: 0 };
@@ -60884,6 +61094,14 @@ async function flushDeltaForFile4(jsonlPath, fileState) {
60884
61094
  const newCursor = fileState.cursorBytes + advanceBy;
60885
61095
  const lines = parsable.split("\n");
60886
61096
  const userId = await getDefaultUserId();
61097
+ if (fileState.venueKind === void 0) {
61098
+ try {
61099
+ fileState.venueKind = sessionVenueKind(jsonlPath);
61100
+ } catch {
61101
+ fileState.venueKind = null;
61102
+ }
61103
+ }
61104
+ const deltaStart = fileState.cursorBytes;
60887
61105
  let inserted = 0, skipped = 0, dedup = 0;
60888
61106
  for (const line of lines) {
60889
61107
  const trimmed = line.trim();
@@ -60900,6 +61118,20 @@ async function flushDeltaForFile4(jsonlPath, fileState) {
60900
61118
  }
60901
61119
  fileState.contentSeen.add(ck);
60902
61120
  const externalUuid = `claude-code:${fileState.sessionId}:${parsed.uuid}`;
61121
+ let venue = fileState.venueKind ?? null;
61122
+ if (fileState.venueKind === "buzz") {
61123
+ const own = parsed.role === "user" ? buzzTurnVenue(parsed.message) : null;
61124
+ if (own) {
61125
+ fileState.buzzVenue = own;
61126
+ } else if (fileState.buzzVenue === void 0) {
61127
+ try {
61128
+ fileState.buzzVenue = lastBuzzVenueInFile(jsonlPath, deltaStart, userTextOf);
61129
+ } catch {
61130
+ fileState.buzzVenue = null;
61131
+ }
61132
+ }
61133
+ venue = own ?? fileState.buzzVenue ?? "buzz";
61134
+ }
60903
61135
  const agentModel = parsed.role === "user" ? null : parsed.agent_model ?? "unknown";
60904
61136
  try {
60905
61137
  const result = await insertRawMemory({
@@ -60909,7 +61141,8 @@ async function flushDeltaForFile4(jsonlPath, fileState) {
60909
61141
  role: parsed.role,
60910
61142
  message: parsed.message,
60911
61143
  external_uuid: externalUuid,
60912
- device_name: DEVICE_NAME9
61144
+ device_name: DEVICE_NAME9,
61145
+ venue
60913
61146
  });
60914
61147
  if (result.inserted) inserted++;
60915
61148
  else dedup++;
@@ -60924,10 +61157,10 @@ async function flushDeltaForFile4(jsonlPath, fileState) {
60924
61157
  async function flushAllFiles4() {
60925
61158
  if (!_state6 || !_state6.projectDir) return { inserted: 0, skipped: 0, dedup: 0 };
60926
61159
  const projectDir = _state6.projectDir;
60927
- if (!fs8.existsSync(projectDir)) return { inserted: 0, skipped: 0, dedup: 0 };
61160
+ if (!fs9.existsSync(projectDir)) return { inserted: 0, skipped: 0, dedup: 0 };
60928
61161
  let entries;
60929
61162
  try {
60930
- entries = fs8.readdirSync(projectDir, { withFileTypes: true });
61163
+ entries = fs9.readdirSync(projectDir, { withFileTypes: true });
60931
61164
  } catch {
60932
61165
  return { inserted: 0, skipped: 0, dedup: 0 };
60933
61166
  }
@@ -60983,7 +61216,7 @@ function armDirWatcher3() {
60983
61216
  if (!_state6 || !_state6.projectDir) return;
60984
61217
  if (_watcher2) return;
60985
61218
  try {
60986
- _watcher2 = fs8.watch(_state6.projectDir, (_eventType, filename) => {
61219
+ _watcher2 = fs9.watch(_state6.projectDir, (_eventType, filename) => {
60987
61220
  if (filename && !filename.endsWith(".jsonl")) return;
60988
61221
  scheduleFlush4();
60989
61222
  });
@@ -61027,7 +61260,7 @@ async function captureSessionEnd6() {
61027
61260
  }
61028
61261
 
61029
61262
  // src/auto_save/codex_capture.ts
61030
- import * as fs9 from "node:fs";
61263
+ import * as fs10 from "node:fs";
61031
61264
  import * as path10 from "node:path";
61032
61265
  import * as os13 from "node:os";
61033
61266
  import { spawnSync } from "node:child_process";
@@ -61075,13 +61308,13 @@ function extractSessionId2(filename) {
61075
61308
  return m ? m[1] : null;
61076
61309
  }
61077
61310
  function* walkRollouts(root) {
61078
- if (!fs9.existsSync(root)) return;
61311
+ if (!fs10.existsSync(root)) return;
61079
61312
  const stack = [root];
61080
61313
  while (stack.length) {
61081
61314
  const dir = stack.pop();
61082
61315
  let entries;
61083
61316
  try {
61084
- entries = fs9.readdirSync(dir, { withFileTypes: true });
61317
+ entries = fs10.readdirSync(dir, { withFileTypes: true });
61085
61318
  } catch {
61086
61319
  continue;
61087
61320
  }
@@ -61096,7 +61329,7 @@ function* walkRollouts(root) {
61096
61329
  }
61097
61330
  }
61098
61331
  function captureSessionStart7(_cwd) {
61099
- const rootExists = fs9.existsSync(SESSIONS_ROOT2);
61332
+ const rootExists = fs10.existsSync(SESSIONS_ROOT2);
61100
61333
  _state7 = {
61101
61334
  rootExists,
61102
61335
  files: /* @__PURE__ */ new Map()
@@ -61108,7 +61341,7 @@ function captureSessionStart7(_cwd) {
61108
61341
  for (const filePath of walkRollouts(SESSIONS_ROOT2)) {
61109
61342
  let stat;
61110
61343
  try {
61111
- stat = fs9.statSync(filePath);
61344
+ stat = fs10.statSync(filePath);
61112
61345
  } catch {
61113
61346
  continue;
61114
61347
  }
@@ -61162,23 +61395,23 @@ function extractModelFromTurnContext(line) {
61162
61395
  }
61163
61396
  }
61164
61397
  async function flushDeltaForFile5(filePath, fileState) {
61165
- if (!fs9.existsSync(filePath)) return { inserted: 0, skipped: 0, dedup: 0 };
61398
+ if (!fs10.existsSync(filePath)) return { inserted: 0, skipped: 0, dedup: 0 };
61166
61399
  let stat;
61167
61400
  try {
61168
- stat = fs9.statSync(filePath);
61401
+ stat = fs10.statSync(filePath);
61169
61402
  } catch {
61170
61403
  return { inserted: 0, skipped: 0, dedup: 0 };
61171
61404
  }
61172
61405
  if (stat.size <= fileState.cursorBytes) return { inserted: 0, skipped: 0, dedup: 0 };
61173
61406
  const length = stat.size - fileState.cursorBytes;
61174
- const fd = fs9.openSync(filePath, "r");
61407
+ const fd = fs10.openSync(filePath, "r");
61175
61408
  let raw;
61176
61409
  try {
61177
61410
  const buf = Buffer.alloc(length);
61178
- fs9.readSync(fd, buf, 0, length, fileState.cursorBytes);
61411
+ fs10.readSync(fd, buf, 0, length, fileState.cursorBytes);
61179
61412
  raw = buf.toString("utf-8");
61180
61413
  } finally {
61181
- fs9.closeSync(fd);
61414
+ fs10.closeSync(fd);
61182
61415
  }
61183
61416
  const lastNl = raw.lastIndexOf("\n");
61184
61417
  if (lastNl === -1) return { inserted: 0, skipped: 0, dedup: 0 };
@@ -61242,7 +61475,7 @@ async function flushAllFiles5() {
61242
61475
  if (!sessionId) continue;
61243
61476
  let stat = null;
61244
61477
  try {
61245
- stat = fs9.statSync(filePath);
61478
+ stat = fs10.statSync(filePath);
61246
61479
  } catch {
61247
61480
  }
61248
61481
  const fileBirthMs = stat ? stat.birthtimeMs || stat.ctimeMs : SERVER_START_MS3;
@@ -61302,7 +61535,7 @@ function armDirWatcher4() {
61302
61535
  if (!_state7 || !_state7.rootExists) return;
61303
61536
  if (_watcher3) return;
61304
61537
  try {
61305
- _watcher3 = fs9.watch(SESSIONS_ROOT2, { recursive: true }, (_evt, filename) => {
61538
+ _watcher3 = fs10.watch(SESSIONS_ROOT2, { recursive: true }, (_evt, filename) => {
61306
61539
  if (!filename) return;
61307
61540
  const base = path10.basename(filename);
61308
61541
  if (!base.startsWith("rollout-") || !base.endsWith(".jsonl")) return;
@@ -61355,16 +61588,16 @@ async function captureSessionEnd7() {
61355
61588
  }
61356
61589
 
61357
61590
  // src/version.ts
61358
- import fs10 from "fs";
61591
+ import fs11 from "fs";
61359
61592
  import path11 from "path";
61360
61593
  import { fileURLToPath as fileURLToPath3 } from "url";
61361
61594
  var __dirname3 = path11.dirname(fileURLToPath3(import.meta.url));
61362
61595
  var packageJsonPath = path11.resolve(__dirname3, "..", "package.json");
61363
- var packageJson = JSON.parse(fs10.readFileSync(packageJsonPath, "utf8"));
61596
+ var packageJson = JSON.parse(fs11.readFileSync(packageJsonPath, "utf8"));
61364
61597
  var PACKAGE_VERSION2 = packageJson.version || "0.0.0";
61365
61598
 
61366
61599
  // src/index.ts
61367
- import fs12 from "fs";
61600
+ import fs13 from "fs";
61368
61601
  var BRIEF_DB_TIMEOUT_MS = 5e3;
61369
61602
  var INSTRUCTIONS_MAX_CHARS = Number(process.env.INSTRUCTIONS_MAX_CHARS ?? 1900);
61370
61603
  var INSTRUCTIONS_SEP = "\n\n---\n\n";
@@ -61561,7 +61794,7 @@ async function runMcpServer() {
61561
61794
  if (process.env.SSH_ENABLED === "true" && !process.env.SSH_KEY_PATH) {
61562
61795
  throw new Error("\u274C SSH_KEY_PATH is required when SSH is enabled");
61563
61796
  }
61564
- if (process.env.SSH_KEY_PATH && !fs12.existsSync(process.env.SSH_KEY_PATH)) {
61797
+ if (process.env.SSH_KEY_PATH && !fs13.existsSync(process.env.SSH_KEY_PATH)) {
61565
61798
  console.error(`\u26A0\uFE0F [WARNING] SSH key not found at: ${process.env.SSH_KEY_PATH}`);
61566
61799
  }
61567
61800
  try {