@tonyclaw/agent-inspector 2.1.6 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-Djazxhew.js → CompareDrawer-BLS7CVvA.js} +1 -1
  3. package/.output/public/assets/{ProxyViewerContainer-BC-z9RPh.js → ProxyViewerContainer-BFZ1WG07.js} +33 -33
  4. package/.output/public/assets/{ReplayDialog-BaD4R6ac.js → ReplayDialog-DIGF807X.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-w6uGdqYp.js → RequestAnatomy-C3Nlvp9P.js} +1 -1
  6. package/.output/public/assets/{ResponseView-VPed-Yif.js → ResponseView-BbZywqHe.js} +1 -1
  7. package/.output/public/assets/{StreamingChunkSequence-CPB8FgHI.js → StreamingChunkSequence-Dk27PfPn.js} +1 -1
  8. package/.output/public/assets/_sessionId-BHpX8AVf.js +1 -0
  9. package/.output/public/assets/index-BXHM9OMb.js +1 -0
  10. package/.output/public/assets/{main-CIV3Chb5.js → main-BxHXMs6B.js} +2 -2
  11. package/.output/server/{_sessionId-CIXQGim9.mjs → _sessionId-D5HNwb9A.mjs} +3 -3
  12. package/.output/server/_ssr/{CompareDrawer-_uFgjkB2.mjs → CompareDrawer-QNk1twf8.mjs} +3 -3
  13. package/.output/server/_ssr/{ProxyViewerContainer-D8YjQDNj.mjs → ProxyViewerContainer-DGhc2le_.mjs} +37 -10
  14. package/.output/server/_ssr/{ReplayDialog-CFwKM7jc.mjs → ReplayDialog-D8wg4VNL.mjs} +4 -4
  15. package/.output/server/_ssr/{RequestAnatomy-2Vr84GxT.mjs → RequestAnatomy-BtJHKVl2.mjs} +3 -3
  16. package/.output/server/_ssr/{ResponseView-CSBWBHRJ.mjs → ResponseView-CndDItiU.mjs} +3 -3
  17. package/.output/server/_ssr/{StreamingChunkSequence-Dr4JApqs.mjs → StreamingChunkSequence-D5Ywpbr7.mjs} +3 -3
  18. package/.output/server/_ssr/{index-WnsY1fh_.mjs → index-DtcUTHAX.mjs} +3 -3
  19. package/.output/server/_ssr/index.mjs +2 -2
  20. package/.output/server/_ssr/{router-sy38X5AX.mjs → router-C0apgqfC.mjs} +541 -120
  21. package/.output/server/{_tanstack-start-manifest_v-Dde-eACV.mjs → _tanstack-start-manifest_v-BoTPaB-V.mjs} +1 -1
  22. package/.output/server/index.mjs +62 -62
  23. package/package.json +1 -1
  24. package/src/components/groups/GroupsDialog.tsx +9 -4
  25. package/src/components/providers/SettingsDialog.tsx +20 -0
  26. package/src/proxy/sessionArchive.ts +410 -0
  27. package/src/proxy/store.ts +121 -6
  28. package/src/routes/api/logs.ts +2 -0
  29. package/src/routes/api/sessions.ts +2 -2
  30. package/.output/public/assets/_sessionId-mnr0O0Ri.js +0 -1
  31. package/.output/public/assets/index-DH1DjJOl.js +0 -1
@@ -2,17 +2,17 @@ import { c as createRouter, a as createRootRoute, b as createFileRoute, l as laz
2
2
  import { j as jsxRuntimeExports } from "../_libs/react.mjs";
3
3
  import { S as SWRConfig } from "../_libs/swr.mjs";
4
4
  import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync, copyFileSync, unlinkSync, createReadStream, readdirSync, statSync, cpSync, rmSync, createWriteStream } from "node:fs";
5
- import fs, { mkdir, appendFile, readFile, writeFile, readdir, open, stat, unlink, rename } from "node:fs/promises";
5
+ import fs, { mkdir, appendFile, readFile, writeFile, readdir, open, stat, unlink, rm, rename } from "node:fs/promises";
6
6
  import { createInterface } from "node:readline";
7
7
  import { Buffer } from "node:buffer";
8
- import path, { basename, join, isAbsolute, dirname, resolve, relative } from "node:path";
8
+ import path, { basename, join, dirname, isAbsolute, resolve, relative } from "node:path";
9
+ import { randomUUID as randomUUID$1, createHash } from "node:crypto";
9
10
  import { execFile, exec, spawn } from "node:child_process";
10
11
  import { fileURLToPath } from "node:url";
11
12
  import { C as Conf } from "../_libs/conf.mjs";
12
13
  import { randomUUID } from "crypto";
13
14
  import { promisify } from "node:util";
14
15
  import { Worker } from "node:worker_threads";
15
- import { randomUUID as randomUUID$1, createHash } from "node:crypto";
16
16
  import { M as McpServer, W as WebStandardStreamableHTTPServerTransport, R as ResourceTemplate } from "../_libs/modelcontextprotocol__server.mjs";
17
17
  import { J as JSZip } from "../_libs/jszip.mjs";
18
18
  import { homedir } from "node:os";
@@ -108,7 +108,7 @@ function RootDocument({ children }) {
108
108
  ] })
109
109
  ] });
110
110
  }
111
- const $$splitComponentImporter$1 = () => import("./index-WnsY1fh_.mjs");
111
+ const $$splitComponentImporter$1 = () => import("./index-DtcUTHAX.mjs");
112
112
  const Route$C = createFileRoute("/")({
113
113
  component: lazyRouteComponent($$splitComponentImporter$1, "component")
114
114
  });
@@ -151,7 +151,7 @@ function decodeSessionIdFromPath(encoded) {
151
151
  function getSessionPath(sessionId) {
152
152
  return `/session/${encodeSessionIdForPath(sessionId)}`;
153
153
  }
154
- const $$splitComponentImporter = () => import("../_sessionId-CIXQGim9.mjs");
154
+ const $$splitComponentImporter = () => import("../_sessionId-D5HNwb9A.mjs");
155
155
  const Route$B = createFileRoute("/session/$sessionId")({
156
156
  component: lazyRouteComponent($$splitComponentImporter, "component"),
157
157
  parseParams: (params) => ({
@@ -865,9 +865,9 @@ function readChunks(path2) {
865
865
  }
866
866
  }
867
867
  const SQLITE_INDEX_FILE = "inspector.sqlite";
868
- const SQLITE_PACKAGE_NAME = "better-sqlite3";
869
- const BUN_SQLITE_MODULE_NAME = "bun:sqlite";
870
- const CREATE_SCHEMA_SQL = `
868
+ const SQLITE_PACKAGE_NAME$1 = "better-sqlite3";
869
+ const BUN_SQLITE_MODULE_NAME$1 = "bun:sqlite";
870
+ const CREATE_SCHEMA_SQL$1 = `
871
871
  CREATE TABLE IF NOT EXISTS log_index (
872
872
  id INTEGER PRIMARY KEY,
873
873
  file TEXT NOT NULL,
@@ -908,7 +908,7 @@ CREATE INDEX IF NOT EXISTS idx_log_index_session_id_id ON log_index(session_id,
908
908
  CREATE INDEX IF NOT EXISTS idx_log_index_model_id ON log_index(model, id);
909
909
  CREATE INDEX IF NOT EXISTS idx_log_index_timestamp ON log_index(timestamp);
910
910
  `;
911
- const UPSERT_SQL = `
911
+ const UPSERT_SQL$1 = `
912
912
  INSERT INTO log_index (
913
913
  id,
914
914
  file,
@@ -985,7 +985,7 @@ ON CONFLICT(id) DO UPDATE SET
985
985
  let sqliteStatePromise = null;
986
986
  let sqliteStatePath = null;
987
987
  let activeDb = null;
988
- let didLogUnavailable = false;
988
+ let didLogUnavailable$1 = false;
989
989
  function isSqliteLogIndexEnabled() {
990
990
  const configured = process.env["AGENT_INSPECTOR_SQLITE_INDEX"];
991
991
  if (configured === "1") return true;
@@ -995,13 +995,13 @@ function isSqliteLogIndexEnabled() {
995
995
  function getSqlitePath() {
996
996
  return join(resolveLogDir(), SQLITE_INDEX_FILE);
997
997
  }
998
- function objectFromUnknown(value) {
998
+ function objectFromUnknown$1(value) {
999
999
  if (value === null) return null;
1000
1000
  if (typeof value === "object" || typeof value === "function") return value;
1001
1001
  return null;
1002
1002
  }
1003
- function readProperty$1(value, name) {
1004
- let current = objectFromUnknown(value);
1003
+ function readProperty$2(value, name) {
1004
+ let current = objectFromUnknown$1(value);
1005
1005
  while (current !== null) {
1006
1006
  const desc = Object.getOwnPropertyDescriptor(current, name);
1007
1007
  if (desc !== void 0) {
@@ -1009,16 +1009,16 @@ function readProperty$1(value, name) {
1009
1009
  return propertyValue;
1010
1010
  }
1011
1011
  const nextPrototype = Object.getPrototypeOf(current);
1012
- current = objectFromUnknown(nextPrototype);
1012
+ current = objectFromUnknown$1(nextPrototype);
1013
1013
  }
1014
1014
  return void 0;
1015
1015
  }
1016
- function readFunction(value, name) {
1017
- const property = readProperty$1(value, name);
1016
+ function readFunction$1(value, name) {
1017
+ const property = readProperty$2(value, name);
1018
1018
  return typeof property === "function" ? property : null;
1019
1019
  }
1020
- function callMethod(target, methodName, args) {
1021
- const method = readFunction(target, methodName);
1020
+ function callMethod$1(target, methodName, args) {
1021
+ const method = readFunction$1(target, methodName);
1022
1022
  if (method === null) return void 0;
1023
1023
  try {
1024
1024
  return Reflect.apply(method, target, [...args]);
@@ -1027,48 +1027,48 @@ function callMethod(target, methodName, args) {
1027
1027
  return void 0;
1028
1028
  }
1029
1029
  }
1030
- function prepareStatement(db, sql) {
1031
- return callMethod(db, "prepare", [sql]);
1030
+ function prepareStatement$1(db, sql) {
1031
+ return callMethod$1(db, "prepare", [sql]);
1032
1032
  }
1033
- function runPrepared(db, sql, params = []) {
1034
- const statement = prepareStatement(db, sql);
1033
+ function runPrepared$1(db, sql, params = []) {
1034
+ const statement = prepareStatement$1(db, sql);
1035
1035
  if (statement === void 0) return false;
1036
- const result = callMethod(statement, "run", params);
1037
- callMethod(statement, "finalize", []);
1036
+ const result = callMethod$1(statement, "run", params);
1037
+ callMethod$1(statement, "finalize", []);
1038
1038
  return result !== void 0;
1039
1039
  }
1040
1040
  function getPrepared(db, sql, params = []) {
1041
- const statement = prepareStatement(db, sql);
1041
+ const statement = prepareStatement$1(db, sql);
1042
1042
  if (statement === void 0) return void 0;
1043
- const result = callMethod(statement, "get", params);
1044
- callMethod(statement, "finalize", []);
1043
+ const result = callMethod$1(statement, "get", params);
1044
+ callMethod$1(statement, "finalize", []);
1045
1045
  return result;
1046
1046
  }
1047
- function allPrepared(db, sql, params = []) {
1048
- const statement = prepareStatement(db, sql);
1047
+ function allPrepared$1(db, sql, params = []) {
1048
+ const statement = prepareStatement$1(db, sql);
1049
1049
  if (statement === void 0) return null;
1050
- const result = callMethod(statement, "all", params);
1051
- callMethod(statement, "finalize", []);
1050
+ const result = callMethod$1(statement, "all", params);
1051
+ callMethod$1(statement, "finalize", []);
1052
1052
  return Array.isArray(result) ? result : null;
1053
1053
  }
1054
- function execSql(db, sql) {
1055
- const result = callMethod(db, "exec", [sql]);
1054
+ function execSql$1(db, sql) {
1055
+ const result = callMethod$1(db, "exec", [sql]);
1056
1056
  return result !== void 0;
1057
1057
  }
1058
- function sqliteConstructorFromModule(moduleValue, exportName) {
1059
- const exportedValue = readProperty$1(moduleValue, exportName);
1058
+ function sqliteConstructorFromModule$1(moduleValue, exportName) {
1059
+ const exportedValue = readProperty$2(moduleValue, exportName);
1060
1060
  if (typeof exportedValue === "function") {
1061
1061
  return (path2) => Reflect.construct(exportedValue, [path2]);
1062
1062
  }
1063
1063
  return null;
1064
1064
  }
1065
- async function loadSqliteModuleConstructor(moduleName, exportName) {
1065
+ async function loadSqliteModuleConstructor$1(moduleName, exportName) {
1066
1066
  try {
1067
1067
  const importedModule = await import(
1068
1068
  /* @vite-ignore */
1069
1069
  moduleName
1070
1070
  );
1071
- const exportedConstructor = sqliteConstructorFromModule(importedModule, exportName);
1071
+ const exportedConstructor = sqliteConstructorFromModule$1(importedModule, exportName);
1072
1072
  if (exportedConstructor !== null) return { constructor: exportedConstructor, reason: null };
1073
1073
  if (exportName === "default" && typeof importedModule === "function") {
1074
1074
  return {
@@ -1081,27 +1081,27 @@ async function loadSqliteModuleConstructor(moduleName, exportName) {
1081
1081
  return { constructor: null, reason: String(err) };
1082
1082
  }
1083
1083
  }
1084
- async function loadSqliteConstructor() {
1084
+ async function loadSqliteConstructor$1() {
1085
1085
  const bunRuntimeDesc = Object.getOwnPropertyDescriptor(process.versions, "bun");
1086
1086
  if (bunRuntimeDesc !== void 0) {
1087
- const bunSqlite2 = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
1087
+ const bunSqlite2 = await loadSqliteModuleConstructor$1(BUN_SQLITE_MODULE_NAME$1, "Database");
1088
1088
  if (bunSqlite2.constructor !== null) return bunSqlite2;
1089
- const betterSqlite2 = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
1089
+ const betterSqlite2 = await loadSqliteModuleConstructor$1(SQLITE_PACKAGE_NAME$1, "default");
1090
1090
  if (betterSqlite2.constructor !== null) return betterSqlite2;
1091
1091
  const reason2 = [bunSqlite2.reason, betterSqlite2.reason].filter((item) => item !== null).join("; ");
1092
- if (!didLogUnavailable) {
1093
- didLogUnavailable = true;
1092
+ if (!didLogUnavailable$1) {
1093
+ didLogUnavailable$1 = true;
1094
1094
  logger.warn("[sqliteLogIndex] Optional SQLite index unavailable:", reason2);
1095
1095
  }
1096
1096
  return { constructor: null, reason: reason2 };
1097
1097
  }
1098
- const betterSqlite = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
1098
+ const betterSqlite = await loadSqliteModuleConstructor$1(SQLITE_PACKAGE_NAME$1, "default");
1099
1099
  if (betterSqlite.constructor !== null) return betterSqlite;
1100
- const bunSqlite = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
1100
+ const bunSqlite = await loadSqliteModuleConstructor$1(BUN_SQLITE_MODULE_NAME$1, "Database");
1101
1101
  if (bunSqlite.constructor !== null) return bunSqlite;
1102
1102
  const reason = [betterSqlite.reason, bunSqlite.reason].filter((item) => item !== null).join("; ");
1103
- if (!didLogUnavailable) {
1104
- didLogUnavailable = true;
1103
+ if (!didLogUnavailable$1) {
1104
+ didLogUnavailable$1 = true;
1105
1105
  logger.warn("[sqliteLogIndex] Optional SQLite index unavailable:", reason);
1106
1106
  }
1107
1107
  return { constructor: null, reason };
@@ -1111,7 +1111,7 @@ async function initializeSqliteState() {
1111
1111
  if (!isSqliteLogIndexEnabled()) {
1112
1112
  return { status: "unavailable", path: path2, reason: "SQLite log index is disabled" };
1113
1113
  }
1114
- const sqliteConstructor = await loadSqliteConstructor();
1114
+ const sqliteConstructor = await loadSqliteConstructor$1();
1115
1115
  if (sqliteConstructor.constructor === null) {
1116
1116
  return {
1117
1117
  status: "unavailable",
@@ -1122,9 +1122,9 @@ async function initializeSqliteState() {
1122
1122
  try {
1123
1123
  await mkdir(dirname(path2), { recursive: true });
1124
1124
  const db = sqliteConstructor.constructor(path2);
1125
- execSql(db, "PRAGMA journal_mode = WAL");
1126
- execSql(db, "PRAGMA synchronous = NORMAL");
1127
- if (!execSql(db, CREATE_SCHEMA_SQL)) {
1125
+ execSql$1(db, "PRAGMA journal_mode = WAL");
1126
+ execSql$1(db, "PRAGMA synchronous = NORMAL");
1127
+ if (!execSql$1(db, CREATE_SCHEMA_SQL$1)) {
1128
1128
  return { status: "unavailable", path: path2, reason: "SQLite schema initialization failed" };
1129
1129
  }
1130
1130
  activeDb = db;
@@ -1147,7 +1147,7 @@ async function getSqliteState() {
1147
1147
  }
1148
1148
  function closeSqliteLogIndex() {
1149
1149
  if (activeDb !== null) {
1150
- callMethod(activeDb, "close", []);
1150
+ callMethod$1(activeDb, "close", []);
1151
1151
  }
1152
1152
  activeDb = null;
1153
1153
  sqliteStatePromise = null;
@@ -1198,19 +1198,19 @@ function entryParams(entry) {
1198
1198
  summary?.error ?? null
1199
1199
  ];
1200
1200
  }
1201
- function readNumber(row, name) {
1202
- const value = readProperty$1(row, name);
1201
+ function readNumber$1(row, name) {
1202
+ const value = readProperty$2(row, name);
1203
1203
  return typeof value === "number" && Number.isFinite(value) ? value : null;
1204
1204
  }
1205
- function readString$1(row, name) {
1206
- const value = readProperty$1(row, name);
1205
+ function readString$2(row, name) {
1206
+ const value = readProperty$2(row, name);
1207
1207
  return typeof value === "string" ? value : null;
1208
1208
  }
1209
1209
  function readBoolean(row, name) {
1210
- return readNumber(row, name) === 1;
1210
+ return readNumber$1(row, name) === 1;
1211
1211
  }
1212
1212
  function readApiFormat(row) {
1213
- const value = readString$1(row, "api_format");
1213
+ const value = readString$2(row, "api_format");
1214
1214
  switch (value) {
1215
1215
  case "anthropic":
1216
1216
  return "anthropic";
@@ -1224,7 +1224,7 @@ function readApiFormat(row) {
1224
1224
  }
1225
1225
  }
1226
1226
  function readWarnings(row) {
1227
- const value = readString$1(row, "warnings_json");
1227
+ const value = readString$2(row, "warnings_json");
1228
1228
  if (value === null) return void 0;
1229
1229
  try {
1230
1230
  const parsed = JSON.parse(value);
@@ -1240,47 +1240,47 @@ function readWarnings(row) {
1240
1240
  }
1241
1241
  }
1242
1242
  function readRequiredNumber(row, name) {
1243
- const value = readNumber(row, name);
1243
+ const value = readNumber$1(row, name);
1244
1244
  return value === null || !Number.isInteger(value) ? null : value;
1245
1245
  }
1246
1246
  function summaryFromRow(row, id) {
1247
1247
  return {
1248
1248
  id,
1249
- timestamp: readString$1(row, "timestamp") ?? "",
1250
- method: readString$1(row, "method") ?? "",
1251
- path: readString$1(row, "path") ?? "",
1252
- model: readString$1(row, "model"),
1253
- sessionId: readString$1(row, "session_id"),
1254
- responseStatus: readNumber(row, "response_status"),
1255
- inputTokens: readNumber(row, "input_tokens"),
1256
- outputTokens: readNumber(row, "output_tokens"),
1257
- cacheCreationInputTokens: readNumber(row, "cache_creation_input_tokens"),
1258
- cacheReadInputTokens: readNumber(row, "cache_read_input_tokens"),
1259
- elapsedMs: readNumber(row, "elapsed_ms"),
1260
- firstChunkMs: readNumber(row, "first_chunk_ms"),
1261
- totalStreamMs: readNumber(row, "total_stream_ms"),
1262
- tokensPerSecond: readNumber(row, "tokens_per_second"),
1249
+ timestamp: readString$2(row, "timestamp") ?? "",
1250
+ method: readString$2(row, "method") ?? "",
1251
+ path: readString$2(row, "path") ?? "",
1252
+ model: readString$2(row, "model"),
1253
+ sessionId: readString$2(row, "session_id"),
1254
+ responseStatus: readNumber$1(row, "response_status"),
1255
+ inputTokens: readNumber$1(row, "input_tokens"),
1256
+ outputTokens: readNumber$1(row, "output_tokens"),
1257
+ cacheCreationInputTokens: readNumber$1(row, "cache_creation_input_tokens"),
1258
+ cacheReadInputTokens: readNumber$1(row, "cache_read_input_tokens"),
1259
+ elapsedMs: readNumber$1(row, "elapsed_ms"),
1260
+ firstChunkMs: readNumber$1(row, "first_chunk_ms"),
1261
+ totalStreamMs: readNumber$1(row, "total_stream_ms"),
1262
+ tokensPerSecond: readNumber$1(row, "tokens_per_second"),
1263
1263
  streaming: readBoolean(row, "streaming"),
1264
- userAgent: readString$1(row, "user_agent"),
1265
- origin: readString$1(row, "origin"),
1264
+ userAgent: readString$2(row, "user_agent"),
1265
+ origin: readString$2(row, "origin"),
1266
1266
  apiFormat: readApiFormat(row),
1267
1267
  isTest: readBoolean(row, "is_test"),
1268
- replayOfLogId: readNumber(row, "replay_of_log_id"),
1269
- providerName: readString$1(row, "provider_name"),
1270
- clientPort: readNumber(row, "client_port"),
1271
- clientPid: readNumber(row, "client_pid"),
1272
- clientCwd: readString$1(row, "client_cwd"),
1273
- clientProjectFolder: readString$1(row, "client_project_folder"),
1274
- streamingChunksPath: readString$1(row, "streaming_chunks_path"),
1275
- rawRequestBodyBytes: readNumber(row, "raw_request_body_bytes"),
1276
- responseTextBytes: readNumber(row, "response_text_bytes"),
1268
+ replayOfLogId: readNumber$1(row, "replay_of_log_id"),
1269
+ providerName: readString$2(row, "provider_name"),
1270
+ clientPort: readNumber$1(row, "client_port"),
1271
+ clientPid: readNumber$1(row, "client_pid"),
1272
+ clientCwd: readString$2(row, "client_cwd"),
1273
+ clientProjectFolder: readString$2(row, "client_project_folder"),
1274
+ streamingChunksPath: readString$2(row, "streaming_chunks_path"),
1275
+ rawRequestBodyBytes: readNumber$1(row, "raw_request_body_bytes"),
1276
+ responseTextBytes: readNumber$1(row, "response_text_bytes"),
1277
1277
  warnings: readWarnings(row),
1278
- error: readString$1(row, "error")
1278
+ error: readString$2(row, "error")
1279
1279
  };
1280
1280
  }
1281
1281
  function entryFromRow(row) {
1282
1282
  const id = readRequiredNumber(row, "id");
1283
- const file = readString$1(row, "file");
1283
+ const file = readString$2(row, "file");
1284
1284
  const byteOffset = readRequiredNumber(row, "byte_offset");
1285
1285
  const byteLength = readRequiredNumber(row, "byte_length");
1286
1286
  if (id === null || file === null || byteOffset === null || byteLength === null) return null;
@@ -1289,8 +1289,8 @@ function entryFromRow(row) {
1289
1289
  file,
1290
1290
  byteOffset,
1291
1291
  byteLength,
1292
- sessionId: readString$1(row, "session_id"),
1293
- model: readString$1(row, "model"),
1292
+ sessionId: readString$2(row, "session_id"),
1293
+ model: readString$2(row, "model"),
1294
1294
  summary: summaryFromRow(row, id)
1295
1295
  };
1296
1296
  }
@@ -1298,30 +1298,30 @@ async function getSqliteLogIndexMaxId() {
1298
1298
  const state = await getSqliteState();
1299
1299
  if (state.status !== "ready") return null;
1300
1300
  const row = getPrepared(state.db, "SELECT MAX(id) AS max_id FROM log_index");
1301
- return readNumber(row, "max_id") ?? 0;
1301
+ return readNumber$1(row, "max_id") ?? 0;
1302
1302
  }
1303
1303
  async function upsertSqliteLogIndexEntry(entry) {
1304
1304
  if (entry.summary === void 0) return false;
1305
1305
  const state = await getSqliteState();
1306
1306
  if (state.status !== "ready") return false;
1307
- return runPrepared(state.db, UPSERT_SQL, entryParams(entry));
1307
+ return runPrepared$1(state.db, UPSERT_SQL$1, entryParams(entry));
1308
1308
  }
1309
1309
  async function syncSqliteLogIndexEntries(entries) {
1310
1310
  const state = await getSqliteState();
1311
1311
  if (state.status !== "ready") return false;
1312
1312
  if (entries.length === 0) return true;
1313
- if (!execSql(state.db, "BEGIN IMMEDIATE")) return false;
1313
+ if (!execSql$1(state.db, "BEGIN IMMEDIATE")) return false;
1314
1314
  try {
1315
1315
  for (const entry of entries) {
1316
1316
  if (entry.summary === void 0) continue;
1317
- if (!runPrepared(state.db, UPSERT_SQL, entryParams(entry))) {
1318
- execSql(state.db, "ROLLBACK");
1317
+ if (!runPrepared$1(state.db, UPSERT_SQL$1, entryParams(entry))) {
1318
+ execSql$1(state.db, "ROLLBACK");
1319
1319
  return false;
1320
1320
  }
1321
1321
  }
1322
- return execSql(state.db, "COMMIT");
1322
+ return execSql$1(state.db, "COMMIT");
1323
1323
  } catch (err) {
1324
- execSql(state.db, "ROLLBACK");
1324
+ execSql$1(state.db, "ROLLBACK");
1325
1325
  logger.warn("[sqliteLogIndex] Failed to sync SQLite index:", String(err));
1326
1326
  return false;
1327
1327
  }
@@ -1349,7 +1349,7 @@ async function listSqliteLogIndexEntries({
1349
1349
  params.push(model);
1350
1350
  }
1351
1351
  const where = clauses.length === 0 ? "" : ` WHERE ${clauses.join(" AND ")}`;
1352
- const rows = allPrepared(state.db, `SELECT * FROM log_index${where} ORDER BY id ASC`, params);
1352
+ const rows = allPrepared$1(state.db, `SELECT * FROM log_index${where} ORDER BY id ASC`, params);
1353
1353
  if (rows === null) return null;
1354
1354
  const entries = [];
1355
1355
  for (const row of rows) {
@@ -1361,22 +1361,22 @@ async function listSqliteLogIndexEntries({
1361
1361
  async function replaceSqliteLogIndexEntries(entries) {
1362
1362
  const state = await getSqliteState();
1363
1363
  if (state.status !== "ready") return false;
1364
- if (!execSql(state.db, "BEGIN IMMEDIATE")) return false;
1364
+ if (!execSql$1(state.db, "BEGIN IMMEDIATE")) return false;
1365
1365
  try {
1366
- if (!runPrepared(state.db, "DELETE FROM log_index")) {
1367
- execSql(state.db, "ROLLBACK");
1366
+ if (!runPrepared$1(state.db, "DELETE FROM log_index")) {
1367
+ execSql$1(state.db, "ROLLBACK");
1368
1368
  return false;
1369
1369
  }
1370
1370
  for (const entry of entries) {
1371
1371
  if (entry.summary === void 0) continue;
1372
- if (!runPrepared(state.db, UPSERT_SQL, entryParams(entry))) {
1373
- execSql(state.db, "ROLLBACK");
1372
+ if (!runPrepared$1(state.db, UPSERT_SQL$1, entryParams(entry))) {
1373
+ execSql$1(state.db, "ROLLBACK");
1374
1374
  return false;
1375
1375
  }
1376
1376
  }
1377
- return execSql(state.db, "COMMIT");
1377
+ return execSql$1(state.db, "COMMIT");
1378
1378
  } catch (err) {
1379
- execSql(state.db, "ROLLBACK");
1379
+ execSql$1(state.db, "ROLLBACK");
1380
1380
  logger.warn("[sqliteLogIndex] Failed to replace SQLite index:", String(err));
1381
1381
  return false;
1382
1382
  }
@@ -1986,6 +1986,342 @@ function apiFormatForPath(path2) {
1986
1986
  formatRegistry.registerPath(PATH_V1_MESSAGES, "anthropic");
1987
1987
  formatRegistry.registerPath(PATH_V1_CHAT_COMPLETIONS, "openai");
1988
1988
  formatRegistry.registerPath(PATH_CHAT_COMPLETIONS, "openai");
1989
+ const SESSION_ARCHIVE_DIR = "sessions";
1990
+ const SESSION_ARCHIVE_FILE = "session.sqlite";
1991
+ const SQLITE_PACKAGE_NAME = "better-sqlite3";
1992
+ const BUN_SQLITE_MODULE_NAME = "bun:sqlite";
1993
+ const CREATE_SCHEMA_SQL = `
1994
+ CREATE TABLE IF NOT EXISTS session_logs (
1995
+ id INTEGER PRIMARY KEY,
1996
+ session_id TEXT NOT NULL,
1997
+ log_json TEXT NOT NULL,
1998
+ updated_at TEXT NOT NULL
1999
+ );
2000
+ CREATE INDEX IF NOT EXISTS idx_session_logs_session_id_id ON session_logs(session_id, id);
2001
+ `;
2002
+ const UPSERT_SQL = `
2003
+ INSERT INTO session_logs (
2004
+ id,
2005
+ session_id,
2006
+ log_json,
2007
+ updated_at
2008
+ ) VALUES (?, ?, ?, ?)
2009
+ ON CONFLICT(id) DO UPDATE SET
2010
+ session_id = excluded.session_id,
2011
+ log_json = excluded.log_json,
2012
+ updated_at = excluded.updated_at
2013
+ `;
2014
+ let didLogUnavailable = false;
2015
+ function getSessionArchiveRoot() {
2016
+ return join(resolveLogDir(), SESSION_ARCHIVE_DIR);
2017
+ }
2018
+ function hashSessionId(sessionId) {
2019
+ return createHash("sha256").update(sessionId).digest("hex").slice(0, 16);
2020
+ }
2021
+ function sanitizeSessionPrefix(sessionId) {
2022
+ const trimmed = sessionId.trim();
2023
+ if (trimmed.length === 0) return "session";
2024
+ const normalized = trimmed.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
2025
+ if (normalized.length === 0) return "session";
2026
+ return normalized.slice(0, 48);
2027
+ }
2028
+ function sessionArchiveKey(sessionId) {
2029
+ return `${sanitizeSessionPrefix(sessionId)}--${hashSessionId(sessionId)}`;
2030
+ }
2031
+ function getSessionArchivePath(sessionId) {
2032
+ return join(getSessionArchiveRoot(), sessionArchiveKey(sessionId), SESSION_ARCHIVE_FILE);
2033
+ }
2034
+ function objectFromUnknown(value) {
2035
+ if (value === null) return null;
2036
+ if (typeof value === "object" || typeof value === "function") return value;
2037
+ return null;
2038
+ }
2039
+ function readProperty$1(value, name) {
2040
+ let current = objectFromUnknown(value);
2041
+ while (current !== null) {
2042
+ const desc = Object.getOwnPropertyDescriptor(current, name);
2043
+ if (desc !== void 0) {
2044
+ const propertyValue = Reflect.get(current, name);
2045
+ return propertyValue;
2046
+ }
2047
+ const nextPrototype = Object.getPrototypeOf(current);
2048
+ current = objectFromUnknown(nextPrototype);
2049
+ }
2050
+ return void 0;
2051
+ }
2052
+ function readFunction(value, name) {
2053
+ const property = readProperty$1(value, name);
2054
+ return typeof property === "function" ? property : null;
2055
+ }
2056
+ function callMethod(target, methodName, args) {
2057
+ const method = readFunction(target, methodName);
2058
+ if (method === null) return void 0;
2059
+ try {
2060
+ return Reflect.apply(method, target, [...args]);
2061
+ } catch (err) {
2062
+ logger.warn("[sessionArchive] SQLite method failed:", methodName, String(err));
2063
+ return void 0;
2064
+ }
2065
+ }
2066
+ function prepareStatement(db, sql) {
2067
+ return callMethod(db, "prepare", [sql]);
2068
+ }
2069
+ function runPrepared(db, sql, params = []) {
2070
+ const statement = prepareStatement(db, sql);
2071
+ if (statement === void 0) return false;
2072
+ const result = callMethod(statement, "run", params);
2073
+ callMethod(statement, "finalize", []);
2074
+ return result !== void 0;
2075
+ }
2076
+ function allPrepared(db, sql, params = []) {
2077
+ const statement = prepareStatement(db, sql);
2078
+ if (statement === void 0) return [];
2079
+ const result = callMethod(statement, "all", params);
2080
+ callMethod(statement, "finalize", []);
2081
+ return Array.isArray(result) ? result : [];
2082
+ }
2083
+ function execSql(db, sql) {
2084
+ const result = callMethod(db, "exec", [sql]);
2085
+ return result !== void 0;
2086
+ }
2087
+ function closeDatabase(db) {
2088
+ callMethod(db, "close", []);
2089
+ }
2090
+ function sqliteConstructorFromModule(moduleValue, exportName) {
2091
+ const exportedValue = readProperty$1(moduleValue, exportName);
2092
+ if (typeof exportedValue === "function") {
2093
+ return (path2) => Reflect.construct(exportedValue, [path2]);
2094
+ }
2095
+ return null;
2096
+ }
2097
+ async function loadSqliteModuleConstructor(moduleName, exportName) {
2098
+ try {
2099
+ const importedModule = await import(
2100
+ /* @vite-ignore */
2101
+ moduleName
2102
+ );
2103
+ const exportedConstructor = sqliteConstructorFromModule(importedModule, exportName);
2104
+ if (exportedConstructor !== null) return { constructor: exportedConstructor, reason: null };
2105
+ if (exportName === "default" && typeof importedModule === "function") {
2106
+ return {
2107
+ constructor: (path2) => Reflect.construct(importedModule, [path2]),
2108
+ reason: null
2109
+ };
2110
+ }
2111
+ return { constructor: null, reason: `${moduleName} did not expose ${exportName}` };
2112
+ } catch (err) {
2113
+ return { constructor: null, reason: String(err) };
2114
+ }
2115
+ }
2116
+ async function loadSqliteConstructor() {
2117
+ const bunRuntimeDesc = Object.getOwnPropertyDescriptor(process.versions, "bun");
2118
+ if (bunRuntimeDesc !== void 0) {
2119
+ const bunSqlite2 = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
2120
+ if (bunSqlite2.constructor !== null) return bunSqlite2;
2121
+ const betterSqlite2 = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
2122
+ if (betterSqlite2.constructor !== null) return betterSqlite2;
2123
+ return {
2124
+ constructor: null,
2125
+ reason: [bunSqlite2.reason, betterSqlite2.reason].filter((item) => item !== null).join("; ")
2126
+ };
2127
+ }
2128
+ const betterSqlite = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
2129
+ if (betterSqlite.constructor !== null) return betterSqlite;
2130
+ const bunSqlite = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
2131
+ if (bunSqlite.constructor !== null) return bunSqlite;
2132
+ return {
2133
+ constructor: null,
2134
+ reason: [betterSqlite.reason, bunSqlite.reason].filter((item) => item !== null).join("; ")
2135
+ };
2136
+ }
2137
+ function logUnavailableOnce(reason) {
2138
+ if (didLogUnavailable) return;
2139
+ didLogUnavailable = true;
2140
+ logger.warn("[sessionArchive] Optional session archive unavailable:", reason);
2141
+ }
2142
+ async function openSessionArchiveDb(filePath, create) {
2143
+ if (!create && !existsSync(filePath)) return null;
2144
+ const sqliteConstructor = await loadSqliteConstructor();
2145
+ if (sqliteConstructor.constructor === null) {
2146
+ logUnavailableOnce(sqliteConstructor.reason ?? "SQLite runtime is not available");
2147
+ return null;
2148
+ }
2149
+ try {
2150
+ if (create) await mkdir(dirname(filePath), { recursive: true });
2151
+ const db = sqliteConstructor.constructor(filePath);
2152
+ execSql(db, "PRAGMA journal_mode = WAL");
2153
+ execSql(db, "PRAGMA synchronous = NORMAL");
2154
+ if (!execSql(db, CREATE_SCHEMA_SQL)) {
2155
+ closeDatabase(db);
2156
+ logger.warn("[sessionArchive] Failed to initialize schema:", filePath);
2157
+ return null;
2158
+ }
2159
+ return db;
2160
+ } catch (err) {
2161
+ logger.warn("[sessionArchive] Failed to open session archive:", filePath, String(err));
2162
+ return null;
2163
+ }
2164
+ }
2165
+ async function archiveSessionLog(log) {
2166
+ const sessionId = log.sessionId;
2167
+ if (sessionId === null || sessionId.trim().length === 0) return false;
2168
+ const db = await openSessionArchiveDb(getSessionArchivePath(sessionId), true);
2169
+ if (db === null) return false;
2170
+ try {
2171
+ return runPrepared(db, UPSERT_SQL, [
2172
+ log.id,
2173
+ sessionId,
2174
+ JSON.stringify(log),
2175
+ (/* @__PURE__ */ new Date()).toISOString()
2176
+ ]);
2177
+ } finally {
2178
+ closeDatabase(db);
2179
+ }
2180
+ }
2181
+ function readString$1(row, name) {
2182
+ const value = readProperty$1(row, name);
2183
+ return typeof value === "string" ? value : null;
2184
+ }
2185
+ function readNumber(row, name) {
2186
+ const value = readProperty$1(row, name);
2187
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
2188
+ }
2189
+ function logFromJson(value) {
2190
+ if (value === null) return null;
2191
+ try {
2192
+ const parsed = JSON.parse(value);
2193
+ const result = CapturedLogSchema.safeParse(parsed);
2194
+ return result.success ? result.data : null;
2195
+ } catch {
2196
+ return null;
2197
+ }
2198
+ }
2199
+ function logsFromRows(rows) {
2200
+ const logs = [];
2201
+ for (const row of rows) {
2202
+ const log = logFromJson(readString$1(row, "log_json"));
2203
+ if (log !== null) logs.push(log);
2204
+ }
2205
+ return logs;
2206
+ }
2207
+ async function listArchivedSessionLogs(sessionId) {
2208
+ const db = await openSessionArchiveDb(getSessionArchivePath(sessionId), false);
2209
+ if (db === null) return [];
2210
+ try {
2211
+ const rows = allPrepared(
2212
+ db,
2213
+ "SELECT log_json FROM session_logs WHERE session_id = ? ORDER BY id ASC",
2214
+ [sessionId]
2215
+ );
2216
+ return logsFromRows(rows);
2217
+ } finally {
2218
+ closeDatabase(db);
2219
+ }
2220
+ }
2221
+ async function listArchivedSessionIds() {
2222
+ const archivePaths = await listArchiveDatabasePaths();
2223
+ const sessionIds = /* @__PURE__ */ new Set();
2224
+ for (const archivePath of archivePaths) {
2225
+ const db = await openSessionArchiveDb(archivePath, false);
2226
+ if (db === null) continue;
2227
+ try {
2228
+ const rows = allPrepared(
2229
+ db,
2230
+ "SELECT DISTINCT session_id FROM session_logs ORDER BY session_id ASC"
2231
+ );
2232
+ for (const row of rows) {
2233
+ const sessionId = readString$1(row, "session_id");
2234
+ if (sessionId !== null && sessionId.length > 0) sessionIds.add(sessionId);
2235
+ }
2236
+ } finally {
2237
+ closeDatabase(db);
2238
+ }
2239
+ }
2240
+ return [...sessionIds].sort();
2241
+ }
2242
+ async function listArchiveDatabasePaths() {
2243
+ const root = getSessionArchiveRoot();
2244
+ if (!existsSync(root)) return [];
2245
+ try {
2246
+ const entries = await readdir(root, { withFileTypes: true });
2247
+ const paths = [];
2248
+ for (const entry of entries) {
2249
+ if (!entry.isDirectory()) continue;
2250
+ const candidate = join(root, entry.name, SESSION_ARCHIVE_FILE);
2251
+ if (existsSync(candidate)) paths.push(candidate);
2252
+ }
2253
+ return paths;
2254
+ } catch (err) {
2255
+ logger.warn("[sessionArchive] Failed to list session archives:", String(err));
2256
+ return [];
2257
+ }
2258
+ }
2259
+ async function findArchivedLogById(id) {
2260
+ const archivePaths = await listArchiveDatabasePaths();
2261
+ for (const archivePath of archivePaths) {
2262
+ const db = await openSessionArchiveDb(archivePath, false);
2263
+ if (db === null) continue;
2264
+ try {
2265
+ const rows = allPrepared(db, "SELECT log_json FROM session_logs WHERE id = ? LIMIT 1", [id]);
2266
+ const first = logsFromRows(rows)[0];
2267
+ if (first !== void 0) return first;
2268
+ } finally {
2269
+ closeDatabase(db);
2270
+ }
2271
+ }
2272
+ return null;
2273
+ }
2274
+ function placeholders(count) {
2275
+ return Array.from({ length: count }, () => "?").join(", ");
2276
+ }
2277
+ function idsFromRows(rows) {
2278
+ const ids = /* @__PURE__ */ new Set();
2279
+ for (const row of rows) {
2280
+ const id = readNumber(row, "id");
2281
+ if (id !== null && Number.isInteger(id)) ids.add(id);
2282
+ }
2283
+ return ids;
2284
+ }
2285
+ async function deleteArchivedLogsByIds(ids) {
2286
+ if (ids.size === 0) return /* @__PURE__ */ new Set();
2287
+ const removedIds = /* @__PURE__ */ new Set();
2288
+ const idValues = [...ids];
2289
+ const sqlPlaceholders = placeholders(idValues.length);
2290
+ const archivePaths = await listArchiveDatabasePaths();
2291
+ for (const archivePath of archivePaths) {
2292
+ const db = await openSessionArchiveDb(archivePath, false);
2293
+ if (db === null) continue;
2294
+ try {
2295
+ const matchingRows = allPrepared(
2296
+ db,
2297
+ `SELECT id FROM session_logs WHERE id IN (${sqlPlaceholders})`,
2298
+ idValues
2299
+ );
2300
+ const matchingIds = idsFromRows(matchingRows);
2301
+ if (matchingIds.size === 0) continue;
2302
+ if (runPrepared(db, `DELETE FROM session_logs WHERE id IN (${sqlPlaceholders})`, idValues)) {
2303
+ for (const id of matchingIds) {
2304
+ removedIds.add(id);
2305
+ }
2306
+ }
2307
+ } finally {
2308
+ closeDatabase(db);
2309
+ }
2310
+ }
2311
+ return removedIds;
2312
+ }
2313
+ async function clearSessionArchives() {
2314
+ const root = getSessionArchiveRoot();
2315
+ if (!existsSync(root)) return 0;
2316
+ const archivePaths = await listArchiveDatabasePaths();
2317
+ try {
2318
+ await rm(root, { recursive: true, force: true });
2319
+ return archivePaths.length;
2320
+ } catch (err) {
2321
+ logger.warn("[sessionArchive] Failed to clear session archives:", String(err));
2322
+ return 0;
2323
+ }
2324
+ }
1989
2325
  const IDLE_TIMEOUT_MS = Number(process.env["SESSION_PROCESS_IDLE_MS"]) || 5 * 60 * 1e3;
1990
2326
  const MAX_RESTARTS = 3;
1991
2327
  const _processes = /* @__PURE__ */ new Map();
@@ -2286,6 +2622,7 @@ const MAX_MEMORY_CACHE = 100;
2286
2622
  const memoryCache = /* @__PURE__ */ new Map();
2287
2623
  const MAX_CURSOR_PAGE_INDEXES = 16;
2288
2624
  const logCursorPageIndexes = /* @__PURE__ */ new Map();
2625
+ let sessionArchiveQueue = Promise.resolve();
2289
2626
  function cursorPageIndexKey(options) {
2290
2627
  return JSON.stringify({
2291
2628
  sessionId: options.sessionId ?? null,
@@ -2355,6 +2692,17 @@ function addToCache(log) {
2355
2692
  upsertLogCursorPageIndexes(cachedLog);
2356
2693
  evictOldestIfNeeded();
2357
2694
  }
2695
+ function archiveLogSnapshot(log) {
2696
+ const archivedLog = normalizeLog(log);
2697
+ sessionArchiveQueue = sessionArchiveQueue.catch(() => void 0).then(async () => {
2698
+ await archiveSessionLog(archivedLog);
2699
+ }).catch((err) => {
2700
+ logger.warn("[store] Failed to archive session log:", String(err));
2701
+ });
2702
+ }
2703
+ async function flushSessionArchiveWrites() {
2704
+ await sessionArchiveQueue;
2705
+ }
2358
2706
  function removeFromCache(id) {
2359
2707
  memoryCache.delete(id);
2360
2708
  removeLogsFromCursorPageIndexes(/* @__PURE__ */ new Set([id]));
@@ -2443,6 +2791,7 @@ async function addTestLogEntry(entry) {
2443
2791
  await addToIndex(id, logFile, -1, -1, createLogIndexEntryMetadata(log));
2444
2792
  });
2445
2793
  addToCache(log);
2794
+ archiveLogSnapshot(log);
2446
2795
  observeSessionLog(log, session.source);
2447
2796
  emitLogUpdate(log);
2448
2797
  return log;
@@ -2506,15 +2855,26 @@ async function createLog(method, path2, requestBody, headers, clientInfo, rawHea
2506
2855
  await addToIndex(id, logFile, -1, -1, createLogIndexEntryMetadata(log));
2507
2856
  });
2508
2857
  addToCache(log);
2858
+ archiveLogSnapshot(log);
2509
2859
  markSessionStarted(log, session.source);
2510
2860
  emitLogUpdate(log);
2511
2861
  return log;
2512
2862
  }
2513
2863
  function finalizeLogUpdate(log) {
2514
2864
  addToCache(log);
2865
+ archiveLogSnapshot(log);
2515
2866
  markSessionFinished(log);
2516
2867
  emitLogUpdate(log);
2517
2868
  }
2869
+ async function getArchivedLogByIdForStore(id) {
2870
+ await flushSessionArchiveWrites();
2871
+ const archivedLog = await findArchivedLogById(id);
2872
+ if (archivedLog === null) return null;
2873
+ const normalized = normalizeLog(archivedLog);
2874
+ addToCache(normalized);
2875
+ observeSessionLog(normalized);
2876
+ return normalized;
2877
+ }
2518
2878
  async function getLogById(id) {
2519
2879
  const cached = memoryCache.get(id);
2520
2880
  if (cached !== void 0) {
@@ -2522,12 +2882,12 @@ async function getLogById(id) {
2522
2882
  }
2523
2883
  const entry = await findInIndex(id);
2524
2884
  if (entry === null) {
2525
- return null;
2885
+ return await getArchivedLogByIdForStore(id);
2526
2886
  }
2527
2887
  try {
2528
2888
  const filePath = join(resolveLogDir(), entry.file);
2529
2889
  if (!existsSync(filePath)) {
2530
- return null;
2890
+ return await getArchivedLogByIdForStore(id);
2531
2891
  }
2532
2892
  if (entry.byteOffset >= 0 && entry.byteLength > 0) {
2533
2893
  const fh = await open(filePath, "r");
@@ -2559,7 +2919,7 @@ async function getLogById(id) {
2559
2919
  } catch (err) {
2560
2920
  logger.error("[store] Failed to read log from disk:", String(err));
2561
2921
  }
2562
- return null;
2922
+ return await getArchivedLogByIdForStore(id);
2563
2923
  }
2564
2924
  async function scanLogFileForId(filePath, id) {
2565
2925
  let lastMatch = null;
@@ -2634,6 +2994,16 @@ async function visitPersistedLogFile(filePath, visitor) {
2634
2994
  logger.error("[store] Failed to read persisted log file:", filePath, String(err));
2635
2995
  }
2636
2996
  }
2997
+ async function visitArchivedSessionLogs(sessionId, visitor) {
2998
+ if (sessionId === void 0) return;
2999
+ await flushSessionArchiveWrites();
3000
+ const logs = await listArchivedSessionLogs(sessionId);
3001
+ for (const archivedLog of logs) {
3002
+ const log = normalizeLog(archivedLog);
3003
+ observeSessionLog(log);
3004
+ visitor(log);
3005
+ }
3006
+ }
2637
3007
  function canUseIndexedListPage(options) {
2638
3008
  return options.sessionId === void 0 && options.model === void 0;
2639
3009
  }
@@ -2698,6 +3068,7 @@ async function listLogsPage(options) {
2698
3068
  observeSessionLog(log);
2699
3069
  visitLog(log);
2700
3070
  });
3071
+ await visitArchivedSessionLogs(options.sessionId, visitLog);
2701
3072
  for (const log of memoryCache.values()) {
2702
3073
  visitLog(log);
2703
3074
  }
@@ -2785,6 +3156,17 @@ async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
2785
3156
  idsById.add(log.id);
2786
3157
  logsById.set(log.id, log);
2787
3158
  }
3159
+ if (options.sessionId !== void 0) {
3160
+ await flushSessionArchiveWrites();
3161
+ const archivedLogs = await listArchivedSessionLogs(options.sessionId);
3162
+ for (const archivedLog of archivedLogs) {
3163
+ const log = normalizeLog(archivedLog);
3164
+ if (!matchesLogFilters(log, options.sessionId, options.model)) continue;
3165
+ observeSessionLog(log);
3166
+ idsById.add(log.id);
3167
+ logsById.set(log.id, log);
3168
+ }
3169
+ }
2788
3170
  return {
2789
3171
  key: cursorPageIndexKey(options),
2790
3172
  sessionId: options.sessionId,
@@ -2807,6 +3189,7 @@ async function buildLogCursorPageIndex(options) {
2807
3189
  observeSessionLog(log);
2808
3190
  visitLog(log);
2809
3191
  });
3192
+ await visitArchivedSessionLogs(options.sessionId, visitLog);
2810
3193
  for (const log of memoryCache.values()) {
2811
3194
  visitLog(log);
2812
3195
  }
@@ -2899,6 +3282,15 @@ async function collectSessionLogSummaries(sessionId, includeHistory) {
2899
3282
  for (const summary of indexedSummaries) {
2900
3283
  summariesById.set(summary.id, summary);
2901
3284
  }
3285
+ await flushSessionArchiveWrites();
3286
+ const archivedLogs = await listArchivedSessionLogs(sessionId);
3287
+ for (const archivedLog of archivedLogs) {
3288
+ const log = normalizeLog(archivedLog);
3289
+ observeSessionLog(log);
3290
+ if (!summariesById.has(log.id)) {
3291
+ summariesById.set(log.id, buildSessionLogSummary(log));
3292
+ }
3293
+ }
2902
3294
  if (includeHistory && summariesById.size === 0) {
2903
3295
  await visitPersistedLogs((log) => {
2904
3296
  observeSessionLog(log);
@@ -2954,8 +3346,13 @@ async function getSessionInfo(sessionId, options) {
2954
3346
  latestLogLimit: options.latestLogLimit
2955
3347
  });
2956
3348
  }
2957
- function getSessions() {
2958
- return getSessionIds();
3349
+ async function listSessions() {
3350
+ await flushSessionArchiveWrites();
3351
+ const sessionIds = new Set(getSessionIds());
3352
+ for (const sessionId of await listArchivedSessionIds()) {
3353
+ sessionIds.add(sessionId);
3354
+ }
3355
+ return [...sessionIds].sort();
2959
3356
  }
2960
3357
  function getModels() {
2961
3358
  const set = /* @__PURE__ */ new Set();
@@ -2999,8 +3396,13 @@ function collectDirectoryStats(dir, shouldCount) {
2999
3396
  function getLogStorageStats() {
3000
3397
  const logDir = resolveLogDir();
3001
3398
  const chunkDir = getChunksDir();
3399
+ const sessionArchiveDir = getSessionArchiveRoot();
3002
3400
  const logStats = collectDirectoryStats(logDir, (fileName) => fileName.endsWith(".jsonl"));
3003
3401
  const chunkStats = collectDirectoryStats(chunkDir, (fileName) => fileName.endsWith(".json"));
3402
+ const sessionArchiveStats = collectDirectoryStats(
3403
+ sessionArchiveDir,
3404
+ (fileName) => fileName === "session.sqlite" || fileName.startsWith("session.sqlite-")
3405
+ );
3004
3406
  return {
3005
3407
  memoryCount: memoryCache.size,
3006
3408
  logDir,
@@ -3008,7 +3410,10 @@ function getLogStorageStats() {
3008
3410
  logBytes: logStats.bytes,
3009
3411
  chunkDir,
3010
3412
  chunkFileCount: chunkStats.fileCount,
3011
- chunkBytes: chunkStats.bytes
3413
+ chunkBytes: chunkStats.bytes,
3414
+ sessionArchiveDir,
3415
+ sessionArchiveFileCount: sessionArchiveStats.fileCount,
3416
+ sessionArchiveBytes: sessionArchiveStats.bytes
3012
3417
  };
3013
3418
  }
3014
3419
  function clearAllLogs() {
@@ -3043,8 +3448,9 @@ async function deleteMatchingFiles(dir, shouldDelete) {
3043
3448
  async function clearPersistedLogStorage() {
3044
3449
  return await runWithFlushedLogWriteLock(async () => {
3045
3450
  await flushIndex();
3451
+ await flushSessionArchiveWrites();
3046
3452
  const result = clearAllLogs();
3047
- const [logFilesDeleted, chunkFilesDeleted] = await Promise.all([
3453
+ const [logFilesDeleted, chunkFilesDeleted, sessionArchiveFilesDeleted] = await Promise.all([
3048
3454
  deleteMatchingFiles(
3049
3455
  resolveLogDir(),
3050
3456
  (fileName) => fileName.endsWith(".jsonl") || fileName === "logs.idx" || fileName === "inspector.sqlite" || fileName.startsWith("inspector.sqlite-")
@@ -3052,13 +3458,15 @@ async function clearPersistedLogStorage() {
3052
3458
  deleteMatchingFiles(
3053
3459
  getChunksDir(),
3054
3460
  (fileName) => fileName.endsWith(".json") || fileName.startsWith(".") && fileName.endsWith(".tmp")
3055
- )
3461
+ ),
3462
+ clearSessionArchives()
3056
3463
  ]);
3057
3464
  await rebuildIndex();
3058
3465
  return {
3059
3466
  cleared: result.cleared,
3060
3467
  logFilesDeleted,
3061
- chunkFilesDeleted
3468
+ chunkFilesDeleted,
3469
+ sessionArchiveFilesDeleted
3062
3470
  };
3063
3471
  });
3064
3472
  }
@@ -3214,18 +3622,25 @@ async function deleteChunkFilesByIds(ids) {
3214
3622
  async function clearPersistedLogsByIds(ids) {
3215
3623
  const uniqueIds = new Set(ids);
3216
3624
  if (uniqueIds.size === 0) {
3217
- return { cleared: 0, logFilesRewritten: 0, chunkFilesDeleted: 0 };
3625
+ return {
3626
+ cleared: 0,
3627
+ logFilesRewritten: 0,
3628
+ chunkFilesDeleted: 0,
3629
+ sessionArchiveLogsDeleted: 0
3630
+ };
3218
3631
  }
3219
3632
  return await runWithFlushedLogWriteLock(async () => {
3220
3633
  await flushIndex();
3634
+ await flushSessionArchiveWrites();
3221
3635
  const memoryRemovedIds = /* @__PURE__ */ new Set();
3222
3636
  for (const id of uniqueIds) {
3223
3637
  if (memoryCache.has(id)) memoryRemovedIds.add(id);
3224
3638
  }
3225
3639
  const result = clearLogsByIds([...uniqueIds]);
3226
- const [rewriteResult, chunkFilesDeleted] = await Promise.all([
3640
+ const [rewriteResult, chunkFilesDeleted, archivedRemovedIds] = await Promise.all([
3227
3641
  rewriteLogFilesWithoutIds(uniqueIds),
3228
- deleteChunkFilesByIds(uniqueIds)
3642
+ deleteChunkFilesByIds(uniqueIds),
3643
+ deleteArchivedLogsByIds(uniqueIds)
3229
3644
  ]);
3230
3645
  await rebuildIndex();
3231
3646
  clearLogCursorPageIndexes();
@@ -3235,10 +3650,14 @@ async function clearPersistedLogsByIds(ids) {
3235
3650
  clearedIds.add(id);
3236
3651
  }
3237
3652
  }
3653
+ for (const id of archivedRemovedIds) {
3654
+ clearedIds.add(id);
3655
+ }
3238
3656
  return {
3239
3657
  cleared: clearedIds.size,
3240
3658
  logFilesRewritten: rewriteResult.logFilesRewritten,
3241
- chunkFilesDeleted
3659
+ chunkFilesDeleted,
3660
+ sessionArchiveLogsDeleted: archivedRemovedIds.size
3242
3661
  };
3243
3662
  });
3244
3663
  }
@@ -6426,7 +6845,7 @@ const Route$z = createFileRoute("/api/sessions")({
6426
6845
  if (details === "true" || details === "1") {
6427
6846
  return Response.json(getSessionSnapshots());
6428
6847
  }
6429
- return Response.json(getSessions());
6848
+ return Response.json(await listSessions());
6430
6849
  }
6431
6850
  }
6432
6851
  }
@@ -7926,7 +8345,7 @@ const Route$w = createFileRoute("/api/models")({
7926
8345
  }
7927
8346
  }
7928
8347
  });
7929
- const version = "2.1.6";
8348
+ const version = "2.1.7";
7930
8349
  const packageJson = {
7931
8350
  version
7932
8351
  };
@@ -10631,7 +11050,8 @@ const Route$u = createFileRoute("/api/logs")({
10631
11050
  success: true,
10632
11051
  cleared: result2.cleared,
10633
11052
  logFilesRewritten: result2.logFilesRewritten,
10634
- chunkFilesDeleted: result2.chunkFilesDeleted
11053
+ chunkFilesDeleted: result2.chunkFilesDeleted,
11054
+ sessionArchiveLogsDeleted: result2.sessionArchiveLogsDeleted
10635
11055
  });
10636
11056
  }
10637
11057
  const result = await clearPersistedLogStorage();
@@ -10639,7 +11059,8 @@ const Route$u = createFileRoute("/api/logs")({
10639
11059
  success: true,
10640
11060
  cleared: result.cleared,
10641
11061
  logFilesDeleted: result.logFilesDeleted,
10642
- chunkFilesDeleted: result.chunkFilesDeleted
11062
+ chunkFilesDeleted: result.chunkFilesDeleted,
11063
+ sessionArchiveFilesDeleted: result.sessionArchiveFilesDeleted
10643
11064
  });
10644
11065
  }
10645
11066
  }