crosscheck-mcp 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,34 +1,45 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
4
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
5
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
6
  }) : x)(function(x) {
5
7
  if (typeof require !== "undefined") return require.apply(this, arguments);
6
8
  throw Error('Dynamic require of "' + x + '" is not supported');
7
9
  });
10
+ var __esm = (fn, res) => function __init() {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ };
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
8
17
 
9
18
  // node_modules/tsup/assets/esm_shims.js
10
19
  import path from "path";
11
20
  import { fileURLToPath } from "url";
12
- var getFilename = () => fileURLToPath(import.meta.url);
13
- var getDirname = () => path.dirname(getFilename());
14
- var __dirname = /* @__PURE__ */ getDirname();
15
-
16
- // src/entrypoints/node-stdio.ts
17
- import { existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
18
- import path9 from "path";
19
- import { fileURLToPath as fileURLToPath3 } from "url";
20
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
-
22
- // src/adapters/storage/better-sqlite3.ts
23
- import DatabaseCtor from "better-sqlite3";
21
+ var getFilename, getDirname, __dirname;
22
+ var init_esm_shims = __esm({
23
+ "node_modules/tsup/assets/esm_shims.js"() {
24
+ "use strict";
25
+ getFilename = () => fileURLToPath(import.meta.url);
26
+ getDirname = () => path.dirname(getFilename());
27
+ __dirname = /* @__PURE__ */ getDirname();
28
+ }
29
+ });
24
30
 
25
31
  // src/adapters/storage/migrations/0001_init.ts
26
- var m0001_init = {
27
- id: "0001_init",
28
- name: "initial schema (sessions, usage_log, claims, ...)",
29
- up: [
30
- // sessions — includes the totals columns that Python adds via ALTER.
31
- `CREATE TABLE IF NOT EXISTS sessions (
32
+ var m0001_init;
33
+ var init_init = __esm({
34
+ "src/adapters/storage/migrations/0001_init.ts"() {
35
+ "use strict";
36
+ init_esm_shims();
37
+ m0001_init = {
38
+ id: "0001_init",
39
+ name: "initial schema (sessions, usage_log, claims, ...)",
40
+ up: [
41
+ // sessions — includes the totals columns that Python adds via ALTER.
42
+ `CREATE TABLE IF NOT EXISTS sessions (
32
43
  session_id TEXT PRIMARY KEY,
33
44
  started_at INTEGER NOT NULL,
34
45
  last_at INTEGER,
@@ -42,8 +53,8 @@ var m0001_init = {
42
53
  total_cost_usd REAL NOT NULL DEFAULT 0.0,
43
54
  total_cpu_ms INTEGER NOT NULL DEFAULT 0
44
55
  )`,
45
- // usage_log — per-call ledger.
46
- `CREATE TABLE IF NOT EXISTS usage_log (
56
+ // usage_log — per-call ledger.
57
+ `CREATE TABLE IF NOT EXISTS usage_log (
47
58
  id INTEGER PRIMARY KEY AUTOINCREMENT,
48
59
  session_id TEXT NOT NULL,
49
60
  ts INTEGER NOT NULL,
@@ -60,10 +71,10 @@ var m0001_init = {
60
71
  wall_ms INTEGER NOT NULL DEFAULT 0,
61
72
  cpu_ms INTEGER NOT NULL DEFAULT 0
62
73
  )`,
63
- `CREATE INDEX IF NOT EXISTS idx_usage_session ON usage_log(session_id)`,
64
- `CREATE INDEX IF NOT EXISTS idx_usage_provider ON usage_log(provider)`,
65
- // claims (FK to sessions, ON DELETE CASCADE).
66
- `CREATE TABLE IF NOT EXISTS claims (
74
+ `CREATE INDEX IF NOT EXISTS idx_usage_session ON usage_log(session_id)`,
75
+ `CREATE INDEX IF NOT EXISTS idx_usage_provider ON usage_log(provider)`,
76
+ // claims (FK to sessions, ON DELETE CASCADE).
77
+ `CREATE TABLE IF NOT EXISTS claims (
67
78
  id INTEGER PRIMARY KEY AUTOINCREMENT,
68
79
  session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
69
80
  text TEXT NOT NULL,
@@ -73,10 +84,10 @@ var m0001_init = {
73
84
  kind TEXT,
74
85
  created_at INTEGER NOT NULL
75
86
  )`,
76
- `CREATE INDEX IF NOT EXISTS idx_claims_session ON claims(session_id)`,
77
- // claim_links (FK to claims). Kind enum widened in Python's
78
- // _migrate_claim_links_check; mirrored here as the CHECK clause.
79
- `CREATE TABLE IF NOT EXISTS claim_links (
87
+ `CREATE INDEX IF NOT EXISTS idx_claims_session ON claims(session_id)`,
88
+ // claim_links (FK to claims). Kind enum widened in Python's
89
+ // _migrate_claim_links_check; mirrored here as the CHECK clause.
90
+ `CREATE TABLE IF NOT EXISTS claim_links (
80
91
  id INTEGER PRIMARY KEY AUTOINCREMENT,
81
92
  src_id INTEGER NOT NULL REFERENCES claims(id) ON DELETE CASCADE,
82
93
  dst_id INTEGER NOT NULL REFERENCES claims(id) ON DELETE CASCADE,
@@ -84,18 +95,18 @@ var m0001_init = {
84
95
  created_at INTEGER NOT NULL,
85
96
  UNIQUE(src_id, dst_id, kind)
86
97
  )`,
87
- `CREATE INDEX IF NOT EXISTS idx_links_src ON claim_links(src_id)`,
88
- `CREATE INDEX IF NOT EXISTS idx_links_dst ON claim_links(dst_id)`,
89
- // provider_stats — ballots accumulator for the smart router.
90
- `CREATE TABLE IF NOT EXISTS provider_stats (
98
+ `CREATE INDEX IF NOT EXISTS idx_links_src ON claim_links(src_id)`,
99
+ `CREATE INDEX IF NOT EXISTS idx_links_dst ON claim_links(dst_id)`,
100
+ // provider_stats — ballots accumulator for the smart router.
101
+ `CREATE TABLE IF NOT EXISTS provider_stats (
91
102
  provider TEXT PRIMARY KEY,
92
103
  wins INTEGER NOT NULL DEFAULT 0,
93
104
  losses INTEGER NOT NULL DEFAULT 0,
94
105
  abstains INTEGER NOT NULL DEFAULT 0,
95
106
  last_at INTEGER
96
107
  )`,
97
- // delegations — cross-model handshake ledger.
98
- `CREATE TABLE IF NOT EXISTS delegations (
108
+ // delegations — cross-model handshake ledger.
109
+ `CREATE TABLE IF NOT EXISTS delegations (
99
110
  id INTEGER PRIMARY KEY AUTOINCREMENT,
100
111
  session_id TEXT,
101
112
  requester TEXT,
@@ -104,10 +115,10 @@ var m0001_init = {
104
115
  accepted INTEGER NOT NULL,
105
116
  created_at INTEGER NOT NULL
106
117
  )`,
107
- `CREATE INDEX IF NOT EXISTS idx_deleg_session ON delegations(session_id)`,
108
- `CREATE INDEX IF NOT EXISTS idx_deleg_req ON delegations(requester)`,
109
- // session_memory — facts / open_questions / decisions ledger.
110
- `CREATE TABLE IF NOT EXISTS session_memory (
118
+ `CREATE INDEX IF NOT EXISTS idx_deleg_session ON delegations(session_id)`,
119
+ `CREATE INDEX IF NOT EXISTS idx_deleg_req ON delegations(requester)`,
120
+ // session_memory — facts / open_questions / decisions ledger.
121
+ `CREATE TABLE IF NOT EXISTS session_memory (
111
122
  id INTEGER PRIMARY KEY AUTOINCREMENT,
112
123
  session_id TEXT NOT NULL,
113
124
  kind TEXT NOT NULL CHECK (kind IN ('fact','open_question','decision')),
@@ -119,27 +130,37 @@ var m0001_init = {
119
130
  stale_at INTEGER,
120
131
  stale_reason TEXT
121
132
  )`,
122
- `CREATE INDEX IF NOT EXISTS idx_session_memory_session ON session_memory(session_id)`,
123
- `CREATE INDEX IF NOT EXISTS idx_session_memory_kind ON session_memory(kind)`,
124
- // fetch_egress — per-session per-host byte ledger.
125
- `CREATE TABLE IF NOT EXISTS fetch_egress (
133
+ `CREATE INDEX IF NOT EXISTS idx_session_memory_session ON session_memory(session_id)`,
134
+ `CREATE INDEX IF NOT EXISTS idx_session_memory_kind ON session_memory(kind)`,
135
+ // fetch_egress — per-session per-host byte ledger.
136
+ `CREATE TABLE IF NOT EXISTS fetch_egress (
126
137
  session_id TEXT NOT NULL,
127
138
  host TEXT NOT NULL,
128
139
  total_bytes INTEGER NOT NULL DEFAULT 0,
129
140
  last_at INTEGER NOT NULL,
130
141
  PRIMARY KEY (session_id, host)
131
142
  )`,
132
- // transcripts_fts — FTS5 virtual table for the recall tool. Python uses
133
- // `tokenize='unicode61 remove_diacritics 2'`; mirrored exactly.
134
- `CREATE VIRTUAL TABLE IF NOT EXISTS transcripts_fts USING fts5(
143
+ // transcripts_fts — FTS5 virtual table for the recall tool. Python uses
144
+ // `tokenize='unicode61 remove_diacritics 2'`; mirrored exactly.
145
+ `CREATE VIRTUAL TABLE IF NOT EXISTS transcripts_fts USING fts5(
135
146
  session_id, tool, ts UNINDEXED, path UNINDEXED, content,
136
147
  tokenize='unicode61 remove_diacritics 2'
137
148
  )`
138
- ]
139
- };
149
+ ]
150
+ };
151
+ }
152
+ });
140
153
 
141
154
  // src/adapters/storage/migrations/index.ts
142
- var MIGRATIONS = [m0001_init];
155
+ var MIGRATIONS;
156
+ var init_migrations = __esm({
157
+ "src/adapters/storage/migrations/index.ts"() {
158
+ "use strict";
159
+ init_esm_shims();
160
+ init_init();
161
+ MIGRATIONS = [m0001_init];
162
+ }
163
+ });
143
164
 
144
165
  // src/adapters/storage/schema.ts
145
166
  function canonicalSchema(reader) {
@@ -256,19 +277,19 @@ function listFks(reader, table) {
256
277
  })
257
278
  ).sort((a, b) => a.id - b.id || a.seq - b.seq);
258
279
  }
280
+ var init_schema = __esm({
281
+ "src/adapters/storage/schema.ts"() {
282
+ "use strict";
283
+ init_esm_shims();
284
+ }
285
+ });
259
286
 
260
287
  // src/adapters/storage/better-sqlite3.ts
261
- var ALLOWED_LINK_KINDS = /* @__PURE__ */ new Set([
262
- "supports",
263
- "attacks",
264
- "derives_from",
265
- "merges_with"
266
- ]);
267
- var ALLOWED_MEMORY_KINDS = /* @__PURE__ */ new Set([
268
- "fact",
269
- "open_question",
270
- "decision"
271
- ]);
288
+ var better_sqlite3_exports = {};
289
+ __export(better_sqlite3_exports, {
290
+ openBetterSqliteStorage: () => openBetterSqliteStorage
291
+ });
292
+ import DatabaseCtor from "better-sqlite3";
272
293
  function openBetterSqliteStorage(opts) {
273
294
  const db = new DatabaseCtor(opts.path);
274
295
  const wantWal = opts.wal ?? opts.path !== ":memory:";
@@ -278,101 +299,119 @@ function openBetterSqliteStorage(opts) {
278
299
  db.pragma("foreign_keys = ON");
279
300
  return new BetterSqliteStorage(db);
280
301
  }
281
- var BetterSqliteStorage = class {
282
- constructor(db) {
283
- this.db = db;
284
- }
285
- db;
286
- stmts = /* @__PURE__ */ new Map();
287
- // ------------------------------------------------------------------
288
- // Lifecycle / lifetime
289
- // ------------------------------------------------------------------
290
- async migrate() {
291
- this.db.exec(
292
- "CREATE TABLE IF NOT EXISTS schema_migrations (id TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)"
293
- );
294
- const existing = new Set(
295
- this.db.prepare("SELECT id FROM schema_migrations").all().map((r) => r.id)
296
- );
297
- const applied = [];
298
- const ordered = [...MIGRATIONS].sort((a, b) => a.id.localeCompare(b.id));
299
- for (const m of ordered) {
300
- if (existing.has(m.id)) continue;
301
- this.applyMigration(m);
302
- applied.push(m.id);
303
- }
304
- return { applied };
305
- }
306
- applyMigration(m) {
307
- const txn = this.db.transaction(() => {
308
- for (const stmt of m.up) this.db.exec(stmt);
309
- this.db.prepare(
310
- "INSERT INTO schema_migrations(id, applied_at) VALUES (?, ?)"
311
- ).run(m.id, Date.now());
312
- });
313
- txn();
314
- }
315
- async canonicalSchema() {
316
- const reader = {
317
- pragma: (name, arg) => arg === void 0 ? this.db.pragma(name) : this.db.pragma(`${name}('${arg.replace(/'/g, "''")}')`),
318
- list: (sql) => this.db.prepare(sql).all()
319
- };
320
- return canonicalSchema(reader);
321
- }
322
- unsafe() {
323
- return {
324
- exec: async (sql, params) => {
325
- const stmt = this.db.prepare(sql);
326
- const info = stmt.run(...params ?? []);
327
- return Number(info.changes);
328
- },
329
- query: async (sql, params) => this.db.prepare(sql).all(...params ?? [])
330
- };
331
- }
332
- async close() {
333
- this.db.close();
334
- }
335
- // ------------------------------------------------------------------
336
- // Transactions. better-sqlite3 supports nested transactions via
337
- // SAVEPOINTs automatically when the outer caller is already inside
338
- // db.transaction(). We expose a Txn that mirrors Storage's surface;
339
- // every method call inside the callback runs inside the open txn.
340
- // ------------------------------------------------------------------
341
- async txn(fn) {
342
- this.db.exec("BEGIN IMMEDIATE");
343
- try {
344
- const result = await fn(this);
345
- this.db.exec("COMMIT");
346
- return result;
347
- } catch (e) {
348
- try {
349
- this.db.exec("ROLLBACK");
350
- } catch {
302
+ var ALLOWED_LINK_KINDS, ALLOWED_MEMORY_KINDS, BetterSqliteStorage;
303
+ var init_better_sqlite3 = __esm({
304
+ "src/adapters/storage/better-sqlite3.ts"() {
305
+ "use strict";
306
+ init_esm_shims();
307
+ init_migrations();
308
+ init_schema();
309
+ ALLOWED_LINK_KINDS = /* @__PURE__ */ new Set([
310
+ "supports",
311
+ "attacks",
312
+ "derives_from",
313
+ "merges_with"
314
+ ]);
315
+ ALLOWED_MEMORY_KINDS = /* @__PURE__ */ new Set([
316
+ "fact",
317
+ "open_question",
318
+ "decision"
319
+ ]);
320
+ BetterSqliteStorage = class {
321
+ constructor(db) {
322
+ this.db = db;
351
323
  }
352
- throw e;
353
- }
354
- }
355
- // ==================================================================
356
- // sessions
357
- // ==================================================================
358
- async getSession(sessionId) {
359
- const row = this.cached(
360
- "session-get",
361
- "SELECT * FROM sessions WHERE session_id = ?"
362
- ).get(sessionId);
363
- return row ?? null;
364
- }
365
- async listSessions(opts) {
366
- const limit = opts?.limit ?? 100;
367
- return this.cached(
368
- "session-list",
369
- "SELECT * FROM sessions ORDER BY last_at DESC LIMIT ?"
370
- ).all(limit);
371
- }
372
- async upsertSession(row) {
373
- this.cached(
374
- "session-upsert",
375
- `INSERT INTO sessions
324
+ db;
325
+ stmts = /* @__PURE__ */ new Map();
326
+ // ------------------------------------------------------------------
327
+ // Lifecycle / lifetime
328
+ // ------------------------------------------------------------------
329
+ async migrate() {
330
+ this.db.exec(
331
+ "CREATE TABLE IF NOT EXISTS schema_migrations (id TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)"
332
+ );
333
+ const existing = new Set(
334
+ this.db.prepare("SELECT id FROM schema_migrations").all().map((r) => r.id)
335
+ );
336
+ const applied = [];
337
+ const ordered = [...MIGRATIONS].sort((a, b) => a.id.localeCompare(b.id));
338
+ for (const m of ordered) {
339
+ if (existing.has(m.id)) continue;
340
+ this.applyMigration(m);
341
+ applied.push(m.id);
342
+ }
343
+ return { applied };
344
+ }
345
+ applyMigration(m) {
346
+ const txn = this.db.transaction(() => {
347
+ for (const stmt of m.up) this.db.exec(stmt);
348
+ this.db.prepare(
349
+ "INSERT INTO schema_migrations(id, applied_at) VALUES (?, ?)"
350
+ ).run(m.id, Date.now());
351
+ });
352
+ txn();
353
+ }
354
+ async canonicalSchema() {
355
+ const reader = {
356
+ pragma: (name, arg) => arg === void 0 ? this.db.pragma(name) : this.db.pragma(`${name}('${arg.replace(/'/g, "''")}')`),
357
+ list: (sql) => this.db.prepare(sql).all()
358
+ };
359
+ return canonicalSchema(reader);
360
+ }
361
+ unsafe() {
362
+ return {
363
+ exec: async (sql, params) => {
364
+ const stmt = this.db.prepare(sql);
365
+ const info = stmt.run(...params ?? []);
366
+ return Number(info.changes);
367
+ },
368
+ query: async (sql, params) => this.db.prepare(sql).all(...params ?? [])
369
+ };
370
+ }
371
+ async close() {
372
+ this.db.close();
373
+ }
374
+ // ------------------------------------------------------------------
375
+ // Transactions. better-sqlite3 supports nested transactions via
376
+ // SAVEPOINTs automatically when the outer caller is already inside
377
+ // db.transaction(). We expose a Txn that mirrors Storage's surface;
378
+ // every method call inside the callback runs inside the open txn.
379
+ // ------------------------------------------------------------------
380
+ async txn(fn) {
381
+ this.db.exec("BEGIN IMMEDIATE");
382
+ try {
383
+ const result = await fn(this);
384
+ this.db.exec("COMMIT");
385
+ return result;
386
+ } catch (e) {
387
+ try {
388
+ this.db.exec("ROLLBACK");
389
+ } catch {
390
+ }
391
+ throw e;
392
+ }
393
+ }
394
+ // ==================================================================
395
+ // sessions
396
+ // ==================================================================
397
+ async getSession(sessionId) {
398
+ const row = this.cached(
399
+ "session-get",
400
+ "SELECT * FROM sessions WHERE session_id = ?"
401
+ ).get(sessionId);
402
+ return row ?? null;
403
+ }
404
+ async listSessions(opts) {
405
+ const limit = opts?.limit ?? 100;
406
+ return this.cached(
407
+ "session-list",
408
+ "SELECT * FROM sessions ORDER BY last_at DESC LIMIT ?"
409
+ ).all(limit);
410
+ }
411
+ async upsertSession(row) {
412
+ this.cached(
413
+ "session-upsert",
414
+ `INSERT INTO sessions
376
415
  (session_id, started_at, last_at, calls, wall_ms, cache_hits,
377
416
  total_prompt_tokens, total_completion_tokens, total_cached_tokens,
378
417
  total_tokens, total_cost_usd, total_cpu_ms)
@@ -388,31 +427,31 @@ var BetterSqliteStorage = class {
388
427
  total_tokens = excluded.total_tokens,
389
428
  total_cost_usd = excluded.total_cost_usd,
390
429
  total_cpu_ms = excluded.total_cpu_ms`
391
- ).run(
392
- row.session_id,
393
- row.started_at,
394
- row.last_at,
395
- row.calls,
396
- row.wall_ms,
397
- row.cache_hits,
398
- row.total_prompt_tokens,
399
- row.total_completion_tokens,
400
- row.total_cached_tokens,
401
- row.total_tokens,
402
- row.total_cost_usd,
403
- row.total_cpu_ms
404
- );
405
- }
406
- async accumulateSessionTotals(sessionId, delta) {
407
- this.cached(
408
- "session-touch",
409
- `INSERT OR IGNORE INTO sessions
430
+ ).run(
431
+ row.session_id,
432
+ row.started_at,
433
+ row.last_at,
434
+ row.calls,
435
+ row.wall_ms,
436
+ row.cache_hits,
437
+ row.total_prompt_tokens,
438
+ row.total_completion_tokens,
439
+ row.total_cached_tokens,
440
+ row.total_tokens,
441
+ row.total_cost_usd,
442
+ row.total_cpu_ms
443
+ );
444
+ }
445
+ async accumulateSessionTotals(sessionId, delta) {
446
+ this.cached(
447
+ "session-touch",
448
+ `INSERT OR IGNORE INTO sessions
410
449
  (session_id, started_at, last_at, calls, wall_ms, cache_hits)
411
450
  VALUES (?, ?, ?, 0, 0, 0)`
412
- ).run(sessionId, delta.last_at ?? 0, delta.last_at ?? null);
413
- this.cached(
414
- "session-acc",
415
- `UPDATE sessions SET
451
+ ).run(sessionId, delta.last_at ?? 0, delta.last_at ?? null);
452
+ this.cached(
453
+ "session-acc",
454
+ `UPDATE sessions SET
416
455
  calls = calls + ?,
417
456
  wall_ms = wall_ms + ?,
418
457
  cache_hits = cache_hits + ?,
@@ -424,75 +463,75 @@ var BetterSqliteStorage = class {
424
463
  total_cpu_ms = total_cpu_ms + ?,
425
464
  last_at = COALESCE(?, last_at)
426
465
  WHERE session_id = ?`
427
- ).run(
428
- delta.calls ?? 0,
429
- delta.wall_ms ?? 0,
430
- delta.cache_hits ?? 0,
431
- delta.total_prompt_tokens ?? 0,
432
- delta.total_completion_tokens ?? 0,
433
- delta.total_cached_tokens ?? 0,
434
- delta.total_tokens ?? 0,
435
- delta.total_cost_usd ?? 0,
436
- delta.total_cpu_ms ?? 0,
437
- delta.last_at ?? null,
438
- sessionId
439
- );
440
- }
441
- // ==================================================================
442
- // usage_log
443
- // ==================================================================
444
- async insertUsage(rows) {
445
- if (rows.length === 0) return;
446
- const stmt = this.cached(
447
- "usage-insert",
448
- `INSERT INTO usage_log
466
+ ).run(
467
+ delta.calls ?? 0,
468
+ delta.wall_ms ?? 0,
469
+ delta.cache_hits ?? 0,
470
+ delta.total_prompt_tokens ?? 0,
471
+ delta.total_completion_tokens ?? 0,
472
+ delta.total_cached_tokens ?? 0,
473
+ delta.total_tokens ?? 0,
474
+ delta.total_cost_usd ?? 0,
475
+ delta.total_cpu_ms ?? 0,
476
+ delta.last_at ?? null,
477
+ sessionId
478
+ );
479
+ }
480
+ // ==================================================================
481
+ // usage_log
482
+ // ==================================================================
483
+ async insertUsage(rows) {
484
+ if (rows.length === 0) return;
485
+ const stmt = this.cached(
486
+ "usage-insert",
487
+ `INSERT INTO usage_log
449
488
  (session_id, ts, tool, purpose, provider, model,
450
489
  prompt_tokens, completion_tokens, cached_tokens, total_tokens,
451
490
  cost_usd, estimated, wall_ms, cpu_ms)
452
491
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
453
- );
454
- const tx = this.db.transaction((items) => {
455
- for (const r of items) {
456
- stmt.run(
457
- r.session_id,
458
- r.ts,
459
- r.tool,
460
- r.purpose,
461
- r.provider,
462
- r.model,
463
- r.prompt_tokens ?? 0,
464
- r.completion_tokens ?? 0,
465
- r.cached_tokens ?? 0,
466
- r.total_tokens ?? 0,
467
- r.cost_usd ?? 0,
468
- r.estimated ?? 0,
469
- r.wall_ms ?? 0,
470
- r.cpu_ms ?? 0
471
492
  );
493
+ const tx = this.db.transaction((items) => {
494
+ for (const r of items) {
495
+ stmt.run(
496
+ r.session_id,
497
+ r.ts,
498
+ r.tool,
499
+ r.purpose,
500
+ r.provider,
501
+ r.model,
502
+ r.prompt_tokens ?? 0,
503
+ r.completion_tokens ?? 0,
504
+ r.cached_tokens ?? 0,
505
+ r.total_tokens ?? 0,
506
+ r.cost_usd ?? 0,
507
+ r.estimated ?? 0,
508
+ r.wall_ms ?? 0,
509
+ r.cpu_ms ?? 0
510
+ );
511
+ }
512
+ });
513
+ tx(rows);
472
514
  }
473
- });
474
- tx(rows);
475
- }
476
- async listUsageForSession(sessionId, opts) {
477
- const where = ["session_id = ?"];
478
- const params = [sessionId];
479
- if (opts?.only_purpose && opts.only_purpose.length > 0) {
480
- where.push(`purpose IN (${opts.only_purpose.map(() => "?").join(",")})`);
481
- params.push(...opts.only_purpose);
482
- }
483
- if (opts?.only_provider && opts.only_provider.length > 0) {
484
- where.push(`provider IN (${opts.only_provider.map(() => "?").join(",")})`);
485
- params.push(...opts.only_provider);
486
- }
487
- const limit = opts?.limit ?? 1e3;
488
- params.push(limit);
489
- const sql = `SELECT * FROM usage_log WHERE ${where.join(" AND ")} ORDER BY id ASC LIMIT ?`;
490
- return this.db.prepare(sql).all(...params);
491
- }
492
- async listUsageGroupedByPurpose(sessionId) {
493
- return this.cached(
494
- "usage-grp-purpose",
495
- `SELECT purpose,
515
+ async listUsageForSession(sessionId, opts) {
516
+ const where = ["session_id = ?"];
517
+ const params = [sessionId];
518
+ if (opts?.only_purpose && opts.only_purpose.length > 0) {
519
+ where.push(`purpose IN (${opts.only_purpose.map(() => "?").join(",")})`);
520
+ params.push(...opts.only_purpose);
521
+ }
522
+ if (opts?.only_provider && opts.only_provider.length > 0) {
523
+ where.push(`provider IN (${opts.only_provider.map(() => "?").join(",")})`);
524
+ params.push(...opts.only_provider);
525
+ }
526
+ const limit = opts?.limit ?? 1e3;
527
+ params.push(limit);
528
+ const sql = `SELECT * FROM usage_log WHERE ${where.join(" AND ")} ORDER BY id ASC LIMIT ?`;
529
+ return this.db.prepare(sql).all(...params);
530
+ }
531
+ async listUsageGroupedByPurpose(sessionId) {
532
+ return this.cached(
533
+ "usage-grp-purpose",
534
+ `SELECT purpose,
496
535
  COUNT(*) AS calls,
497
536
  COALESCE(SUM(prompt_tokens), 0) AS prompt_tokens,
498
537
  COALESCE(SUM(completion_tokens), 0) AS completion_tokens,
@@ -504,13 +543,13 @@ var BetterSqliteStorage = class {
504
543
  WHERE session_id = ?
505
544
  GROUP BY purpose
506
545
  ORDER BY purpose`
507
- ).all(sessionId);
508
- }
509
- async listUsageGroupedByProvider(purpose) {
510
- if (purpose !== void 0) {
511
- return this.cached(
512
- "usage-grp-provider-p",
513
- `SELECT provider,
546
+ ).all(sessionId);
547
+ }
548
+ async listUsageGroupedByProvider(purpose) {
549
+ if (purpose !== void 0) {
550
+ return this.cached(
551
+ "usage-grp-provider-p",
552
+ `SELECT provider,
514
553
  COUNT(*) AS calls,
515
554
  COALESCE(SUM(total_tokens), 0) AS total_tokens,
516
555
  COALESCE(SUM(cost_usd), 0) AS cost_usd,
@@ -519,11 +558,11 @@ var BetterSqliteStorage = class {
519
558
  WHERE purpose = ?
520
559
  GROUP BY provider
521
560
  ORDER BY provider`
522
- ).all(purpose);
523
- }
524
- return this.cached(
525
- "usage-grp-provider",
526
- `SELECT provider,
561
+ ).all(purpose);
562
+ }
563
+ return this.cached(
564
+ "usage-grp-provider",
565
+ `SELECT provider,
527
566
  COUNT(*) AS calls,
528
567
  COALESCE(SUM(total_tokens), 0) AS total_tokens,
529
568
  COALESCE(SUM(cost_usd), 0) AS cost_usd,
@@ -531,13 +570,13 @@ var BetterSqliteStorage = class {
531
570
  FROM usage_log
532
571
  GROUP BY provider
533
572
  ORDER BY provider`
534
- ).all();
535
- }
536
- async listRouterStatsByPurpose(purpose, sinceMs) {
537
- if (sinceMs !== void 0) {
538
- return this.cached(
539
- "router-stats-purpose-since",
540
- `SELECT LOWER(provider) AS provider,
573
+ ).all();
574
+ }
575
+ async listRouterStatsByPurpose(purpose, sinceMs) {
576
+ if (sinceMs !== void 0) {
577
+ return this.cached(
578
+ "router-stats-purpose-since",
579
+ `SELECT LOWER(provider) AS provider,
541
580
  COUNT(*) AS calls,
542
581
  COALESCE(SUM(total_tokens), 0) AS tokens_sum,
543
582
  COALESCE(AVG(total_tokens), 0) AS avg_total_tokens,
@@ -547,11 +586,11 @@ var BetterSqliteStorage = class {
547
586
  WHERE purpose = ? AND ts >= ? AND provider IS NOT NULL
548
587
  GROUP BY LOWER(provider)
549
588
  ORDER BY provider`
550
- ).all(purpose, sinceMs);
551
- }
552
- return this.cached(
553
- "router-stats-purpose",
554
- `SELECT LOWER(provider) AS provider,
589
+ ).all(purpose, sinceMs);
590
+ }
591
+ return this.cached(
592
+ "router-stats-purpose",
593
+ `SELECT LOWER(provider) AS provider,
555
594
  COUNT(*) AS calls,
556
595
  COALESCE(SUM(total_tokens), 0) AS tokens_sum,
557
596
  COALESCE(AVG(total_tokens), 0) AS avg_total_tokens,
@@ -561,321 +600,334 @@ var BetterSqliteStorage = class {
561
600
  WHERE purpose = ? AND provider IS NOT NULL
562
601
  GROUP BY LOWER(provider)
563
602
  ORDER BY provider`
564
- ).all(purpose);
565
- }
566
- // ==================================================================
567
- // claims
568
- // ==================================================================
569
- async insertClaim(claim) {
570
- const info = this.cached(
571
- "claim-insert",
572
- `INSERT INTO claims
603
+ ).all(purpose);
604
+ }
605
+ // ==================================================================
606
+ // claims
607
+ // ==================================================================
608
+ async insertClaim(claim) {
609
+ const info = this.cached(
610
+ "claim-insert",
611
+ `INSERT INTO claims
573
612
  (session_id, text, provider, confidence, citations_json, kind, created_at)
574
613
  VALUES (?, ?, ?, ?, ?, ?, ?)`
575
- ).run(
576
- claim.session_id,
577
- claim.text,
578
- claim.provider ?? null,
579
- claim.confidence ?? null,
580
- claim.citations ? JSON.stringify(claim.citations) : null,
581
- claim.kind ?? null,
582
- Date.now()
583
- );
584
- return Number(info.lastInsertRowid);
585
- }
586
- async insertClaimLink(srcId, dstId, kind) {
587
- if (!ALLOWED_LINK_KINDS.has(kind)) {
588
- throw new RangeError(`invalid claim_link kind: ${kind}`);
589
- }
590
- this.cached(
591
- "claim-link-insert",
592
- `INSERT OR IGNORE INTO claim_links (src_id, dst_id, kind, created_at)
614
+ ).run(
615
+ claim.session_id,
616
+ claim.text,
617
+ claim.provider ?? null,
618
+ claim.confidence ?? null,
619
+ claim.citations ? JSON.stringify(claim.citations) : null,
620
+ claim.kind ?? null,
621
+ Date.now()
622
+ );
623
+ return Number(info.lastInsertRowid);
624
+ }
625
+ async insertClaimLink(srcId, dstId, kind) {
626
+ if (!ALLOWED_LINK_KINDS.has(kind)) {
627
+ throw new RangeError(`invalid claim_link kind: ${kind}`);
628
+ }
629
+ this.cached(
630
+ "claim-link-insert",
631
+ `INSERT OR IGNORE INTO claim_links (src_id, dst_id, kind, created_at)
593
632
  VALUES (?, ?, ?, ?)`
594
- ).run(srcId, dstId, kind, Date.now());
595
- }
596
- async listClaimsForSession(sessionId) {
597
- return this.cached(
598
- "claim-list-session",
599
- "SELECT * FROM claims WHERE session_id = ? ORDER BY id"
600
- ).all(sessionId);
601
- }
602
- async getClaim(claimId) {
603
- const row = this.cached(
604
- "claim-get",
605
- "SELECT * FROM claims WHERE id = ?"
606
- ).get(claimId);
607
- return row ?? null;
608
- }
609
- async listClaimLinksForSession(sessionId) {
610
- return this.cached(
611
- "claim-link-list-session",
612
- `SELECT cl.*
633
+ ).run(srcId, dstId, kind, Date.now());
634
+ }
635
+ async listClaimsForSession(sessionId) {
636
+ return this.cached(
637
+ "claim-list-session",
638
+ "SELECT * FROM claims WHERE session_id = ? ORDER BY id"
639
+ ).all(sessionId);
640
+ }
641
+ async getClaim(claimId) {
642
+ const row = this.cached(
643
+ "claim-get",
644
+ "SELECT * FROM claims WHERE id = ?"
645
+ ).get(claimId);
646
+ return row ?? null;
647
+ }
648
+ async listClaimLinksForSession(sessionId) {
649
+ return this.cached(
650
+ "claim-link-list-session",
651
+ `SELECT cl.*
613
652
  FROM claim_links cl
614
653
  JOIN claims c ON c.id = cl.src_id OR c.id = cl.dst_id
615
654
  WHERE c.session_id = ?
616
655
  GROUP BY cl.id
617
656
  ORDER BY cl.id`
618
- ).all(sessionId);
619
- }
620
- async deleteClaimsForSession(sessionId) {
621
- const info = this.cached(
622
- "claim-delete-session",
623
- "DELETE FROM claims WHERE session_id = ?"
624
- ).run(sessionId);
625
- return Number(info.changes);
626
- }
627
- // ==================================================================
628
- // provider_stats
629
- // ==================================================================
630
- async listProviderStats(opts) {
631
- const limit = opts?.limit ?? 100;
632
- return this.cached(
633
- "provider-stats-list",
634
- "SELECT * FROM provider_stats ORDER BY (wins + losses + abstains) DESC, provider ASC LIMIT ?"
635
- ).all(limit);
636
- }
637
- async getProviderStats(provider) {
638
- const row = this.cached(
639
- "provider-stats-get",
640
- "SELECT * FROM provider_stats WHERE provider = ?"
641
- ).get(provider);
642
- return row ?? null;
643
- }
644
- async bumpProviderBallot(provider, ballot, at) {
645
- const column = ballot === "agree" ? "wins" : ballot === "disagree" ? "losses" : "abstains";
646
- this.db.prepare(
647
- `INSERT INTO provider_stats(provider, wins, losses, abstains, last_at)
657
+ ).all(sessionId);
658
+ }
659
+ async deleteClaimsForSession(sessionId) {
660
+ const info = this.cached(
661
+ "claim-delete-session",
662
+ "DELETE FROM claims WHERE session_id = ?"
663
+ ).run(sessionId);
664
+ return Number(info.changes);
665
+ }
666
+ // ==================================================================
667
+ // provider_stats
668
+ // ==================================================================
669
+ async listProviderStats(opts) {
670
+ const limit = opts?.limit ?? 100;
671
+ return this.cached(
672
+ "provider-stats-list",
673
+ "SELECT * FROM provider_stats ORDER BY (wins + losses + abstains) DESC, provider ASC LIMIT ?"
674
+ ).all(limit);
675
+ }
676
+ async getProviderStats(provider) {
677
+ const row = this.cached(
678
+ "provider-stats-get",
679
+ "SELECT * FROM provider_stats WHERE provider = ?"
680
+ ).get(provider);
681
+ return row ?? null;
682
+ }
683
+ async bumpProviderBallot(provider, ballot, at) {
684
+ const column = ballot === "agree" ? "wins" : ballot === "disagree" ? "losses" : "abstains";
685
+ this.db.prepare(
686
+ `INSERT INTO provider_stats(provider, wins, losses, abstains, last_at)
648
687
  VALUES (?, 0, 0, 0, ?)
649
688
  ON CONFLICT(provider) DO NOTHING`
650
- ).run(provider, at);
651
- this.db.prepare(
652
- `UPDATE provider_stats SET ${column} = ${column} + 1, last_at = ? WHERE provider = ?`
653
- ).run(at, provider);
654
- }
655
- // ==================================================================
656
- // delegations
657
- // ==================================================================
658
- async insertDelegation(row) {
659
- this.cached(
660
- "delegation-insert",
661
- `INSERT INTO delegations
689
+ ).run(provider, at);
690
+ this.db.prepare(
691
+ `UPDATE provider_stats SET ${column} = ${column} + 1, last_at = ? WHERE provider = ?`
692
+ ).run(at, provider);
693
+ }
694
+ // ==================================================================
695
+ // delegations
696
+ // ==================================================================
697
+ async insertDelegation(row) {
698
+ this.cached(
699
+ "delegation-insert",
700
+ `INSERT INTO delegations
662
701
  (session_id, requester, tool_call, via, accepted, created_at)
663
702
  VALUES (?, ?, ?, ?, ?, ?)`
664
- ).run(
665
- row.session_id,
666
- row.requester,
667
- row.tool_call,
668
- row.via,
669
- row.accepted,
670
- row.created_at
671
- );
672
- }
673
- async listDelegationsForSession(sessionId) {
674
- return this.cached(
675
- "delegation-list-session",
676
- "SELECT * FROM delegations WHERE session_id = ? ORDER BY id"
677
- ).all(sessionId);
678
- }
679
- async countDelegationsByRequester(requester) {
680
- const r = this.cached(
681
- "delegation-count-req",
682
- "SELECT COUNT(*) AS n FROM delegations WHERE requester = ?"
683
- ).get(requester);
684
- return Number(r.n);
685
- }
686
- async countDelegationsBySession(sessionId) {
687
- const r = this.cached(
688
- "delegation-count-session",
689
- "SELECT COUNT(*) AS n FROM delegations WHERE session_id = ?"
690
- ).get(sessionId);
691
- return Number(r.n);
692
- }
693
- async countAcceptedDelegationsBySession(sessionId) {
694
- const r = this.cached(
695
- "delegation-count-accepted-session",
696
- "SELECT COUNT(*) AS n FROM delegations WHERE session_id = ? AND accepted = 1"
697
- ).get(sessionId);
698
- return Number(r.n);
699
- }
700
- async countAcceptedDelegationsByRequester(requester) {
701
- const r = this.cached(
702
- "delegation-count-accepted-requester",
703
- "SELECT COUNT(*) AS n FROM delegations WHERE requester = ? AND accepted = 1"
704
- ).get(requester);
705
- return Number(r.n);
706
- }
707
- async listDelegationAggregatesByRequester() {
708
- const rows = this.cached(
709
- "delegation-agg-requester",
710
- "SELECT requester, accepted, COUNT(*) AS n FROM delegations WHERE requester IS NOT NULL GROUP BY requester, accepted"
711
- ).all();
712
- return rows.map((r) => ({
713
- requester: String(r.requester),
714
- accepted: r.accepted === 1 ? 1 : 0,
715
- count: Number(r.n)
716
- }));
717
- }
718
- // ==================================================================
719
- // global counts (scoreboard / observability)
720
- // ==================================================================
721
- async countScoreboardTotals() {
722
- const countOne = (table) => {
723
- try {
724
- const r = this.db.prepare(`SELECT COUNT(*) AS n FROM ${table}`).get();
725
- return r ? Number(r.n) : 0;
726
- } catch {
727
- return 0;
703
+ ).run(
704
+ row.session_id,
705
+ row.requester,
706
+ row.tool_call,
707
+ row.via,
708
+ row.accepted,
709
+ row.created_at
710
+ );
728
711
  }
729
- };
730
- return {
731
- sessions: countOne("sessions"),
732
- claims: countOne("claims"),
733
- claim_links: countOne("claim_links"),
734
- delegations: countOne("delegations")
735
- };
736
- }
737
- // ==================================================================
738
- // session_memory
739
- // ==================================================================
740
- async insertSessionMemory(row) {
741
- if (!ALLOWED_MEMORY_KINDS.has(row.kind)) {
742
- throw new RangeError(`invalid session_memory kind: ${row.kind}`);
743
- }
744
- const info = this.cached(
745
- "memory-insert",
746
- `INSERT INTO session_memory
712
+ async listDelegationsForSession(sessionId) {
713
+ return this.cached(
714
+ "delegation-list-session",
715
+ "SELECT * FROM delegations WHERE session_id = ? ORDER BY id"
716
+ ).all(sessionId);
717
+ }
718
+ async countDelegationsByRequester(requester) {
719
+ const r = this.cached(
720
+ "delegation-count-req",
721
+ "SELECT COUNT(*) AS n FROM delegations WHERE requester = ?"
722
+ ).get(requester);
723
+ return Number(r.n);
724
+ }
725
+ async countDelegationsBySession(sessionId) {
726
+ const r = this.cached(
727
+ "delegation-count-session",
728
+ "SELECT COUNT(*) AS n FROM delegations WHERE session_id = ?"
729
+ ).get(sessionId);
730
+ return Number(r.n);
731
+ }
732
+ async countAcceptedDelegationsBySession(sessionId) {
733
+ const r = this.cached(
734
+ "delegation-count-accepted-session",
735
+ "SELECT COUNT(*) AS n FROM delegations WHERE session_id = ? AND accepted = 1"
736
+ ).get(sessionId);
737
+ return Number(r.n);
738
+ }
739
+ async countAcceptedDelegationsByRequester(requester) {
740
+ const r = this.cached(
741
+ "delegation-count-accepted-requester",
742
+ "SELECT COUNT(*) AS n FROM delegations WHERE requester = ? AND accepted = 1"
743
+ ).get(requester);
744
+ return Number(r.n);
745
+ }
746
+ async listDelegationAggregatesByRequester() {
747
+ const rows = this.cached(
748
+ "delegation-agg-requester",
749
+ "SELECT requester, accepted, COUNT(*) AS n FROM delegations WHERE requester IS NOT NULL GROUP BY requester, accepted"
750
+ ).all();
751
+ return rows.map((r) => ({
752
+ requester: String(r.requester),
753
+ accepted: r.accepted === 1 ? 1 : 0,
754
+ count: Number(r.n)
755
+ }));
756
+ }
757
+ // ==================================================================
758
+ // global counts (scoreboard / observability)
759
+ // ==================================================================
760
+ async countScoreboardTotals() {
761
+ const countOne = (table) => {
762
+ try {
763
+ const r = this.db.prepare(`SELECT COUNT(*) AS n FROM ${table}`).get();
764
+ return r ? Number(r.n) : 0;
765
+ } catch {
766
+ return 0;
767
+ }
768
+ };
769
+ return {
770
+ sessions: countOne("sessions"),
771
+ claims: countOne("claims"),
772
+ claim_links: countOne("claim_links"),
773
+ delegations: countOne("delegations")
774
+ };
775
+ }
776
+ // ==================================================================
777
+ // session_memory
778
+ // ==================================================================
779
+ async insertSessionMemory(row) {
780
+ if (!ALLOWED_MEMORY_KINDS.has(row.kind)) {
781
+ throw new RangeError(`invalid session_memory kind: ${row.kind}`);
782
+ }
783
+ const info = this.cached(
784
+ "memory-insert",
785
+ `INSERT INTO session_memory
747
786
  (session_id, kind, content, source_tool, source_call_id, confidence, created_at)
748
787
  VALUES (?, ?, ?, ?, ?, ?, ?)`
749
- ).run(
750
- row.session_id,
751
- row.kind,
752
- row.content,
753
- row.source_tool ?? null,
754
- row.source_call_id ?? null,
755
- row.confidence ?? null,
756
- row.created_at
757
- );
758
- return Number(info.lastInsertRowid);
759
- }
760
- async listSessionMemory(sessionId, opts) {
761
- const where = ["session_id = ?"];
762
- const params = [sessionId];
763
- if (!opts?.include_stale) where.push("stale_at IS NULL");
764
- if (opts?.kinds && opts.kinds.length > 0) {
765
- where.push(`kind IN (${opts.kinds.map(() => "?").join(",")})`);
766
- params.push(...opts.kinds);
767
- }
768
- const limit = opts?.limit ?? 50;
769
- params.push(limit);
770
- const sql = `SELECT * FROM session_memory WHERE ${where.join(" AND ")} ORDER BY id DESC LIMIT ?`;
771
- return this.db.prepare(sql).all(...params);
772
- }
773
- async markSessionMemoryStale(sessionId, at, opts) {
774
- const where = ["session_id = ?", "stale_at IS NULL"];
775
- const params = [at, opts?.reason ?? "manual", sessionId];
776
- if (opts?.ids && opts.ids.length > 0) {
777
- where.push(`id IN (${opts.ids.map(() => "?").join(",")})`);
778
- params.push(...opts.ids);
779
- }
780
- if (opts?.kinds && opts.kinds.length > 0) {
781
- where.push(`kind IN (${opts.kinds.map(() => "?").join(",")})`);
782
- params.push(...opts.kinds);
783
- }
784
- const sql = `UPDATE session_memory SET stale_at = ?, stale_reason = ? WHERE ${where.join(" AND ")}`;
785
- const info = this.db.prepare(sql).run(...params);
786
- return Number(info.changes);
787
- }
788
- async clearSessionMemory(sessionId) {
789
- const info = this.cached(
790
- "memory-clear",
791
- "DELETE FROM session_memory WHERE session_id = ?"
792
- ).run(sessionId);
793
- return Number(info.changes);
794
- }
795
- // ==================================================================
796
- // fetch_egress
797
- // ==================================================================
798
- async recordFetchEgress(sessionId, host, bytes, at) {
799
- this.cached(
800
- "fetch-egress-upsert",
801
- `INSERT INTO fetch_egress (session_id, host, total_bytes, last_at)
788
+ ).run(
789
+ row.session_id,
790
+ row.kind,
791
+ row.content,
792
+ row.source_tool ?? null,
793
+ row.source_call_id ?? null,
794
+ row.confidence ?? null,
795
+ row.created_at
796
+ );
797
+ return Number(info.lastInsertRowid);
798
+ }
799
+ async listSessionMemory(sessionId, opts) {
800
+ const where = ["session_id = ?"];
801
+ const params = [sessionId];
802
+ if (!opts?.include_stale) where.push("stale_at IS NULL");
803
+ if (opts?.kinds && opts.kinds.length > 0) {
804
+ where.push(`kind IN (${opts.kinds.map(() => "?").join(",")})`);
805
+ params.push(...opts.kinds);
806
+ }
807
+ const limit = opts?.limit ?? 50;
808
+ params.push(limit);
809
+ const sql = `SELECT * FROM session_memory WHERE ${where.join(" AND ")} ORDER BY id DESC LIMIT ?`;
810
+ return this.db.prepare(sql).all(...params);
811
+ }
812
+ async markSessionMemoryStale(sessionId, at, opts) {
813
+ const where = ["session_id = ?", "stale_at IS NULL"];
814
+ const params = [at, opts?.reason ?? "manual", sessionId];
815
+ if (opts?.ids && opts.ids.length > 0) {
816
+ where.push(`id IN (${opts.ids.map(() => "?").join(",")})`);
817
+ params.push(...opts.ids);
818
+ }
819
+ if (opts?.kinds && opts.kinds.length > 0) {
820
+ where.push(`kind IN (${opts.kinds.map(() => "?").join(",")})`);
821
+ params.push(...opts.kinds);
822
+ }
823
+ const sql = `UPDATE session_memory SET stale_at = ?, stale_reason = ? WHERE ${where.join(" AND ")}`;
824
+ const info = this.db.prepare(sql).run(...params);
825
+ return Number(info.changes);
826
+ }
827
+ async clearSessionMemory(sessionId) {
828
+ const info = this.cached(
829
+ "memory-clear",
830
+ "DELETE FROM session_memory WHERE session_id = ?"
831
+ ).run(sessionId);
832
+ return Number(info.changes);
833
+ }
834
+ // ==================================================================
835
+ // fetch_egress
836
+ // ==================================================================
837
+ async recordFetchEgress(sessionId, host, bytes, at) {
838
+ this.cached(
839
+ "fetch-egress-upsert",
840
+ `INSERT INTO fetch_egress (session_id, host, total_bytes, last_at)
802
841
  VALUES (?, ?, ?, ?)
803
842
  ON CONFLICT(session_id, host) DO UPDATE SET
804
843
  total_bytes = total_bytes + excluded.total_bytes,
805
844
  last_at = excluded.last_at`
806
- ).run(sessionId, host, bytes, at);
807
- }
808
- async getFetchEgressTotals(sessionId) {
809
- const r = this.cached(
810
- "fetch-egress-totals",
811
- "SELECT COALESCE(SUM(total_bytes), 0) AS total_bytes, COUNT(DISTINCT host) AS unique_hosts FROM fetch_egress WHERE session_id = ?"
812
- ).get(sessionId);
813
- return {
814
- total_bytes: Number(r.total_bytes ?? 0),
815
- unique_hosts: Number(r.unique_hosts ?? 0)
816
- };
817
- }
818
- async hasFetchEgressHost(sessionId, host) {
819
- const r = this.cached(
820
- "fetch-egress-has-host",
821
- "SELECT 1 AS one FROM fetch_egress WHERE session_id = ? AND host = ? LIMIT 1"
822
- ).get(sessionId, host);
823
- return r !== void 0;
824
- }
825
- // ==================================================================
826
- // transcripts_fts — the encapsulated FTS5 surface.
827
- // ==================================================================
828
- async indexTranscript(row) {
829
- this.cached(
830
- "fts-insert",
831
- `INSERT INTO transcripts_fts (session_id, tool, ts, path, content)
845
+ ).run(sessionId, host, bytes, at);
846
+ }
847
+ async getFetchEgressTotals(sessionId) {
848
+ const r = this.cached(
849
+ "fetch-egress-totals",
850
+ "SELECT COALESCE(SUM(total_bytes), 0) AS total_bytes, COUNT(DISTINCT host) AS unique_hosts FROM fetch_egress WHERE session_id = ?"
851
+ ).get(sessionId);
852
+ return {
853
+ total_bytes: Number(r.total_bytes ?? 0),
854
+ unique_hosts: Number(r.unique_hosts ?? 0)
855
+ };
856
+ }
857
+ async hasFetchEgressHost(sessionId, host) {
858
+ const r = this.cached(
859
+ "fetch-egress-has-host",
860
+ "SELECT 1 AS one FROM fetch_egress WHERE session_id = ? AND host = ? LIMIT 1"
861
+ ).get(sessionId, host);
862
+ return r !== void 0;
863
+ }
864
+ // ==================================================================
865
+ // transcripts_fts — the encapsulated FTS5 surface.
866
+ // ==================================================================
867
+ async indexTranscript(row) {
868
+ this.cached(
869
+ "fts-insert",
870
+ `INSERT INTO transcripts_fts (session_id, tool, ts, path, content)
832
871
  VALUES (?, ?, ?, ?, ?)`
833
- ).run(row.session_id ?? "", row.tool, String(row.ts), row.path, row.content);
834
- }
835
- async recallSearch(query, k, opts) {
836
- const where = ["transcripts_fts MATCH ?"];
837
- const params = [query];
838
- if (opts?.session_id) {
839
- where.push("session_id = ?");
840
- params.push(opts.session_id);
841
- }
842
- if (opts?.tool) {
843
- where.push("tool = ?");
844
- params.push(opts.tool);
845
- }
846
- if (opts?.since_ms !== void 0) {
847
- where.push("CAST(ts AS INTEGER) >= ?");
848
- params.push(opts.since_ms);
849
- }
850
- params.push(k);
851
- const sql = `SELECT path, session_id, tool, ts, snippet(transcripts_fts, -1, '[[', ']]', '...', 16) AS snippet, bm25(transcripts_fts) AS rank FROM transcripts_fts WHERE ${where.join(" AND ")} ORDER BY rank LIMIT ?`;
852
- const rows = this.db.prepare(sql).all(...params);
853
- return rows.map((r) => ({
854
- path: r.path,
855
- session_id: r.session_id ?? null,
856
- tool: r.tool ?? null,
857
- ts: Number(r.ts),
858
- snippet: r.snippet,
859
- score: 1 / (1 + Math.max(0, r.rank ?? 0))
860
- }));
861
- }
862
- // ------------------------------------------------------------------
863
- // Prepared-statement cache. better-sqlite3 prepares statements lazily
864
- // and caches them internally, but the JS-side reference still costs
865
- // a hashmap lookup on every call. Keeping our own map by key lets
866
- // hot-path queries hit a single Map.get().
867
- // ------------------------------------------------------------------
868
- cached(key, sql) {
869
- let s = this.stmts.get(key);
870
- if (!s) {
871
- s = this.db.prepare(sql);
872
- this.stmts.set(key, s);
873
- }
874
- return s;
872
+ ).run(row.session_id ?? "", row.tool, String(row.ts), row.path, row.content);
873
+ }
874
+ async recallSearch(query, k, opts) {
875
+ const where = ["transcripts_fts MATCH ?"];
876
+ const params = [query];
877
+ if (opts?.session_id) {
878
+ where.push("session_id = ?");
879
+ params.push(opts.session_id);
880
+ }
881
+ if (opts?.tool) {
882
+ where.push("tool = ?");
883
+ params.push(opts.tool);
884
+ }
885
+ if (opts?.since_ms !== void 0) {
886
+ where.push("CAST(ts AS INTEGER) >= ?");
887
+ params.push(opts.since_ms);
888
+ }
889
+ params.push(k);
890
+ const sql = `SELECT path, session_id, tool, ts, snippet(transcripts_fts, -1, '[[', ']]', '...', 16) AS snippet, bm25(transcripts_fts) AS rank FROM transcripts_fts WHERE ${where.join(" AND ")} ORDER BY rank LIMIT ?`;
891
+ const rows = this.db.prepare(sql).all(...params);
892
+ return rows.map((r) => ({
893
+ path: r.path,
894
+ session_id: r.session_id ?? null,
895
+ tool: r.tool ?? null,
896
+ ts: Number(r.ts),
897
+ snippet: r.snippet,
898
+ score: 1 / (1 + Math.max(0, r.rank ?? 0))
899
+ }));
900
+ }
901
+ // ------------------------------------------------------------------
902
+ // Prepared-statement cache. better-sqlite3 prepares statements lazily
903
+ // and caches them internally, but the JS-side reference still costs
904
+ // a hashmap lookup on every call. Keeping our own map by key lets
905
+ // hot-path queries hit a single Map.get().
906
+ // ------------------------------------------------------------------
907
+ cached(key, sql) {
908
+ let s = this.stmts.get(key);
909
+ if (!s) {
910
+ s = this.db.prepare(sql);
911
+ this.stmts.set(key, s);
912
+ }
913
+ return s;
914
+ }
915
+ };
875
916
  }
876
- };
917
+ });
918
+
919
+ // src/entrypoints/node-stdio.ts
920
+ init_esm_shims();
921
+ import { existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
922
+ import path9 from "path";
923
+ import { fileURLToPath as fileURLToPath3 } from "url";
924
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
925
+
926
+ // src/bridge/index.ts
927
+ init_esm_shims();
877
928
 
878
929
  // src/bridge/python-bridge.ts
930
+ init_esm_shims();
879
931
  import path2 from "path";
880
932
  import { fileURLToPath as fileURLToPath2 } from "url";
881
933
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
@@ -975,6 +1027,7 @@ async function fetchToolNames(client, timeoutMs) {
975
1027
  }
976
1028
 
977
1029
  // src/bridge/proxy-tools.ts
1030
+ init_esm_shims();
978
1031
  function buildPythonProxies(bridge) {
979
1032
  const proxies = /* @__PURE__ */ new Map();
980
1033
  for (const name of bridge.toolNames) {
@@ -1015,6 +1068,7 @@ function makeProxy(bridge, name) {
1015
1068
  }
1016
1069
 
1017
1070
  // src/core/events.ts
1071
+ init_esm_shims();
1018
1072
  import { appendFileSync, mkdirSync } from "fs";
1019
1073
  import { dirname } from "path";
1020
1074
  var StderrEmitter = class {
@@ -1115,6 +1169,7 @@ function envelopeBytes(v) {
1115
1169
  }
1116
1170
 
1117
1171
  // src/core/pricing.ts
1172
+ init_esm_shims();
1118
1173
  import { readFileSync } from "fs";
1119
1174
  function loadPricing(path10) {
1120
1175
  let raw;
@@ -1168,7 +1223,14 @@ function roundTo(x, n) {
1168
1223
  return Number(x.toFixed(n));
1169
1224
  }
1170
1225
 
1226
+ // src/providers/registry.ts
1227
+ init_esm_shims();
1228
+
1229
+ // src/providers/anthropic.ts
1230
+ init_esm_shims();
1231
+
1171
1232
  // src/core/provider-caps.ts
1233
+ init_esm_shims();
1172
1234
  var PROVIDER_CAPS = {
1173
1235
  anthropic: {
1174
1236
  family: "anthropic",
@@ -1211,6 +1273,7 @@ function supportsTemperature(provider, model) {
1211
1273
  }
1212
1274
 
1213
1275
  // src/providers/types.ts
1276
+ init_esm_shims();
1214
1277
  var ProviderError = class extends Error {
1215
1278
  name = "ProviderError";
1216
1279
  kind;
@@ -1392,6 +1455,7 @@ async function sendAnthropic(args) {
1392
1455
  }
1393
1456
 
1394
1457
  // src/providers/gemini.ts
1458
+ init_esm_shims();
1395
1459
  var GEMINI_API_URL_BASE = "https://generativelanguage.googleapis.com/v1beta/models";
1396
1460
  function jsonSchemaToGeminiSchema(schema) {
1397
1461
  const out = {};
@@ -1574,6 +1638,7 @@ async function sendGemini(args) {
1574
1638
  }
1575
1639
 
1576
1640
  // src/providers/openai-compatible.ts
1641
+ init_esm_shims();
1577
1642
  var OPENAI_COMPAT_DEFAULT_URLS = {
1578
1643
  openai: "https://api.openai.com/v1/chat/completions",
1579
1644
  xai: "https://api.x.ai/v1/chat/completions",
@@ -1823,6 +1888,7 @@ function makeGeminiProvider(model, apiKey, opts) {
1823
1888
  }
1824
1889
 
1825
1890
  // src/server.ts
1891
+ init_esm_shims();
1826
1892
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
1827
1893
  import {
1828
1894
  CallToolRequestSchema,
@@ -1830,6 +1896,7 @@ import {
1830
1896
  } from "@modelcontextprotocol/sdk/types.js";
1831
1897
 
1832
1898
  // src/instructions.ts
1899
+ init_esm_shims();
1833
1900
  var ROUTABLE_TOOLS = [
1834
1901
  // Single-shot
1835
1902
  "pick",
@@ -1888,13 +1955,19 @@ This convention is opt-in: a user message without the \`xc\`/\`XC\` prefix shoul
1888
1955
  }
1889
1956
 
1890
1957
  // src/tools/index.ts
1958
+ init_esm_shims();
1891
1959
  import { z } from "zod";
1892
1960
 
1893
1961
  // src/tools/audit.ts
1962
+ init_esm_shims();
1894
1963
  import { readdirSync, readFileSync as readFileSync2, statSync } from "fs";
1895
1964
  import { join } from "path";
1896
1965
 
1966
+ // src/core/structured.ts
1967
+ init_esm_shims();
1968
+
1897
1969
  // src/core/extract-json.ts
1970
+ init_esm_shims();
1898
1971
  function extractJson(text) {
1899
1972
  if (typeof text !== "string") return null;
1900
1973
  const s = text.trim();
@@ -1949,6 +2022,7 @@ function extractJson(text) {
1949
2022
  }
1950
2023
 
1951
2024
  // src/core/json-schema.ts
2025
+ init_esm_shims();
1952
2026
  function validateSchema(value, schema, path10 = "") {
1953
2027
  const errs = [];
1954
2028
  if ("anyOf" in schema) {
@@ -2112,6 +2186,7 @@ function pyReprType(t) {
2112
2186
  }
2113
2187
 
2114
2188
  // src/core/usage.ts
2189
+ init_esm_shims();
2115
2190
  function emptyUsage(provider, model, purpose = "worker") {
2116
2191
  return {
2117
2192
  provider,
@@ -2245,6 +2320,7 @@ async function askOne(provider, messages, opts) {
2245
2320
  }
2246
2321
 
2247
2322
  // src/core/retarget.ts
2323
+ init_esm_shims();
2248
2324
  function retargetProvider(p, newModel) {
2249
2325
  if (p.model === newModel) return p;
2250
2326
  return {
@@ -2269,7 +2345,11 @@ async function loadProviderWeights(storage, names) {
2269
2345
  return out;
2270
2346
  }
2271
2347
 
2348
+ // src/core/tiers.ts
2349
+ init_esm_shims();
2350
+
2272
2351
  // src/core/pyrepr.ts
2352
+ init_esm_shims();
2273
2353
  function pyStrRepr(s) {
2274
2354
  const hasSingle = s.indexOf("'") >= 0;
2275
2355
  const hasDouble = s.indexOf('"') >= 0;
@@ -2971,13 +3051,19 @@ function boolArg(v, defaultVal) {
2971
3051
  }
2972
3052
 
2973
3053
  // src/tools/bench.ts
3054
+ init_esm_shims();
2974
3055
  import { existsSync, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
2975
3056
  import path3 from "path";
2976
3057
 
3058
+ // src/tools/confer.ts
3059
+ init_esm_shims();
3060
+
2977
3061
  // src/core/canary.ts
3062
+ init_esm_shims();
2978
3063
  import { createHash, randomBytes } from "crypto";
2979
3064
 
2980
3065
  // src/core/injection.ts
3066
+ init_esm_shims();
2981
3067
  var INJECTION_PHRASES_RE = new RegExp(
2982
3068
  "\\b((?:ignore|disregard|forget)\\s+(?:all\\s+)?(?:previous\\s+|prior\\s+|the\\s+(?:above\\s+)?)?(?:instructions|directions|prompts|rules|context)|you are now\\b|act as (?:a |an )?(?:[A-Za-z]+)|pretend (?:to be|you are)|system prompt:?|new instructions:?)",
2983
3069
  "gi"
@@ -3042,6 +3128,7 @@ function countOccurrences(haystack, needle) {
3042
3128
  }
3043
3129
 
3044
3130
  // src/core/panel-judges.ts
3131
+ init_esm_shims();
3045
3132
  function pickPanelJudge(providers, moderatorName, pricing) {
3046
3133
  if (pricing) {
3047
3134
  const tiers = tierLadder(pricing);
@@ -3223,6 +3310,7 @@ var STRUCTURED_SYNTHESIS_SCHEMA = {
3223
3310
  };
3224
3311
 
3225
3312
  // src/core/router.ts
3313
+ init_esm_shims();
3226
3314
  var ROUTER_DEFAULT_WINDOW_SECONDS = 30 * 24 * 3600;
3227
3315
  var ROUTER_COLD_START_THRESHOLD = 5;
3228
3316
  function routerScore(stats, minCost, maxCost) {
@@ -3371,6 +3459,7 @@ async function pickAutoPanel(storage, purpose, n, providers, allowlist) {
3371
3459
  }
3372
3460
 
3373
3461
  // src/core/session-memory.ts
3462
+ init_esm_shims();
3374
3463
  var SESSION_MEMORY_DEFAULT_LIMIT = 50;
3375
3464
  var SESSION_MEMORY_INJECT_BUDGET_CHARS = 4e3;
3376
3465
  async function renderSessionMemoryBlock(storage, sessionId) {
@@ -3418,6 +3507,7 @@ async function renderSessionMemoryBlock(storage, sessionId) {
3418
3507
  }
3419
3508
 
3420
3509
  // src/core/worker-tools.ts
3510
+ init_esm_shims();
3421
3511
  var WORKER_TOOL_ALLOWLIST = /* @__PURE__ */ new Set(["fetch", "verify"]);
3422
3512
  var WORKER_TOOL_HOP_BUDGET = 2;
3423
3513
  var WORKER_TOOLS_MAX_RESULT_CHARS = 4e3;
@@ -4264,6 +4354,7 @@ ${existing.content}`
4264
4354
  }
4265
4355
 
4266
4356
  // src/tools/review.ts
4357
+ init_esm_shims();
4267
4358
  async function runReview(args, opts) {
4268
4359
  const snippet = typeof args["snippet"] === "string" ? args["snippet"] : String(args["snippet"] ?? "");
4269
4360
  const intent = typeof args["intent"] === "string" ? args["intent"] : "";
@@ -4285,9 +4376,11 @@ ${snippet}
4285
4376
  }
4286
4377
 
4287
4378
  // src/tools/verify.ts
4379
+ init_esm_shims();
4288
4380
  import { performance as performance2 } from "perf_hooks";
4289
4381
 
4290
4382
  // src/core/sandbox.ts
4383
+ init_esm_shims();
4291
4384
  import { spawn } from "child_process";
4292
4385
  import { mkdtemp, rm } from "fs/promises";
4293
4386
  import { tmpdir } from "os";
@@ -4448,6 +4541,7 @@ function tryKill(child, signal, isUnix) {
4448
4541
  }
4449
4542
 
4450
4543
  // src/core/shlex.ts
4544
+ init_esm_shims();
4451
4545
  function shlexSplit(s) {
4452
4546
  const out = [];
4453
4547
  let current = "";
@@ -5090,6 +5184,7 @@ function isObj4(v) {
5090
5184
  }
5091
5185
 
5092
5186
  // src/tools/config-pin.ts
5187
+ init_esm_shims();
5093
5188
  import { createHash as createHash2 } from "crypto";
5094
5189
  import {
5095
5190
  existsSync as existsSync2,
@@ -5329,14 +5424,17 @@ function pyRepr2(v) {
5329
5424
  }
5330
5425
 
5331
5426
  // src/tools/create.ts
5427
+ init_esm_shims();
5332
5428
  import { createHash as createHash4 } from "crypto";
5333
5429
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
5334
5430
  import path6 from "path";
5335
5431
 
5336
5432
  // src/tools/orchestrate.ts
5433
+ init_esm_shims();
5337
5434
  import { performance as performance3 } from "perf_hooks";
5338
5435
 
5339
5436
  // src/core/dead-models.ts
5437
+ init_esm_shims();
5340
5438
  var DEAD_MODELS_TTL_MS = 5 * 60 * 1e3;
5341
5439
  var deadModels = /* @__PURE__ */ new Map();
5342
5440
  function makeKey(provider, model) {
@@ -6097,6 +6195,7 @@ function pyRound6(x) {
6097
6195
  }
6098
6196
 
6099
6197
  // src/tools/fetch.ts
6198
+ init_esm_shims();
6100
6199
  import { createHash as createHash3 } from "crypto";
6101
6200
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
6102
6201
  import path5 from "path";
@@ -6328,6 +6427,7 @@ function errorPayload(code, message, hint, kind = "client") {
6328
6427
  }
6329
6428
 
6330
6429
  // src/core/call-context.ts
6430
+ init_esm_shims();
6331
6431
  function buildCallContext(args) {
6332
6432
  const ctx = {
6333
6433
  cheap_mode: args.cheapMode,
@@ -6749,6 +6849,7 @@ function errorEnvelope6(toolName, code, message, hint) {
6749
6849
  }
6750
6850
 
6751
6851
  // src/tools/coordinate.ts
6852
+ init_esm_shims();
6752
6853
  var DEFERRED_OPTS3 = [
6753
6854
  // empty — every coordinate opt runs natively when its deps
6754
6855
  // (storage / innerCallers) are wired. Without them the
@@ -7148,6 +7249,7 @@ function errorEnvelope7(code, message, hint) {
7148
7249
  }
7149
7250
 
7150
7251
  // src/tools/critique.ts
7252
+ init_esm_shims();
7151
7253
  var CRITIQUE_MAX_WEAKNESSES = 5;
7152
7254
  var SEVERITY_ALIASES2 = {
7153
7255
  medium: "med",
@@ -7368,6 +7470,7 @@ function isObj6(v) {
7368
7470
  }
7369
7471
 
7370
7472
  // src/tools/debate.ts
7473
+ init_esm_shims();
7371
7474
  var DEFERRED_OPTS4 = [
7372
7475
  // empty — every debate opt runs natively when its deps
7373
7476
  // (storage / innerCallers) are wired.
@@ -7724,6 +7827,7 @@ function errorEnvelope9(code, message, hint) {
7724
7827
  }
7725
7828
 
7726
7829
  // src/tools/delegate.ts
7830
+ init_esm_shims();
7727
7831
  var DELEGABLE_TOOLS = /* @__PURE__ */ new Set(["confer", "review"]);
7728
7832
  var DEFAULT_DELEGATION_LIMITS = {
7729
7833
  max_per_session: 50,
@@ -7889,6 +7993,7 @@ function pyListRepr2(xs) {
7889
7993
  }
7890
7994
 
7891
7995
  // src/tools/explain.ts
7996
+ init_esm_shims();
7892
7997
  import { readdirSync as readdirSync3, readFileSync as readFileSync7, statSync as statSync4, existsSync as existsSync5 } from "fs";
7893
7998
  import path7 from "path";
7894
7999
  async function runExplain(args, opts) {
@@ -8213,6 +8318,7 @@ function errorEnvelope11(code, message, hint, kind = "client", extra = {}) {
8213
8318
  }
8214
8319
 
8215
8320
  // src/tools/list-providers.ts
8321
+ init_esm_shims();
8216
8322
  var KNOWN_PROVIDERS6 = [
8217
8323
  "anthropic",
8218
8324
  "openai",
@@ -8244,6 +8350,7 @@ function runListProviders(_args, opts) {
8244
8350
  }
8245
8351
 
8246
8352
  // src/tools/pick.ts
8353
+ init_esm_shims();
8247
8354
  var PICK_SCORES_SCHEMA = {
8248
8355
  type: "object",
8249
8356
  additionalProperties: false,
@@ -8560,6 +8667,7 @@ function toArray(v) {
8560
8667
  }
8561
8668
 
8562
8669
  // src/tools/plan.ts
8670
+ init_esm_shims();
8563
8671
  var PLAN_MODE_PRESETS = {
8564
8672
  fast: { max_rounds: 2, early_stop: true, early_stop_threshold: 0.7 },
8565
8673
  thorough: { max_rounds: 5, early_stop: false, early_stop_threshold: 0.7 }
@@ -8599,6 +8707,7 @@ Return: (1) the plan as numbered steps, (2) risks, (3) alternatives considered.`
8599
8707
  }
8600
8708
 
8601
8709
  // src/tools/recall.ts
8710
+ init_esm_shims();
8602
8711
  async function runRecall(args, opts) {
8603
8712
  const queryRaw = args["query"];
8604
8713
  const query = typeof queryRaw === "string" ? queryRaw.trim() : "";
@@ -8696,6 +8805,7 @@ function errorEnvelope12(code, message, hint) {
8696
8805
  }
8697
8806
 
8698
8807
  // src/tools/recommend-panel.ts
8808
+ init_esm_shims();
8699
8809
  async function runRecommendPanel(args, opts) {
8700
8810
  const purpose = typeof args["purpose"] === "string" ? args["purpose"] : "";
8701
8811
  if (!purpose) {
@@ -8812,6 +8922,7 @@ function toStringArray3(v) {
8812
8922
  }
8813
8923
 
8814
8924
  // src/tools/scoreboard.ts
8925
+ init_esm_shims();
8815
8926
  import { readFileSync as readFileSync8, existsSync as existsSync6 } from "fs";
8816
8927
  async function runScoreboard(args, opts) {
8817
8928
  if (!opts.storage) {
@@ -8947,6 +9058,7 @@ function errorEnvelope14(code, message, hint) {
8947
9058
  }
8948
9059
 
8949
9060
  // src/tools/session-memory.ts
9061
+ init_esm_shims();
8950
9062
  var VALID_KINDS = /* @__PURE__ */ new Set([
8951
9063
  "fact",
8952
9064
  "open_question",
@@ -9123,6 +9235,7 @@ function pyRepr6(v) {
9123
9235
  }
9124
9236
 
9125
9237
  // src/tools/solve.ts
9238
+ init_esm_shims();
9126
9239
  import { performance as performance4 } from "perf_hooks";
9127
9240
  async function runSolve(args, opts) {
9128
9241
  const problem = typeof args["problem"] === "string" ? args["problem"] : String(args["problem"] ?? "");
@@ -9492,6 +9605,7 @@ function pyRepr7(v) {
9492
9605
  }
9493
9606
 
9494
9607
  // src/tools/update-crosscheck.ts
9608
+ init_esm_shims();
9495
9609
  import { spawnSync } from "child_process";
9496
9610
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
9497
9611
  import path8 from "path";
@@ -9710,6 +9824,7 @@ function withTimeout2(promise, ms) {
9710
9824
  }
9711
9825
 
9712
9826
  // src/tools/triangulate.ts
9827
+ init_esm_shims();
9713
9828
  async function runTriangulate(args, opts) {
9714
9829
  const question = typeof args["question"] === "string" ? args["question"] : String(args["question"] ?? "");
9715
9830
  const context = typeof args["context"] === "string" ? args["context"] : "";
@@ -10579,7 +10694,7 @@ function pingTool() {
10579
10694
 
10580
10695
  // src/server.ts
10581
10696
  var SERVER_NAME = "crosscheck-agent";
10582
- var SERVER_VERSION = "0.1.0";
10697
+ var SERVER_VERSION = true ? "0.1.3" : "0.0.0-dev";
10583
10698
  function createServer(opts = {}) {
10584
10699
  const server = new Server(
10585
10700
  { name: SERVER_NAME, version: SERVER_VERSION },
@@ -10734,7 +10849,8 @@ async function main() {
10734
10849
  if (dbPath) {
10735
10850
  try {
10736
10851
  mkdirSync6(path9.dirname(dbPath), { recursive: true });
10737
- storage = openBetterSqliteStorage({ path: dbPath });
10852
+ const { openBetterSqliteStorage: openBetterSqliteStorage2 } = await Promise.resolve().then(() => (init_better_sqlite3(), better_sqlite3_exports));
10853
+ storage = openBetterSqliteStorage2({ path: dbPath });
10738
10854
  await storage.migrate();
10739
10855
  process.stderr.write(
10740
10856
  `crosscheck-agent: storage wired at ${dbPath}