claude-memory-layer 1.0.44 → 1.0.46

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.
@@ -68,6 +68,7 @@ var DefaultEmbeddingMaintenanceService = class {
68
68
  this.options = options;
69
69
  this.fileSystem = options.fileSystem ?? defaultFileSystem;
70
70
  }
71
+ options;
71
72
  fileSystem;
72
73
  getEmbeddingModelName() {
73
74
  return this.options.getEmbeddingModelName();
@@ -102,8 +103,7 @@ var DefaultEmbeddingMaintenanceService = class {
102
103
  }
103
104
  const worker = this.options.getVectorWorker();
104
105
  const wasRunning = worker?.isRunning() || false;
105
- if (wasRunning)
106
- worker?.stop();
106
+ if (wasRunning) worker?.stop();
107
107
  await this.options.vectorStore.clearAll();
108
108
  await this.options.eventStore.clearEmbeddingOutbox();
109
109
  const enqueued = await this.reenqueueAllEvents();
@@ -120,8 +120,7 @@ var DefaultEmbeddingMaintenanceService = class {
120
120
  2
121
121
  )
122
122
  );
123
- if (wasRunning)
124
- worker?.start();
123
+ if (wasRunning) worker?.start();
125
124
  return {
126
125
  changed: true,
127
126
  previousModel,
@@ -146,15 +145,13 @@ var DefaultEmbeddingMaintenanceService = class {
146
145
  let enqueued = 0;
147
146
  while (true) {
148
147
  const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
149
- if (page.length === 0)
150
- break;
148
+ if (page.length === 0) break;
151
149
  for (const event of page) {
152
150
  await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
153
151
  enqueued += 1;
154
152
  }
155
153
  offset += page.length;
156
- if (page.length < DEFAULT_PAGE_SIZE)
157
- break;
154
+ if (page.length < DEFAULT_PAGE_SIZE) break;
158
155
  }
159
156
  return enqueued;
160
157
  }
@@ -172,12 +169,9 @@ import { randomUUID } from "crypto";
172
169
  // src/core/db-wrapper.ts
173
170
  import BetterSqlite3 from "better-sqlite3";
174
171
  function toDate(value) {
175
- if (value instanceof Date)
176
- return value;
177
- if (typeof value === "string")
178
- return new Date(value);
179
- if (typeof value === "number")
180
- return new Date(value);
172
+ if (value instanceof Date) return value;
173
+ if (typeof value === "string") return new Date(value);
174
+ if (typeof value === "number") return new Date(value);
181
175
  return new Date(String(value));
182
176
  }
183
177
  function createDatabase(dbPath, options) {
@@ -201,6 +195,8 @@ var WorkingSetStore = class {
201
195
  this.eventStore = eventStore;
202
196
  this.config = config;
203
197
  }
198
+ eventStore;
199
+ config;
204
200
  get db() {
205
201
  return this.eventStore.getDatabase();
206
202
  }
@@ -286,8 +282,7 @@ var WorkingSetStore = class {
286
282
  * Prune specific events from working set (after consolidation)
287
283
  */
288
284
  async prune(eventIds) {
289
- if (eventIds.length === 0)
290
- return;
285
+ if (eventIds.length === 0) return;
291
286
  const placeholders = eventIds.map(() => "?").join(",");
292
287
  await dbRun(
293
288
  this.db,
@@ -357,8 +352,7 @@ var WorkingSetStore = class {
357
352
  LIMIT ?`,
358
353
  [maxEvents]
359
354
  );
360
- if (keepIds.length === 0)
361
- return;
355
+ if (keepIds.length === 0) return;
362
356
  const keepIdList = keepIds.map((r) => r.id);
363
357
  const placeholders = keepIdList.map(() => "?").join(",");
364
358
  await dbRun(
@@ -405,6 +399,7 @@ var ConsolidatedStore = class {
405
399
  constructor(eventStore) {
406
400
  this.eventStore = eventStore;
407
401
  }
402
+ eventStore;
408
403
  get db() {
409
404
  return this.eventStore.getDatabase();
410
405
  }
@@ -437,8 +432,7 @@ var ConsolidatedStore = class {
437
432
  `SELECT * FROM consolidated_memories WHERE memory_id = ?`,
438
433
  [memoryId]
439
434
  );
440
- if (rows.length === 0)
441
- return null;
435
+ if (rows.length === 0) return null;
442
436
  return this.rowToMemory(rows[0]);
443
437
  }
444
438
  /**
@@ -656,8 +650,7 @@ var ConsolidatedStore = class {
656
650
  WHERE source_events LIKE ?`,
657
651
  [`%"${eventId}"%`]
658
652
  );
659
- if ((result[0]?.count || 0) > 0)
660
- return true;
653
+ if ((result[0]?.count || 0) > 0) return true;
661
654
  }
662
655
  return false;
663
656
  }
@@ -671,8 +664,7 @@ var ConsolidatedStore = class {
671
664
  ORDER BY created_at DESC
672
665
  LIMIT 1`
673
666
  );
674
- if (result.length === 0)
675
- return null;
667
+ if (result.length === 0) return null;
676
668
  return new Date(result[0].created_at);
677
669
  }
678
670
  /**
@@ -702,6 +694,9 @@ var ConsolidationWorker = class {
702
694
  this.consolidatedStore = consolidatedStore;
703
695
  this.config = config;
704
696
  }
697
+ workingSetStore;
698
+ consolidatedStore;
699
+ config;
705
700
  running = false;
706
701
  timeout = null;
707
702
  lastActivity = /* @__PURE__ */ new Date();
@@ -709,8 +704,7 @@ var ConsolidationWorker = class {
709
704
  * Start the consolidation worker
710
705
  */
711
706
  start() {
712
- if (this.running)
713
- return;
707
+ if (this.running) return;
714
708
  this.running = true;
715
709
  this.scheduleNext();
716
710
  }
@@ -753,8 +747,7 @@ var ConsolidationWorker = class {
753
747
  * Schedule the next consolidation check
754
748
  */
755
749
  scheduleNext() {
756
- if (!this.running)
757
- return;
750
+ if (!this.running) return;
758
751
  this.timeout = setTimeout(
759
752
  () => this.run(),
760
753
  this.config.consolidation.triggerIntervalMs
@@ -764,8 +757,7 @@ var ConsolidationWorker = class {
764
757
  * Run consolidation check
765
758
  */
766
759
  async run() {
767
- if (!this.running)
768
- return;
760
+ if (!this.running) return;
769
761
  try {
770
762
  await this.checkAndConsolidate();
771
763
  } catch (error) {
@@ -803,12 +795,10 @@ var ConsolidationWorker = class {
803
795
  let consolidatedCount = 0;
804
796
  const createdMemoryIds = [];
805
797
  for (const group of groups) {
806
- if (group.events.length < 3)
807
- continue;
798
+ if (group.events.length < 3) continue;
808
799
  const eventIds = group.events.map((e) => e.id);
809
800
  const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);
810
- if (alreadyConsolidated)
811
- continue;
801
+ if (alreadyConsolidated) continue;
812
802
  const summary = await this.summarize(group);
813
803
  const memoryId = await this.consolidatedStore.create({
814
804
  summary,
@@ -824,8 +814,7 @@ var ConsolidationWorker = class {
824
814
  const consolidatedEventIds = groups.filter((g) => g.events.length >= 3).flatMap((g) => g.events.map((e) => e.id));
825
815
  const oldEventIds = consolidatedEventIds.filter((id) => {
826
816
  const event = workingSet.recentEvents.find((e) => e.id === id);
827
- if (!event)
828
- return false;
817
+ if (!event) return false;
829
818
  const ageHours = (Date.now() - event.timestamp.getTime()) / (1e3 * 60 * 60);
830
819
  return ageHours > this.config.workingSet.timeWindowHours / 2;
831
820
  });
@@ -840,18 +829,13 @@ var ConsolidationWorker = class {
840
829
  let promoted = 0;
841
830
  for (const memoryId of memoryIds) {
842
831
  const memory = await this.consolidatedStore.get(memoryId);
843
- if (!memory)
844
- continue;
845
- if (memory.confidence < 0.55)
846
- continue;
847
- if (memory.sourceEvents.length < 4)
848
- continue;
832
+ if (!memory) continue;
833
+ if (memory.confidence < 0.55) continue;
834
+ if (memory.sourceEvents.length < 4) continue;
849
835
  const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);
850
- if (exists)
851
- continue;
836
+ if (exists) continue;
852
837
  const rule = this.buildRuleFromSummary(memory.summary, memory.topics);
853
- if (!rule)
854
- continue;
838
+ if (!rule) continue;
855
839
  await this.consolidatedStore.createRule({
856
840
  rule,
857
841
  topics: memory.topics,
@@ -867,8 +851,7 @@ var ConsolidationWorker = class {
867
851
  const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !l.toLowerCase().startsWith("topics:"));
868
852
  const bullet = lines.find((l) => l.startsWith("- "))?.replace(/^-\s*/, "");
869
853
  const seed = bullet || lines[0];
870
- if (!seed || seed.length < 8)
871
- return null;
854
+ if (!seed || seed.length < 8) return null;
872
855
  const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(", ")}] ` : "";
873
856
  return `${topicPrefix}${seed}`;
874
857
  }
@@ -1029,8 +1012,7 @@ var ConsolidationWorker = class {
1029
1012
  */
1030
1013
  extractKeyPoint(content) {
1031
1014
  const sentences = content.split(/[.!?\n]+/).filter((s) => s.trim().length > 10);
1032
- if (sentences.length === 0)
1033
- return null;
1015
+ if (sentences.length === 0) return null;
1034
1016
  const firstSentence = sentences[0].trim();
1035
1017
  if (firstSentence.length > 100) {
1036
1018
  return firstSentence.slice(0, 100) + "...";
@@ -1050,8 +1032,7 @@ var ConsolidationWorker = class {
1050
1032
  * Calculate time proximity score
1051
1033
  */
1052
1034
  calculateTimeProximity(events) {
1053
- if (events.length < 2)
1054
- return 1;
1035
+ if (events.length < 2) return 1;
1055
1036
  const timestamps = events.map((e) => e.timestamp.getTime()).sort((a, b) => a - b);
1056
1037
  const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];
1057
1038
  const avgGap = timeSpan / (events.length - 1);
@@ -1070,6 +1051,8 @@ var ContinuityManager = class {
1070
1051
  this.eventStore = eventStore;
1071
1052
  this.config = config;
1072
1053
  }
1054
+ eventStore;
1055
+ config;
1073
1056
  lastContext = null;
1074
1057
  get db() {
1075
1058
  return this.eventStore.getDatabase();
@@ -1189,8 +1172,7 @@ var ContinuityManager = class {
1189
1172
  * Calculate overlap between two arrays
1190
1173
  */
1191
1174
  calculateOverlap(a, b) {
1192
- if (a.length === 0 || b.length === 0)
1193
- return 0;
1175
+ if (a.length === 0 || b.length === 0) return 0;
1194
1176
  const setA = new Set(a.map((s) => s.toLowerCase()));
1195
1177
  const setB = new Set(b.map((s) => s.toLowerCase()));
1196
1178
  const intersection = [...setA].filter((x) => setB.has(x));
@@ -1363,6 +1345,7 @@ var DefaultEndlessMemoryServices = class {
1363
1345
  this.options = options;
1364
1346
  this.factories = options.factories ? { ...options.factories, randomUUID: options.factories.randomUUID ?? randomUUID4 } : defaultFactories;
1365
1347
  }
1348
+ options;
1366
1349
  factories;
1367
1350
  workingSetStore = null;
1368
1351
  consolidatedStore = null;
@@ -1377,8 +1360,7 @@ var DefaultEndlessMemoryServices = class {
1377
1360
  }
1378
1361
  }
1379
1362
  async initializeEndlessMode() {
1380
- if (this.consolidationWorker)
1381
- return;
1363
+ if (this.consolidationWorker) return;
1382
1364
  const config = await this.getEndlessConfig();
1383
1365
  const workingSetStore = this.factories.createWorkingSetStore(this.options.eventStore, config);
1384
1366
  const consolidatedStore = this.factories.createConsolidatedStore(this.options.eventStore);
@@ -1410,8 +1392,7 @@ var DefaultEndlessMemoryServices = class {
1410
1392
  }
1411
1393
  async setMode(mode) {
1412
1394
  await this.options.initialize();
1413
- if (mode === this.mode)
1414
- return;
1395
+ if (mode === this.mode) return;
1415
1396
  this.mode = mode;
1416
1397
  await this.options.configStore.setEndlessConfig("mode", mode);
1417
1398
  if (mode === "endless") {
@@ -1427,33 +1408,27 @@ var DefaultEndlessMemoryServices = class {
1427
1408
  return this.mode === "endless";
1428
1409
  }
1429
1410
  async addToWorkingSet(eventId, relevanceScore) {
1430
- if (!this.workingSetStore)
1431
- return;
1411
+ if (!this.workingSetStore) return;
1432
1412
  await this.workingSetStore.add(eventId, relevanceScore);
1433
1413
  }
1434
1414
  async getWorkingSet() {
1435
- if (!this.workingSetStore)
1436
- return null;
1415
+ if (!this.workingSetStore) return null;
1437
1416
  return this.workingSetStore.get();
1438
1417
  }
1439
1418
  async searchConsolidated(query, options) {
1440
- if (!this.consolidatedStore)
1441
- return [];
1419
+ if (!this.consolidatedStore) return [];
1442
1420
  return this.consolidatedStore.search(query, options);
1443
1421
  }
1444
1422
  async getConsolidatedMemories(limit) {
1445
- if (!this.consolidatedStore)
1446
- return [];
1423
+ if (!this.consolidatedStore) return [];
1447
1424
  return this.consolidatedStore.getAll({ limit });
1448
1425
  }
1449
1426
  async markMemoryAccessed(memoryId) {
1450
- if (!this.consolidatedStore)
1451
- return;
1427
+ if (!this.consolidatedStore) return;
1452
1428
  await this.consolidatedStore.markAccessed(memoryId);
1453
1429
  }
1454
1430
  async calculateContinuity(content, metadata) {
1455
- if (!this.continuityManager)
1456
- return null;
1431
+ if (!this.continuityManager) return null;
1457
1432
  const snapshot = this.continuityManager.createSnapshot(
1458
1433
  this.factories.randomUUID(),
1459
1434
  content,
@@ -1465,8 +1440,7 @@ var DefaultEndlessMemoryServices = class {
1465
1440
  this.consolidationWorker?.recordActivity();
1466
1441
  }
1467
1442
  async forceConsolidation() {
1468
- if (!this.consolidationWorker)
1469
- return 0;
1443
+ if (!this.consolidationWorker) return 0;
1470
1444
  return this.consolidationWorker.forceRun();
1471
1445
  }
1472
1446
  async getEndlessModeStatus() {
@@ -1558,8 +1532,7 @@ var Embedder = class _Embedder {
1558
1532
  * Initialize the embedding pipeline
1559
1533
  */
1560
1534
  async initialize() {
1561
- if (this.initialized)
1562
- return;
1535
+ if (this.initialized) return;
1563
1536
  const pipeline = await withSuppressedKnownTransformersWarnings(async () => {
1564
1537
  try {
1565
1538
  return await loadTransformersPipeline();
@@ -1676,8 +1649,7 @@ async function withSuppressedKnownTransformersWarnings(fn) {
1676
1649
  originalConsoleWarn = console.warn;
1677
1650
  console.warn = (...args) => {
1678
1651
  const message = args.map(String).join(" ");
1679
- if (isKnownBenignTransformersWarning(message))
1680
- return;
1652
+ if (isKnownBenignTransformersWarning(message)) return;
1681
1653
  (originalConsoleWarn ?? console.warn)(...args);
1682
1654
  };
1683
1655
  }
@@ -1959,8 +1931,7 @@ var GraduationPipeline = class {
1959
1931
  const preferenceKeywords = ["prefer", "like", "want", "always", "never", "favorite"];
1960
1932
  const preferences = [];
1961
1933
  for (const event of events) {
1962
- if (event.eventType !== "user_prompt")
1963
- continue;
1934
+ if (event.eventType !== "user_prompt") continue;
1964
1935
  const lowerContent = event.content.toLowerCase();
1965
1936
  for (const keyword of preferenceKeywords) {
1966
1937
  if (lowerContent.includes(keyword)) {
@@ -2126,11 +2097,9 @@ function sanitizeSegment(input, fallback) {
2126
2097
  return v || fallback;
2127
2098
  }
2128
2099
  function getAtPath(obj, dotted) {
2129
- if (!obj)
2130
- return void 0;
2100
+ if (!obj) return void 0;
2131
2101
  return dotted.split(".").reduce((acc, key) => {
2132
- if (!acc || typeof acc !== "object")
2133
- return void 0;
2102
+ if (!acc || typeof acc !== "object") return void 0;
2134
2103
  return acc[key];
2135
2104
  }, obj);
2136
2105
  }
@@ -2150,6 +2119,7 @@ var MarkdownMirror = class {
2150
2119
  constructor(rootDir) {
2151
2120
  this.rootDir = rootDir;
2152
2121
  }
2122
+ rootDir;
2153
2123
  async append(event, eventId) {
2154
2124
  const out = buildMirrorPath(this.rootDir, event);
2155
2125
  fs2.mkdirSync(path2.dirname(out), { recursive: true });
@@ -2285,10 +2255,8 @@ function sqliteClose(db) {
2285
2255
  db.close();
2286
2256
  }
2287
2257
  function toDateFromSQLite(value) {
2288
- if (value instanceof Date)
2289
- return value;
2290
- if (typeof value === "number")
2291
- return new Date(value);
2258
+ if (value instanceof Date) return value;
2259
+ if (typeof value === "number") return new Date(value);
2292
2260
  if (typeof value === "string") {
2293
2261
  const trimmed = value.trim();
2294
2262
  if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(trimmed)) {
@@ -2310,8 +2278,7 @@ var DEFAULT_CATEGORY = "uncategorized";
2310
2278
  function sanitizeSegment2(input, fallback) {
2311
2279
  const raw = String(input ?? "").trim().toLowerCase();
2312
2280
  const safe = raw.normalize("NFKD").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
2313
- if (!safe || safe === "." || safe === "..")
2314
- return fallback;
2281
+ if (!safe || safe === "." || safe === "..") return fallback;
2315
2282
  return safe;
2316
2283
  }
2317
2284
  function getCategorySegments(metadata, eventType) {
@@ -2352,6 +2319,7 @@ var MarkdownMirror2 = class {
2352
2319
  constructor(rootDir) {
2353
2320
  this.rootDir = rootDir;
2354
2321
  }
2322
+ rootDir;
2355
2323
  async append(event) {
2356
2324
  const outPath = buildMirrorPath2(this.rootDir, event);
2357
2325
  await fs5.mkdir(path4.dirname(outPath), { recursive: true });
@@ -2374,6 +2342,7 @@ var VectorOutbox = class {
2374
2342
  this.db = db;
2375
2343
  this.config = { ...DEFAULT_CONFIG2, ...config };
2376
2344
  }
2345
+ db;
2377
2346
  config;
2378
2347
  /**
2379
2348
  * Enqueue item for vectorization (idempotent).
@@ -2470,8 +2439,7 @@ var VectorOutbox = class {
2470
2439
  `SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
2471
2440
  [jobId]
2472
2441
  );
2473
- if (rows.length === 0)
2474
- return;
2442
+ if (rows.length === 0) return;
2475
2443
  const retryCount = rows[0].retry_count;
2476
2444
  const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
2477
2445
  await dbRun(
@@ -2491,8 +2459,7 @@ var VectorOutbox = class {
2491
2459
  `SELECT * FROM vector_outbox WHERE job_id = ?`,
2492
2460
  [jobId]
2493
2461
  );
2494
- if (rows.length === 0)
2495
- return null;
2462
+ if (rows.length === 0) return null;
2496
2463
  return this.rowToJob(rows[0]);
2497
2464
  }
2498
2465
  /**
@@ -2626,30 +2593,24 @@ function isRetrievalDebugLaneName(value) {
2626
2593
  return typeof value === "string" && RETRIEVAL_DEBUG_LANE_NAME_SET.has(value);
2627
2594
  }
2628
2595
  function normalizeRetrievalDebugLanes(value, maxItems = 6) {
2629
- if (!Array.isArray(value) || maxItems <= 0)
2630
- return [];
2596
+ if (!Array.isArray(value) || maxItems <= 0) return [];
2631
2597
  const normalized = [];
2632
2598
  const seen = /* @__PURE__ */ new Set();
2633
2599
  for (const item of value) {
2634
2600
  const lane = normalizeRetrievalDebugLane(item);
2635
- if (!lane)
2636
- continue;
2601
+ if (!lane) continue;
2637
2602
  const key = [lane.lane, lane.reason, lane.score ?? ""].join("\0");
2638
- if (seen.has(key))
2639
- continue;
2603
+ if (seen.has(key)) continue;
2640
2604
  seen.add(key);
2641
2605
  normalized.push(lane);
2642
- if (normalized.length >= maxItems)
2643
- break;
2606
+ if (normalized.length >= maxItems) break;
2644
2607
  }
2645
2608
  return normalized;
2646
2609
  }
2647
2610
  function normalizeRetrievalDebugLane(value) {
2648
- if (!value || typeof value !== "object")
2649
- return null;
2611
+ if (!value || typeof value !== "object") return null;
2650
2612
  const raw = value;
2651
- if (!isRetrievalDebugLaneName(raw.lane))
2652
- return null;
2613
+ if (!isRetrievalDebugLaneName(raw.lane)) return null;
2653
2614
  const reason = sanitizeRetrievalLaneReason(typeof raw.reason === "string" ? raw.reason : "") || "unspecified";
2654
2615
  const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? Math.max(0, Math.min(1, raw.score)) : void 0;
2655
2616
  return score === void 0 ? { lane: raw.lane, reason } : { lane: raw.lane, reason, score };
@@ -2672,27 +2633,21 @@ function normalizeRetrievalTraceDetails(details) {
2672
2633
  eventId: detail.eventId,
2673
2634
  score: detail.score
2674
2635
  };
2675
- if (detail.semanticScore !== void 0)
2676
- normalized.semanticScore = detail.semanticScore;
2677
- if (detail.lexicalScore !== void 0)
2678
- normalized.lexicalScore = detail.lexicalScore;
2679
- if (detail.recencyScore !== void 0)
2680
- normalized.recencyScore = detail.recencyScore;
2681
- if (lanes.length > 0)
2682
- normalized.lanes = lanes;
2636
+ if (detail.semanticScore !== void 0) normalized.semanticScore = detail.semanticScore;
2637
+ if (detail.lexicalScore !== void 0) normalized.lexicalScore = detail.lexicalScore;
2638
+ if (detail.recencyScore !== void 0) normalized.recencyScore = detail.recencyScore;
2639
+ if (lanes.length > 0) normalized.lanes = lanes;
2683
2640
  return normalized;
2684
2641
  });
2685
2642
  }
2686
2643
  function parseRetrievalTraceDetails(value) {
2687
- if (typeof value !== "string" || value.length === 0)
2688
- return [];
2644
+ if (typeof value !== "string" || value.length === 0) return [];
2689
2645
  const parsed = JSON.parse(value);
2690
2646
  return Array.isArray(parsed) ? normalizeRetrievalTraceDetails(parsed) : [];
2691
2647
  }
2692
2648
  function normalizeQueryRewriteKind(value) {
2693
2649
  const normalized = (value || "").trim().toLowerCase();
2694
- if (normalized === "follow-up-context" || normalized === "intent-rewrite")
2695
- return normalized;
2650
+ if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
2696
2651
  return "none";
2697
2652
  }
2698
2653
  var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
@@ -2710,8 +2665,7 @@ function isRecord(value) {
2710
2665
  function getNestedRecord(root, path14) {
2711
2666
  let cursor = root;
2712
2667
  for (const key of path14) {
2713
- if (!isRecord(cursor))
2714
- return void 0;
2668
+ if (!isRecord(cursor)) return void 0;
2715
2669
  cursor = cursor[key];
2716
2670
  }
2717
2671
  return isRecord(cursor) ? cursor : void 0;
@@ -2719,8 +2673,7 @@ function getNestedRecord(root, path14) {
2719
2673
  function getNestedString(root, path14) {
2720
2674
  let cursor = root;
2721
2675
  for (const key of path14) {
2722
- if (!isRecord(cursor))
2723
- return void 0;
2676
+ if (!isRecord(cursor)) return void 0;
2724
2677
  cursor = cursor[key];
2725
2678
  }
2726
2679
  return typeof cursor === "string" && cursor.length > 0 ? cursor : void 0;
@@ -2736,8 +2689,7 @@ function metadataProjectPaths(metadata) {
2736
2689
  ];
2737
2690
  const paths = [];
2738
2691
  for (const value of candidates) {
2739
- if (value && !paths.includes(value))
2740
- paths.push(value);
2692
+ if (value && !paths.includes(value)) paths.push(value);
2741
2693
  }
2742
2694
  return paths;
2743
2695
  }
@@ -2758,12 +2710,9 @@ function maybeQuarantinePredicate(options, column = "metadata") {
2758
2710
  return options?.includeQuarantined ? "1=1" : notActiveQuarantinedSql(column);
2759
2711
  }
2760
2712
  function safeParseMetadataValue(value) {
2761
- if (!value)
2762
- return void 0;
2763
- if (typeof value === "object")
2764
- return isRecord(value) ? value : void 0;
2765
- if (typeof value !== "string")
2766
- return void 0;
2713
+ if (!value) return void 0;
2714
+ if (typeof value === "object") return isRecord(value) ? value : void 0;
2715
+ if (typeof value !== "string") return void 0;
2767
2716
  try {
2768
2717
  const parsed = JSON.parse(value);
2769
2718
  return isRecord(parsed) ? parsed : void 0;
@@ -2772,16 +2721,14 @@ function safeParseMetadataValue(value) {
2772
2721
  }
2773
2722
  }
2774
2723
  function isImportedOrLegacyScopedMetadata(metadata) {
2775
- if (!metadata)
2776
- return false;
2724
+ if (!metadata) return false;
2777
2725
  return Boolean(
2778
2726
  metadata.importedFrom || metadata.sourceSessionId || metadata.sourceSessionHash || metadata.hermesSource || metadata.projectPath || metadata.sourceProjectPath || metadata.source === "hermes" || metadata.source === "claude" || metadata.source === "codex"
2779
2727
  );
2780
2728
  }
2781
2729
  function addMetadataTag(metadata, tag) {
2782
2730
  const current = Array.isArray(metadata.tags) ? metadata.tags.filter((value) => typeof value === "string") : [];
2783
- if (!current.includes(tag))
2784
- metadata.tags = [...current, tag];
2731
+ if (!current.includes(tag)) metadata.tags = [...current, tag];
2785
2732
  }
2786
2733
  function buildRepairResult(projectHash, dryRun) {
2787
2734
  return {
@@ -2799,8 +2746,7 @@ function normalizeRepoName(value) {
2799
2746
  return value.replace(/\.git$/i, "").trim().toLowerCase();
2800
2747
  }
2801
2748
  function projectBasename(projectPath) {
2802
- if (!projectPath)
2803
- return void 0;
2749
+ if (!projectPath) return void 0;
2804
2750
  const trimmed = projectPath.replace(/[\\/]+$/, "");
2805
2751
  const basename3 = nodePath2.basename(trimmed);
2806
2752
  return basename3 ? normalizeRepoName(basename3) : void 0;
@@ -2813,23 +2759,19 @@ function isProjectScopeRepairExplanation(content) {
2813
2759
  }
2814
2760
  function hasConflictingContentProjectHint(content, projectPath) {
2815
2761
  const currentName = projectBasename(projectPath);
2816
- if (!currentName)
2817
- return false;
2818
- if (isProjectScopeRepairExplanation(content))
2819
- return false;
2762
+ if (!currentName) return false;
2763
+ if (isProjectScopeRepairExplanation(content)) return false;
2820
2764
  const githubRepoPattern = /github\.com[:/]([^/\s`'"#)]+)\/([^/\s`'"#)]+)(?:\.git)?/gi;
2821
2765
  let githubMatch;
2822
2766
  while ((githubMatch = githubRepoPattern.exec(content)) !== null) {
2823
2767
  const repo = normalizeRepoName(githubMatch[2] || "");
2824
- if (repo && repo !== currentName)
2825
- return true;
2768
+ if (repo && repo !== currentName) return true;
2826
2769
  }
2827
2770
  const workspacePathPattern = /\/workspace\/([^/\s`'"#)]+)/gi;
2828
2771
  let workspaceMatch;
2829
2772
  while ((workspaceMatch = workspacePathPattern.exec(content)) !== null) {
2830
2773
  const repo = normalizeRepoName(workspaceMatch[1] || "");
2831
- if (repo && repo !== currentName)
2832
- return true;
2774
+ if (repo && repo !== currentName) return true;
2833
2775
  }
2834
2776
  return false;
2835
2777
  }
@@ -2849,15 +2791,12 @@ var SQLiteEventStore = class {
2849
2791
  this.vectorOutbox = this.createVectorOutbox(options?.vectorOutbox);
2850
2792
  }
2851
2793
  createVectorOutbox(option) {
2852
- if (this.readOnly || option === false)
2853
- return null;
2854
- if (option instanceof VectorOutbox)
2855
- return option;
2794
+ if (this.readOnly || option === false) return null;
2795
+ if (option instanceof VectorOutbox) return option;
2856
2796
  return new VectorOutbox(this.db, option ?? {});
2857
2797
  }
2858
2798
  enqueueVectorOutboxEventSync(eventId) {
2859
- if (!this.vectorOutbox)
2860
- return;
2799
+ if (!this.vectorOutbox) return;
2861
2800
  this.vectorOutbox.enqueueSync("event", eventId);
2862
2801
  }
2863
2802
  async enqueueVectorOutboxEvent(eventId) {
@@ -2867,8 +2806,7 @@ var SQLiteEventStore = class {
2867
2806
  * Initialize database schema
2868
2807
  */
2869
2808
  async initialize() {
2870
- if (this.initialized)
2871
- return;
2809
+ if (this.initialized) return;
2872
2810
  if (this.readOnly) {
2873
2811
  this.initialized = true;
2874
2812
  return;
@@ -3426,10 +3364,8 @@ var SQLiteEventStore = class {
3426
3364
  try {
3427
3365
  const edgeIndexes = sqliteAll(this.db, `PRAGMA index_list(memory_action_edges)`, []);
3428
3366
  const hasSourceAwareUnique = edgeIndexes.some((index) => {
3429
- if (Number(index.unique) !== 1)
3430
- return false;
3431
- if (!/^[A-Za-z0-9_]+$/.test(index.name))
3432
- return false;
3367
+ if (Number(index.unique) !== 1) return false;
3368
+ if (!/^[A-Za-z0-9_]+$/.test(index.name)) return false;
3433
3369
  const escapedName = index.name.replace(/"/g, '""');
3434
3370
  const columns = sqliteAll(this.db, 'PRAGMA index_info("' + escapedName + '")', []).map((column) => column.name);
3435
3371
  return columns.length === 5 && columns[0] === "src_action_id" && columns[1] === "rel_type" && columns[2] === "dst_type" && columns[3] === "dst_id" && columns[4] === "source";
@@ -3669,8 +3605,7 @@ var SQLiteEventStore = class {
3669
3605
  `SELECT * FROM events WHERE id = ? AND ${maybeQuarantinePredicate(options)}`,
3670
3606
  [id]
3671
3607
  );
3672
- if (!row)
3673
- return null;
3608
+ if (!row) return null;
3674
3609
  return this.rowToEvent(row);
3675
3610
  }
3676
3611
  /**
@@ -3708,10 +3643,8 @@ var SQLiteEventStore = class {
3708
3643
  * NOTE: This bypasses the append() id generation to preserve stable IDs.
3709
3644
  */
3710
3645
  async importEvents(events) {
3711
- if (events.length === 0)
3712
- return { inserted: 0, skipped: 0 };
3713
- if (this.readOnly)
3714
- return { inserted: 0, skipped: events.length };
3646
+ if (events.length === 0) return { inserted: 0, skipped: 0 };
3647
+ if (this.readOnly) return { inserted: 0, skipped: events.length };
3715
3648
  await this.initialize();
3716
3649
  const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);
3717
3650
  const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);
@@ -3829,8 +3762,7 @@ var SQLiteEventStore = class {
3829
3762
  `SELECT * FROM sessions WHERE id = ?`,
3830
3763
  [id]
3831
3764
  );
3832
- if (!row)
3833
- return null;
3765
+ if (!row) return null;
3834
3766
  return {
3835
3767
  id: row.id,
3836
3768
  startedAt: toDateFromSQLite(row.started_at),
@@ -3885,8 +3817,7 @@ var SQLiteEventStore = class {
3885
3817
  LIMIT ?`,
3886
3818
  [limit]
3887
3819
  );
3888
- if (pending.length === 0)
3889
- return [];
3820
+ if (pending.length === 0) return [];
3890
3821
  const ids = pending.map((r) => r.id);
3891
3822
  const placeholders = ids.map(() => "?").join(",");
3892
3823
  sqliteRun(
@@ -3910,8 +3841,7 @@ var SQLiteEventStore = class {
3910
3841
  * Mark outbox items as done
3911
3842
  */
3912
3843
  async completeOutboxItems(ids) {
3913
- if (ids.length === 0)
3914
- return;
3844
+ if (ids.length === 0) return;
3915
3845
  const placeholders = ids.map(() => "?").join(",");
3916
3846
  sqliteRun(
3917
3847
  this.db,
@@ -3950,8 +3880,7 @@ var SQLiteEventStore = class {
3950
3880
  * Mark outbox items as failed
3951
3881
  */
3952
3882
  async failOutboxItems(ids, error) {
3953
- if (ids.length === 0)
3954
- return;
3883
+ if (ids.length === 0) return;
3955
3884
  const placeholders = ids.map(() => "?").join(",");
3956
3885
  sqliteRun(
3957
3886
  this.db,
@@ -4078,8 +4007,7 @@ var SQLiteEventStore = class {
4078
4007
  []
4079
4008
  );
4080
4009
  const sample = (entry) => {
4081
- if (result.samples.length < 20)
4082
- result.samples.push(entry);
4010
+ if (result.samples.length < 20) result.samples.push(entry);
4083
4011
  };
4084
4012
  for (const row of rows) {
4085
4013
  result.scanned++;
@@ -4206,12 +4134,10 @@ var SQLiteEventStore = class {
4206
4134
  `SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`
4207
4135
  );
4208
4136
  const processingAgeMs = (value) => {
4209
- if (value === null || value === void 0)
4210
- return null;
4137
+ if (value === null || value === void 0) return null;
4211
4138
  const date = toDateFromSQLite(value);
4212
4139
  const time = date.getTime();
4213
- if (!Number.isFinite(time))
4214
- return null;
4140
+ if (!Number.isFinite(time)) return null;
4215
4141
  return Math.max(0, now.getTime() - time);
4216
4142
  };
4217
4143
  const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
@@ -4360,8 +4286,7 @@ var SQLiteEventStore = class {
4360
4286
  `SELECT value FROM endless_config WHERE key = ?`,
4361
4287
  [key]
4362
4288
  );
4363
- if (!row)
4364
- return null;
4289
+ if (!row) return null;
4365
4290
  return JSON.parse(row.value);
4366
4291
  }
4367
4292
  /**
@@ -4380,8 +4305,7 @@ var SQLiteEventStore = class {
4380
4305
  * Increment access count for events
4381
4306
  */
4382
4307
  async incrementAccessCount(eventIds) {
4383
- if (eventIds.length === 0 || this.readOnly)
4384
- return;
4308
+ if (eventIds.length === 0 || this.readOnly) return;
4385
4309
  await this.initialize();
4386
4310
  const placeholders = eventIds.map(() => "?").join(",");
4387
4311
  const currentTime = toSQLiteTimestamp(/* @__PURE__ */ new Date());
@@ -4424,8 +4348,7 @@ var SQLiteEventStore = class {
4424
4348
  * Record a memory retrieval for helpfulness tracking
4425
4349
  */
4426
4350
  async recordRetrieval(eventId, sessionId, score, query) {
4427
- if (this.readOnly)
4428
- return;
4351
+ if (this.readOnly) return;
4429
4352
  await this.initialize();
4430
4353
  const id = randomUUID6();
4431
4354
  sqliteRun(
@@ -4455,16 +4378,14 @@ var SQLiteEventStore = class {
4455
4378
  * Called at session end - uses behavioral signals to compute score
4456
4379
  */
4457
4380
  async evaluateSessionHelpfulness(sessionId) {
4458
- if (this.readOnly)
4459
- return;
4381
+ if (this.readOnly) return;
4460
4382
  await this.initialize();
4461
4383
  const retrievals = sqliteAll(
4462
4384
  this.db,
4463
4385
  `SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,
4464
4386
  [sessionId]
4465
4387
  );
4466
- if (retrievals.length === 0)
4467
- return;
4388
+ if (retrievals.length === 0) return;
4468
4389
  const sessionEvents = sqliteAll(
4469
4390
  this.db,
4470
4391
  `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
@@ -4477,8 +4398,7 @@ var SQLiteEventStore = class {
4477
4398
  for (const t of toolEvents) {
4478
4399
  try {
4479
4400
  const content = JSON.parse(t.content);
4480
- if (content.success !== false)
4481
- toolSuccessCount++;
4401
+ if (content.success !== false) toolSuccessCount++;
4482
4402
  } catch {
4483
4403
  toolSuccessCount++;
4484
4404
  }
@@ -4496,8 +4416,7 @@ var SQLiteEventStore = class {
4496
4416
  const pWords = new Set(p.content.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
4497
4417
  let overlap = 0;
4498
4418
  for (const w of queryWords) {
4499
- if (pWords.has(w))
4500
- overlap++;
4419
+ if (pWords.has(w)) overlap++;
4501
4420
  }
4502
4421
  if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {
4503
4422
  wasReasked = 1;
@@ -4679,8 +4598,7 @@ var SQLiteEventStore = class {
4679
4598
  return this.db;
4680
4599
  }
4681
4600
  hasTableColumn(tableName, columnName2) {
4682
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName))
4683
- return false;
4601
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName)) return false;
4684
4602
  try {
4685
4603
  const rows = sqliteAll(this.db, `PRAGMA table_info("${tableName}")`, []);
4686
4604
  return rows.some((row) => row.name === columnName2);
@@ -4747,8 +4665,7 @@ var SQLiteEventStore = class {
4747
4665
  createdAt: toDateFromSQLite(row.created_at)
4748
4666
  }));
4749
4667
  } catch (err) {
4750
- if (err?.message?.includes("no such table"))
4751
- return [];
4668
+ if (err?.message?.includes("no such table")) return [];
4752
4669
  throw err;
4753
4670
  }
4754
4671
  }
@@ -4921,8 +4838,7 @@ var SQLiteEventStore = class {
4921
4838
  `SELECT id FROM events WHERE session_id = ?`,
4922
4839
  [sessionId]
4923
4840
  );
4924
- if (events.length === 0)
4925
- return 0;
4841
+ if (events.length === 0) return 0;
4926
4842
  const eventIds = events.map((e) => e.id);
4927
4843
  const placeholders = eventIds.map(() => "?").join(",");
4928
4844
  const ftsTriggersDropped = [];
@@ -5134,8 +5050,7 @@ function sanitizeGovernanceAuditValue(value, key) {
5134
5050
  return value;
5135
5051
  }
5136
5052
  function sanitizeAuditJson(value) {
5137
- if (value === void 0)
5138
- return void 0;
5053
+ if (value === void 0) return void 0;
5139
5054
  return sanitizeGovernanceAuditValue(value);
5140
5055
  }
5141
5056
  function normalizeSourceEventIds(sourceEventIds) {
@@ -5184,12 +5099,10 @@ async function writeGovernanceAuditEntry(db, input) {
5184
5099
 
5185
5100
  // src/core/operations/facet-repository.ts
5186
5101
  function parseStringArray(value) {
5187
- if (typeof value !== "string")
5188
- return [];
5102
+ if (typeof value !== "string") return [];
5189
5103
  try {
5190
5104
  const parsed = JSON.parse(value);
5191
- if (!Array.isArray(parsed))
5192
- return [];
5105
+ if (!Array.isArray(parsed)) return [];
5193
5106
  return parsed.filter((item) => typeof item === "string" && item.length > 0);
5194
5107
  } catch {
5195
5108
  return [];
@@ -5233,6 +5146,7 @@ var FacetRepository = class {
5233
5146
  constructor(db) {
5234
5147
  this.db = db;
5235
5148
  }
5149
+ db;
5236
5150
  async assign(input) {
5237
5151
  const assignment = parseFacetAssignmentInput(input);
5238
5152
  const existing = this.findByUniqueKey(assignment);
@@ -5537,19 +5451,14 @@ var RetentionFacetSchema = z5.object({
5537
5451
  confidence: z5.number().min(0).max(1).default(1)
5538
5452
  });
5539
5453
  var DateLikeSchema = z5.preprocess((value) => {
5540
- if (value instanceof Date)
5541
- return value;
5542
- if (typeof value === "string" || typeof value === "number")
5543
- return new Date(value);
5454
+ if (value instanceof Date) return value;
5455
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
5544
5456
  return value;
5545
5457
  }, z5.date());
5546
5458
  var NullableDateLikeSchema = z5.preprocess((value) => {
5547
- if (value === null || value === void 0 || value === "")
5548
- return null;
5549
- if (value instanceof Date)
5550
- return value;
5551
- if (typeof value === "string" || typeof value === "number")
5552
- return new Date(value);
5459
+ if (value === null || value === void 0 || value === "") return null;
5460
+ if (value instanceof Date) return value;
5461
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
5553
5462
  return value;
5554
5463
  }, z5.date().nullable());
5555
5464
  var OptionalTrimmedStringSchema2 = z5.preprocess(
@@ -5578,10 +5487,8 @@ import { z as z6 } from "zod";
5578
5487
  var RequiredTrimmedStringSchema = z6.string().trim().min(1);
5579
5488
  var OptionalTrimmedStringSchema3 = z6.string().trim().min(1).optional();
5580
5489
  var DateLikeSchema2 = z6.preprocess((value) => {
5581
- if (value instanceof Date)
5582
- return value;
5583
- if (typeof value === "string" || typeof value === "number")
5584
- return new Date(value);
5490
+ if (value instanceof Date) return value;
5491
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
5585
5492
  return value;
5586
5493
  }, z6.date());
5587
5494
  var RetentionReasonSchema = z6.object({
@@ -5770,8 +5677,7 @@ var MemoryOperationsConfigSchema = z7.object({
5770
5677
  }).default({});
5771
5678
  var MemoryLessonNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
5772
5679
  var MemoryLessonStringArraySchema = z7.preprocess((value) => {
5773
- if (!Array.isArray(value))
5774
- return value;
5680
+ if (!Array.isArray(value)) return value;
5775
5681
  return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
5776
5682
  }, z7.array(MemoryLessonNonEmptyStringSchema)).default([]);
5777
5683
  var MemoryLessonSchema = z7.object({
@@ -5816,14 +5722,12 @@ var ListMemoryLessonsInputSchema = z7.object({
5816
5722
  });
5817
5723
  var PerspectiveMemoryNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
5818
5724
  var PerspectiveMemoryOptionalStringSchema = z7.preprocess((value) => {
5819
- if (typeof value !== "string")
5820
- return value;
5725
+ if (typeof value !== "string") return value;
5821
5726
  const normalized = value.trim();
5822
5727
  return normalized.length > 0 ? normalized : void 0;
5823
5728
  }, PerspectiveMemoryNonEmptyStringSchema.optional());
5824
5729
  var PerspectiveMemoryStringArraySchema = z7.preprocess((value) => {
5825
- if (!Array.isArray(value))
5826
- return value;
5730
+ if (!Array.isArray(value)) return value;
5827
5731
  return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
5828
5732
  }, z7.array(PerspectiveMemoryNonEmptyStringSchema)).default([]);
5829
5733
  var ActorCardSensitivePattern = /(?:\b(?:api[_-]?key|secret|password|passwd|token|access[_-]?token|client[_-]?secret|bearer)\b\s*[:=])|(?:\b(?:api[_-]?key|secret|password|passwd|token|access[_-]?token|client[_-]?secret|bearer)=)|(?:^|\s)(?:\/[A-Za-z0-9._-][^\s`'\"]*)/i;
@@ -6481,6 +6385,7 @@ var GraphPathService = class {
6481
6385
  constructor(db) {
6482
6386
  this.db = db;
6483
6387
  }
6388
+ db;
6484
6389
  expand(input) {
6485
6390
  const graph = this.loadGraph(input.direction ?? "both");
6486
6391
  const effectiveMaxHops = normalizeMaxHops(input.maxHops);
@@ -6498,11 +6403,9 @@ var GraphPathService = class {
6498
6403
  while (queue.length > 0) {
6499
6404
  queue.sort((a, b) => a.totalCost - b.totalCost || a.hops - b.hops || a.key.localeCompare(b.key));
6500
6405
  const current = queue.shift();
6501
- if (current.hops >= effectiveMaxHops)
6502
- continue;
6406
+ if (current.hops >= effectiveMaxHops) continue;
6503
6407
  for (const edge of graph.adjacency.get(current.key) ?? []) {
6504
- if (current.visited.has(edge.toKey))
6505
- continue;
6408
+ if (current.visited.has(edge.toKey)) continue;
6506
6409
  const nextHops = current.hops + 1;
6507
6410
  const nextTotalCost = current.totalCost + edge.step.cost;
6508
6411
  const nextSteps = [...current.steps, edge.step];
@@ -6582,17 +6485,13 @@ function addTraversal(adjacency, fromKey, edge) {
6582
6485
  adjacency.set(fromKey, edges);
6583
6486
  }
6584
6487
  function normalizeMaxHops(maxHops) {
6585
- if (maxHops === void 0)
6586
- return 1;
6587
- if (!Number.isFinite(maxHops))
6588
- return MAX_HOPS;
6488
+ if (maxHops === void 0) return 1;
6489
+ if (!Number.isFinite(maxHops)) return MAX_HOPS;
6589
6490
  return Math.min(Math.max(0, Math.trunc(maxHops)), MAX_HOPS);
6590
6491
  }
6591
6492
  function normalizeMaxResults(maxResults) {
6592
- if (maxResults === void 0)
6593
- return DEFAULT_MAX_RESULTS;
6594
- if (!Number.isFinite(maxResults))
6595
- return DEFAULT_MAX_RESULTS;
6493
+ if (maxResults === void 0) return DEFAULT_MAX_RESULTS;
6494
+ if (!Number.isFinite(maxResults)) return DEFAULT_MAX_RESULTS;
6596
6495
  return Math.min(Math.max(0, Math.trunc(maxResults)), MAX_RESULTS);
6597
6496
  }
6598
6497
  function isBetterPath(totalCost, hops, signature, existing) {
@@ -6604,18 +6503,15 @@ function pathSignature(steps) {
6604
6503
  function edgeWeight(metaJson) {
6605
6504
  const meta = parseMeta(metaJson);
6606
6505
  const raw = meta.weight;
6607
- if (typeof raw === "number" && Number.isFinite(raw) && raw > 0)
6608
- return raw;
6506
+ if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
6609
6507
  if (typeof raw === "string") {
6610
6508
  const parsed = Number(raw);
6611
- if (Number.isFinite(parsed) && parsed > 0)
6612
- return parsed;
6509
+ if (Number.isFinite(parsed) && parsed > 0) return parsed;
6613
6510
  }
6614
6511
  return DEFAULT_WEIGHT;
6615
6512
  }
6616
6513
  function parseMeta(metaJson) {
6617
- if (!metaJson)
6618
- return {};
6514
+ if (!metaJson) return {};
6619
6515
  try {
6620
6516
  const parsed = JSON.parse(metaJson);
6621
6517
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
@@ -6628,8 +6524,7 @@ function nodeKey(node) {
6628
6524
  }
6629
6525
  function nodeFromKey(key) {
6630
6526
  const index = key.indexOf(":");
6631
- if (index === -1)
6632
- return { type: "entity", id: key };
6527
+ if (index === -1) return { type: "entity", id: key };
6633
6528
  return { type: key.slice(0, index), id: key.slice(index + 1) };
6634
6529
  }
6635
6530
 
@@ -6685,6 +6580,7 @@ var QueryEntityExtractor = class {
6685
6580
  constructor(db) {
6686
6581
  this.db = db;
6687
6582
  }
6583
+ db;
6688
6584
  extract(query, options = {}) {
6689
6585
  const maxCandidates = normalizeMaxCandidates(options.maxCandidates);
6690
6586
  const candidates = [];
@@ -6706,8 +6602,7 @@ var QueryEntityExtractor = class {
6706
6602
  let match;
6707
6603
  while ((match = regex.exec(query)) !== null) {
6708
6604
  const text = cleanCandidateText(match[2] ?? "");
6709
- if (!isUsefulCandidate(text))
6710
- continue;
6605
+ if (!isUsefulCandidate(text)) continue;
6711
6606
  const start = match.index + 1;
6712
6607
  const end = start + text.length;
6713
6608
  ranges.push([match.index, match.index + match[0].length]);
@@ -6721,8 +6616,7 @@ var QueryEntityExtractor = class {
6721
6616
  return ranges;
6722
6617
  }
6723
6618
  extractKnownAliases(query, candidates) {
6724
- if (!this.db)
6725
- return;
6619
+ if (!this.db) return;
6726
6620
  const rows = sqliteAll(
6727
6621
  this.db,
6728
6622
  `SELECT
@@ -6746,11 +6640,9 @@ var QueryEntityExtractor = class {
6746
6640
  ]).filter(isUsefulCandidate);
6747
6641
  for (const alias of aliasLabels) {
6748
6642
  const normalizedAlias = normalizeForContainment(alias);
6749
- if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias))
6750
- continue;
6643
+ if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias)) continue;
6751
6644
  const aliasKey = `${row.entity_id}:${normalizedAlias}`;
6752
- if (seenAliases.has(aliasKey))
6753
- continue;
6645
+ if (seenAliases.has(aliasKey)) continue;
6754
6646
  seenAliases.add(aliasKey);
6755
6647
  const range = findRange(query, alias);
6756
6648
  pushCandidate(candidates, {
@@ -6771,8 +6663,7 @@ var QueryEntityExtractor = class {
6771
6663
  let match;
6772
6664
  while ((match = regex.exec(query)) !== null) {
6773
6665
  const text = cleanCandidateText(match[2] ?? "");
6774
- if (!isUsefulCandidate(text))
6775
- continue;
6666
+ if (!isUsefulCandidate(text)) continue;
6776
6667
  const start = match.index + (match[1]?.length ?? 0);
6777
6668
  pushCandidate(candidates, {
6778
6669
  text,
@@ -6787,8 +6678,7 @@ var QueryEntityExtractor = class {
6787
6678
  let match;
6788
6679
  while ((match = regex.exec(query)) !== null) {
6789
6680
  const text = cleanCandidateText(match[2] ?? "");
6790
- if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./"))
6791
- continue;
6681
+ if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./")) continue;
6792
6682
  const start = match.index + (match[1]?.length ?? 0);
6793
6683
  pushCandidate(candidates, {
6794
6684
  text,
@@ -6807,21 +6697,17 @@ var QueryEntityExtractor = class {
6807
6697
  if (previous && query.slice(previous.end, token.start).match(/^\s+$/)) {
6808
6698
  current.push(token);
6809
6699
  } else {
6810
- if (current.length > 0)
6811
- groups.push(current);
6700
+ if (current.length > 0) groups.push(current);
6812
6701
  current = [token];
6813
6702
  }
6814
6703
  }
6815
- if (current.length > 0)
6816
- groups.push(current);
6704
+ if (current.length > 0) groups.push(current);
6817
6705
  for (const group of groups) {
6818
- if (group.length === 1 && !isStrongSingleCapitalized(group[0].text))
6819
- continue;
6706
+ if (group.length === 1 && !isStrongSingleCapitalized(group[0].text)) continue;
6820
6707
  const start = group[0].start;
6821
6708
  const end = group[group.length - 1].end;
6822
6709
  const text = query.slice(start, end);
6823
- if (!isUsefulCandidate(text))
6824
- continue;
6710
+ if (!isUsefulCandidate(text)) continue;
6825
6711
  pushCandidate(candidates, {
6826
6712
  text,
6827
6713
  source: "capitalized_term",
@@ -6842,8 +6728,7 @@ function collectCapitalizedTokens(query) {
6842
6728
  }
6843
6729
  function pushCandidate(candidates, input) {
6844
6730
  const text = cleanCandidateText(input.text);
6845
- if (!isUsefulCandidate(text))
6846
- return;
6731
+ if (!isUsefulCandidate(text)) return;
6847
6732
  const source = input.source;
6848
6733
  candidates.push({
6849
6734
  ...input,
@@ -6861,15 +6746,13 @@ function dedupeAndSort(candidates) {
6861
6746
  for (const candidate of sorted) {
6862
6747
  if (candidate.source === "entity_alias") {
6863
6748
  const aliasKey = `alias:${candidate.entityId ?? ""}:${normalizeCandidate(candidate.matchedAlias ?? candidate.text)}`;
6864
- if (seenAliasKeys.has(aliasKey))
6865
- continue;
6749
+ if (seenAliasKeys.has(aliasKey)) continue;
6866
6750
  seenAliasKeys.add(aliasKey);
6867
6751
  seenNormalized.add(candidate.normalized);
6868
6752
  result.push(candidate);
6869
6753
  continue;
6870
6754
  }
6871
- if (seenNormalized.has(candidate.normalized))
6872
- continue;
6755
+ if (seenNormalized.has(candidate.normalized)) continue;
6873
6756
  seenNormalized.add(candidate.normalized);
6874
6757
  result.push(candidate);
6875
6758
  }
@@ -6879,8 +6762,7 @@ function compareCandidates(a, b) {
6879
6762
  return a.priority - b.priority || a.start - b.start || a.end - b.end || compareStrings(a.text, b.text) || compareStrings(a.entityId ?? "", b.entityId ?? "") || compareStrings(a.matchedAlias ?? "", b.matchedAlias ?? "");
6880
6763
  }
6881
6764
  function compareStrings(a, b) {
6882
- if (a === b)
6883
- return 0;
6765
+ if (a === b) return 0;
6884
6766
  return a < b ? -1 : 1;
6885
6767
  }
6886
6768
  function stripPriority(candidate) {
@@ -6888,10 +6770,8 @@ function stripPriority(candidate) {
6888
6770
  return publicCandidate;
6889
6771
  }
6890
6772
  function normalizeMaxCandidates(maxCandidates) {
6891
- if (maxCandidates === void 0)
6892
- return DEFAULT_MAX_CANDIDATES;
6893
- if (!Number.isFinite(maxCandidates))
6894
- return DEFAULT_MAX_CANDIDATES;
6773
+ if (maxCandidates === void 0) return DEFAULT_MAX_CANDIDATES;
6774
+ if (!Number.isFinite(maxCandidates)) return DEFAULT_MAX_CANDIDATES;
6895
6775
  return Math.min(Math.max(0, Math.trunc(maxCandidates)), MAX_CANDIDATES);
6896
6776
  }
6897
6777
  function cleanCandidateText(text) {
@@ -6913,21 +6793,17 @@ function aliasLabelFromCanonicalKey(canonicalKey) {
6913
6793
  function findRange(query, alias) {
6914
6794
  const normalizedAlias = normalizeForContainment(alias);
6915
6795
  const directIndex = query.toLowerCase().indexOf(alias.toLowerCase());
6916
- if (directIndex >= 0)
6917
- return { start: directIndex, end: directIndex + alias.length };
6796
+ if (directIndex >= 0) return { start: directIndex, end: directIndex + alias.length };
6918
6797
  const normalizedQuery = normalizeForContainment(query);
6919
6798
  const normalizedIndex = normalizedQuery.indexOf(normalizedAlias);
6920
- if (normalizedIndex < 0)
6921
- return { start: 0, end: 0 };
6799
+ if (normalizedIndex < 0) return { start: 0, end: 0 };
6922
6800
  const queryLower = query.toLowerCase();
6923
6801
  const words = normalizedAlias.split(" ").filter(Boolean);
6924
- if (words.length === 0)
6925
- return { start: 0, end: 0 };
6802
+ if (words.length === 0) return { start: 0, end: 0 };
6926
6803
  const first = queryLower.indexOf(words[0]);
6927
6804
  const lastWord = words[words.length - 1];
6928
6805
  const last = queryLower.indexOf(lastWord, first >= 0 ? first : 0);
6929
- if (first >= 0 && last >= 0)
6930
- return { start: first, end: last + lastWord.length };
6806
+ if (first >= 0 && last >= 0) return { start: first, end: last + lastWord.length };
6931
6807
  return { start: normalizedIndex, end: normalizedIndex + normalizedAlias.length };
6932
6808
  }
6933
6809
  function isUsefulCandidate(text) {
@@ -6938,10 +6814,8 @@ function isInsideAnyRange(index, ranges) {
6938
6814
  return ranges.some(([start, end]) => index >= start && index < end);
6939
6815
  }
6940
6816
  function isStrongSingleCapitalized(text) {
6941
- if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text))
6942
- return true;
6943
- if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text))
6944
- return true;
6817
+ if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text)) return true;
6818
+ if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text)) return true;
6945
6819
  return text.length >= 4 && !SENTENCE_START_STOPWORDS.has(text);
6946
6820
  }
6947
6821
  function uniqueStrings(values) {
@@ -6949,8 +6823,7 @@ function uniqueStrings(values) {
6949
6823
  const result = [];
6950
6824
  for (const value of values) {
6951
6825
  const key = normalizeForContainment(value);
6952
- if (!key || seen.has(key))
6953
- continue;
6826
+ if (!key || seen.has(key)) continue;
6954
6827
  seen.add(key);
6955
6828
  result.push(value);
6956
6829
  }
@@ -6972,8 +6845,7 @@ var LessonCandidateInputSchema = z9.object({
6972
6845
  import { z as z10 } from "zod";
6973
6846
  var NonEmptyStringSchema5 = z10.string().transform((value) => value.trim()).pipe(z10.string().min(1));
6974
6847
  var PromotionStringArraySchema = z10.preprocess((value) => {
6975
- if (!Array.isArray(value))
6976
- return value;
6848
+ if (!Array.isArray(value)) return value;
6977
6849
  return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
6978
6850
  }, z10.array(NonEmptyStringSchema5).max(100));
6979
6851
  var ReviewedLessonCandidateSchema = z10.object({
@@ -7021,8 +6893,7 @@ function projectHashFromStorage(projectHash) {
7021
6893
  return projectHash.length > 0 ? projectHash : void 0;
7022
6894
  }
7023
6895
  function parseJsonRecord(value) {
7024
- if (!value)
7025
- return void 0;
6896
+ if (!value) return void 0;
7026
6897
  try {
7027
6898
  const parsed = JSON.parse(value);
7028
6899
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
@@ -7034,8 +6905,7 @@ function sanitizeString(value) {
7034
6905
  return String(sanitizeGovernanceAuditValue(value)).trim();
7035
6906
  }
7036
6907
  function sanitizeMetadata(metadata) {
7037
- if (!metadata)
7038
- return void 0;
6908
+ if (!metadata) return void 0;
7039
6909
  return sanitizeGovernanceAuditValue(metadata);
7040
6910
  }
7041
6911
  function slugActorPart(value) {
@@ -7043,8 +6913,7 @@ function slugActorPart(value) {
7043
6913
  return slug.length > 0 ? slug : "unknown";
7044
6914
  }
7045
6915
  function stableActorId(input) {
7046
- if (input.actorId)
7047
- return sanitizeString(input.actorId);
6916
+ if (input.actorId) return sanitizeString(input.actorId);
7048
6917
  const projectPart = input.projectHash ? `project:${slugActorPart(input.projectHash)}` : "global";
7049
6918
  return [
7050
6919
  "actor",
@@ -7067,12 +6936,10 @@ function rowToActor(row) {
7067
6936
  });
7068
6937
  }
7069
6938
  function metadataString(metadata, keys) {
7070
- if (!metadata)
7071
- return void 0;
6939
+ if (!metadata) return void 0;
7072
6940
  for (const key of keys) {
7073
6941
  const value = metadata[key];
7074
- if (typeof value === "string" && value.trim().length > 0)
7075
- return value.trim();
6942
+ if (typeof value === "string" && value.trim().length > 0) return value.trim();
7076
6943
  }
7077
6944
  return void 0;
7078
6945
  }
@@ -7122,6 +6989,7 @@ var ActorRepository = class {
7122
6989
  constructor(db) {
7123
6990
  this.db = db;
7124
6991
  }
6992
+ db;
7125
6993
  async upsert(input) {
7126
6994
  const parsed = UpsertMemoryActorInputSchema.parse(input);
7127
6995
  const actorId = stableActorId(parsed);
@@ -7175,8 +7043,7 @@ var ActorRepository = class {
7175
7043
  }
7176
7044
  require(actorId) {
7177
7045
  const actor = this.get(actorId);
7178
- if (!actor)
7179
- throw new Error(`Memory actor not found: ${actorId}`);
7046
+ if (!actor) throw new Error(`Memory actor not found: ${actorId}`);
7180
7047
  return actor;
7181
7048
  }
7182
7049
  async list(input = {}) {
@@ -7212,8 +7079,7 @@ function projectHashFromStorage2(projectHash) {
7212
7079
  return projectHash.length > 0 ? projectHash : void 0;
7213
7080
  }
7214
7081
  function parseJsonRecord2(value) {
7215
- if (!value)
7216
- return void 0;
7082
+ if (!value) return void 0;
7217
7083
  try {
7218
7084
  const parsed = JSON.parse(value);
7219
7085
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
@@ -7222,8 +7088,7 @@ function parseJsonRecord2(value) {
7222
7088
  }
7223
7089
  }
7224
7090
  function sanitizeMetadata2(metadata) {
7225
- if (!metadata)
7226
- return void 0;
7091
+ if (!metadata) return void 0;
7227
7092
  return sanitizeGovernanceAuditValue(metadata);
7228
7093
  }
7229
7094
  function rowToSessionActor(row) {
@@ -7243,6 +7108,7 @@ var SessionActorRepository = class {
7243
7108
  constructor(db) {
7244
7109
  this.db = db;
7245
7110
  }
7111
+ db;
7246
7112
  async upsertMembership(input) {
7247
7113
  const parsed = UpsertSessionActorInputSchema.parse(input);
7248
7114
  const projectHash = projectHashToStorage3(parsed.projectHash);
@@ -7289,8 +7155,7 @@ var SessionActorRepository = class {
7289
7155
  );
7290
7156
  }
7291
7157
  const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
7292
- if (!saved)
7293
- throw new Error("session actor membership was not saved");
7158
+ if (!saved) throw new Error("session actor membership was not saved");
7294
7159
  return saved;
7295
7160
  }
7296
7161
  async listBySession(input) {
@@ -7326,8 +7191,7 @@ var SessionActorRepository = class {
7326
7191
  ]
7327
7192
  );
7328
7193
  const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
7329
- if (!saved)
7330
- throw new Error("session actor membership not found after update");
7194
+ if (!saved) throw new Error("session actor membership not found after update");
7331
7195
  return saved;
7332
7196
  }
7333
7197
  get(projectHash, sessionId, actorId) {
@@ -7349,8 +7213,7 @@ function projectHashFromStorage3(projectHash) {
7349
7213
  return projectHash.length > 0 ? projectHash : void 0;
7350
7214
  }
7351
7215
  function parseStringArray2(value) {
7352
- if (!value)
7353
- return [];
7216
+ if (!value) return [];
7354
7217
  try {
7355
7218
  const parsed = JSON.parse(value);
7356
7219
  return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
@@ -7359,8 +7222,7 @@ function parseStringArray2(value) {
7359
7222
  }
7360
7223
  }
7361
7224
  function parseJsonRecord3(value) {
7362
- if (!value)
7363
- return void 0;
7225
+ if (!value) return void 0;
7364
7226
  try {
7365
7227
  const parsed = JSON.parse(value);
7366
7228
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
@@ -7376,8 +7238,7 @@ function sanitizeStoredStringArray(values) {
7376
7238
  return values.map(sanitizeStoredString).filter((value) => value.length > 0);
7377
7239
  }
7378
7240
  function sanitizeStoredRecord(value) {
7379
- if (!value)
7380
- return void 0;
7241
+ if (!value) return void 0;
7381
7242
  return sanitizeGovernanceAuditValue(value);
7382
7243
  }
7383
7244
  function stableHash(value) {
@@ -7428,8 +7289,7 @@ function sanitizedObservationSnapshot(observation) {
7428
7289
  });
7429
7290
  }
7430
7291
  function queryScore(observation, terms) {
7431
- if (terms.length === 0)
7432
- return 0;
7292
+ if (terms.length === 0) return 0;
7433
7293
  const haystack = [observation.content, observation.level, observation.sessionId ?? ""].join(" ").toLowerCase();
7434
7294
  return terms.reduce((score, term) => score + (haystack.includes(term) ? 1 : 0), 0);
7435
7295
  }
@@ -7475,12 +7335,12 @@ var PerspectiveObservationRepository = class {
7475
7335
  this.vectorOutbox = options.vectorOutbox;
7476
7336
  }
7477
7337
  }
7338
+ db;
7478
7339
  vectorOutbox = null;
7479
7340
  vectorOutboxOption;
7480
7341
  getVectorOutbox() {
7481
7342
  const option = this.vectorOutboxOption;
7482
- if (option === false)
7483
- return null;
7343
+ if (option === false) return null;
7484
7344
  if (option instanceof VectorOutbox) {
7485
7345
  this.vectorOutbox = option;
7486
7346
  return option;
@@ -7492,8 +7352,7 @@ var PerspectiveObservationRepository = class {
7492
7352
  }
7493
7353
  enqueueObservationSync(observationId) {
7494
7354
  const outbox = this.getVectorOutbox();
7495
- if (!outbox)
7496
- return;
7355
+ if (!outbox) return;
7497
7356
  outbox.enqueueSync("perspective_observation", observationId);
7498
7357
  }
7499
7358
  async create(input) {
@@ -7555,14 +7414,12 @@ var PerspectiveObservationRepository = class {
7555
7414
  contentHash,
7556
7415
  sourceHash
7557
7416
  );
7558
- if (!saved)
7559
- throw new Error("perspective observation was not saved");
7417
+ if (!saved) throw new Error("perspective observation was not saved");
7560
7418
  this.enqueueObservationSync(saved.observationId);
7561
7419
  });
7562
7420
  transaction();
7563
7421
  const savedObservation = saved;
7564
- if (!savedObservation)
7565
- throw new Error("perspective observation was not saved");
7422
+ if (!savedObservation) throw new Error("perspective observation was not saved");
7566
7423
  await this.writeCreateAudit({ ...parsed, observerActorId, observedActorId, sessionId, content, sourceEventIds, sourceObservationIds, createdBy, actor, metadata }, savedObservation);
7567
7424
  return savedObservation;
7568
7425
  }
@@ -7572,8 +7429,7 @@ var PerspectiveObservationRepository = class {
7572
7429
  const ftsQuery = buildObservationFtsQuery(parsed.query);
7573
7430
  if (ftsQuery) {
7574
7431
  const ftsResult = this.queryWithFts(parsed, ftsQuery);
7575
- if (ftsResult)
7576
- return ftsResult;
7432
+ if (ftsResult) return ftsResult;
7577
7433
  }
7578
7434
  }
7579
7435
  return this.queryWithPrefetch(parsed);
@@ -7594,8 +7450,7 @@ var PerspectiveObservationRepository = class {
7594
7450
  );
7595
7451
  return rows.map(rowToObservation);
7596
7452
  } catch (error) {
7597
- if (isFtsUnavailableError(error))
7598
- return null;
7453
+ if (isFtsUnavailableError(error)) return null;
7599
7454
  throw error;
7600
7455
  }
7601
7456
  }
@@ -7636,8 +7491,7 @@ var PerspectiveObservationRepository = class {
7636
7491
  const parsed = DeletePerspectiveObservationInputSchema.parse(input);
7637
7492
  const projectHash = projectHashToStorage4(parsed.projectHash);
7638
7493
  const before = this.get(projectHash, parsed.observationId);
7639
- if (!before)
7640
- throw new Error("perspective observation not found");
7494
+ if (!before) throw new Error("perspective observation not found");
7641
7495
  const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
7642
7496
  sqliteRun(
7643
7497
  this.db,
@@ -7647,8 +7501,7 @@ var PerspectiveObservationRepository = class {
7647
7501
  [deletedAt, deletedAt, projectHash, parsed.observationId]
7648
7502
  );
7649
7503
  const after = this.get(projectHash, parsed.observationId);
7650
- if (!after)
7651
- throw new Error("perspective observation not found after delete");
7504
+ if (!after) throw new Error("perspective observation not found after delete");
7652
7505
  await writeGovernanceAuditEntry(this.db, {
7653
7506
  operation: "perspective_observation_delete",
7654
7507
  actor: parsed.actor,
@@ -7704,11 +7557,9 @@ var DEFAULT_CONFIG3 = {
7704
7557
  var MAX_OBSERVATION_CONTENT_CHARS = 600;
7705
7558
  var RuleBasedPerspectiveObservationExtractor = class {
7706
7559
  async extract(event) {
7707
- if (!isSupportedSourceEvent(event))
7708
- return [];
7560
+ if (!isSupportedSourceEvent(event)) return [];
7709
7561
  const content = normalizeObservationContent(event.content);
7710
- if (!content)
7711
- return [];
7562
+ if (!content) return [];
7712
7563
  return [{
7713
7564
  content,
7714
7565
  confidence: 0.6,
@@ -7779,8 +7630,7 @@ var PerspectiveDeriver = class {
7779
7630
  for (const candidate of candidates) {
7780
7631
  const observedActorId = candidate.observedActorId ?? sourceActor.actorId;
7781
7632
  const observers = selectObservers(members, observedActorId, this.config.deriver.maxObserversPerSession);
7782
- if (observers.length === 0)
7783
- continue;
7633
+ if (observers.length === 0) continue;
7784
7634
  for (const observerActorId of observers) {
7785
7635
  await this.observations.create({
7786
7636
  projectHash,
@@ -7833,28 +7683,22 @@ function normalizeConfig(config) {
7833
7683
  };
7834
7684
  }
7835
7685
  function clampInteger(value, fallback, min, max) {
7836
- if (!Number.isFinite(value))
7837
- return fallback;
7686
+ if (!Number.isFinite(value)) return fallback;
7838
7687
  return Math.max(min, Math.min(max, Math.trunc(Number(value))));
7839
7688
  }
7840
7689
  function isSupportedSourceEvent(event) {
7841
7690
  return event.eventType === "user_prompt" || event.eventType === "agent_response";
7842
7691
  }
7843
7692
  function roleForEvent(event) {
7844
- if (event.eventType === "user_prompt")
7845
- return "speaker";
7846
- if (event.eventType === "agent_response")
7847
- return "assistant";
7848
- if (event.eventType === "tool_observation")
7849
- return "tool";
7850
- if (event.eventType === "session_summary")
7851
- return "system";
7693
+ if (event.eventType === "user_prompt") return "speaker";
7694
+ if (event.eventType === "agent_response") return "assistant";
7695
+ if (event.eventType === "tool_observation") return "tool";
7696
+ if (event.eventType === "session_summary") return "system";
7852
7697
  return "unknown";
7853
7698
  }
7854
7699
  function normalizeCandidate2(candidate) {
7855
7700
  const content = normalizeObservationContent(candidate.content);
7856
- if (!content)
7857
- return null;
7701
+ if (!content) return null;
7858
7702
  return {
7859
7703
  content,
7860
7704
  confidence: clampNumber(candidate.confidence, 0.6, 0, 1),
@@ -7866,8 +7710,7 @@ function normalizeCandidate2(candidate) {
7866
7710
  }
7867
7711
  function normalizeObservationContent(content) {
7868
7712
  const normalized = content.replace(/\s+/g, " ").trim();
7869
- if (!normalized)
7870
- return null;
7713
+ if (!normalized) return null;
7871
7714
  return normalized.slice(0, MAX_OBSERVATION_CONTENT_CHARS);
7872
7715
  }
7873
7716
  function normalizeOptionalString2(value) {
@@ -7875,13 +7718,11 @@ function normalizeOptionalString2(value) {
7875
7718
  return normalized.length > 0 ? normalized : void 0;
7876
7719
  }
7877
7720
  function clampNumber(value, fallback, min, max) {
7878
- if (!Number.isFinite(value))
7879
- return fallback;
7721
+ if (!Number.isFinite(value)) return fallback;
7880
7722
  return Math.max(min, Math.min(max, Number(value)));
7881
7723
  }
7882
7724
  function sanitizeCandidateMetadata(metadata) {
7883
- if (!metadata)
7884
- return void 0;
7725
+ if (!metadata) return void 0;
7885
7726
  const result = {};
7886
7727
  for (const [key, value] of Object.entries(metadata)) {
7887
7728
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
@@ -7894,12 +7735,9 @@ function selectObservers(members, observedActorId, maxObservers) {
7894
7735
  const selected = [];
7895
7736
  for (const member of members) {
7896
7737
  const canObserve = member.actorId === observedActorId ? member.observeSelf : member.observeOthers;
7897
- if (!canObserve)
7898
- continue;
7899
- if (!selected.includes(member.actorId))
7900
- selected.push(member.actorId);
7901
- if (selected.length >= maxObservers)
7902
- break;
7738
+ if (!canObserve) continue;
7739
+ if (!selected.includes(member.actorId)) selected.push(member.actorId);
7740
+ if (selected.length >= maxObservers) break;
7903
7741
  }
7904
7742
  return selected;
7905
7743
  }
@@ -7935,6 +7773,7 @@ var VectorStore = class {
7935
7773
  constructor(dbPath) {
7936
7774
  this.dbPath = dbPath;
7937
7775
  }
7776
+ dbPath;
7938
7777
  db = null;
7939
7778
  tableCache = /* @__PURE__ */ new Map();
7940
7779
  defaultTableName = "conversations";
@@ -7946,8 +7785,7 @@ var VectorStore = class {
7946
7785
  * conversations table.
7947
7786
  */
7948
7787
  async initialize() {
7949
- if (this.db)
7950
- return;
7788
+ if (this.db) return;
7951
7789
  this.db = await lancedb.connect(this.dbPath);
7952
7790
  }
7953
7791
  /**
@@ -7961,8 +7799,7 @@ var VectorStore = class {
7961
7799
  * Add or update multiple vector records in batch, grouped by inferred table.
7962
7800
  */
7963
7801
  async upsertBatch(records) {
7964
- if (records.length === 0)
7965
- return;
7802
+ if (records.length === 0) return;
7966
7803
  await this.initialize();
7967
7804
  if (!this.db) {
7968
7805
  throw new Error("Database not initialized");
@@ -8017,8 +7854,7 @@ var VectorStore = class {
8017
7854
  async delete(eventId) {
8018
7855
  await this.initialize();
8019
7856
  const table = await this.getExistingTable(this.defaultTableName);
8020
- if (!table)
8021
- return;
7857
+ if (!table) return;
8022
7858
  await table.delete(`eventId = ${toLanceSqlString(eventId)}`);
8023
7859
  }
8024
7860
  /**
@@ -8027,8 +7863,7 @@ var VectorStore = class {
8027
7863
  async count() {
8028
7864
  await this.initialize();
8029
7865
  const table = await this.getExistingTable(this.defaultTableName);
8030
- if (!table)
8031
- return 0;
7866
+ if (!table) return 0;
8032
7867
  const result = await table.countRows();
8033
7868
  return result;
8034
7869
  }
@@ -8037,8 +7872,7 @@ var VectorStore = class {
8037
7872
  */
8038
7873
  async clearAll() {
8039
7874
  await this.initialize();
8040
- if (!this.db)
8041
- return;
7875
+ if (!this.db) return;
8042
7876
  try {
8043
7877
  if (typeof this.db.dropTable === "function") {
8044
7878
  await this.db.dropTable(this.defaultTableName);
@@ -8055,8 +7889,7 @@ var VectorStore = class {
8055
7889
  async exists(eventId) {
8056
7890
  await this.initialize();
8057
7891
  const table = await this.getExistingTable(this.defaultTableName);
8058
- if (!table)
8059
- return false;
7892
+ if (!table) return false;
8060
7893
  const results = await table.search([]).where(`eventId = ${toLanceSqlString(eventId)}`).limit(1).toArray();
8061
7894
  return results.length > 0;
8062
7895
  }
@@ -8091,8 +7924,7 @@ var VectorStore = class {
8091
7924
  throw new Error("Database not initialized");
8092
7925
  }
8093
7926
  const cached = this.tableCache.get(tableName);
8094
- if (cached)
8095
- return cached;
7927
+ if (cached) return cached;
8096
7928
  const tableNames = await this.db.tableNames();
8097
7929
  if (!tableNames.includes(tableName)) {
8098
7930
  return null;
@@ -8171,12 +8003,9 @@ var IngestInterceptorRegistry = class {
8171
8003
  }
8172
8004
  };
8173
8005
  function mergeHierarchicalMetadata(base, patch) {
8174
- if (!base && !patch)
8175
- return void 0;
8176
- if (!base)
8177
- return patch;
8178
- if (!patch)
8179
- return base;
8006
+ if (!base && !patch) return void 0;
8007
+ if (!base) return patch;
8008
+ if (!patch) return base;
8180
8009
  const result = { ...base };
8181
8010
  for (const [key, value] of Object.entries(patch)) {
8182
8011
  const current = result[key];
@@ -8206,33 +8035,26 @@ var VALID_TAG_NAMESPACES = new Set(Object.values(TAG_NAMESPACES));
8206
8035
  function parseTag(tag) {
8207
8036
  const value = (tag || "").trim();
8208
8037
  const idx = value.indexOf(":");
8209
- if (idx <= 0)
8210
- return { value };
8038
+ if (idx <= 0) return { value };
8211
8039
  const namespace = `${value.slice(0, idx)}:`;
8212
8040
  const tagValue = value.slice(idx + 1);
8213
- if (!tagValue)
8214
- return { value };
8041
+ if (!tagValue) return { value };
8215
8042
  return { namespace, value: tagValue };
8216
8043
  }
8217
8044
  function validateTag(tag) {
8218
8045
  const normalized = (tag || "").trim();
8219
- if (!normalized)
8220
- return false;
8046
+ if (!normalized) return false;
8221
8047
  const { namespace } = parseTag(normalized);
8222
- if (!namespace)
8223
- return true;
8048
+ if (!namespace) return true;
8224
8049
  return VALID_TAG_NAMESPACES.has(namespace);
8225
8050
  }
8226
8051
  function normalizeTags(tags) {
8227
- if (!Array.isArray(tags))
8228
- return [];
8052
+ if (!Array.isArray(tags)) return [];
8229
8053
  const dedup = /* @__PURE__ */ new Set();
8230
8054
  for (const item of tags) {
8231
- if (typeof item !== "string")
8232
- continue;
8055
+ if (typeof item !== "string") continue;
8233
8056
  const normalized = item.trim();
8234
- if (!validateTag(normalized))
8235
- continue;
8057
+ if (!validateTag(normalized)) continue;
8236
8058
  dedup.add(normalized);
8237
8059
  }
8238
8060
  return [...dedup];
@@ -8249,10 +8071,8 @@ var SummaryDeriver = class {
8249
8071
  * orchestration, while this class owns summary text and metadata decisions.
8250
8072
  */
8251
8073
  deriveSessionSummary(events) {
8252
- if (events.length < 3)
8253
- return null;
8254
- if (events.some((event) => event.eventType === "session_summary"))
8255
- return null;
8074
+ if (events.length < 3) return null;
8075
+ if (events.some((event) => event.eventType === "session_summary")) return null;
8256
8076
  const prompts = events.filter((event) => event.eventType === "user_prompt");
8257
8077
  const toolObservations = events.filter((event) => event.eventType === "tool_observation");
8258
8078
  const toolNames = Array.from(new Set(
@@ -8400,8 +8220,7 @@ var MemoryIngestService = class {
8400
8220
  await this.initialize();
8401
8221
  const events = await this.eventStore.getSessionEvents(sessionId);
8402
8222
  const summary = this.summaryDeriver.deriveSessionSummary(events);
8403
- if (!summary)
8404
- return;
8223
+ if (!summary) return;
8405
8224
  await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
8406
8225
  }
8407
8226
  async storeToolObservation(sessionId, payload) {
@@ -8469,10 +8288,8 @@ var MemoryIngestService = class {
8469
8288
  }
8470
8289
  }
8471
8290
  async runPerspectiveDeriver(input, eventId, operation) {
8472
- if (!this.perspectiveDeriver)
8473
- return;
8474
- if (operation !== "user_prompt" && operation !== "agent_response")
8475
- return;
8291
+ if (!this.perspectiveDeriver) return;
8292
+ if (operation !== "user_prompt" && operation !== "agent_response") return;
8476
8293
  const event = {
8477
8294
  id: eventId,
8478
8295
  eventType: input.eventType,
@@ -8542,11 +8359,13 @@ var MemoryQueryService = class {
8542
8359
  this.queryStore = queryStore;
8543
8360
  this.deps = deps;
8544
8361
  }
8362
+ initialize;
8363
+ queryStore;
8364
+ deps;
8545
8365
  async keywordSearch(query, options) {
8546
8366
  await this.initialize();
8547
8367
  const results = await this.queryStore.keywordSearch(query, options?.topK ?? 10);
8548
- if (results.length === 0)
8549
- return [];
8368
+ if (results.length === 0) return [];
8550
8369
  const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
8551
8370
  const minRank = Math.max(...results.map((r) => r.rank), -1e3);
8552
8371
  const rankRange = maxRank - minRank || 1;
@@ -8641,6 +8460,18 @@ var COMMAND_ARTIFACT_PATTERNS = [
8641
8460
  /<local-command-stdout>[\s\S]*?<\/local-command-stdout>/i,
8642
8461
  /<local-command-stderr>[\s\S]*?<\/local-command-stderr>/i
8643
8462
  ];
8463
+ var LOW_SIGNAL_CONTEXT_PATTERNS = [
8464
+ /<environment_context\b[\s\S]*<\/environment_context>/i,
8465
+ /<turn_aborted>/i,
8466
+ /^#\s*AGENTS\.md\s+instructions\b[\s\S]*<INSTRUCTIONS>/i,
8467
+ /^\s*(?:understood[,\s.]*)?(?:stopping|stopped|pausing|paused)\s+here\b[\s\S]{0,180}\blet\s+me\s+know\s+when\s+you(?:'d|\s+would)?\s+like\s+to\s+continue\b/i,
8468
+ /^\s*\[?CONTEXT\s+COMPACTION\s*[—-]\s*REFERENCE\s+ONLY\]?\b[\s\S]{0,600}\b(?:earlier\s+turns\s+were\s+compacted|handoff\s+from\s+a\s+previous\s+context\s+window|active\s+task)\b/i,
8469
+ /^\s*Summary\s+generation\s+was\s+unavailable\.\s*\d+\s+message\(s\)\s+were\s+removed\s+to\s+free\s+context\s+space\b/i,
8470
+ /^\s*---\s*END\s+OF\s+CONTEXT\s+SUMMARY\b/i,
8471
+ /^\s*\[Your\s+active\s+task\s+list\s+was\s+preserved\s+across\s+context\s+compression\]/i,
8472
+ /^➜\s+\S+\s+git:\([^)]*\)\s+/i,
8473
+ /^\$\s+\S+/i
8474
+ ];
8644
8475
  var CONTINUATION_QUERY_PATTERNS = [
8645
8476
  /^\s*(?:continue|resume|next|what(?:'s| is)? next|next\s+(?:step|task|action)|recommended\s+(?:next\s+)?(?:step|task|action)|what should (?:we|i) do next)\??\s*$/i,
8646
8477
  /^\s*(?:응\s*)?(?:이어서(?:\s*진행(?:해줘)?)?|계속(?:\s*해줘)?|다음\s*(?:단계|작업|추천\s*작업|추천|할\s*일)?(?:은|는)?(?:\s*(?:뭐야|진행(?:해줘)?))?\??|남은\s*(?:추가(?:로)?\s*)?(?:(?:할\s*만한\s*)?(?:작업|일)|할\s*일)?(?:은|는)?\s*(?:있어|있나|있나요|뭐야)\??|추천\s*작업(?:은|는)?(?:\s*뭐야)?\??|진행해줘)\s*$/i
@@ -8652,7 +8483,7 @@ var SHORT_REPAIR_FOLLOW_UP_PATTERNS = [
8652
8483
  var CURRENT_STATE_QUERY_PATTERNS = [
8653
8484
  /\bcurrent\b.*\b(?:state|status|deployment|blocker|pr|pull request)\b/i,
8654
8485
  /\b(?:still|as current|current)\b.*\b(?:unresolved|open|pending|not completed)\b/i,
8655
- /\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|state|status)\b/i,
8486
+ /\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|status)\b/i,
8656
8487
  /(?:현재|아직|이전|오래된|해결된).*(?:상태|미해결|열린|블로커|PR|풀리퀘스트)/i
8657
8488
  ];
8658
8489
  var STALE_CONTENT_PATTERNS = [
@@ -8792,55 +8623,67 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
8792
8623
  ]);
8793
8624
  function isCommandArtifactQuery(query) {
8794
8625
  const trimmed = query.trim();
8795
- if (!trimmed)
8796
- return false;
8626
+ if (!trimmed) return false;
8797
8627
  const normalized = trimmed.toLowerCase();
8798
- if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr"))
8799
- return true;
8800
- if (normalized.includes("command-name") || normalized.includes("command-message"))
8801
- return true;
8628
+ if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
8629
+ if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
8802
8630
  return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
8803
8631
  }
8632
+ function isCommandArtifactContent(content) {
8633
+ const trimmed = content.trim();
8634
+ if (!trimmed) return false;
8635
+ const normalized = trimmed.toLowerCase();
8636
+ if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
8637
+ if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
8638
+ return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
8639
+ }
8640
+ function isLowSignalContextContent(content) {
8641
+ const trimmed = content.trim();
8642
+ if (!trimmed) return true;
8643
+ if (isCommandArtifactContent(trimmed)) return true;
8644
+ if (LOW_SIGNAL_CONTEXT_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
8645
+ return false;
8646
+ }
8804
8647
  function isGenericContinuationQuery(query) {
8805
8648
  const trimmed = query.trim();
8806
- if (!trimmed)
8807
- return false;
8808
- if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed)))
8809
- return false;
8810
- if (extractTechnicalQueryTerms(trimmed).length > 0)
8811
- return false;
8649
+ if (!trimmed) return false;
8650
+ if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
8651
+ if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
8812
8652
  const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
8813
- if (tokens.length > 10)
8814
- return false;
8653
+ if (tokens.length > 10) return false;
8815
8654
  return !/[A-Za-z0-9_-]+\.[A-Za-z0-9]+/.test(trimmed) && !/(?:^|\s)(?:feat|fix|chore|refactor|docs)\/[A-Za-z0-9._-]+/.test(trimmed) && !/[A-Za-z]:?[\\/]|\/Users\/|\.\/|\.\.\//.test(trimmed);
8816
8655
  }
8817
8656
  function isShortRepairFollowUpQuery(query) {
8818
8657
  const trimmed = query.trim();
8819
- if (!trimmed)
8820
- return false;
8821
- if (extractTechnicalQueryTerms(trimmed).length > 0)
8822
- return false;
8658
+ if (!trimmed) return false;
8659
+ if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
8823
8660
  const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
8824
- if (tokens.length > 8)
8825
- return false;
8661
+ if (tokens.length > 8) return false;
8826
8662
  return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
8827
8663
  }
8664
+ function isLowConfidenceContextFallbackQuery(query) {
8665
+ const trimmed = query.trim();
8666
+ if (!trimmed) return false;
8667
+ if (isGenericContinuationQuery(trimmed) || isShortRepairFollowUpQuery(trimmed)) return true;
8668
+ const terms = new Set(tokenizeQualityText(trimmed));
8669
+ if ((terms.has("compacted") || terms.has("compaction")) && terms.has("handoff")) return false;
8670
+ const hasContinuationRecall = /^(?:continue|resume)\b/i.test(trimmed) && (terms.has("work") || terms.has("step") || terms.has("task") || terms.has("last") || terms.has("completed"));
8671
+ const hasValidationGateRecall = terms.has("validation") && (terms.has("gate") || terms.has("check")) && (terms.has("run") || terms.has("before") || terms.has("commit") || terms.has("committing") || terms.has("change"));
8672
+ return hasContinuationRecall || hasValidationGateRecall;
8673
+ }
8828
8674
  function isCurrentStateQuery(query) {
8829
8675
  const trimmed = query.trim();
8830
- if (!trimmed)
8831
- return false;
8676
+ if (!trimmed) return false;
8832
8677
  return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
8833
8678
  }
8834
8679
  function isStaleOrSupersededContent(content) {
8835
8680
  const trimmed = content.trim();
8836
- if (!trimmed)
8837
- return false;
8681
+ if (!trimmed) return false;
8838
8682
  return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
8839
8683
  }
8840
8684
  function buildRetrievalQualityQuery(query) {
8841
8685
  const trimmed = query.trim();
8842
- if (!trimmed)
8843
- return query;
8686
+ if (!trimmed) return query;
8844
8687
  if (isRetrievalPrivacyDecisionQuery(trimmed)) {
8845
8688
  return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
8846
8689
  }
@@ -8854,12 +8697,10 @@ function buildRetrievalQualityQuery(query) {
8854
8697
  }
8855
8698
  function isRetrievalPrivacyDecisionQuery(query) {
8856
8699
  const trimmed = query.trim();
8857
- if (!trimmed)
8858
- return false;
8700
+ if (!trimmed) return false;
8859
8701
  const terms = new Set(tokenizeQualityText(trimmed));
8860
8702
  const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
8861
- if (!hasDecisionSignal)
8862
- return false;
8703
+ if (!hasDecisionSignal) return false;
8863
8704
  const hasRawQuerySignal = terms.has("raw") && terms.has("query");
8864
8705
  const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
8865
8706
  const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
@@ -8872,16 +8713,14 @@ function extractTechnicalQueryTerms(query) {
8872
8713
  const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
8873
8714
  const terms = matches.filter((term) => {
8874
8715
  const lower = term.toLowerCase();
8875
- if (GENERIC_TECHNICAL_TERMS.has(lower))
8876
- return false;
8716
+ if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
8877
8717
  return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
8878
8718
  });
8879
8719
  return Array.from(new Set(terms.map((term) => term.toLowerCase())));
8880
8720
  }
8881
8721
  function hasTechnicalTermOverlap(query, content) {
8882
8722
  const terms = extractTechnicalQueryTerms(query);
8883
- if (terms.length === 0)
8884
- return true;
8723
+ if (terms.length === 0) return true;
8885
8724
  const normalizedContent = content.toLowerCase();
8886
8725
  return terms.some((term) => normalizedContent.includes(term));
8887
8726
  }
@@ -8897,15 +8736,12 @@ function hasDiscriminativeTermOverlap(query, content) {
8897
8736
  return topicTerms.some((term) => contentTerms.has(term));
8898
8737
  }
8899
8738
  }
8900
- if (queryTerms.length < 3)
8901
- return true;
8739
+ if (queryTerms.length < 3) return true;
8902
8740
  const requiredHits = queryTerms.length >= 3 ? 2 : 1;
8903
8741
  let hits = 0;
8904
8742
  for (const term of queryTerms) {
8905
- if (contentTerms.has(term))
8906
- hits += 1;
8907
- if (hits >= requiredHits)
8908
- return true;
8743
+ if (contentTerms.has(term)) hits += 1;
8744
+ if (hits >= requiredHits) return true;
8909
8745
  }
8910
8746
  return false;
8911
8747
  }
@@ -8915,17 +8751,14 @@ function shouldApplyTechnicalGuard(query) {
8915
8751
  function hasAnyTerm(terms, expectedTerms) {
8916
8752
  let found = false;
8917
8753
  expectedTerms.forEach((term) => {
8918
- if (terms.has(term))
8919
- found = true;
8754
+ if (terms.has(term)) found = true;
8920
8755
  });
8921
8756
  return found;
8922
8757
  }
8923
8758
  function shouldRequireDecisionTopicOverlap(query) {
8924
- if (isRetrievalPrivacyDecisionQuery(query))
8925
- return false;
8759
+ if (isRetrievalPrivacyDecisionQuery(query)) return false;
8926
8760
  const trimmed = query.trim();
8927
- if (!trimmed)
8928
- return false;
8761
+ if (!trimmed) return false;
8929
8762
  const terms = new Set(tokenizeQualityText(trimmed));
8930
8763
  return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
8931
8764
  }
@@ -8933,12 +8766,9 @@ function extractDiscriminativeQueryTerms(query) {
8933
8766
  const seen = /* @__PURE__ */ new Set();
8934
8767
  const terms = [];
8935
8768
  for (const token of tokenizeQualityText(query)) {
8936
- if (LOW_INFORMATION_QUERY_TERMS.has(token))
8937
- continue;
8938
- if (GENERIC_TECHNICAL_TERMS.has(token))
8939
- continue;
8940
- if (seen.has(token))
8941
- continue;
8769
+ if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
8770
+ if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
8771
+ if (seen.has(token)) continue;
8942
8772
  seen.add(token);
8943
8773
  terms.push(token);
8944
8774
  }
@@ -8953,14 +8783,10 @@ function tokenizeQualityText(text) {
8953
8783
  return text.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().replace(/[^A-Za-z0-9가-힣\s_.:-]/g, " ").split(/\s+/).flatMap((token) => token.split(/(?=[._:-])|(?<=[._:-])/g)).map((token) => normalizeQualityToken(token.replace(/^[._:-]+|[._:-]+$/g, ""))).filter((token) => token.length >= 2);
8954
8784
  }
8955
8785
  function normalizeQualityToken(token) {
8956
- if (token === "apis")
8957
- return "api";
8958
- if (token === "ids")
8959
- return "id";
8960
- if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token))
8961
- return token;
8962
- if (token.length > 4 && token.endsWith("ies"))
8963
- return `${token.slice(0, -3)}y`;
8786
+ if (token === "apis") return "api";
8787
+ if (token === "ids") return "id";
8788
+ if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
8789
+ if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
8964
8790
  if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
8965
8791
  return token.slice(0, -1);
8966
8792
  }
@@ -9112,7 +8938,14 @@ var Retriever = class {
9112
8938
  };
9113
8939
  fallbackTrace.push("fallback:summary");
9114
8940
  }
9115
- const memories = await this.enrichResults(current.results.slice(0, opts.topK), opts);
8941
+ const selectedResults = current.results.slice(0, opts.topK).filter((result) => {
8942
+ if (current.matchResult.confidence !== "none") return true;
8943
+ if (isLowConfidenceContextFallbackQuery(query)) {
8944
+ return (result.semanticScore ?? result.score) >= 0.5 || result.score >= 0.5;
8945
+ }
8946
+ return (result.semanticScore ?? result.score) >= 0.62 || result.score >= 0.62;
8947
+ });
8948
+ const memories = await this.enrichResults(selectedResults, opts, query);
9116
8949
  const context = this.buildContext(memories, opts.maxTokens);
9117
8950
  return {
9118
8951
  memories,
@@ -9120,7 +8953,7 @@ var Retriever = class {
9120
8953
  totalTokens: this.estimateTokens(context),
9121
8954
  context,
9122
8955
  fallbackTrace,
9123
- selectedDebug: current.results.slice(0, opts.topK).map((r) => this.debugDetailForResult(r)),
8956
+ selectedDebug: selectedResults.map((r) => this.debugDetailForResult(r)),
9124
8957
  candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r) => this.debugDetailForResult(r)),
9125
8958
  rawQueryText: current.queryRewriteKind ? query : void 0,
9126
8959
  effectiveQueryText: current.effectiveQueryText,
@@ -9142,8 +8975,7 @@ var Retriever = class {
9142
8975
  const sharedMemories = [];
9143
8976
  for (const result of sharedVectorResults) {
9144
8977
  const entry = await this.sharedStore.get(result.entryId);
9145
- if (!entry)
9146
- continue;
8978
+ if (!entry) continue;
9147
8979
  if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
9148
8980
  sharedMemories.push(entry);
9149
8981
  await this.sharedStore.recordUsage(entry.entryId);
@@ -9216,6 +9048,7 @@ var Retriever = class {
9216
9048
  if (isCurrentStateQuery(options.query)) {
9217
9049
  filtered = filtered.filter((result) => !isStaleOrSupersededContent(result.content));
9218
9050
  }
9051
+ filtered = filtered.filter((result) => !isLowSignalContextContent(result.content));
9219
9052
  filtered = filtered.filter(
9220
9053
  (result) => this.isGraphPathResult(result) || hasDiscriminativeTermOverlap(options.query, result.content)
9221
9054
  );
@@ -9224,18 +9057,15 @@ var Retriever = class {
9224
9057
  (result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
9225
9058
  );
9226
9059
  }
9227
- if (filtered.length <= 2)
9228
- return filtered;
9060
+ if (filtered.length <= 2) return filtered;
9229
9061
  const topScore = filtered[0].score;
9230
- if (topScore < 0.8)
9231
- return filtered;
9062
+ if (topScore < 0.8) return filtered;
9232
9063
  const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
9233
9064
  return filtered.filter((result) => result.score >= cliffThreshold);
9234
9065
  }
9235
9066
  mergeResults(primary, secondary, limit) {
9236
9067
  const byId = /* @__PURE__ */ new Map();
9237
- for (const row of primary)
9238
- byId.set(row.eventId, row);
9068
+ for (const row of primary) byId.set(row.eventId, row);
9239
9069
  for (const row of secondary) {
9240
9070
  const prev = byId.get(row.eventId);
9241
9071
  if (!prev || row.score > prev.score) {
@@ -9246,23 +9076,19 @@ var Retriever = class {
9246
9076
  }
9247
9077
  async expandGraphHops(seeds, opts) {
9248
9078
  const byId = /* @__PURE__ */ new Map();
9249
- for (const s of seeds)
9250
- byId.set(s.eventId, s);
9079
+ for (const s of seeds) byId.set(s.eventId, s);
9251
9080
  let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
9252
9081
  for (let hop = 1; hop <= opts.maxHops; hop += 1) {
9253
9082
  const next = [];
9254
9083
  for (const f of frontier) {
9255
9084
  const ev = await this.eventStore.getEvent(f.row.eventId);
9256
- if (!ev)
9257
- continue;
9085
+ if (!ev) continue;
9258
9086
  const rel = ev.metadata?.relatedEventIds ?? [];
9259
9087
  const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
9260
9088
  for (const rid of relatedIds) {
9261
- if (byId.has(rid))
9262
- continue;
9089
+ if (byId.has(rid)) continue;
9263
9090
  const target = await this.eventStore.getEvent(rid);
9264
- if (!target)
9265
- continue;
9091
+ if (!target) continue;
9266
9092
  const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
9267
9093
  const row = {
9268
9094
  id: `hop-${hop}-${rid}`,
@@ -9276,15 +9102,12 @@ var Retriever = class {
9276
9102
  };
9277
9103
  byId.set(row.eventId, row);
9278
9104
  next.push({ row, hop });
9279
- if (byId.size >= opts.limit)
9280
- break;
9105
+ if (byId.size >= opts.limit) break;
9281
9106
  }
9282
- if (byId.size >= opts.limit)
9283
- break;
9107
+ if (byId.size >= opts.limit) break;
9284
9108
  }
9285
9109
  frontier = next;
9286
- if (frontier.length === 0 || byId.size >= opts.limit)
9287
- break;
9110
+ if (frontier.length === 0 || byId.size >= opts.limit) break;
9288
9111
  }
9289
9112
  if (opts.queryGraphEnabled) {
9290
9113
  await this.expandQueryGraphPaths(opts.query, byId, opts);
@@ -9292,8 +9115,7 @@ var Retriever = class {
9292
9115
  return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9293
9116
  }
9294
9117
  async expandQueryGraphPaths(query, byId, opts) {
9295
- if (!query.trim() || !this.eventStore.getDatabase)
9296
- return;
9118
+ if (!query.trim() || !this.eventStore.getDatabase) return;
9297
9119
  try {
9298
9120
  const db = this.eventStore.getDatabase();
9299
9121
  const extraction = new QueryEntityExtractor(db).extract(query, {
@@ -9302,8 +9124,7 @@ var Retriever = class {
9302
9124
  });
9303
9125
  const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
9304
9126
  const startNodes = uniqueEntityStartNodes(startCandidates);
9305
- if (startNodes.length === 0)
9306
- return;
9127
+ if (startNodes.length === 0) return;
9307
9128
  const expansion = new GraphPathService(db).expand({
9308
9129
  startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
9309
9130
  maxHops: opts.maxHops,
@@ -9312,11 +9133,9 @@ var Retriever = class {
9312
9133
  });
9313
9134
  const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
9314
9135
  for (const path14 of expansion.paths) {
9315
- if (path14.target.type !== "event")
9316
- continue;
9136
+ if (path14.target.type !== "event") continue;
9317
9137
  const target = await this.eventStore.getEvent(path14.target.id);
9318
- if (!target)
9319
- continue;
9138
+ if (!target) continue;
9320
9139
  const graphPath = toRetrievalGraphPathDebug(path14, titleByEntityId);
9321
9140
  const score = graphPathScore(path14, opts.hopPenalty);
9322
9141
  const existing = byId.get(target.id);
@@ -9342,17 +9161,14 @@ var Retriever = class {
9342
9161
  lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
9343
9162
  };
9344
9163
  byId.set(row.eventId, row);
9345
- if (byId.size >= opts.limit)
9346
- break;
9164
+ if (byId.size >= opts.limit) break;
9347
9165
  }
9348
9166
  } catch {
9349
9167
  }
9350
9168
  }
9351
9169
  shouldFallback(matchResult, results) {
9352
- if (results.length === 0)
9353
- return true;
9354
- if (matchResult.confidence === "none")
9355
- return true;
9170
+ if (results.length === 0) return true;
9171
+ if (matchResult.confidence === "none") return true;
9356
9172
  return false;
9357
9173
  }
9358
9174
  async buildSummaryFallback(query, topK) {
@@ -9457,29 +9273,21 @@ var Retriever = class {
9457
9273
  (value) => typeof value === "string" && value.length > 0
9458
9274
  )
9459
9275
  );
9460
- if (!scope && projectScopeMode === "global" && facetFilters === null)
9461
- return results;
9276
+ if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
9462
9277
  const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
9463
9278
  const filtered = [];
9464
9279
  for (const result of results) {
9465
- if (scope?.sessionId && result.sessionId !== scope.sessionId)
9466
- continue;
9467
- if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix))
9468
- continue;
9469
- if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType))
9470
- continue;
9280
+ if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
9281
+ if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
9282
+ if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
9471
9283
  const event = await this.eventStore.getEvent(result.eventId);
9472
- if (!event)
9473
- continue;
9474
- if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
9475
- continue;
9284
+ if (!event) continue;
9285
+ if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
9476
9286
  if (normalizedIncludes.length > 0) {
9477
9287
  const lc = event.content.toLowerCase();
9478
- if (!normalizedIncludes.some((needle) => lc.includes(needle)))
9479
- continue;
9288
+ if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
9480
9289
  }
9481
- if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
9482
- continue;
9290
+ if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
9483
9291
  const projectHash = this.extractProjectHash(event.metadata);
9484
9292
  filtered.push({ result, projectHash });
9485
9293
  }
@@ -9496,27 +9304,21 @@ var Retriever = class {
9496
9304
  });
9497
9305
  }
9498
9306
  normalizeFacetFilters(facets) {
9499
- if (!facets || facets.length === 0)
9500
- return null;
9307
+ if (!facets || facets.length === 0) return null;
9501
9308
  const normalized = [];
9502
9309
  for (const facet of facets) {
9503
9310
  const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
9504
9311
  const value = typeof facet.value === "string" ? facet.value.trim() : "";
9505
- if (!parsedDimension.success || !value)
9506
- return [];
9312
+ if (!parsedDimension.success || !value) return [];
9507
9313
  normalized.push({ dimension: parsedDimension.data, value });
9508
9314
  }
9509
9315
  return normalized;
9510
9316
  }
9511
9317
  async applyFacetFilters(results, options) {
9512
- if (options.facets === null)
9513
- return results;
9514
- if (options.facets.length === 0)
9515
- return [];
9516
- if (!options.projectHash)
9517
- return [];
9518
- if (!this.eventStore.getDatabase)
9519
- return [];
9318
+ if (options.facets === null) return results;
9319
+ if (options.facets.length === 0) return [];
9320
+ if (!options.projectHash) return [];
9321
+ if (!this.eventStore.getDatabase) return [];
9520
9322
  const repo = new FacetRepository(this.eventStore.getDatabase());
9521
9323
  const filtered = [];
9522
9324
  for (const result of results) {
@@ -9573,14 +9375,11 @@ var Retriever = class {
9573
9375
  return (result.graphPaths || []).length > 0;
9574
9376
  }
9575
9377
  extractProjectHash(metadata) {
9576
- if (!metadata || typeof metadata !== "object")
9577
- return void 0;
9378
+ if (!metadata || typeof metadata !== "object") return void 0;
9578
9379
  const scope = metadata.scope;
9579
- if (!scope || typeof scope !== "object")
9580
- return void 0;
9380
+ if (!scope || typeof scope !== "object") return void 0;
9581
9381
  const project = scope.project;
9582
- if (!project || typeof project !== "object")
9583
- return void 0;
9382
+ if (!project || typeof project !== "object") return void 0;
9584
9383
  const hash = project.hash;
9585
9384
  return typeof hash === "string" && hash.length > 0 ? hash : void 0;
9586
9385
  }
@@ -9590,52 +9389,48 @@ var Retriever = class {
9590
9389
  async retrieveRecent(limit = 100) {
9591
9390
  return this.eventStore.getRecentEvents(limit);
9592
9391
  }
9593
- async enrichResults(results, options) {
9392
+ async enrichResults(results, options, query) {
9594
9393
  const memories = [];
9595
9394
  for (const result of results) {
9596
9395
  const event = await this.eventStore.getEvent(result.eventId);
9597
- if (!event)
9598
- continue;
9396
+ if (!event) continue;
9599
9397
  if (this.graduation) {
9600
9398
  this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
9601
9399
  }
9602
9400
  let sessionContext;
9603
9401
  if (options.includeSessionContext) {
9604
- sessionContext = await this.getSessionContext(event.sessionId, event.id);
9402
+ sessionContext = await this.getSessionContext(event.sessionId, event.id, query);
9605
9403
  }
9606
9404
  memories.push({ event, score: result.score, sessionContext });
9607
9405
  }
9608
9406
  return memories;
9609
9407
  }
9610
- async getSessionContext(sessionId, eventId) {
9408
+ async getSessionContext(sessionId, eventId, query) {
9611
9409
  const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9612
9410
  const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
9613
- if (eventIndex === -1)
9614
- return void 0;
9411
+ if (eventIndex === -1) return void 0;
9615
9412
  const start = Math.max(0, eventIndex - 1);
9616
9413
  const end = Math.min(sessionEvents.length, eventIndex + 2);
9617
9414
  const contextEvents = sessionEvents.slice(start, end);
9618
- if (contextEvents.length <= 1)
9619
- return void 0;
9620
- return contextEvents.filter((e) => e.id !== eventId).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`).join("\n");
9415
+ if (contextEvents.length <= 1) return void 0;
9416
+ const suppressStaleState = isCurrentStateQuery(query);
9417
+ const contextLines = contextEvents.filter((e) => e.id !== eventId).filter((e) => !isLowSignalContextContent(e.content)).filter((e) => !(suppressStaleState && isStaleOrSupersededContent(e.content))).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`);
9418
+ return contextLines.length > 0 ? contextLines.join("\n") : void 0;
9621
9419
  }
9622
9420
  buildUnifiedContext(projectResult, sharedMemories) {
9623
9421
  let context = projectResult.context;
9624
- if (sharedMemories.length === 0)
9625
- return context;
9422
+ if (sharedMemories.length === 0) return context;
9626
9423
  context += "\n\n## Cross-Project Knowledge\n\n";
9627
9424
  for (const memory of sharedMemories.slice(0, 3)) {
9628
9425
  context += `### ${memory.title}
9629
9426
  `;
9630
- if (memory.symptoms.length > 0)
9631
- context += `**Symptoms:** ${memory.symptoms.join(", ")}
9427
+ if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
9632
9428
  `;
9633
9429
  context += `**Root Cause:** ${memory.rootCause}
9634
9430
  `;
9635
9431
  context += `**Solution:** ${memory.solution}
9636
9432
  `;
9637
- if (memory.technologies && memory.technologies.length > 0)
9638
- context += `**Technologies:** ${memory.technologies.join(", ")}
9433
+ if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
9639
9434
  `;
9640
9435
  context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
9641
9436
 
@@ -9649,13 +9444,11 @@ var Retriever = class {
9649
9444
  for (const memory of memories) {
9650
9445
  const memoryText = this.formatMemory(memory);
9651
9446
  const memoryTokens = this.estimateTokens(memoryText);
9652
- if (currentTokens + memoryTokens > maxTokens)
9653
- break;
9447
+ if (currentTokens + memoryTokens > maxTokens) break;
9654
9448
  parts.push(memoryText);
9655
9449
  currentTokens += memoryTokens;
9656
9450
  }
9657
- if (parts.length === 0)
9658
- return "";
9451
+ if (parts.length === 0) return "";
9659
9452
  return `## Relevant Memories
9660
9453
 
9661
9454
  ${parts.join("\n\n---\n\n")}`;
@@ -9665,19 +9458,16 @@ ${parts.join("\n\n---\n\n")}`;
9665
9458
  const date = event.timestamp.toISOString().split("T")[0];
9666
9459
  let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
9667
9460
  ${event.content}`;
9668
- if (sessionContext)
9669
- text += `
9461
+ if (sessionContext) text += `
9670
9462
 
9671
9463
  _Context:_ ${sessionContext}`;
9672
9464
  return text;
9673
9465
  }
9674
9466
  matchesMetadataScope(metadata, expected) {
9675
- if (!metadata)
9676
- return false;
9467
+ if (!metadata) return false;
9677
9468
  return Object.entries(expected).every(([path14, value]) => {
9678
9469
  const actual = path14.split(".").reduce((acc, key) => {
9679
- if (typeof acc !== "object" || acc === null)
9680
- return void 0;
9470
+ if (typeof acc !== "object" || acc === null) return void 0;
9681
9471
  return acc[key];
9682
9472
  }, metadata);
9683
9473
  return actual === value;
@@ -9687,27 +9477,20 @@ _Context:_ ${sessionContext}`;
9687
9477
  return text.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().replace(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/).map((token) => this.normalizeToken(token)).filter((t) => t.length >= 2).slice(0, 64);
9688
9478
  }
9689
9479
  normalizeToken(token) {
9690
- if (token === "apis")
9691
- return "api";
9692
- if (token === "ids")
9693
- return "id";
9694
- if (token === "does")
9695
- return token;
9696
- if (token.length > 4 && token.endsWith("ies"))
9697
- return `${token.slice(0, -3)}y`;
9480
+ if (token === "apis") return "api";
9481
+ if (token === "ids") return "id";
9482
+ if (token === "does") return token;
9483
+ if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
9698
9484
  if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
9699
9485
  return token.slice(0, -1);
9700
9486
  }
9701
9487
  return token;
9702
9488
  }
9703
9489
  keywordOverlap(a, b) {
9704
- if (a.length === 0 || b.length === 0)
9705
- return 0;
9490
+ if (a.length === 0 || b.length === 0) return 0;
9706
9491
  const bs = new Set(b);
9707
9492
  let hit = 0;
9708
- for (const t of a)
9709
- if (bs.has(t))
9710
- hit += 1;
9493
+ for (const t of a) if (bs.has(t)) hit += 1;
9711
9494
  return hit / a.length;
9712
9495
  }
9713
9496
  estimateTokens(text) {
@@ -9728,8 +9511,7 @@ function uniqueEntityStartNodes(candidates) {
9728
9511
  const seen = /* @__PURE__ */ new Set();
9729
9512
  const nodes = [];
9730
9513
  for (const candidate of candidates) {
9731
- if (!candidate.entityId || seen.has(candidate.entityId))
9732
- continue;
9514
+ if (!candidate.entityId || seen.has(candidate.entityId)) continue;
9733
9515
  seen.add(candidate.entityId);
9734
9516
  nodes.push({ entityId: candidate.entityId, title: candidate.text });
9735
9517
  }
@@ -9753,16 +9535,14 @@ function graphPathScore(path14, hopPenalty) {
9753
9535
  return Math.max(0.05, base - hopPenalty * Math.max(0, path14.hops - 1));
9754
9536
  }
9755
9537
  function clampGraphHops(maxHops) {
9756
- if (!Number.isFinite(maxHops))
9757
- return 2;
9538
+ if (!Number.isFinite(maxHops)) return 2;
9758
9539
  return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
9759
9540
  }
9760
9541
  function mergeGraphPaths(existing, incoming) {
9761
9542
  const byKey = /* @__PURE__ */ new Map();
9762
9543
  for (const path14 of [...existing, ...incoming]) {
9763
9544
  const key = [path14.startEntityId, path14.targetType, path14.targetId, path14.hops, ...path14.relationPath].join("\0");
9764
- if (!byKey.has(key))
9765
- byKey.set(key, path14);
9545
+ if (!byKey.has(key)) byKey.set(key, path14);
9766
9546
  }
9767
9547
  return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
9768
9548
  }
@@ -9770,10 +9550,8 @@ function graphPathSignature(path14) {
9770
9550
  return [path14.startEntityId, path14.targetType, path14.targetId, path14.hops, ...path14.relationPath].join("|");
9771
9551
  }
9772
9552
  function compareStable(a, b) {
9773
- if (a < b)
9774
- return -1;
9775
- if (a > b)
9776
- return 1;
9553
+ if (a < b) return -1;
9554
+ if (a > b) return 1;
9777
9555
  return 0;
9778
9556
  }
9779
9557
  function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
@@ -9785,6 +9563,7 @@ var RetrievalAnalyticsService = class {
9785
9563
  constructor(deps) {
9786
9564
  this.deps = deps;
9787
9565
  }
9566
+ deps;
9788
9567
  async getRetrievalTraceStats() {
9789
9568
  await this.deps.initialize();
9790
9569
  return this.deps.retrievalStore.getRetrievalTraceStats();
@@ -9862,6 +9641,7 @@ var RetrievalDisclosureService = class {
9862
9641
  constructor(deps) {
9863
9642
  this.deps = deps;
9864
9643
  }
9644
+ deps;
9865
9645
  async search(query, options) {
9866
9646
  const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
9867
9647
  const debugByEventId = this.buildDebugIndex(result);
@@ -9891,8 +9671,7 @@ var RetrievalDisclosureService = class {
9891
9671
  return this.expandShared(parsedId.entryId);
9892
9672
  }
9893
9673
  const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
9894
- if (!targetEvent)
9895
- return null;
9674
+ if (!targetEvent) return null;
9896
9675
  const windowSize = Math.max(0, options?.windowSize ?? 3);
9897
9676
  const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
9898
9677
  const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
@@ -9916,8 +9695,7 @@ var RetrievalDisclosureService = class {
9916
9695
  return this.sourceShared(parsedId.entryId);
9917
9696
  }
9918
9697
  const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
9919
- if (!rawEvent)
9920
- return null;
9698
+ if (!rawEvent) return null;
9921
9699
  return {
9922
9700
  ...this.sourceReferenceForEvent(rawEvent),
9923
9701
  rawEvents: [rawEvent],
@@ -9926,8 +9704,7 @@ var RetrievalDisclosureService = class {
9926
9704
  }
9927
9705
  async expandShared(entryId) {
9928
9706
  const entry = await this.deps.sharedStore?.get(entryId);
9929
- if (!entry)
9930
- return null;
9707
+ if (!entry) return null;
9931
9708
  return {
9932
9709
  target: this.sharedToEnvelope(entry),
9933
9710
  surroundingFacts: [],
@@ -9938,8 +9715,7 @@ var RetrievalDisclosureService = class {
9938
9715
  }
9939
9716
  async sourceShared(entryId) {
9940
9717
  const entry = await this.deps.sharedStore?.get(entryId);
9941
- if (!entry)
9942
- return null;
9718
+ if (!entry) return null;
9943
9719
  const sourceReference = this.sourceReferenceForShared(entry);
9944
9720
  return {
9945
9721
  ...sourceReference,
@@ -10025,38 +9801,25 @@ var RetrievalDisclosureService = class {
10025
9801
  const reasons = /* @__PURE__ */ new Set();
10026
9802
  const usedVector = this.usedVector(result);
10027
9803
  const usedKeyword = this.usedKeyword(result);
10028
- if (usedVector && (debug?.semanticScore ?? 0) > 0)
10029
- reasons.add("semantic_match");
10030
- if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword)
10031
- reasons.add("keyword_match");
10032
- if ((debug?.recencyScore ?? 0) > 0)
10033
- reasons.add("recent_relevance");
10034
- if ((debug?.facetMatches || []).length > 0)
10035
- reasons.add("facet_match");
10036
- if ((debug?.graphPaths || []).length > 0)
10037
- reasons.add("entity_overlap");
10038
- if ((result.fallbackTrace || []).some((step) => step === "fallback:summary"))
10039
- reasons.add("summary_fallback");
10040
- if (memory.sessionContext)
10041
- reasons.add("continuity_link");
10042
- if (memory.event.eventType === "tool_observation")
10043
- reasons.add("tool_followup");
10044
- if (reasons.size === 0)
10045
- reasons.add(usedVector ? "semantic_match" : "keyword_match");
9804
+ if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
9805
+ if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
9806
+ if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
9807
+ if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
9808
+ if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
9809
+ if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
9810
+ if (memory.sessionContext) reasons.add("continuity_link");
9811
+ if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
9812
+ if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
10046
9813
  return Array.from(reasons);
10047
9814
  }
10048
9815
  reasonsForContextEvent(event) {
10049
- if (event.eventType === "tool_observation")
10050
- return ["tool_followup"];
10051
- if (event.eventType === "session_summary")
10052
- return ["summary_fallback"];
9816
+ if (event.eventType === "tool_observation") return ["tool_followup"];
9817
+ if (event.eventType === "session_summary") return ["summary_fallback"];
10053
9818
  return ["continuity_link"];
10054
9819
  }
10055
9820
  resultTypeForEvent(event) {
10056
- if (event.eventType === "session_summary")
10057
- return "summary";
10058
- if (event.eventType === "tool_observation")
10059
- return "tool_evidence";
9821
+ if (event.eventType === "session_summary") return "summary";
9822
+ if (event.eventType === "tool_observation") return "tool_evidence";
10060
9823
  return "source";
10061
9824
  }
10062
9825
  sourceReferenceForEvent(event) {
@@ -10080,21 +9843,15 @@ var RetrievalDisclosureService = class {
10080
9843
  }
10081
9844
  sourceTypeForEvent(event) {
10082
9845
  const metadata = event.metadata || {};
10083
- if (event.eventType === "tool_observation")
10084
- return "tool_output";
10085
- if (typeof metadata.transcriptPath === "string")
10086
- return "transcript";
10087
- if (typeof metadata.importedFrom === "string")
10088
- return "imported_history";
9846
+ if (event.eventType === "tool_observation") return "tool_output";
9847
+ if (typeof metadata.transcriptPath === "string") return "transcript";
9848
+ if (typeof metadata.importedFrom === "string") return "imported_history";
10089
9849
  return "raw_event";
10090
9850
  }
10091
9851
  titleForEvent(event) {
10092
- if (event.eventType === "session_summary")
10093
- return "Session summary";
10094
- if (event.eventType === "tool_observation")
10095
- return "Tool evidence";
10096
- if (event.eventType === "agent_response")
10097
- return "Agent response";
9852
+ if (event.eventType === "session_summary") return "Session summary";
9853
+ if (event.eventType === "tool_observation") return "Tool evidence";
9854
+ if (event.eventType === "agent_response") return "Agent response";
10098
9855
  return "User prompt";
10099
9856
  }
10100
9857
  usedVector(result) {
@@ -10120,8 +9877,7 @@ var RetrievalDisclosureService = class {
10120
9877
  }
10121
9878
  preview(content, maxLength) {
10122
9879
  const normalized = content.replace(/\s+/g, " ").trim();
10123
- if (normalized.length <= maxLength)
10124
- return normalized;
9880
+ if (normalized.length <= maxLength) return normalized;
10125
9881
  return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
10126
9882
  }
10127
9883
  };
@@ -10150,6 +9906,7 @@ var RetrievalOrchestrator = class {
10150
9906
  this.deps = deps;
10151
9907
  this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
10152
9908
  }
9909
+ deps;
10153
9910
  /**
10154
9911
  * Retrieve relevant memories for a query.
10155
9912
  */
@@ -10231,8 +9988,7 @@ var RetrievalOrchestrator = class {
10231
9988
  * the heavier retrieval/vector initialization path for prompt telemetry.
10232
9989
  */
10233
9990
  async incrementMemoryAccess(eventIds) {
10234
- if (eventIds.length === 0)
10235
- return;
9991
+ if (eventIds.length === 0) return;
10236
9992
  await this.deps.accessStore.incrementAccessCount(eventIds);
10237
9993
  }
10238
9994
  /**
@@ -10245,10 +10001,8 @@ var RetrievalOrchestrator = class {
10245
10001
  resolveGraphHopOptions(callerOptions) {
10246
10002
  const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
10247
10003
  const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
10248
- if (!callerOptions)
10249
- return durableOptions;
10250
- if (!graphExpansion)
10251
- return callerOptions;
10004
+ if (!callerOptions) return durableOptions;
10005
+ if (!graphExpansion) return callerOptions;
10252
10006
  if (graphExpansion.enabled !== true) {
10253
10007
  return {
10254
10008
  ...callerOptions,
@@ -10308,12 +10062,10 @@ var RetrievalOrchestrator = class {
10308
10062
  const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
10309
10063
  const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
10310
10064
  const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
10311
- if (!allFinite)
10312
- return void 0;
10065
+ if (!allFinite) return void 0;
10313
10066
  const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
10314
10067
  const total = semantic + lexical + recency;
10315
- if (!nonNegative || total <= 0)
10316
- return void 0;
10068
+ if (!nonNegative || total <= 0) return void 0;
10317
10069
  return {
10318
10070
  semantic: semantic / total,
10319
10071
  lexical: lexical / total,
@@ -10322,17 +10074,14 @@ var RetrievalOrchestrator = class {
10322
10074
  }
10323
10075
  async getRerankWeights(adaptive) {
10324
10076
  const configured = this.getConfiguredRerankWeights();
10325
- if (configured)
10326
- return configured;
10327
- if (adaptive)
10328
- return this.getAdaptiveRerankWeights();
10077
+ if (configured) return configured;
10078
+ if (adaptive) return this.getAdaptiveRerankWeights();
10329
10079
  return void 0;
10330
10080
  }
10331
10081
  async getAdaptiveRerankWeights() {
10332
10082
  try {
10333
10083
  const stats = await this.deps.traceStore.getHelpfulnessStats();
10334
- if (stats.totalEvaluated < 20)
10335
- return void 0;
10084
+ if (stats.totalEvaluated < 20) return void 0;
10336
10085
  let semantic = 0.7;
10337
10086
  let lexical = 0.2;
10338
10087
  let recency = 0.1;
@@ -10354,11 +10103,9 @@ var RetrievalOrchestrator = class {
10354
10103
  }
10355
10104
  }
10356
10105
  async rewriteQueryIntent(query) {
10357
- if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
10358
- return null;
10106
+ if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
10359
10107
  const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
10360
- if (!apiUrl)
10361
- return null;
10108
+ if (!apiUrl) return null;
10362
10109
  const controller = new AbortController();
10363
10110
  const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
10364
10111
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
@@ -10384,11 +10131,9 @@ var RetrievalOrchestrator = class {
10384
10131
  signal: controller.signal
10385
10132
  });
10386
10133
  const text = (await res.text()).trim();
10387
- if (!text)
10388
- return null;
10134
+ if (!text) return null;
10389
10135
  const oneLine = text.replace(/^data:\s*/gm, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ").slice(0, 240);
10390
- if (!oneLine || oneLine.toLowerCase() === query.toLowerCase())
10391
- return null;
10136
+ if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
10392
10137
  return oneLine;
10393
10138
  } catch {
10394
10139
  return null;
@@ -10530,8 +10275,7 @@ function createMemoryEngineServices(options) {
10530
10275
  };
10531
10276
  }
10532
10277
  function shouldEnablePerspectiveDeriver(options) {
10533
- if (options.readOnly)
10534
- return false;
10278
+ if (options.readOnly) return false;
10535
10279
  const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
10536
10280
  return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
10537
10281
  }
@@ -10565,6 +10309,9 @@ var GraduationWorker = class {
10565
10309
  this.graduation = graduation;
10566
10310
  this.config = config;
10567
10311
  }
10312
+ eventStore;
10313
+ graduation;
10314
+ config;
10568
10315
  running = false;
10569
10316
  timeout = null;
10570
10317
  lastEvaluated = /* @__PURE__ */ new Map();
@@ -10572,8 +10319,7 @@ var GraduationWorker = class {
10572
10319
  * Start the graduation worker
10573
10320
  */
10574
10321
  start() {
10575
- if (this.running)
10576
- return;
10322
+ if (this.running) return;
10577
10323
  this.running = true;
10578
10324
  this.scheduleNext();
10579
10325
  }
@@ -10603,8 +10349,7 @@ var GraduationWorker = class {
10603
10349
  * Schedule the next graduation check
10604
10350
  */
10605
10351
  scheduleNext() {
10606
- if (!this.running)
10607
- return;
10352
+ if (!this.running) return;
10608
10353
  this.timeout = setTimeout(
10609
10354
  () => this.run(),
10610
10355
  this.config.evaluationIntervalMs
@@ -10614,8 +10359,7 @@ var GraduationWorker = class {
10614
10359
  * Run graduation evaluation
10615
10360
  */
10616
10361
  async run() {
10617
- if (!this.running)
10618
- return;
10362
+ if (!this.running) return;
10619
10363
  try {
10620
10364
  await this.runGraduation();
10621
10365
  } catch (error) {
@@ -10679,10 +10423,8 @@ var DEFAULT_CONFIG5 = {
10679
10423
  maxRetries: 3
10680
10424
  };
10681
10425
  function parseJsonArray(value) {
10682
- if (Array.isArray(value))
10683
- return value;
10684
- if (typeof value !== "string" || value.trim().length === 0)
10685
- return [];
10426
+ if (Array.isArray(value)) return value;
10427
+ if (typeof value !== "string" || value.trim().length === 0) return [];
10686
10428
  try {
10687
10429
  const parsed = JSON.parse(value);
10688
10430
  return Array.isArray(parsed) ? parsed : [];
@@ -10712,8 +10454,7 @@ var VectorWorker = class {
10712
10454
  * Start the worker polling loop
10713
10455
  */
10714
10456
  start() {
10715
- if (this.running)
10716
- return;
10457
+ if (this.running) return;
10717
10458
  this.running = true;
10718
10459
  this.stopping = false;
10719
10460
  this.poll();
@@ -10789,8 +10530,7 @@ var VectorWorker = class {
10789
10530
  * Poll for new items
10790
10531
  */
10791
10532
  async poll() {
10792
- if (!this.running || this.stopping)
10793
- return;
10533
+ if (!this.running || this.stopping) return;
10794
10534
  try {
10795
10535
  await this.processBatch();
10796
10536
  } catch (error) {
@@ -10835,6 +10575,7 @@ var DefaultContentProvider = class {
10835
10575
  constructor(db) {
10836
10576
  this.db = db;
10837
10577
  }
10578
+ db;
10838
10579
  async getContent(itemKind, itemId) {
10839
10580
  switch (itemKind) {
10840
10581
  case "entry":
@@ -10855,8 +10596,7 @@ var DefaultContentProvider = class {
10855
10596
  `SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
10856
10597
  [entryId]
10857
10598
  );
10858
- if (rows.length === 0)
10859
- return null;
10599
+ if (rows.length === 0) return null;
10860
10600
  const row = rows[0];
10861
10601
  const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
10862
10602
  return {
@@ -10875,8 +10615,7 @@ ${JSON.stringify(contentJson)}`,
10875
10615
  WHERE entity_id = ? AND entity_type = 'task'`,
10876
10616
  [taskId]
10877
10617
  );
10878
- if (rows.length === 0)
10879
- return null;
10618
+ if (rows.length === 0) return null;
10880
10619
  const row = rows[0];
10881
10620
  return {
10882
10621
  content: row.search_text || row.title,
@@ -10892,8 +10631,7 @@ ${JSON.stringify(contentJson)}`,
10892
10631
  `SELECT content, event_type, session_id FROM events WHERE id = ?`,
10893
10632
  [eventId]
10894
10633
  );
10895
- if (rows.length === 0)
10896
- return null;
10634
+ if (rows.length === 0) return null;
10897
10635
  const row = rows[0];
10898
10636
  return {
10899
10637
  content: row.content,
@@ -10921,8 +10659,7 @@ ${JSON.stringify(contentJson)}`,
10921
10659
  }
10922
10660
  throw error;
10923
10661
  }
10924
- if (rows.length === 0)
10925
- return null;
10662
+ if (rows.length === 0) return null;
10926
10663
  const row = rows[0];
10927
10664
  const sourceEventIds = parseJsonArray(row.source_event_ids_json);
10928
10665
  const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
@@ -10964,8 +10701,7 @@ var VectorWorkerV2 = class {
10964
10701
  * Start the worker polling loop
10965
10702
  */
10966
10703
  start() {
10967
- if (this.running)
10968
- return;
10704
+ if (this.running) return;
10969
10705
  this.running = true;
10970
10706
  this.stopping = false;
10971
10707
  this.poll();
@@ -11035,8 +10771,7 @@ var VectorWorkerV2 = class {
11035
10771
  * Poll for new jobs
11036
10772
  */
11037
10773
  async poll() {
11038
- if (!this.running || this.stopping)
11039
- return;
10774
+ if (!this.running || this.stopping) return;
11040
10775
  try {
11041
10776
  await this.processBatch();
11042
10777
  } catch (error) {
@@ -11103,8 +10838,7 @@ function createMemoryRuntimeService(deps) {
11103
10838
  let graduationWorker = null;
11104
10839
  return {
11105
10840
  async initialize() {
11106
- if (initialized)
11107
- return;
10841
+ if (initialized) return;
11108
10842
  await deps.sqliteStore.initialize();
11109
10843
  if (deps.lightweightMode) {
11110
10844
  initialized = true;
@@ -11198,8 +10932,7 @@ var SharedEventStore = class {
11198
10932
  this.db = createDatabase(dbPath);
11199
10933
  }
11200
10934
  async initialize() {
11201
- if (this.initialized)
11202
- return;
10935
+ if (this.initialized) return;
11203
10936
  await dbRun(this.db, `
11204
10937
  CREATE TABLE IF NOT EXISTS shared_troubleshooting (
11205
10938
  entry_id VARCHAR PRIMARY KEY,
@@ -11289,6 +11022,10 @@ var SharedPromoter = class {
11289
11022
  this.embedder = embedder;
11290
11023
  this.config = config;
11291
11024
  }
11025
+ sharedStore;
11026
+ sharedVectorStore;
11027
+ embedder;
11028
+ config;
11292
11029
  /**
11293
11030
  * Check if an entry is eligible for promotion
11294
11031
  */
@@ -11470,6 +11207,7 @@ var SharedStore = class {
11470
11207
  constructor(sharedEventStore) {
11471
11208
  this.sharedEventStore = sharedEventStore;
11472
11209
  }
11210
+ sharedEventStore;
11473
11211
  get db() {
11474
11212
  return this.sharedEventStore.getDatabase();
11475
11213
  }
@@ -11574,8 +11312,7 @@ var SharedStore = class {
11574
11312
  `SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
11575
11313
  [entryId]
11576
11314
  );
11577
- if (rows.length === 0)
11578
- return null;
11315
+ if (rows.length === 0) return null;
11579
11316
  return this.rowToEntry(rows[0]);
11580
11317
  }
11581
11318
  /**
@@ -11588,8 +11325,7 @@ var SharedStore = class {
11588
11325
  WHERE source_project_hash = ? AND source_entry_id = ?`,
11589
11326
  [projectHash, sourceEntryId]
11590
11327
  );
11591
- if (rows.length === 0)
11592
- return null;
11328
+ if (rows.length === 0) return null;
11593
11329
  return this.rowToEntry(rows[0]);
11594
11330
  }
11595
11331
  /**
@@ -11699,6 +11435,7 @@ var SharedVectorStore = class {
11699
11435
  constructor(dbPath) {
11700
11436
  this.dbPath = dbPath;
11701
11437
  }
11438
+ dbPath;
11702
11439
  db = null;
11703
11440
  table = null;
11704
11441
  tableName = "shared_knowledge";
@@ -11706,8 +11443,7 @@ var SharedVectorStore = class {
11706
11443
  * Initialize LanceDB connection
11707
11444
  */
11708
11445
  async initialize() {
11709
- if (this.db)
11710
- return;
11446
+ if (this.db) return;
11711
11447
  this.db = await lancedb2.connect(this.dbPath);
11712
11448
  try {
11713
11449
  const tables = await this.db.tableNames();
@@ -11749,8 +11485,7 @@ var SharedVectorStore = class {
11749
11485
  * Add multiple records in batch
11750
11486
  */
11751
11487
  async upsertBatch(records) {
11752
- if (records.length === 0)
11753
- return;
11488
+ if (records.length === 0) return;
11754
11489
  await this.initialize();
11755
11490
  if (!this.db) {
11756
11491
  throw new Error("Database not initialized");
@@ -11811,24 +11546,21 @@ var SharedVectorStore = class {
11811
11546
  * Delete vector by entry ID
11812
11547
  */
11813
11548
  async delete(entryId) {
11814
- if (!this.table)
11815
- return;
11549
+ if (!this.table) return;
11816
11550
  await this.table.delete(`entryId = '${entryId}'`);
11817
11551
  }
11818
11552
  /**
11819
11553
  * Get total count
11820
11554
  */
11821
11555
  async count() {
11822
- if (!this.table)
11823
- return 0;
11556
+ if (!this.table) return 0;
11824
11557
  return this.table.countRows();
11825
11558
  }
11826
11559
  /**
11827
11560
  * Check if vector exists for entry
11828
11561
  */
11829
11562
  async exists(entryId) {
11830
- if (!this.table)
11831
- return false;
11563
+ if (!this.table) return false;
11832
11564
  try {
11833
11565
  const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
11834
11566
  return results.length > 0;
@@ -11846,6 +11578,7 @@ var SharedMemoryServices = class {
11846
11578
  constructor(options) {
11847
11579
  this.options = options;
11848
11580
  }
11581
+ options;
11849
11582
  sharedEventStore = null;
11850
11583
  sharedStore = null;
11851
11584
  sharedVectorStore = null;
@@ -11870,8 +11603,7 @@ var SharedMemoryServices = class {
11870
11603
  return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
11871
11604
  }
11872
11605
  async initialize() {
11873
- if (this.options.config?.enabled === false || this.options.readOnly)
11874
- return;
11606
+ if (this.options.config?.enabled === false || this.options.readOnly) return;
11875
11607
  const sharedPath = this.getSharedStoragePath();
11876
11608
  this.ensureDirectory(sharedPath, { allowCreate: true });
11877
11609
  const store = await this.openStore(sharedPath);
@@ -11888,14 +11620,11 @@ var SharedMemoryServices = class {
11888
11620
  this.options.retriever.setSharedStores(store, this.sharedVectorStore);
11889
11621
  }
11890
11622
  async ensureStoreForRead() {
11891
- if (this.options.config?.enabled === false)
11892
- return null;
11893
- if (this.sharedStore)
11894
- return this.sharedStore;
11623
+ if (this.options.config?.enabled === false) return null;
11624
+ if (this.sharedStore) return this.sharedStore;
11895
11625
  const sharedPath = this.getSharedStoragePath();
11896
11626
  const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
11897
- if (!directoryReady)
11898
- return null;
11627
+ if (!directoryReady) return null;
11899
11628
  return this.openStore(sharedPath);
11900
11629
  }
11901
11630
  async getEntryForDisclosure(entryId) {
@@ -11912,13 +11641,11 @@ var SharedMemoryServices = class {
11912
11641
  return this.sharedPromoter.promoteEntry(entry, projectHash);
11913
11642
  }
11914
11643
  async getStats() {
11915
- if (!this.sharedStore)
11916
- return null;
11644
+ if (!this.sharedStore) return null;
11917
11645
  return this.sharedStore.getStats();
11918
11646
  }
11919
11647
  async search(query, options) {
11920
- if (!this.sharedStore)
11921
- return [];
11648
+ if (!this.sharedStore) return [];
11922
11649
  return this.sharedStore.search(query, options);
11923
11650
  }
11924
11651
  async close() {
@@ -11935,8 +11662,7 @@ var SharedMemoryServices = class {
11935
11662
  this.openStorePromise = null;
11936
11663
  }
11937
11664
  async openStore(sharedPath) {
11938
- if (this.sharedStore)
11939
- return this.sharedStore;
11665
+ if (this.sharedStore) return this.sharedStore;
11940
11666
  if (!this.openStorePromise) {
11941
11667
  this.openStorePromise = this.createOpenStorePromise(sharedPath);
11942
11668
  }
@@ -11960,10 +11686,8 @@ var SharedMemoryServices = class {
11960
11686
  return this.sharedStore;
11961
11687
  }
11962
11688
  ensureDirectory(sharedPath, options) {
11963
- if (this.factories.existsSync(sharedPath))
11964
- return true;
11965
- if (!options.allowCreate)
11966
- return false;
11689
+ if (this.factories.existsSync(sharedPath)) return true;
11690
+ if (!options.allowCreate) return false;
11967
11691
  this.factories.mkdirSync(sharedPath);
11968
11692
  return true;
11969
11693
  }
@@ -13170,15 +12894,13 @@ function countRowValue(db, sql, params = []) {
13170
12894
  return Number(row?.count ?? 0);
13171
12895
  }
13172
12896
  function projectFilter(projectHash, column = "project_hash") {
13173
- if (!projectHash)
13174
- return { clause: "", params: [] };
12897
+ if (!projectHash) return { clause: "", params: [] };
13175
12898
  return { clause: `WHERE ${column} = ?`, params: [projectHash] };
13176
12899
  }
13177
12900
  function sanitizeAggregateLabel(value) {
13178
12901
  const raw = typeof value === "string" ? value : String(value ?? "unknown");
13179
12902
  const sanitized = String(sanitizeGovernanceAuditValue(raw));
13180
- if (sanitized !== raw || sanitized.includes("[REDACTED]"))
13181
- return "[REDACTED]";
12903
+ if (sanitized !== raw || sanitized.includes("[REDACTED]")) return "[REDACTED]";
13182
12904
  const trimmed = sanitized.trim();
13183
12905
  return trimmed.length > 0 ? trimmed.slice(0, 96) : "unknown";
13184
12906
  }
@@ -13522,8 +13244,7 @@ function buildPerspectiveSourceEvidence(db, projectHash) {
13522
13244
  function sortCountRows(rows, labelKey) {
13523
13245
  return [...rows].sort((a, b) => {
13524
13246
  const countDiff = Number(b.count ?? 0) - Number(a.count ?? 0);
13525
- if (countDiff !== 0)
13526
- return countDiff;
13247
+ if (countDiff !== 0) return countDiff;
13527
13248
  return String(a[labelKey] ?? "").localeCompare(String(b[labelKey] ?? ""));
13528
13249
  });
13529
13250
  }
@@ -13606,8 +13327,7 @@ var DEFAULT_KPI_THRESHOLDS = {
13606
13327
  function loadKpiThresholds() {
13607
13328
  try {
13608
13329
  const filePath = path11.resolve(process.cwd(), "config", "kpi-thresholds.json");
13609
- if (!fs9.existsSync(filePath))
13610
- return DEFAULT_KPI_THRESHOLDS;
13330
+ if (!fs9.existsSync(filePath)) return DEFAULT_KPI_THRESHOLDS;
13611
13331
  const parsed = JSON.parse(fs9.readFileSync(filePath, "utf-8"));
13612
13332
  return {
13613
13333
  usefulRecallRateMin: Number(parsed.usefulRecallRateMin ?? DEFAULT_KPI_THRESHOLDS.usefulRecallRateMin),
@@ -13621,10 +13341,8 @@ function loadKpiThresholds() {
13621
13341
  }
13622
13342
  }
13623
13343
  function windowToMs(window) {
13624
- if (window === "24h")
13625
- return 24 * 60 * 60 * 1e3;
13626
- if (window === "7d")
13627
- return 7 * 24 * 60 * 60 * 1e3;
13344
+ if (window === "24h") return 24 * 60 * 60 * 1e3;
13345
+ if (window === "7d") return 7 * 24 * 60 * 60 * 1e3;
13628
13346
  return 30 * 24 * 60 * 60 * 1e3;
13629
13347
  }
13630
13348
  function inWindow(e, now, window) {
@@ -13634,8 +13352,7 @@ function isEditToolName(name) {
13634
13352
  return ["Write", "Edit", "MultiEdit", "NotebookEdit"].includes(name);
13635
13353
  }
13636
13354
  function parseToolPayload(e) {
13637
- if (e.eventType !== "tool_observation")
13638
- return null;
13355
+ if (e.eventType !== "tool_observation") return null;
13639
13356
  try {
13640
13357
  const payload = JSON.parse(e.content);
13641
13358
  return {
@@ -13654,13 +13371,11 @@ function parseToolPayload(e) {
13654
13371
  }
13655
13372
  }
13656
13373
  function isTestLikeCommand(command) {
13657
- if (!command)
13658
- return false;
13374
+ if (!command) return false;
13659
13375
  return /(test|jest|vitest|pytest|go test|cargo test|lint|eslint|build|tsc)/i.test(command);
13660
13376
  }
13661
13377
  function safeRatio(num, den) {
13662
- if (!Number.isFinite(num) || !Number.isFinite(den) || den <= 0)
13663
- return 0;
13378
+ if (!Number.isFinite(num) || !Number.isFinite(den) || den <= 0) return 0;
13664
13379
  return num / den;
13665
13380
  }
13666
13381
  function round(value, digits = 4) {
@@ -13671,28 +13386,23 @@ function computeSessionTurnCount(sessionEvents) {
13671
13386
  const turnIds = /* @__PURE__ */ new Set();
13672
13387
  for (const e of sessionEvents) {
13673
13388
  const turnId = e.metadata?.turnId;
13674
- if (typeof turnId === "string" && turnId.length > 0)
13675
- turnIds.add(turnId);
13389
+ if (typeof turnId === "string" && turnId.length > 0) turnIds.add(turnId);
13676
13390
  }
13677
- if (turnIds.size > 0)
13678
- return turnIds.size;
13391
+ if (turnIds.size > 0) return turnIds.size;
13679
13392
  return sessionEvents.filter((e) => e.eventType === "user_prompt").length;
13680
13393
  }
13681
13394
  function normalizeQueryRewriteKind2(value) {
13682
13395
  const normalized = (value || "").trim().toLowerCase();
13683
- if (normalized === "follow-up-context" || normalized === "intent-rewrite")
13684
- return normalized;
13396
+ if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
13685
13397
  return "none";
13686
13398
  }
13687
13399
  function normalizeMetric(value) {
13688
13400
  const numberValue = Number(value || 0);
13689
- if (!Number.isFinite(numberValue))
13690
- return 0;
13401
+ if (!Number.isFinite(numberValue)) return 0;
13691
13402
  return Math.max(0, Math.min(1, numberValue));
13692
13403
  }
13693
13404
  function getTimestampMs(value) {
13694
- if (value instanceof Date)
13695
- return value.getTime();
13405
+ if (value instanceof Date) return value.getTime();
13696
13406
  if (typeof value === "string") {
13697
13407
  const parsed = new Date(value).getTime();
13698
13408
  return Number.isFinite(parsed) ? parsed : 0;
@@ -13750,8 +13460,7 @@ function makeRetrievalReviewItem(trace) {
13750
13460
  detail = `${selectedCount} of ${candidateCount} candidates were selected.`;
13751
13461
  action = "Inspect score distribution and MMR/diversity settings before lowering thresholds.";
13752
13462
  }
13753
- if (!reason)
13754
- return null;
13463
+ if (!reason) return null;
13755
13464
  return {
13756
13465
  traceId: trace.traceId || "unknown-trace",
13757
13466
  reason,
@@ -13800,24 +13509,17 @@ function buildRetrievalReviewQueue(traces, limit) {
13800
13509
  };
13801
13510
  }
13802
13511
  function parseStatsLimit(value, fallback, max) {
13803
- if (!value)
13804
- return fallback;
13805
- if (!/^\d+$/.test(value))
13806
- return fallback;
13512
+ if (!value) return fallback;
13513
+ if (!/^\d+$/.test(value)) return fallback;
13807
13514
  const parsed = Number(value);
13808
- if (!Number.isFinite(parsed) || parsed <= 0)
13809
- return fallback;
13515
+ if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
13810
13516
  return Math.min(parsed, max);
13811
13517
  }
13812
13518
  function usefulnessScoreLabel(score, confidence) {
13813
- if (confidence <= 0)
13814
- return "unknown";
13815
- if (score >= 80)
13816
- return "excellent";
13817
- if (score >= 60)
13818
- return "good";
13819
- if (score >= 40)
13820
- return "watch";
13519
+ if (confidence <= 0) return "unknown";
13520
+ if (score >= 80) return "excellent";
13521
+ if (score >= 60) return "good";
13522
+ if (score >= 40) return "watch";
13821
13523
  return "low";
13822
13524
  }
13823
13525
  function buildMemoryUsefulnessDiagnostics(input) {
@@ -14063,8 +13765,7 @@ function computeKpiMetrics(events, usefulRecallRate) {
14063
13765
  let seenEdit = false;
14064
13766
  for (const e of sorted) {
14065
13767
  const payload = parseToolPayload(e);
14066
- if (!payload?.toolName)
14067
- continue;
13768
+ if (!payload?.toolName) continue;
14068
13769
  if (isEditToolName(payload.toolName) && payload.success === true) {
14069
13770
  editActions.push({ sessionId, timestamp: e.timestamp.getTime(), filePath: payload.filePath });
14070
13771
  seenEdit = true;
@@ -14072,8 +13773,7 @@ function computeKpiMetrics(events, usefulRecallRate) {
14072
13773
  }
14073
13774
  if (seenEdit && isTestLikeCommand(payload.command)) {
14074
13775
  testRunsAfterEdit++;
14075
- if (payload.success === false)
14076
- failedTestRunsAfterEdit++;
13776
+ if (payload.success === false) failedTestRunsAfterEdit++;
14077
13777
  }
14078
13778
  }
14079
13779
  }
@@ -14082,8 +13782,7 @@ function computeKpiMetrics(events, usefulRecallRate) {
14082
13782
  const bySessionFile = /* @__PURE__ */ new Map();
14083
13783
  const sortedEdits = [...editActions].sort((a, b) => a.timestamp - b.timestamp);
14084
13784
  for (const edit of sortedEdits) {
14085
- if (!edit.filePath)
14086
- continue;
13785
+ if (!edit.filePath) continue;
14087
13786
  const key = `${edit.sessionId}::${edit.filePath}`;
14088
13787
  const prev = bySessionFile.get(key);
14089
13788
  if (typeof prev === "number" && edit.timestamp - prev <= THIRTY_MIN_MS) {
@@ -14458,12 +14157,9 @@ statsRouter.get("/timeline", async (c) => {
14458
14157
  acc[day] = { date: day, total: 0, prompts: 0, responses: 0, tools: 0 };
14459
14158
  }
14460
14159
  acc[day].total++;
14461
- if (e.eventType === "user_prompt")
14462
- acc[day].prompts++;
14463
- if (e.eventType === "agent_response")
14464
- acc[day].responses++;
14465
- if (e.eventType === "tool_observation")
14466
- acc[day].tools++;
14160
+ if (e.eventType === "user_prompt") acc[day].prompts++;
14161
+ if (e.eventType === "agent_response") acc[day].responses++;
14162
+ if (e.eventType === "tool_observation") acc[day].tools++;
14467
14163
  return acc;
14468
14164
  }, {});
14469
14165
  return c.json({
@@ -14674,8 +14370,7 @@ statsRouter.get("/kpi", async (c) => {
14674
14370
  for (const edit of dayEditActions) {
14675
14371
  const key = `${edit.sessionId}::${edit.filePath}`;
14676
14372
  const prev = dayBySessionFile.get(key);
14677
- if (typeof prev === "number" && edit.timestamp - prev <= THIRTY_MIN_MS)
14678
- dayReworkCount++;
14373
+ if (typeof prev === "number" && edit.timestamp - prev <= THIRTY_MIN_MS) dayReworkCount++;
14679
14374
  dayBySessionFile.set(key, edit.timestamp);
14680
14375
  }
14681
14376
  const dayTests = dayEvents.filter((e) => {
@@ -15015,8 +14710,7 @@ projectsRouter.get("/", async (c) => {
15015
14710
  }
15016
14711
  });
15017
14712
  function formatBytes(bytes) {
15018
- if (bytes === 0)
15019
- return "0 B";
14713
+ if (bytes === 0) return "0 B";
15020
14714
  const k = 1024;
15021
14715
  const sizes = ["B", "KB", "MB", "GB"];
15022
14716
  const i = Math.floor(Math.log(bytes) / Math.log(k));
@@ -15034,6 +14728,7 @@ var ProviderFailure = class extends Error {
15034
14728
  this.code = code;
15035
14729
  this.name = "ProviderFailure";
15036
14730
  }
14731
+ code;
15037
14732
  };
15038
14733
  var CLAUDE_TIMEOUT_MS = 12e4;
15039
14734
  chatRouter.post("/", async (c) => {
@@ -15110,8 +14805,7 @@ async function collectMemoryContext(memoryService, query) {
15110
14805
  async function collectStatsContext(memoryService) {
15111
14806
  try {
15112
14807
  const stats = await memoryService.getStats?.();
15113
- if (!stats)
15114
- return "";
14808
+ if (!stats) return "";
15115
14809
  const levels = stats.levelStats.map((l) => `${l.level}: ${l.count}`).join(", ");
15116
14810
  return [
15117
14811
  "## Memory Stats",
@@ -15124,8 +14818,7 @@ async function collectStatsContext(memoryService) {
15124
14818
  }
15125
14819
  }
15126
14820
  function formatMemoryContext(memoryHits) {
15127
- if (memoryHits.length === 0)
15128
- return "";
14821
+ if (memoryHits.length === 0) return "";
15129
14822
  const parts = ["## Relevant Memories\n"];
15130
14823
  for (const m of memoryHits) {
15131
14824
  const date = m.event.timestamp ? new Date(m.event.timestamp).toISOString().split("T")[0] : "unknown-date";
@@ -15247,8 +14940,7 @@ function streamClaudeResponse(prompt, stream) {
15247
14940
  const lines = buffer.split("\n");
15248
14941
  buffer = lines.pop() || "";
15249
14942
  for (const line of lines) {
15250
- if (!line.trim())
15251
- continue;
14943
+ if (!line.trim()) continue;
15252
14944
  try {
15253
14945
  const parsed = JSON.parse(line);
15254
14946
  if (parsed.type === "assistant" && parsed.message?.content) {
@@ -15477,21 +15169,17 @@ function timingSafeStringEqual(a, b) {
15477
15169
  return left.length === right.length && timingSafeEqual(left, right);
15478
15170
  }
15479
15171
  function verifyDashboardSessionToken(token, password, maxAgeSeconds, now) {
15480
- if (!token)
15481
- return false;
15172
+ if (!token) return false;
15482
15173
  const [payload, signature, extra] = token.split(".");
15483
- if (!payload || !signature || extra !== void 0 || !/^\d+$/.test(payload))
15484
- return false;
15174
+ if (!payload || !signature || extra !== void 0 || !/^\d+$/.test(payload)) return false;
15485
15175
  const expectedSignature = signSessionPayload(payload, password);
15486
- if (!timingSafeStringEqual(signature, expectedSignature))
15487
- return false;
15176
+ if (!timingSafeStringEqual(signature, expectedSignature)) return false;
15488
15177
  const issuedAt = Number.parseInt(payload, 10);
15489
15178
  const age = nowSeconds(now) - issuedAt;
15490
15179
  return Number.isSafeInteger(issuedAt) && age >= 0 && age <= maxAgeSeconds;
15491
15180
  }
15492
15181
  function isDashboardAuthenticated(c, options) {
15493
- if (!options.password)
15494
- return true;
15182
+ if (!options.password) return true;
15495
15183
  return verifyDashboardSessionToken(
15496
15184
  getCookie(c, DASHBOARD_SESSION_COOKIE),
15497
15185
  options.password,
@@ -15578,8 +15266,7 @@ function createDashboardApp(options = {}) {
15578
15266
  }
15579
15267
  const submittedPassword = await readSubmittedPassword(c);
15580
15268
  if (!timingSafeStringEqual(submittedPassword, authOptions.password)) {
15581
- if (wantsAuthJson(c))
15582
- return c.json({ error: "Invalid password" }, 401);
15269
+ if (wantsAuthJson(c)) return c.json({ error: "Invalid password" }, 401);
15583
15270
  return c.html(renderLoginPage("Invalid password"), 401);
15584
15271
  }
15585
15272
  const token = createDashboardSessionToken(authOptions.password, authOptions.now);
@@ -15590,14 +15277,12 @@ function createDashboardApp(options = {}) {
15590
15277
  path: "/",
15591
15278
  maxAge: authOptions.cookieMaxAgeSeconds
15592
15279
  });
15593
- if (wantsAuthJson(c))
15594
- return c.json({ authenticated: true });
15280
+ if (wantsAuthJson(c)) return c.json({ authenticated: true });
15595
15281
  return c.redirect("/", 303);
15596
15282
  });
15597
15283
  app2.post("/api/auth/logout", (c) => {
15598
15284
  deleteCookie(c, DASHBOARD_SESSION_COOKIE, { path: "/" });
15599
- if (wantsAuthJson(c))
15600
- return c.json({ authenticated: false });
15285
+ if (wantsAuthJson(c)) return c.json({ authenticated: false });
15601
15286
  return c.redirect("/", 303);
15602
15287
  });
15603
15288
  if (authOptions.password) {
@@ -15606,8 +15291,7 @@ function createDashboardApp(options = {}) {
15606
15291
  await next();
15607
15292
  return;
15608
15293
  }
15609
- if (isApiRequest(c))
15610
- return c.json({ error: "Authentication required" }, 401);
15294
+ if (isApiRequest(c)) return c.json({ error: "Authentication required" }, 401);
15611
15295
  return c.html(renderLoginPage(), 401);
15612
15296
  });
15613
15297
  }