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.
@@ -57,6 +57,7 @@ var DefaultEmbeddingMaintenanceService = class {
57
57
  this.options = options;
58
58
  this.fileSystem = options.fileSystem ?? defaultFileSystem;
59
59
  }
60
+ options;
60
61
  fileSystem;
61
62
  getEmbeddingModelName() {
62
63
  return this.options.getEmbeddingModelName();
@@ -91,8 +92,7 @@ var DefaultEmbeddingMaintenanceService = class {
91
92
  }
92
93
  const worker = this.options.getVectorWorker();
93
94
  const wasRunning = worker?.isRunning() || false;
94
- if (wasRunning)
95
- worker?.stop();
95
+ if (wasRunning) worker?.stop();
96
96
  await this.options.vectorStore.clearAll();
97
97
  await this.options.eventStore.clearEmbeddingOutbox();
98
98
  const enqueued = await this.reenqueueAllEvents();
@@ -109,8 +109,7 @@ var DefaultEmbeddingMaintenanceService = class {
109
109
  2
110
110
  )
111
111
  );
112
- if (wasRunning)
113
- worker?.start();
112
+ if (wasRunning) worker?.start();
114
113
  return {
115
114
  changed: true,
116
115
  previousModel,
@@ -135,15 +134,13 @@ var DefaultEmbeddingMaintenanceService = class {
135
134
  let enqueued = 0;
136
135
  while (true) {
137
136
  const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
138
- if (page.length === 0)
139
- break;
137
+ if (page.length === 0) break;
140
138
  for (const event of page) {
141
139
  await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
142
140
  enqueued += 1;
143
141
  }
144
142
  offset += page.length;
145
- if (page.length < DEFAULT_PAGE_SIZE)
146
- break;
143
+ if (page.length < DEFAULT_PAGE_SIZE) break;
147
144
  }
148
145
  return enqueued;
149
146
  }
@@ -161,12 +158,9 @@ import { randomUUID } from "crypto";
161
158
  // src/core/db-wrapper.ts
162
159
  import BetterSqlite3 from "better-sqlite3";
163
160
  function toDate(value) {
164
- if (value instanceof Date)
165
- return value;
166
- if (typeof value === "string")
167
- return new Date(value);
168
- if (typeof value === "number")
169
- return new Date(value);
161
+ if (value instanceof Date) return value;
162
+ if (typeof value === "string") return new Date(value);
163
+ if (typeof value === "number") return new Date(value);
170
164
  return new Date(String(value));
171
165
  }
172
166
  function createDatabase(dbPath, options) {
@@ -190,6 +184,8 @@ var WorkingSetStore = class {
190
184
  this.eventStore = eventStore;
191
185
  this.config = config;
192
186
  }
187
+ eventStore;
188
+ config;
193
189
  get db() {
194
190
  return this.eventStore.getDatabase();
195
191
  }
@@ -275,8 +271,7 @@ var WorkingSetStore = class {
275
271
  * Prune specific events from working set (after consolidation)
276
272
  */
277
273
  async prune(eventIds) {
278
- if (eventIds.length === 0)
279
- return;
274
+ if (eventIds.length === 0) return;
280
275
  const placeholders = eventIds.map(() => "?").join(",");
281
276
  await dbRun(
282
277
  this.db,
@@ -346,8 +341,7 @@ var WorkingSetStore = class {
346
341
  LIMIT ?`,
347
342
  [maxEvents]
348
343
  );
349
- if (keepIds.length === 0)
350
- return;
344
+ if (keepIds.length === 0) return;
351
345
  const keepIdList = keepIds.map((r) => r.id);
352
346
  const placeholders = keepIdList.map(() => "?").join(",");
353
347
  await dbRun(
@@ -394,6 +388,7 @@ var ConsolidatedStore = class {
394
388
  constructor(eventStore) {
395
389
  this.eventStore = eventStore;
396
390
  }
391
+ eventStore;
397
392
  get db() {
398
393
  return this.eventStore.getDatabase();
399
394
  }
@@ -426,8 +421,7 @@ var ConsolidatedStore = class {
426
421
  `SELECT * FROM consolidated_memories WHERE memory_id = ?`,
427
422
  [memoryId]
428
423
  );
429
- if (rows.length === 0)
430
- return null;
424
+ if (rows.length === 0) return null;
431
425
  return this.rowToMemory(rows[0]);
432
426
  }
433
427
  /**
@@ -645,8 +639,7 @@ var ConsolidatedStore = class {
645
639
  WHERE source_events LIKE ?`,
646
640
  [`%"${eventId}"%`]
647
641
  );
648
- if ((result[0]?.count || 0) > 0)
649
- return true;
642
+ if ((result[0]?.count || 0) > 0) return true;
650
643
  }
651
644
  return false;
652
645
  }
@@ -660,8 +653,7 @@ var ConsolidatedStore = class {
660
653
  ORDER BY created_at DESC
661
654
  LIMIT 1`
662
655
  );
663
- if (result.length === 0)
664
- return null;
656
+ if (result.length === 0) return null;
665
657
  return new Date(result[0].created_at);
666
658
  }
667
659
  /**
@@ -691,6 +683,9 @@ var ConsolidationWorker = class {
691
683
  this.consolidatedStore = consolidatedStore;
692
684
  this.config = config;
693
685
  }
686
+ workingSetStore;
687
+ consolidatedStore;
688
+ config;
694
689
  running = false;
695
690
  timeout = null;
696
691
  lastActivity = /* @__PURE__ */ new Date();
@@ -698,8 +693,7 @@ var ConsolidationWorker = class {
698
693
  * Start the consolidation worker
699
694
  */
700
695
  start() {
701
- if (this.running)
702
- return;
696
+ if (this.running) return;
703
697
  this.running = true;
704
698
  this.scheduleNext();
705
699
  }
@@ -742,8 +736,7 @@ var ConsolidationWorker = class {
742
736
  * Schedule the next consolidation check
743
737
  */
744
738
  scheduleNext() {
745
- if (!this.running)
746
- return;
739
+ if (!this.running) return;
747
740
  this.timeout = setTimeout(
748
741
  () => this.run(),
749
742
  this.config.consolidation.triggerIntervalMs
@@ -753,8 +746,7 @@ var ConsolidationWorker = class {
753
746
  * Run consolidation check
754
747
  */
755
748
  async run() {
756
- if (!this.running)
757
- return;
749
+ if (!this.running) return;
758
750
  try {
759
751
  await this.checkAndConsolidate();
760
752
  } catch (error) {
@@ -792,12 +784,10 @@ var ConsolidationWorker = class {
792
784
  let consolidatedCount = 0;
793
785
  const createdMemoryIds = [];
794
786
  for (const group of groups) {
795
- if (group.events.length < 3)
796
- continue;
787
+ if (group.events.length < 3) continue;
797
788
  const eventIds = group.events.map((e) => e.id);
798
789
  const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);
799
- if (alreadyConsolidated)
800
- continue;
790
+ if (alreadyConsolidated) continue;
801
791
  const summary = await this.summarize(group);
802
792
  const memoryId = await this.consolidatedStore.create({
803
793
  summary,
@@ -813,8 +803,7 @@ var ConsolidationWorker = class {
813
803
  const consolidatedEventIds = groups.filter((g) => g.events.length >= 3).flatMap((g) => g.events.map((e) => e.id));
814
804
  const oldEventIds = consolidatedEventIds.filter((id) => {
815
805
  const event = workingSet.recentEvents.find((e) => e.id === id);
816
- if (!event)
817
- return false;
806
+ if (!event) return false;
818
807
  const ageHours = (Date.now() - event.timestamp.getTime()) / (1e3 * 60 * 60);
819
808
  return ageHours > this.config.workingSet.timeWindowHours / 2;
820
809
  });
@@ -829,18 +818,13 @@ var ConsolidationWorker = class {
829
818
  let promoted = 0;
830
819
  for (const memoryId of memoryIds) {
831
820
  const memory = await this.consolidatedStore.get(memoryId);
832
- if (!memory)
833
- continue;
834
- if (memory.confidence < 0.55)
835
- continue;
836
- if (memory.sourceEvents.length < 4)
837
- continue;
821
+ if (!memory) continue;
822
+ if (memory.confidence < 0.55) continue;
823
+ if (memory.sourceEvents.length < 4) continue;
838
824
  const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);
839
- if (exists)
840
- continue;
825
+ if (exists) continue;
841
826
  const rule = this.buildRuleFromSummary(memory.summary, memory.topics);
842
- if (!rule)
843
- continue;
827
+ if (!rule) continue;
844
828
  await this.consolidatedStore.createRule({
845
829
  rule,
846
830
  topics: memory.topics,
@@ -856,8 +840,7 @@ var ConsolidationWorker = class {
856
840
  const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !l.toLowerCase().startsWith("topics:"));
857
841
  const bullet = lines.find((l) => l.startsWith("- "))?.replace(/^-\s*/, "");
858
842
  const seed = bullet || lines[0];
859
- if (!seed || seed.length < 8)
860
- return null;
843
+ if (!seed || seed.length < 8) return null;
861
844
  const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(", ")}] ` : "";
862
845
  return `${topicPrefix}${seed}`;
863
846
  }
@@ -1018,8 +1001,7 @@ var ConsolidationWorker = class {
1018
1001
  */
1019
1002
  extractKeyPoint(content) {
1020
1003
  const sentences = content.split(/[.!?\n]+/).filter((s) => s.trim().length > 10);
1021
- if (sentences.length === 0)
1022
- return null;
1004
+ if (sentences.length === 0) return null;
1023
1005
  const firstSentence = sentences[0].trim();
1024
1006
  if (firstSentence.length > 100) {
1025
1007
  return firstSentence.slice(0, 100) + "...";
@@ -1039,8 +1021,7 @@ var ConsolidationWorker = class {
1039
1021
  * Calculate time proximity score
1040
1022
  */
1041
1023
  calculateTimeProximity(events) {
1042
- if (events.length < 2)
1043
- return 1;
1024
+ if (events.length < 2) return 1;
1044
1025
  const timestamps = events.map((e) => e.timestamp.getTime()).sort((a, b) => a - b);
1045
1026
  const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];
1046
1027
  const avgGap = timeSpan / (events.length - 1);
@@ -1059,6 +1040,8 @@ var ContinuityManager = class {
1059
1040
  this.eventStore = eventStore;
1060
1041
  this.config = config;
1061
1042
  }
1043
+ eventStore;
1044
+ config;
1062
1045
  lastContext = null;
1063
1046
  get db() {
1064
1047
  return this.eventStore.getDatabase();
@@ -1178,8 +1161,7 @@ var ContinuityManager = class {
1178
1161
  * Calculate overlap between two arrays
1179
1162
  */
1180
1163
  calculateOverlap(a, b) {
1181
- if (a.length === 0 || b.length === 0)
1182
- return 0;
1164
+ if (a.length === 0 || b.length === 0) return 0;
1183
1165
  const setA = new Set(a.map((s) => s.toLowerCase()));
1184
1166
  const setB = new Set(b.map((s) => s.toLowerCase()));
1185
1167
  const intersection = [...setA].filter((x) => setB.has(x));
@@ -1352,6 +1334,7 @@ var DefaultEndlessMemoryServices = class {
1352
1334
  this.options = options;
1353
1335
  this.factories = options.factories ? { ...options.factories, randomUUID: options.factories.randomUUID ?? randomUUID4 } : defaultFactories;
1354
1336
  }
1337
+ options;
1355
1338
  factories;
1356
1339
  workingSetStore = null;
1357
1340
  consolidatedStore = null;
@@ -1366,8 +1349,7 @@ var DefaultEndlessMemoryServices = class {
1366
1349
  }
1367
1350
  }
1368
1351
  async initializeEndlessMode() {
1369
- if (this.consolidationWorker)
1370
- return;
1352
+ if (this.consolidationWorker) return;
1371
1353
  const config = await this.getEndlessConfig();
1372
1354
  const workingSetStore = this.factories.createWorkingSetStore(this.options.eventStore, config);
1373
1355
  const consolidatedStore = this.factories.createConsolidatedStore(this.options.eventStore);
@@ -1399,8 +1381,7 @@ var DefaultEndlessMemoryServices = class {
1399
1381
  }
1400
1382
  async setMode(mode) {
1401
1383
  await this.options.initialize();
1402
- if (mode === this.mode)
1403
- return;
1384
+ if (mode === this.mode) return;
1404
1385
  this.mode = mode;
1405
1386
  await this.options.configStore.setEndlessConfig("mode", mode);
1406
1387
  if (mode === "endless") {
@@ -1416,33 +1397,27 @@ var DefaultEndlessMemoryServices = class {
1416
1397
  return this.mode === "endless";
1417
1398
  }
1418
1399
  async addToWorkingSet(eventId, relevanceScore) {
1419
- if (!this.workingSetStore)
1420
- return;
1400
+ if (!this.workingSetStore) return;
1421
1401
  await this.workingSetStore.add(eventId, relevanceScore);
1422
1402
  }
1423
1403
  async getWorkingSet() {
1424
- if (!this.workingSetStore)
1425
- return null;
1404
+ if (!this.workingSetStore) return null;
1426
1405
  return this.workingSetStore.get();
1427
1406
  }
1428
1407
  async searchConsolidated(query, options) {
1429
- if (!this.consolidatedStore)
1430
- return [];
1408
+ if (!this.consolidatedStore) return [];
1431
1409
  return this.consolidatedStore.search(query, options);
1432
1410
  }
1433
1411
  async getConsolidatedMemories(limit) {
1434
- if (!this.consolidatedStore)
1435
- return [];
1412
+ if (!this.consolidatedStore) return [];
1436
1413
  return this.consolidatedStore.getAll({ limit });
1437
1414
  }
1438
1415
  async markMemoryAccessed(memoryId) {
1439
- if (!this.consolidatedStore)
1440
- return;
1416
+ if (!this.consolidatedStore) return;
1441
1417
  await this.consolidatedStore.markAccessed(memoryId);
1442
1418
  }
1443
1419
  async calculateContinuity(content, metadata) {
1444
- if (!this.continuityManager)
1445
- return null;
1420
+ if (!this.continuityManager) return null;
1446
1421
  const snapshot = this.continuityManager.createSnapshot(
1447
1422
  this.factories.randomUUID(),
1448
1423
  content,
@@ -1454,8 +1429,7 @@ var DefaultEndlessMemoryServices = class {
1454
1429
  this.consolidationWorker?.recordActivity();
1455
1430
  }
1456
1431
  async forceConsolidation() {
1457
- if (!this.consolidationWorker)
1458
- return 0;
1432
+ if (!this.consolidationWorker) return 0;
1459
1433
  return this.consolidationWorker.forceRun();
1460
1434
  }
1461
1435
  async getEndlessModeStatus() {
@@ -1547,8 +1521,7 @@ var Embedder = class _Embedder {
1547
1521
  * Initialize the embedding pipeline
1548
1522
  */
1549
1523
  async initialize() {
1550
- if (this.initialized)
1551
- return;
1524
+ if (this.initialized) return;
1552
1525
  const pipeline = await withSuppressedKnownTransformersWarnings(async () => {
1553
1526
  try {
1554
1527
  return await loadTransformersPipeline();
@@ -1665,8 +1638,7 @@ async function withSuppressedKnownTransformersWarnings(fn) {
1665
1638
  originalConsoleWarn = console.warn;
1666
1639
  console.warn = (...args) => {
1667
1640
  const message = args.map(String).join(" ");
1668
- if (isKnownBenignTransformersWarning(message))
1669
- return;
1641
+ if (isKnownBenignTransformersWarning(message)) return;
1670
1642
  (originalConsoleWarn ?? console.warn)(...args);
1671
1643
  };
1672
1644
  }
@@ -1948,8 +1920,7 @@ var GraduationPipeline = class {
1948
1920
  const preferenceKeywords = ["prefer", "like", "want", "always", "never", "favorite"];
1949
1921
  const preferences = [];
1950
1922
  for (const event of events) {
1951
- if (event.eventType !== "user_prompt")
1952
- continue;
1923
+ if (event.eventType !== "user_prompt") continue;
1953
1924
  const lowerContent = event.content.toLowerCase();
1954
1925
  for (const keyword of preferenceKeywords) {
1955
1926
  if (lowerContent.includes(keyword)) {
@@ -2115,11 +2086,9 @@ function sanitizeSegment(input, fallback) {
2115
2086
  return v || fallback;
2116
2087
  }
2117
2088
  function getAtPath(obj, dotted) {
2118
- if (!obj)
2119
- return void 0;
2089
+ if (!obj) return void 0;
2120
2090
  return dotted.split(".").reduce((acc, key) => {
2121
- if (!acc || typeof acc !== "object")
2122
- return void 0;
2091
+ if (!acc || typeof acc !== "object") return void 0;
2123
2092
  return acc[key];
2124
2093
  }, obj);
2125
2094
  }
@@ -2139,6 +2108,7 @@ var MarkdownMirror = class {
2139
2108
  constructor(rootDir) {
2140
2109
  this.rootDir = rootDir;
2141
2110
  }
2111
+ rootDir;
2142
2112
  async append(event, eventId) {
2143
2113
  const out = buildMirrorPath(this.rootDir, event);
2144
2114
  fs2.mkdirSync(path2.dirname(out), { recursive: true });
@@ -2270,10 +2240,8 @@ function sqliteClose(db) {
2270
2240
  db.close();
2271
2241
  }
2272
2242
  function toDateFromSQLite(value) {
2273
- if (value instanceof Date)
2274
- return value;
2275
- if (typeof value === "number")
2276
- return new Date(value);
2243
+ if (value instanceof Date) return value;
2244
+ if (typeof value === "number") return new Date(value);
2277
2245
  if (typeof value === "string") {
2278
2246
  const trimmed = value.trim();
2279
2247
  if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(trimmed)) {
@@ -2295,8 +2263,7 @@ var DEFAULT_CATEGORY = "uncategorized";
2295
2263
  function sanitizeSegment2(input, fallback) {
2296
2264
  const raw = String(input ?? "").trim().toLowerCase();
2297
2265
  const safe = raw.normalize("NFKD").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
2298
- if (!safe || safe === "." || safe === "..")
2299
- return fallback;
2266
+ if (!safe || safe === "." || safe === "..") return fallback;
2300
2267
  return safe;
2301
2268
  }
2302
2269
  function getCategorySegments(metadata, eventType) {
@@ -2337,6 +2304,7 @@ var MarkdownMirror2 = class {
2337
2304
  constructor(rootDir) {
2338
2305
  this.rootDir = rootDir;
2339
2306
  }
2307
+ rootDir;
2340
2308
  async append(event) {
2341
2309
  const outPath = buildMirrorPath2(this.rootDir, event);
2342
2310
  await fs5.mkdir(path4.dirname(outPath), { recursive: true });
@@ -2359,6 +2327,7 @@ var VectorOutbox = class {
2359
2327
  this.db = db;
2360
2328
  this.config = { ...DEFAULT_CONFIG2, ...config };
2361
2329
  }
2330
+ db;
2362
2331
  config;
2363
2332
  /**
2364
2333
  * Enqueue item for vectorization (idempotent).
@@ -2455,8 +2424,7 @@ var VectorOutbox = class {
2455
2424
  `SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
2456
2425
  [jobId]
2457
2426
  );
2458
- if (rows.length === 0)
2459
- return;
2427
+ if (rows.length === 0) return;
2460
2428
  const retryCount = rows[0].retry_count;
2461
2429
  const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
2462
2430
  await dbRun(
@@ -2476,8 +2444,7 @@ var VectorOutbox = class {
2476
2444
  `SELECT * FROM vector_outbox WHERE job_id = ?`,
2477
2445
  [jobId]
2478
2446
  );
2479
- if (rows.length === 0)
2480
- return null;
2447
+ if (rows.length === 0) return null;
2481
2448
  return this.rowToJob(rows[0]);
2482
2449
  }
2483
2450
  /**
@@ -2611,30 +2578,24 @@ function isRetrievalDebugLaneName(value) {
2611
2578
  return typeof value === "string" && RETRIEVAL_DEBUG_LANE_NAME_SET.has(value);
2612
2579
  }
2613
2580
  function normalizeRetrievalDebugLanes(value, maxItems = 6) {
2614
- if (!Array.isArray(value) || maxItems <= 0)
2615
- return [];
2581
+ if (!Array.isArray(value) || maxItems <= 0) return [];
2616
2582
  const normalized = [];
2617
2583
  const seen = /* @__PURE__ */ new Set();
2618
2584
  for (const item of value) {
2619
2585
  const lane = normalizeRetrievalDebugLane(item);
2620
- if (!lane)
2621
- continue;
2586
+ if (!lane) continue;
2622
2587
  const key = [lane.lane, lane.reason, lane.score ?? ""].join("\0");
2623
- if (seen.has(key))
2624
- continue;
2588
+ if (seen.has(key)) continue;
2625
2589
  seen.add(key);
2626
2590
  normalized.push(lane);
2627
- if (normalized.length >= maxItems)
2628
- break;
2591
+ if (normalized.length >= maxItems) break;
2629
2592
  }
2630
2593
  return normalized;
2631
2594
  }
2632
2595
  function normalizeRetrievalDebugLane(value) {
2633
- if (!value || typeof value !== "object")
2634
- return null;
2596
+ if (!value || typeof value !== "object") return null;
2635
2597
  const raw = value;
2636
- if (!isRetrievalDebugLaneName(raw.lane))
2637
- return null;
2598
+ if (!isRetrievalDebugLaneName(raw.lane)) return null;
2638
2599
  const reason = sanitizeRetrievalLaneReason(typeof raw.reason === "string" ? raw.reason : "") || "unspecified";
2639
2600
  const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? Math.max(0, Math.min(1, raw.score)) : void 0;
2640
2601
  return score === void 0 ? { lane: raw.lane, reason } : { lane: raw.lane, reason, score };
@@ -2657,27 +2618,21 @@ function normalizeRetrievalTraceDetails(details) {
2657
2618
  eventId: detail.eventId,
2658
2619
  score: detail.score
2659
2620
  };
2660
- if (detail.semanticScore !== void 0)
2661
- normalized.semanticScore = detail.semanticScore;
2662
- if (detail.lexicalScore !== void 0)
2663
- normalized.lexicalScore = detail.lexicalScore;
2664
- if (detail.recencyScore !== void 0)
2665
- normalized.recencyScore = detail.recencyScore;
2666
- if (lanes.length > 0)
2667
- normalized.lanes = lanes;
2621
+ if (detail.semanticScore !== void 0) normalized.semanticScore = detail.semanticScore;
2622
+ if (detail.lexicalScore !== void 0) normalized.lexicalScore = detail.lexicalScore;
2623
+ if (detail.recencyScore !== void 0) normalized.recencyScore = detail.recencyScore;
2624
+ if (lanes.length > 0) normalized.lanes = lanes;
2668
2625
  return normalized;
2669
2626
  });
2670
2627
  }
2671
2628
  function parseRetrievalTraceDetails(value) {
2672
- if (typeof value !== "string" || value.length === 0)
2673
- return [];
2629
+ if (typeof value !== "string" || value.length === 0) return [];
2674
2630
  const parsed = JSON.parse(value);
2675
2631
  return Array.isArray(parsed) ? normalizeRetrievalTraceDetails(parsed) : [];
2676
2632
  }
2677
2633
  function normalizeQueryRewriteKind(value) {
2678
2634
  const normalized = (value || "").trim().toLowerCase();
2679
- if (normalized === "follow-up-context" || normalized === "intent-rewrite")
2680
- return normalized;
2635
+ if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
2681
2636
  return "none";
2682
2637
  }
2683
2638
  var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
@@ -2695,8 +2650,7 @@ function isRecord(value) {
2695
2650
  function getNestedRecord(root, path14) {
2696
2651
  let cursor = root;
2697
2652
  for (const key of path14) {
2698
- if (!isRecord(cursor))
2699
- return void 0;
2653
+ if (!isRecord(cursor)) return void 0;
2700
2654
  cursor = cursor[key];
2701
2655
  }
2702
2656
  return isRecord(cursor) ? cursor : void 0;
@@ -2704,8 +2658,7 @@ function getNestedRecord(root, path14) {
2704
2658
  function getNestedString(root, path14) {
2705
2659
  let cursor = root;
2706
2660
  for (const key of path14) {
2707
- if (!isRecord(cursor))
2708
- return void 0;
2661
+ if (!isRecord(cursor)) return void 0;
2709
2662
  cursor = cursor[key];
2710
2663
  }
2711
2664
  return typeof cursor === "string" && cursor.length > 0 ? cursor : void 0;
@@ -2721,8 +2674,7 @@ function metadataProjectPaths(metadata) {
2721
2674
  ];
2722
2675
  const paths = [];
2723
2676
  for (const value of candidates) {
2724
- if (value && !paths.includes(value))
2725
- paths.push(value);
2677
+ if (value && !paths.includes(value)) paths.push(value);
2726
2678
  }
2727
2679
  return paths;
2728
2680
  }
@@ -2743,12 +2695,9 @@ function maybeQuarantinePredicate(options, column = "metadata") {
2743
2695
  return options?.includeQuarantined ? "1=1" : notActiveQuarantinedSql(column);
2744
2696
  }
2745
2697
  function safeParseMetadataValue(value) {
2746
- if (!value)
2747
- return void 0;
2748
- if (typeof value === "object")
2749
- return isRecord(value) ? value : void 0;
2750
- if (typeof value !== "string")
2751
- return void 0;
2698
+ if (!value) return void 0;
2699
+ if (typeof value === "object") return isRecord(value) ? value : void 0;
2700
+ if (typeof value !== "string") return void 0;
2752
2701
  try {
2753
2702
  const parsed = JSON.parse(value);
2754
2703
  return isRecord(parsed) ? parsed : void 0;
@@ -2757,16 +2706,14 @@ function safeParseMetadataValue(value) {
2757
2706
  }
2758
2707
  }
2759
2708
  function isImportedOrLegacyScopedMetadata(metadata) {
2760
- if (!metadata)
2761
- return false;
2709
+ if (!metadata) return false;
2762
2710
  return Boolean(
2763
2711
  metadata.importedFrom || metadata.sourceSessionId || metadata.sourceSessionHash || metadata.hermesSource || metadata.projectPath || metadata.sourceProjectPath || metadata.source === "hermes" || metadata.source === "claude" || metadata.source === "codex"
2764
2712
  );
2765
2713
  }
2766
2714
  function addMetadataTag(metadata, tag) {
2767
2715
  const current = Array.isArray(metadata.tags) ? metadata.tags.filter((value) => typeof value === "string") : [];
2768
- if (!current.includes(tag))
2769
- metadata.tags = [...current, tag];
2716
+ if (!current.includes(tag)) metadata.tags = [...current, tag];
2770
2717
  }
2771
2718
  function buildRepairResult(projectHash, dryRun) {
2772
2719
  return {
@@ -2784,8 +2731,7 @@ function normalizeRepoName(value) {
2784
2731
  return value.replace(/\.git$/i, "").trim().toLowerCase();
2785
2732
  }
2786
2733
  function projectBasename(projectPath) {
2787
- if (!projectPath)
2788
- return void 0;
2734
+ if (!projectPath) return void 0;
2789
2735
  const trimmed = projectPath.replace(/[\\/]+$/, "");
2790
2736
  const basename2 = nodePath2.basename(trimmed);
2791
2737
  return basename2 ? normalizeRepoName(basename2) : void 0;
@@ -2798,23 +2744,19 @@ function isProjectScopeRepairExplanation(content) {
2798
2744
  }
2799
2745
  function hasConflictingContentProjectHint(content, projectPath) {
2800
2746
  const currentName = projectBasename(projectPath);
2801
- if (!currentName)
2802
- return false;
2803
- if (isProjectScopeRepairExplanation(content))
2804
- return false;
2747
+ if (!currentName) return false;
2748
+ if (isProjectScopeRepairExplanation(content)) return false;
2805
2749
  const githubRepoPattern = /github\.com[:/]([^/\s`'"#)]+)\/([^/\s`'"#)]+)(?:\.git)?/gi;
2806
2750
  let githubMatch;
2807
2751
  while ((githubMatch = githubRepoPattern.exec(content)) !== null) {
2808
2752
  const repo = normalizeRepoName(githubMatch[2] || "");
2809
- if (repo && repo !== currentName)
2810
- return true;
2753
+ if (repo && repo !== currentName) return true;
2811
2754
  }
2812
2755
  const workspacePathPattern = /\/workspace\/([^/\s`'"#)]+)/gi;
2813
2756
  let workspaceMatch;
2814
2757
  while ((workspaceMatch = workspacePathPattern.exec(content)) !== null) {
2815
2758
  const repo = normalizeRepoName(workspaceMatch[1] || "");
2816
- if (repo && repo !== currentName)
2817
- return true;
2759
+ if (repo && repo !== currentName) return true;
2818
2760
  }
2819
2761
  return false;
2820
2762
  }
@@ -2834,15 +2776,12 @@ var SQLiteEventStore = class {
2834
2776
  this.vectorOutbox = this.createVectorOutbox(options?.vectorOutbox);
2835
2777
  }
2836
2778
  createVectorOutbox(option) {
2837
- if (this.readOnly || option === false)
2838
- return null;
2839
- if (option instanceof VectorOutbox)
2840
- return option;
2779
+ if (this.readOnly || option === false) return null;
2780
+ if (option instanceof VectorOutbox) return option;
2841
2781
  return new VectorOutbox(this.db, option ?? {});
2842
2782
  }
2843
2783
  enqueueVectorOutboxEventSync(eventId) {
2844
- if (!this.vectorOutbox)
2845
- return;
2784
+ if (!this.vectorOutbox) return;
2846
2785
  this.vectorOutbox.enqueueSync("event", eventId);
2847
2786
  }
2848
2787
  async enqueueVectorOutboxEvent(eventId) {
@@ -2852,8 +2791,7 @@ var SQLiteEventStore = class {
2852
2791
  * Initialize database schema
2853
2792
  */
2854
2793
  async initialize() {
2855
- if (this.initialized)
2856
- return;
2794
+ if (this.initialized) return;
2857
2795
  if (this.readOnly) {
2858
2796
  this.initialized = true;
2859
2797
  return;
@@ -3411,10 +3349,8 @@ var SQLiteEventStore = class {
3411
3349
  try {
3412
3350
  const edgeIndexes = sqliteAll(this.db, `PRAGMA index_list(memory_action_edges)`, []);
3413
3351
  const hasSourceAwareUnique = edgeIndexes.some((index) => {
3414
- if (Number(index.unique) !== 1)
3415
- return false;
3416
- if (!/^[A-Za-z0-9_]+$/.test(index.name))
3417
- return false;
3352
+ if (Number(index.unique) !== 1) return false;
3353
+ if (!/^[A-Za-z0-9_]+$/.test(index.name)) return false;
3418
3354
  const escapedName = index.name.replace(/"/g, '""');
3419
3355
  const columns = sqliteAll(this.db, 'PRAGMA index_info("' + escapedName + '")', []).map((column) => column.name);
3420
3356
  return columns.length === 5 && columns[0] === "src_action_id" && columns[1] === "rel_type" && columns[2] === "dst_type" && columns[3] === "dst_id" && columns[4] === "source";
@@ -3654,8 +3590,7 @@ var SQLiteEventStore = class {
3654
3590
  `SELECT * FROM events WHERE id = ? AND ${maybeQuarantinePredicate(options)}`,
3655
3591
  [id]
3656
3592
  );
3657
- if (!row)
3658
- return null;
3593
+ if (!row) return null;
3659
3594
  return this.rowToEvent(row);
3660
3595
  }
3661
3596
  /**
@@ -3693,10 +3628,8 @@ var SQLiteEventStore = class {
3693
3628
  * NOTE: This bypasses the append() id generation to preserve stable IDs.
3694
3629
  */
3695
3630
  async importEvents(events) {
3696
- if (events.length === 0)
3697
- return { inserted: 0, skipped: 0 };
3698
- if (this.readOnly)
3699
- return { inserted: 0, skipped: events.length };
3631
+ if (events.length === 0) return { inserted: 0, skipped: 0 };
3632
+ if (this.readOnly) return { inserted: 0, skipped: events.length };
3700
3633
  await this.initialize();
3701
3634
  const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);
3702
3635
  const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);
@@ -3814,8 +3747,7 @@ var SQLiteEventStore = class {
3814
3747
  `SELECT * FROM sessions WHERE id = ?`,
3815
3748
  [id]
3816
3749
  );
3817
- if (!row)
3818
- return null;
3750
+ if (!row) return null;
3819
3751
  return {
3820
3752
  id: row.id,
3821
3753
  startedAt: toDateFromSQLite(row.started_at),
@@ -3870,8 +3802,7 @@ var SQLiteEventStore = class {
3870
3802
  LIMIT ?`,
3871
3803
  [limit]
3872
3804
  );
3873
- if (pending.length === 0)
3874
- return [];
3805
+ if (pending.length === 0) return [];
3875
3806
  const ids = pending.map((r) => r.id);
3876
3807
  const placeholders = ids.map(() => "?").join(",");
3877
3808
  sqliteRun(
@@ -3895,8 +3826,7 @@ var SQLiteEventStore = class {
3895
3826
  * Mark outbox items as done
3896
3827
  */
3897
3828
  async completeOutboxItems(ids) {
3898
- if (ids.length === 0)
3899
- return;
3829
+ if (ids.length === 0) return;
3900
3830
  const placeholders = ids.map(() => "?").join(",");
3901
3831
  sqliteRun(
3902
3832
  this.db,
@@ -3935,8 +3865,7 @@ var SQLiteEventStore = class {
3935
3865
  * Mark outbox items as failed
3936
3866
  */
3937
3867
  async failOutboxItems(ids, error) {
3938
- if (ids.length === 0)
3939
- return;
3868
+ if (ids.length === 0) return;
3940
3869
  const placeholders = ids.map(() => "?").join(",");
3941
3870
  sqliteRun(
3942
3871
  this.db,
@@ -4063,8 +3992,7 @@ var SQLiteEventStore = class {
4063
3992
  []
4064
3993
  );
4065
3994
  const sample = (entry) => {
4066
- if (result.samples.length < 20)
4067
- result.samples.push(entry);
3995
+ if (result.samples.length < 20) result.samples.push(entry);
4068
3996
  };
4069
3997
  for (const row of rows) {
4070
3998
  result.scanned++;
@@ -4191,12 +4119,10 @@ var SQLiteEventStore = class {
4191
4119
  `SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`
4192
4120
  );
4193
4121
  const processingAgeMs = (value) => {
4194
- if (value === null || value === void 0)
4195
- return null;
4122
+ if (value === null || value === void 0) return null;
4196
4123
  const date = toDateFromSQLite(value);
4197
4124
  const time = date.getTime();
4198
- if (!Number.isFinite(time))
4199
- return null;
4125
+ if (!Number.isFinite(time)) return null;
4200
4126
  return Math.max(0, now.getTime() - time);
4201
4127
  };
4202
4128
  const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
@@ -4345,8 +4271,7 @@ var SQLiteEventStore = class {
4345
4271
  `SELECT value FROM endless_config WHERE key = ?`,
4346
4272
  [key]
4347
4273
  );
4348
- if (!row)
4349
- return null;
4274
+ if (!row) return null;
4350
4275
  return JSON.parse(row.value);
4351
4276
  }
4352
4277
  /**
@@ -4365,8 +4290,7 @@ var SQLiteEventStore = class {
4365
4290
  * Increment access count for events
4366
4291
  */
4367
4292
  async incrementAccessCount(eventIds) {
4368
- if (eventIds.length === 0 || this.readOnly)
4369
- return;
4293
+ if (eventIds.length === 0 || this.readOnly) return;
4370
4294
  await this.initialize();
4371
4295
  const placeholders = eventIds.map(() => "?").join(",");
4372
4296
  const currentTime = toSQLiteTimestamp(/* @__PURE__ */ new Date());
@@ -4409,8 +4333,7 @@ var SQLiteEventStore = class {
4409
4333
  * Record a memory retrieval for helpfulness tracking
4410
4334
  */
4411
4335
  async recordRetrieval(eventId, sessionId, score, query) {
4412
- if (this.readOnly)
4413
- return;
4336
+ if (this.readOnly) return;
4414
4337
  await this.initialize();
4415
4338
  const id = randomUUID6();
4416
4339
  sqliteRun(
@@ -4440,16 +4363,14 @@ var SQLiteEventStore = class {
4440
4363
  * Called at session end - uses behavioral signals to compute score
4441
4364
  */
4442
4365
  async evaluateSessionHelpfulness(sessionId) {
4443
- if (this.readOnly)
4444
- return;
4366
+ if (this.readOnly) return;
4445
4367
  await this.initialize();
4446
4368
  const retrievals = sqliteAll(
4447
4369
  this.db,
4448
4370
  `SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,
4449
4371
  [sessionId]
4450
4372
  );
4451
- if (retrievals.length === 0)
4452
- return;
4373
+ if (retrievals.length === 0) return;
4453
4374
  const sessionEvents = sqliteAll(
4454
4375
  this.db,
4455
4376
  `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
@@ -4462,8 +4383,7 @@ var SQLiteEventStore = class {
4462
4383
  for (const t of toolEvents) {
4463
4384
  try {
4464
4385
  const content = JSON.parse(t.content);
4465
- if (content.success !== false)
4466
- toolSuccessCount++;
4386
+ if (content.success !== false) toolSuccessCount++;
4467
4387
  } catch {
4468
4388
  toolSuccessCount++;
4469
4389
  }
@@ -4481,8 +4401,7 @@ var SQLiteEventStore = class {
4481
4401
  const pWords = new Set(p.content.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
4482
4402
  let overlap = 0;
4483
4403
  for (const w of queryWords) {
4484
- if (pWords.has(w))
4485
- overlap++;
4404
+ if (pWords.has(w)) overlap++;
4486
4405
  }
4487
4406
  if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {
4488
4407
  wasReasked = 1;
@@ -4664,8 +4583,7 @@ var SQLiteEventStore = class {
4664
4583
  return this.db;
4665
4584
  }
4666
4585
  hasTableColumn(tableName, columnName2) {
4667
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName))
4668
- return false;
4586
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName)) return false;
4669
4587
  try {
4670
4588
  const rows = sqliteAll(this.db, `PRAGMA table_info("${tableName}")`, []);
4671
4589
  return rows.some((row) => row.name === columnName2);
@@ -4732,8 +4650,7 @@ var SQLiteEventStore = class {
4732
4650
  createdAt: toDateFromSQLite(row.created_at)
4733
4651
  }));
4734
4652
  } catch (err) {
4735
- if (err?.message?.includes("no such table"))
4736
- return [];
4653
+ if (err?.message?.includes("no such table")) return [];
4737
4654
  throw err;
4738
4655
  }
4739
4656
  }
@@ -4906,8 +4823,7 @@ var SQLiteEventStore = class {
4906
4823
  `SELECT id FROM events WHERE session_id = ?`,
4907
4824
  [sessionId]
4908
4825
  );
4909
- if (events.length === 0)
4910
- return 0;
4826
+ if (events.length === 0) return 0;
4911
4827
  const eventIds = events.map((e) => e.id);
4912
4828
  const placeholders = eventIds.map(() => "?").join(",");
4913
4829
  const ftsTriggersDropped = [];
@@ -5119,8 +5035,7 @@ function sanitizeGovernanceAuditValue(value, key) {
5119
5035
  return value;
5120
5036
  }
5121
5037
  function sanitizeAuditJson(value) {
5122
- if (value === void 0)
5123
- return void 0;
5038
+ if (value === void 0) return void 0;
5124
5039
  return sanitizeGovernanceAuditValue(value);
5125
5040
  }
5126
5041
  function normalizeSourceEventIds(sourceEventIds) {
@@ -5169,12 +5084,10 @@ async function writeGovernanceAuditEntry(db, input) {
5169
5084
 
5170
5085
  // src/core/operations/facet-repository.ts
5171
5086
  function parseStringArray(value) {
5172
- if (typeof value !== "string")
5173
- return [];
5087
+ if (typeof value !== "string") return [];
5174
5088
  try {
5175
5089
  const parsed = JSON.parse(value);
5176
- if (!Array.isArray(parsed))
5177
- return [];
5090
+ if (!Array.isArray(parsed)) return [];
5178
5091
  return parsed.filter((item) => typeof item === "string" && item.length > 0);
5179
5092
  } catch {
5180
5093
  return [];
@@ -5218,6 +5131,7 @@ var FacetRepository = class {
5218
5131
  constructor(db) {
5219
5132
  this.db = db;
5220
5133
  }
5134
+ db;
5221
5135
  async assign(input) {
5222
5136
  const assignment = parseFacetAssignmentInput(input);
5223
5137
  const existing = this.findByUniqueKey(assignment);
@@ -5522,19 +5436,14 @@ var RetentionFacetSchema = z5.object({
5522
5436
  confidence: z5.number().min(0).max(1).default(1)
5523
5437
  });
5524
5438
  var DateLikeSchema = z5.preprocess((value) => {
5525
- if (value instanceof Date)
5526
- return value;
5527
- if (typeof value === "string" || typeof value === "number")
5528
- return new Date(value);
5439
+ if (value instanceof Date) return value;
5440
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
5529
5441
  return value;
5530
5442
  }, z5.date());
5531
5443
  var NullableDateLikeSchema = z5.preprocess((value) => {
5532
- if (value === null || value === void 0 || value === "")
5533
- return null;
5534
- if (value instanceof Date)
5535
- return value;
5536
- if (typeof value === "string" || typeof value === "number")
5537
- return new Date(value);
5444
+ if (value === null || value === void 0 || value === "") return null;
5445
+ if (value instanceof Date) return value;
5446
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
5538
5447
  return value;
5539
5448
  }, z5.date().nullable());
5540
5449
  var OptionalTrimmedStringSchema2 = z5.preprocess(
@@ -5563,10 +5472,8 @@ import { z as z6 } from "zod";
5563
5472
  var RequiredTrimmedStringSchema = z6.string().trim().min(1);
5564
5473
  var OptionalTrimmedStringSchema3 = z6.string().trim().min(1).optional();
5565
5474
  var DateLikeSchema2 = z6.preprocess((value) => {
5566
- if (value instanceof Date)
5567
- return value;
5568
- if (typeof value === "string" || typeof value === "number")
5569
- return new Date(value);
5475
+ if (value instanceof Date) return value;
5476
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
5570
5477
  return value;
5571
5478
  }, z6.date());
5572
5479
  var RetentionReasonSchema = z6.object({
@@ -5755,8 +5662,7 @@ var MemoryOperationsConfigSchema = z7.object({
5755
5662
  }).default({});
5756
5663
  var MemoryLessonNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
5757
5664
  var MemoryLessonStringArraySchema = z7.preprocess((value) => {
5758
- if (!Array.isArray(value))
5759
- return value;
5665
+ if (!Array.isArray(value)) return value;
5760
5666
  return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
5761
5667
  }, z7.array(MemoryLessonNonEmptyStringSchema)).default([]);
5762
5668
  var MemoryLessonSchema = z7.object({
@@ -5801,14 +5707,12 @@ var ListMemoryLessonsInputSchema = z7.object({
5801
5707
  });
5802
5708
  var PerspectiveMemoryNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
5803
5709
  var PerspectiveMemoryOptionalStringSchema = z7.preprocess((value) => {
5804
- if (typeof value !== "string")
5805
- return value;
5710
+ if (typeof value !== "string") return value;
5806
5711
  const normalized = value.trim();
5807
5712
  return normalized.length > 0 ? normalized : void 0;
5808
5713
  }, PerspectiveMemoryNonEmptyStringSchema.optional());
5809
5714
  var PerspectiveMemoryStringArraySchema = z7.preprocess((value) => {
5810
- if (!Array.isArray(value))
5811
- return value;
5715
+ if (!Array.isArray(value)) return value;
5812
5716
  return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
5813
5717
  }, z7.array(PerspectiveMemoryNonEmptyStringSchema)).default([]);
5814
5718
  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;
@@ -6466,6 +6370,7 @@ var GraphPathService = class {
6466
6370
  constructor(db) {
6467
6371
  this.db = db;
6468
6372
  }
6373
+ db;
6469
6374
  expand(input) {
6470
6375
  const graph = this.loadGraph(input.direction ?? "both");
6471
6376
  const effectiveMaxHops = normalizeMaxHops(input.maxHops);
@@ -6483,11 +6388,9 @@ var GraphPathService = class {
6483
6388
  while (queue.length > 0) {
6484
6389
  queue.sort((a, b) => a.totalCost - b.totalCost || a.hops - b.hops || a.key.localeCompare(b.key));
6485
6390
  const current = queue.shift();
6486
- if (current.hops >= effectiveMaxHops)
6487
- continue;
6391
+ if (current.hops >= effectiveMaxHops) continue;
6488
6392
  for (const edge of graph.adjacency.get(current.key) ?? []) {
6489
- if (current.visited.has(edge.toKey))
6490
- continue;
6393
+ if (current.visited.has(edge.toKey)) continue;
6491
6394
  const nextHops = current.hops + 1;
6492
6395
  const nextTotalCost = current.totalCost + edge.step.cost;
6493
6396
  const nextSteps = [...current.steps, edge.step];
@@ -6567,17 +6470,13 @@ function addTraversal(adjacency, fromKey, edge) {
6567
6470
  adjacency.set(fromKey, edges);
6568
6471
  }
6569
6472
  function normalizeMaxHops(maxHops) {
6570
- if (maxHops === void 0)
6571
- return 1;
6572
- if (!Number.isFinite(maxHops))
6573
- return MAX_HOPS;
6473
+ if (maxHops === void 0) return 1;
6474
+ if (!Number.isFinite(maxHops)) return MAX_HOPS;
6574
6475
  return Math.min(Math.max(0, Math.trunc(maxHops)), MAX_HOPS);
6575
6476
  }
6576
6477
  function normalizeMaxResults(maxResults) {
6577
- if (maxResults === void 0)
6578
- return DEFAULT_MAX_RESULTS;
6579
- if (!Number.isFinite(maxResults))
6580
- return DEFAULT_MAX_RESULTS;
6478
+ if (maxResults === void 0) return DEFAULT_MAX_RESULTS;
6479
+ if (!Number.isFinite(maxResults)) return DEFAULT_MAX_RESULTS;
6581
6480
  return Math.min(Math.max(0, Math.trunc(maxResults)), MAX_RESULTS);
6582
6481
  }
6583
6482
  function isBetterPath(totalCost, hops, signature, existing) {
@@ -6589,18 +6488,15 @@ function pathSignature(steps) {
6589
6488
  function edgeWeight(metaJson) {
6590
6489
  const meta = parseMeta(metaJson);
6591
6490
  const raw = meta.weight;
6592
- if (typeof raw === "number" && Number.isFinite(raw) && raw > 0)
6593
- return raw;
6491
+ if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
6594
6492
  if (typeof raw === "string") {
6595
6493
  const parsed = Number(raw);
6596
- if (Number.isFinite(parsed) && parsed > 0)
6597
- return parsed;
6494
+ if (Number.isFinite(parsed) && parsed > 0) return parsed;
6598
6495
  }
6599
6496
  return DEFAULT_WEIGHT;
6600
6497
  }
6601
6498
  function parseMeta(metaJson) {
6602
- if (!metaJson)
6603
- return {};
6499
+ if (!metaJson) return {};
6604
6500
  try {
6605
6501
  const parsed = JSON.parse(metaJson);
6606
6502
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
@@ -6613,8 +6509,7 @@ function nodeKey(node) {
6613
6509
  }
6614
6510
  function nodeFromKey(key) {
6615
6511
  const index = key.indexOf(":");
6616
- if (index === -1)
6617
- return { type: "entity", id: key };
6512
+ if (index === -1) return { type: "entity", id: key };
6618
6513
  return { type: key.slice(0, index), id: key.slice(index + 1) };
6619
6514
  }
6620
6515
 
@@ -6670,6 +6565,7 @@ var QueryEntityExtractor = class {
6670
6565
  constructor(db) {
6671
6566
  this.db = db;
6672
6567
  }
6568
+ db;
6673
6569
  extract(query, options = {}) {
6674
6570
  const maxCandidates = normalizeMaxCandidates(options.maxCandidates);
6675
6571
  const candidates = [];
@@ -6691,8 +6587,7 @@ var QueryEntityExtractor = class {
6691
6587
  let match;
6692
6588
  while ((match = regex.exec(query)) !== null) {
6693
6589
  const text = cleanCandidateText(match[2] ?? "");
6694
- if (!isUsefulCandidate(text))
6695
- continue;
6590
+ if (!isUsefulCandidate(text)) continue;
6696
6591
  const start = match.index + 1;
6697
6592
  const end = start + text.length;
6698
6593
  ranges.push([match.index, match.index + match[0].length]);
@@ -6706,8 +6601,7 @@ var QueryEntityExtractor = class {
6706
6601
  return ranges;
6707
6602
  }
6708
6603
  extractKnownAliases(query, candidates) {
6709
- if (!this.db)
6710
- return;
6604
+ if (!this.db) return;
6711
6605
  const rows = sqliteAll(
6712
6606
  this.db,
6713
6607
  `SELECT
@@ -6731,11 +6625,9 @@ var QueryEntityExtractor = class {
6731
6625
  ]).filter(isUsefulCandidate);
6732
6626
  for (const alias of aliasLabels) {
6733
6627
  const normalizedAlias = normalizeForContainment(alias);
6734
- if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias))
6735
- continue;
6628
+ if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias)) continue;
6736
6629
  const aliasKey = `${row.entity_id}:${normalizedAlias}`;
6737
- if (seenAliases.has(aliasKey))
6738
- continue;
6630
+ if (seenAliases.has(aliasKey)) continue;
6739
6631
  seenAliases.add(aliasKey);
6740
6632
  const range = findRange(query, alias);
6741
6633
  pushCandidate(candidates, {
@@ -6756,8 +6648,7 @@ var QueryEntityExtractor = class {
6756
6648
  let match;
6757
6649
  while ((match = regex.exec(query)) !== null) {
6758
6650
  const text = cleanCandidateText(match[2] ?? "");
6759
- if (!isUsefulCandidate(text))
6760
- continue;
6651
+ if (!isUsefulCandidate(text)) continue;
6761
6652
  const start = match.index + (match[1]?.length ?? 0);
6762
6653
  pushCandidate(candidates, {
6763
6654
  text,
@@ -6772,8 +6663,7 @@ var QueryEntityExtractor = class {
6772
6663
  let match;
6773
6664
  while ((match = regex.exec(query)) !== null) {
6774
6665
  const text = cleanCandidateText(match[2] ?? "");
6775
- if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./"))
6776
- continue;
6666
+ if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./")) continue;
6777
6667
  const start = match.index + (match[1]?.length ?? 0);
6778
6668
  pushCandidate(candidates, {
6779
6669
  text,
@@ -6792,21 +6682,17 @@ var QueryEntityExtractor = class {
6792
6682
  if (previous && query.slice(previous.end, token.start).match(/^\s+$/)) {
6793
6683
  current.push(token);
6794
6684
  } else {
6795
- if (current.length > 0)
6796
- groups.push(current);
6685
+ if (current.length > 0) groups.push(current);
6797
6686
  current = [token];
6798
6687
  }
6799
6688
  }
6800
- if (current.length > 0)
6801
- groups.push(current);
6689
+ if (current.length > 0) groups.push(current);
6802
6690
  for (const group of groups) {
6803
- if (group.length === 1 && !isStrongSingleCapitalized(group[0].text))
6804
- continue;
6691
+ if (group.length === 1 && !isStrongSingleCapitalized(group[0].text)) continue;
6805
6692
  const start = group[0].start;
6806
6693
  const end = group[group.length - 1].end;
6807
6694
  const text = query.slice(start, end);
6808
- if (!isUsefulCandidate(text))
6809
- continue;
6695
+ if (!isUsefulCandidate(text)) continue;
6810
6696
  pushCandidate(candidates, {
6811
6697
  text,
6812
6698
  source: "capitalized_term",
@@ -6827,8 +6713,7 @@ function collectCapitalizedTokens(query) {
6827
6713
  }
6828
6714
  function pushCandidate(candidates, input) {
6829
6715
  const text = cleanCandidateText(input.text);
6830
- if (!isUsefulCandidate(text))
6831
- return;
6716
+ if (!isUsefulCandidate(text)) return;
6832
6717
  const source = input.source;
6833
6718
  candidates.push({
6834
6719
  ...input,
@@ -6846,15 +6731,13 @@ function dedupeAndSort(candidates) {
6846
6731
  for (const candidate of sorted) {
6847
6732
  if (candidate.source === "entity_alias") {
6848
6733
  const aliasKey = `alias:${candidate.entityId ?? ""}:${normalizeCandidate(candidate.matchedAlias ?? candidate.text)}`;
6849
- if (seenAliasKeys.has(aliasKey))
6850
- continue;
6734
+ if (seenAliasKeys.has(aliasKey)) continue;
6851
6735
  seenAliasKeys.add(aliasKey);
6852
6736
  seenNormalized.add(candidate.normalized);
6853
6737
  result.push(candidate);
6854
6738
  continue;
6855
6739
  }
6856
- if (seenNormalized.has(candidate.normalized))
6857
- continue;
6740
+ if (seenNormalized.has(candidate.normalized)) continue;
6858
6741
  seenNormalized.add(candidate.normalized);
6859
6742
  result.push(candidate);
6860
6743
  }
@@ -6864,8 +6747,7 @@ function compareCandidates(a, b) {
6864
6747
  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 ?? "");
6865
6748
  }
6866
6749
  function compareStrings(a, b) {
6867
- if (a === b)
6868
- return 0;
6750
+ if (a === b) return 0;
6869
6751
  return a < b ? -1 : 1;
6870
6752
  }
6871
6753
  function stripPriority(candidate) {
@@ -6873,10 +6755,8 @@ function stripPriority(candidate) {
6873
6755
  return publicCandidate;
6874
6756
  }
6875
6757
  function normalizeMaxCandidates(maxCandidates) {
6876
- if (maxCandidates === void 0)
6877
- return DEFAULT_MAX_CANDIDATES;
6878
- if (!Number.isFinite(maxCandidates))
6879
- return DEFAULT_MAX_CANDIDATES;
6758
+ if (maxCandidates === void 0) return DEFAULT_MAX_CANDIDATES;
6759
+ if (!Number.isFinite(maxCandidates)) return DEFAULT_MAX_CANDIDATES;
6880
6760
  return Math.min(Math.max(0, Math.trunc(maxCandidates)), MAX_CANDIDATES);
6881
6761
  }
6882
6762
  function cleanCandidateText(text) {
@@ -6898,21 +6778,17 @@ function aliasLabelFromCanonicalKey(canonicalKey) {
6898
6778
  function findRange(query, alias) {
6899
6779
  const normalizedAlias = normalizeForContainment(alias);
6900
6780
  const directIndex = query.toLowerCase().indexOf(alias.toLowerCase());
6901
- if (directIndex >= 0)
6902
- return { start: directIndex, end: directIndex + alias.length };
6781
+ if (directIndex >= 0) return { start: directIndex, end: directIndex + alias.length };
6903
6782
  const normalizedQuery = normalizeForContainment(query);
6904
6783
  const normalizedIndex = normalizedQuery.indexOf(normalizedAlias);
6905
- if (normalizedIndex < 0)
6906
- return { start: 0, end: 0 };
6784
+ if (normalizedIndex < 0) return { start: 0, end: 0 };
6907
6785
  const queryLower = query.toLowerCase();
6908
6786
  const words = normalizedAlias.split(" ").filter(Boolean);
6909
- if (words.length === 0)
6910
- return { start: 0, end: 0 };
6787
+ if (words.length === 0) return { start: 0, end: 0 };
6911
6788
  const first = queryLower.indexOf(words[0]);
6912
6789
  const lastWord = words[words.length - 1];
6913
6790
  const last = queryLower.indexOf(lastWord, first >= 0 ? first : 0);
6914
- if (first >= 0 && last >= 0)
6915
- return { start: first, end: last + lastWord.length };
6791
+ if (first >= 0 && last >= 0) return { start: first, end: last + lastWord.length };
6916
6792
  return { start: normalizedIndex, end: normalizedIndex + normalizedAlias.length };
6917
6793
  }
6918
6794
  function isUsefulCandidate(text) {
@@ -6923,10 +6799,8 @@ function isInsideAnyRange(index, ranges) {
6923
6799
  return ranges.some(([start, end]) => index >= start && index < end);
6924
6800
  }
6925
6801
  function isStrongSingleCapitalized(text) {
6926
- if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text))
6927
- return true;
6928
- if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text))
6929
- return true;
6802
+ if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text)) return true;
6803
+ if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text)) return true;
6930
6804
  return text.length >= 4 && !SENTENCE_START_STOPWORDS.has(text);
6931
6805
  }
6932
6806
  function uniqueStrings(values) {
@@ -6934,8 +6808,7 @@ function uniqueStrings(values) {
6934
6808
  const result = [];
6935
6809
  for (const value of values) {
6936
6810
  const key = normalizeForContainment(value);
6937
- if (!key || seen.has(key))
6938
- continue;
6811
+ if (!key || seen.has(key)) continue;
6939
6812
  seen.add(key);
6940
6813
  result.push(value);
6941
6814
  }
@@ -6957,8 +6830,7 @@ var LessonCandidateInputSchema = z9.object({
6957
6830
  import { z as z10 } from "zod";
6958
6831
  var NonEmptyStringSchema5 = z10.string().transform((value) => value.trim()).pipe(z10.string().min(1));
6959
6832
  var PromotionStringArraySchema = z10.preprocess((value) => {
6960
- if (!Array.isArray(value))
6961
- return value;
6833
+ if (!Array.isArray(value)) return value;
6962
6834
  return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
6963
6835
  }, z10.array(NonEmptyStringSchema5).max(100));
6964
6836
  var ReviewedLessonCandidateSchema = z10.object({
@@ -7006,8 +6878,7 @@ function projectHashFromStorage(projectHash) {
7006
6878
  return projectHash.length > 0 ? projectHash : void 0;
7007
6879
  }
7008
6880
  function parseJsonRecord(value) {
7009
- if (!value)
7010
- return void 0;
6881
+ if (!value) return void 0;
7011
6882
  try {
7012
6883
  const parsed = JSON.parse(value);
7013
6884
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
@@ -7019,8 +6890,7 @@ function sanitizeString(value) {
7019
6890
  return String(sanitizeGovernanceAuditValue(value)).trim();
7020
6891
  }
7021
6892
  function sanitizeMetadata(metadata) {
7022
- if (!metadata)
7023
- return void 0;
6893
+ if (!metadata) return void 0;
7024
6894
  return sanitizeGovernanceAuditValue(metadata);
7025
6895
  }
7026
6896
  function slugActorPart(value) {
@@ -7028,8 +6898,7 @@ function slugActorPart(value) {
7028
6898
  return slug.length > 0 ? slug : "unknown";
7029
6899
  }
7030
6900
  function stableActorId(input) {
7031
- if (input.actorId)
7032
- return sanitizeString(input.actorId);
6901
+ if (input.actorId) return sanitizeString(input.actorId);
7033
6902
  const projectPart = input.projectHash ? `project:${slugActorPart(input.projectHash)}` : "global";
7034
6903
  return [
7035
6904
  "actor",
@@ -7052,12 +6921,10 @@ function rowToActor(row) {
7052
6921
  });
7053
6922
  }
7054
6923
  function metadataString(metadata, keys) {
7055
- if (!metadata)
7056
- return void 0;
6924
+ if (!metadata) return void 0;
7057
6925
  for (const key of keys) {
7058
6926
  const value = metadata[key];
7059
- if (typeof value === "string" && value.trim().length > 0)
7060
- return value.trim();
6927
+ if (typeof value === "string" && value.trim().length > 0) return value.trim();
7061
6928
  }
7062
6929
  return void 0;
7063
6930
  }
@@ -7107,6 +6974,7 @@ var ActorRepository = class {
7107
6974
  constructor(db) {
7108
6975
  this.db = db;
7109
6976
  }
6977
+ db;
7110
6978
  async upsert(input) {
7111
6979
  const parsed = UpsertMemoryActorInputSchema.parse(input);
7112
6980
  const actorId = stableActorId(parsed);
@@ -7160,8 +7028,7 @@ var ActorRepository = class {
7160
7028
  }
7161
7029
  require(actorId) {
7162
7030
  const actor = this.get(actorId);
7163
- if (!actor)
7164
- throw new Error(`Memory actor not found: ${actorId}`);
7031
+ if (!actor) throw new Error(`Memory actor not found: ${actorId}`);
7165
7032
  return actor;
7166
7033
  }
7167
7034
  async list(input = {}) {
@@ -7197,8 +7064,7 @@ function projectHashFromStorage2(projectHash) {
7197
7064
  return projectHash.length > 0 ? projectHash : void 0;
7198
7065
  }
7199
7066
  function parseJsonRecord2(value) {
7200
- if (!value)
7201
- return void 0;
7067
+ if (!value) return void 0;
7202
7068
  try {
7203
7069
  const parsed = JSON.parse(value);
7204
7070
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
@@ -7207,8 +7073,7 @@ function parseJsonRecord2(value) {
7207
7073
  }
7208
7074
  }
7209
7075
  function sanitizeMetadata2(metadata) {
7210
- if (!metadata)
7211
- return void 0;
7076
+ if (!metadata) return void 0;
7212
7077
  return sanitizeGovernanceAuditValue(metadata);
7213
7078
  }
7214
7079
  function rowToSessionActor(row) {
@@ -7228,6 +7093,7 @@ var SessionActorRepository = class {
7228
7093
  constructor(db) {
7229
7094
  this.db = db;
7230
7095
  }
7096
+ db;
7231
7097
  async upsertMembership(input) {
7232
7098
  const parsed = UpsertSessionActorInputSchema.parse(input);
7233
7099
  const projectHash = projectHashToStorage3(parsed.projectHash);
@@ -7274,8 +7140,7 @@ var SessionActorRepository = class {
7274
7140
  );
7275
7141
  }
7276
7142
  const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
7277
- if (!saved)
7278
- throw new Error("session actor membership was not saved");
7143
+ if (!saved) throw new Error("session actor membership was not saved");
7279
7144
  return saved;
7280
7145
  }
7281
7146
  async listBySession(input) {
@@ -7311,8 +7176,7 @@ var SessionActorRepository = class {
7311
7176
  ]
7312
7177
  );
7313
7178
  const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
7314
- if (!saved)
7315
- throw new Error("session actor membership not found after update");
7179
+ if (!saved) throw new Error("session actor membership not found after update");
7316
7180
  return saved;
7317
7181
  }
7318
7182
  get(projectHash, sessionId, actorId) {
@@ -7334,8 +7198,7 @@ function projectHashFromStorage3(projectHash) {
7334
7198
  return projectHash.length > 0 ? projectHash : void 0;
7335
7199
  }
7336
7200
  function parseStringArray2(value) {
7337
- if (!value)
7338
- return [];
7201
+ if (!value) return [];
7339
7202
  try {
7340
7203
  const parsed = JSON.parse(value);
7341
7204
  return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
@@ -7344,8 +7207,7 @@ function parseStringArray2(value) {
7344
7207
  }
7345
7208
  }
7346
7209
  function parseJsonRecord3(value) {
7347
- if (!value)
7348
- return void 0;
7210
+ if (!value) return void 0;
7349
7211
  try {
7350
7212
  const parsed = JSON.parse(value);
7351
7213
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
@@ -7361,8 +7223,7 @@ function sanitizeStoredStringArray(values) {
7361
7223
  return values.map(sanitizeStoredString).filter((value) => value.length > 0);
7362
7224
  }
7363
7225
  function sanitizeStoredRecord(value) {
7364
- if (!value)
7365
- return void 0;
7226
+ if (!value) return void 0;
7366
7227
  return sanitizeGovernanceAuditValue(value);
7367
7228
  }
7368
7229
  function stableHash(value) {
@@ -7413,8 +7274,7 @@ function sanitizedObservationSnapshot(observation) {
7413
7274
  });
7414
7275
  }
7415
7276
  function queryScore(observation, terms) {
7416
- if (terms.length === 0)
7417
- return 0;
7277
+ if (terms.length === 0) return 0;
7418
7278
  const haystack = [observation.content, observation.level, observation.sessionId ?? ""].join(" ").toLowerCase();
7419
7279
  return terms.reduce((score, term) => score + (haystack.includes(term) ? 1 : 0), 0);
7420
7280
  }
@@ -7460,12 +7320,12 @@ var PerspectiveObservationRepository = class {
7460
7320
  this.vectorOutbox = options.vectorOutbox;
7461
7321
  }
7462
7322
  }
7323
+ db;
7463
7324
  vectorOutbox = null;
7464
7325
  vectorOutboxOption;
7465
7326
  getVectorOutbox() {
7466
7327
  const option = this.vectorOutboxOption;
7467
- if (option === false)
7468
- return null;
7328
+ if (option === false) return null;
7469
7329
  if (option instanceof VectorOutbox) {
7470
7330
  this.vectorOutbox = option;
7471
7331
  return option;
@@ -7477,8 +7337,7 @@ var PerspectiveObservationRepository = class {
7477
7337
  }
7478
7338
  enqueueObservationSync(observationId) {
7479
7339
  const outbox = this.getVectorOutbox();
7480
- if (!outbox)
7481
- return;
7340
+ if (!outbox) return;
7482
7341
  outbox.enqueueSync("perspective_observation", observationId);
7483
7342
  }
7484
7343
  async create(input) {
@@ -7540,14 +7399,12 @@ var PerspectiveObservationRepository = class {
7540
7399
  contentHash,
7541
7400
  sourceHash
7542
7401
  );
7543
- if (!saved)
7544
- throw new Error("perspective observation was not saved");
7402
+ if (!saved) throw new Error("perspective observation was not saved");
7545
7403
  this.enqueueObservationSync(saved.observationId);
7546
7404
  });
7547
7405
  transaction();
7548
7406
  const savedObservation = saved;
7549
- if (!savedObservation)
7550
- throw new Error("perspective observation was not saved");
7407
+ if (!savedObservation) throw new Error("perspective observation was not saved");
7551
7408
  await this.writeCreateAudit({ ...parsed, observerActorId, observedActorId, sessionId, content, sourceEventIds, sourceObservationIds, createdBy, actor, metadata }, savedObservation);
7552
7409
  return savedObservation;
7553
7410
  }
@@ -7557,8 +7414,7 @@ var PerspectiveObservationRepository = class {
7557
7414
  const ftsQuery = buildObservationFtsQuery(parsed.query);
7558
7415
  if (ftsQuery) {
7559
7416
  const ftsResult = this.queryWithFts(parsed, ftsQuery);
7560
- if (ftsResult)
7561
- return ftsResult;
7417
+ if (ftsResult) return ftsResult;
7562
7418
  }
7563
7419
  }
7564
7420
  return this.queryWithPrefetch(parsed);
@@ -7579,8 +7435,7 @@ var PerspectiveObservationRepository = class {
7579
7435
  );
7580
7436
  return rows.map(rowToObservation);
7581
7437
  } catch (error) {
7582
- if (isFtsUnavailableError(error))
7583
- return null;
7438
+ if (isFtsUnavailableError(error)) return null;
7584
7439
  throw error;
7585
7440
  }
7586
7441
  }
@@ -7621,8 +7476,7 @@ var PerspectiveObservationRepository = class {
7621
7476
  const parsed = DeletePerspectiveObservationInputSchema.parse(input);
7622
7477
  const projectHash = projectHashToStorage4(parsed.projectHash);
7623
7478
  const before = this.get(projectHash, parsed.observationId);
7624
- if (!before)
7625
- throw new Error("perspective observation not found");
7479
+ if (!before) throw new Error("perspective observation not found");
7626
7480
  const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
7627
7481
  sqliteRun(
7628
7482
  this.db,
@@ -7632,8 +7486,7 @@ var PerspectiveObservationRepository = class {
7632
7486
  [deletedAt, deletedAt, projectHash, parsed.observationId]
7633
7487
  );
7634
7488
  const after = this.get(projectHash, parsed.observationId);
7635
- if (!after)
7636
- throw new Error("perspective observation not found after delete");
7489
+ if (!after) throw new Error("perspective observation not found after delete");
7637
7490
  await writeGovernanceAuditEntry(this.db, {
7638
7491
  operation: "perspective_observation_delete",
7639
7492
  actor: parsed.actor,
@@ -7689,11 +7542,9 @@ var DEFAULT_CONFIG3 = {
7689
7542
  var MAX_OBSERVATION_CONTENT_CHARS = 600;
7690
7543
  var RuleBasedPerspectiveObservationExtractor = class {
7691
7544
  async extract(event) {
7692
- if (!isSupportedSourceEvent(event))
7693
- return [];
7545
+ if (!isSupportedSourceEvent(event)) return [];
7694
7546
  const content = normalizeObservationContent(event.content);
7695
- if (!content)
7696
- return [];
7547
+ if (!content) return [];
7697
7548
  return [{
7698
7549
  content,
7699
7550
  confidence: 0.6,
@@ -7764,8 +7615,7 @@ var PerspectiveDeriver = class {
7764
7615
  for (const candidate of candidates) {
7765
7616
  const observedActorId = candidate.observedActorId ?? sourceActor.actorId;
7766
7617
  const observers = selectObservers(members, observedActorId, this.config.deriver.maxObserversPerSession);
7767
- if (observers.length === 0)
7768
- continue;
7618
+ if (observers.length === 0) continue;
7769
7619
  for (const observerActorId of observers) {
7770
7620
  await this.observations.create({
7771
7621
  projectHash,
@@ -7818,28 +7668,22 @@ function normalizeConfig(config) {
7818
7668
  };
7819
7669
  }
7820
7670
  function clampInteger(value, fallback, min, max) {
7821
- if (!Number.isFinite(value))
7822
- return fallback;
7671
+ if (!Number.isFinite(value)) return fallback;
7823
7672
  return Math.max(min, Math.min(max, Math.trunc(Number(value))));
7824
7673
  }
7825
7674
  function isSupportedSourceEvent(event) {
7826
7675
  return event.eventType === "user_prompt" || event.eventType === "agent_response";
7827
7676
  }
7828
7677
  function roleForEvent(event) {
7829
- if (event.eventType === "user_prompt")
7830
- return "speaker";
7831
- if (event.eventType === "agent_response")
7832
- return "assistant";
7833
- if (event.eventType === "tool_observation")
7834
- return "tool";
7835
- if (event.eventType === "session_summary")
7836
- return "system";
7678
+ if (event.eventType === "user_prompt") return "speaker";
7679
+ if (event.eventType === "agent_response") return "assistant";
7680
+ if (event.eventType === "tool_observation") return "tool";
7681
+ if (event.eventType === "session_summary") return "system";
7837
7682
  return "unknown";
7838
7683
  }
7839
7684
  function normalizeCandidate2(candidate) {
7840
7685
  const content = normalizeObservationContent(candidate.content);
7841
- if (!content)
7842
- return null;
7686
+ if (!content) return null;
7843
7687
  return {
7844
7688
  content,
7845
7689
  confidence: clampNumber(candidate.confidence, 0.6, 0, 1),
@@ -7851,8 +7695,7 @@ function normalizeCandidate2(candidate) {
7851
7695
  }
7852
7696
  function normalizeObservationContent(content) {
7853
7697
  const normalized = content.replace(/\s+/g, " ").trim();
7854
- if (!normalized)
7855
- return null;
7698
+ if (!normalized) return null;
7856
7699
  return normalized.slice(0, MAX_OBSERVATION_CONTENT_CHARS);
7857
7700
  }
7858
7701
  function normalizeOptionalString2(value) {
@@ -7860,13 +7703,11 @@ function normalizeOptionalString2(value) {
7860
7703
  return normalized.length > 0 ? normalized : void 0;
7861
7704
  }
7862
7705
  function clampNumber(value, fallback, min, max) {
7863
- if (!Number.isFinite(value))
7864
- return fallback;
7706
+ if (!Number.isFinite(value)) return fallback;
7865
7707
  return Math.max(min, Math.min(max, Number(value)));
7866
7708
  }
7867
7709
  function sanitizeCandidateMetadata(metadata) {
7868
- if (!metadata)
7869
- return void 0;
7710
+ if (!metadata) return void 0;
7870
7711
  const result = {};
7871
7712
  for (const [key, value] of Object.entries(metadata)) {
7872
7713
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
@@ -7879,12 +7720,9 @@ function selectObservers(members, observedActorId, maxObservers) {
7879
7720
  const selected = [];
7880
7721
  for (const member of members) {
7881
7722
  const canObserve = member.actorId === observedActorId ? member.observeSelf : member.observeOthers;
7882
- if (!canObserve)
7883
- continue;
7884
- if (!selected.includes(member.actorId))
7885
- selected.push(member.actorId);
7886
- if (selected.length >= maxObservers)
7887
- break;
7723
+ if (!canObserve) continue;
7724
+ if (!selected.includes(member.actorId)) selected.push(member.actorId);
7725
+ if (selected.length >= maxObservers) break;
7888
7726
  }
7889
7727
  return selected;
7890
7728
  }
@@ -7903,6 +7741,7 @@ var VectorStore = class {
7903
7741
  constructor(dbPath) {
7904
7742
  this.dbPath = dbPath;
7905
7743
  }
7744
+ dbPath;
7906
7745
  db = null;
7907
7746
  tableCache = /* @__PURE__ */ new Map();
7908
7747
  defaultTableName = "conversations";
@@ -7914,8 +7753,7 @@ var VectorStore = class {
7914
7753
  * conversations table.
7915
7754
  */
7916
7755
  async initialize() {
7917
- if (this.db)
7918
- return;
7756
+ if (this.db) return;
7919
7757
  this.db = await lancedb.connect(this.dbPath);
7920
7758
  }
7921
7759
  /**
@@ -7929,8 +7767,7 @@ var VectorStore = class {
7929
7767
  * Add or update multiple vector records in batch, grouped by inferred table.
7930
7768
  */
7931
7769
  async upsertBatch(records) {
7932
- if (records.length === 0)
7933
- return;
7770
+ if (records.length === 0) return;
7934
7771
  await this.initialize();
7935
7772
  if (!this.db) {
7936
7773
  throw new Error("Database not initialized");
@@ -7985,8 +7822,7 @@ var VectorStore = class {
7985
7822
  async delete(eventId) {
7986
7823
  await this.initialize();
7987
7824
  const table = await this.getExistingTable(this.defaultTableName);
7988
- if (!table)
7989
- return;
7825
+ if (!table) return;
7990
7826
  await table.delete(`eventId = ${toLanceSqlString(eventId)}`);
7991
7827
  }
7992
7828
  /**
@@ -7995,8 +7831,7 @@ var VectorStore = class {
7995
7831
  async count() {
7996
7832
  await this.initialize();
7997
7833
  const table = await this.getExistingTable(this.defaultTableName);
7998
- if (!table)
7999
- return 0;
7834
+ if (!table) return 0;
8000
7835
  const result = await table.countRows();
8001
7836
  return result;
8002
7837
  }
@@ -8005,8 +7840,7 @@ var VectorStore = class {
8005
7840
  */
8006
7841
  async clearAll() {
8007
7842
  await this.initialize();
8008
- if (!this.db)
8009
- return;
7843
+ if (!this.db) return;
8010
7844
  try {
8011
7845
  if (typeof this.db.dropTable === "function") {
8012
7846
  await this.db.dropTable(this.defaultTableName);
@@ -8023,8 +7857,7 @@ var VectorStore = class {
8023
7857
  async exists(eventId) {
8024
7858
  await this.initialize();
8025
7859
  const table = await this.getExistingTable(this.defaultTableName);
8026
- if (!table)
8027
- return false;
7860
+ if (!table) return false;
8028
7861
  const results = await table.search([]).where(`eventId = ${toLanceSqlString(eventId)}`).limit(1).toArray();
8029
7862
  return results.length > 0;
8030
7863
  }
@@ -8059,8 +7892,7 @@ var VectorStore = class {
8059
7892
  throw new Error("Database not initialized");
8060
7893
  }
8061
7894
  const cached = this.tableCache.get(tableName);
8062
- if (cached)
8063
- return cached;
7895
+ if (cached) return cached;
8064
7896
  const tableNames = await this.db.tableNames();
8065
7897
  if (!tableNames.includes(tableName)) {
8066
7898
  return null;
@@ -8139,12 +7971,9 @@ var IngestInterceptorRegistry = class {
8139
7971
  }
8140
7972
  };
8141
7973
  function mergeHierarchicalMetadata(base, patch) {
8142
- if (!base && !patch)
8143
- return void 0;
8144
- if (!base)
8145
- return patch;
8146
- if (!patch)
8147
- return base;
7974
+ if (!base && !patch) return void 0;
7975
+ if (!base) return patch;
7976
+ if (!patch) return base;
8148
7977
  const result = { ...base };
8149
7978
  for (const [key, value] of Object.entries(patch)) {
8150
7979
  const current = result[key];
@@ -8174,33 +8003,26 @@ var VALID_TAG_NAMESPACES = new Set(Object.values(TAG_NAMESPACES));
8174
8003
  function parseTag(tag) {
8175
8004
  const value = (tag || "").trim();
8176
8005
  const idx = value.indexOf(":");
8177
- if (idx <= 0)
8178
- return { value };
8006
+ if (idx <= 0) return { value };
8179
8007
  const namespace = `${value.slice(0, idx)}:`;
8180
8008
  const tagValue = value.slice(idx + 1);
8181
- if (!tagValue)
8182
- return { value };
8009
+ if (!tagValue) return { value };
8183
8010
  return { namespace, value: tagValue };
8184
8011
  }
8185
8012
  function validateTag(tag) {
8186
8013
  const normalized = (tag || "").trim();
8187
- if (!normalized)
8188
- return false;
8014
+ if (!normalized) return false;
8189
8015
  const { namespace } = parseTag(normalized);
8190
- if (!namespace)
8191
- return true;
8016
+ if (!namespace) return true;
8192
8017
  return VALID_TAG_NAMESPACES.has(namespace);
8193
8018
  }
8194
8019
  function normalizeTags(tags) {
8195
- if (!Array.isArray(tags))
8196
- return [];
8020
+ if (!Array.isArray(tags)) return [];
8197
8021
  const dedup = /* @__PURE__ */ new Set();
8198
8022
  for (const item of tags) {
8199
- if (typeof item !== "string")
8200
- continue;
8023
+ if (typeof item !== "string") continue;
8201
8024
  const normalized = item.trim();
8202
- if (!validateTag(normalized))
8203
- continue;
8025
+ if (!validateTag(normalized)) continue;
8204
8026
  dedup.add(normalized);
8205
8027
  }
8206
8028
  return [...dedup];
@@ -8217,10 +8039,8 @@ var SummaryDeriver = class {
8217
8039
  * orchestration, while this class owns summary text and metadata decisions.
8218
8040
  */
8219
8041
  deriveSessionSummary(events) {
8220
- if (events.length < 3)
8221
- return null;
8222
- if (events.some((event) => event.eventType === "session_summary"))
8223
- return null;
8042
+ if (events.length < 3) return null;
8043
+ if (events.some((event) => event.eventType === "session_summary")) return null;
8224
8044
  const prompts = events.filter((event) => event.eventType === "user_prompt");
8225
8045
  const toolObservations = events.filter((event) => event.eventType === "tool_observation");
8226
8046
  const toolNames = Array.from(new Set(
@@ -8368,8 +8188,7 @@ var MemoryIngestService = class {
8368
8188
  await this.initialize();
8369
8189
  const events = await this.eventStore.getSessionEvents(sessionId);
8370
8190
  const summary = this.summaryDeriver.deriveSessionSummary(events);
8371
- if (!summary)
8372
- return;
8191
+ if (!summary) return;
8373
8192
  await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
8374
8193
  }
8375
8194
  async storeToolObservation(sessionId, payload) {
@@ -8437,10 +8256,8 @@ var MemoryIngestService = class {
8437
8256
  }
8438
8257
  }
8439
8258
  async runPerspectiveDeriver(input, eventId, operation) {
8440
- if (!this.perspectiveDeriver)
8441
- return;
8442
- if (operation !== "user_prompt" && operation !== "agent_response")
8443
- return;
8259
+ if (!this.perspectiveDeriver) return;
8260
+ if (operation !== "user_prompt" && operation !== "agent_response") return;
8444
8261
  const event = {
8445
8262
  id: eventId,
8446
8263
  eventType: input.eventType,
@@ -8510,11 +8327,13 @@ var MemoryQueryService = class {
8510
8327
  this.queryStore = queryStore;
8511
8328
  this.deps = deps;
8512
8329
  }
8330
+ initialize;
8331
+ queryStore;
8332
+ deps;
8513
8333
  async keywordSearch(query, options) {
8514
8334
  await this.initialize();
8515
8335
  const results = await this.queryStore.keywordSearch(query, options?.topK ?? 10);
8516
- if (results.length === 0)
8517
- return [];
8336
+ if (results.length === 0) return [];
8518
8337
  const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
8519
8338
  const minRank = Math.max(...results.map((r) => r.rank), -1e3);
8520
8339
  const rankRange = maxRank - minRank || 1;
@@ -8609,6 +8428,18 @@ var COMMAND_ARTIFACT_PATTERNS = [
8609
8428
  /<local-command-stdout>[\s\S]*?<\/local-command-stdout>/i,
8610
8429
  /<local-command-stderr>[\s\S]*?<\/local-command-stderr>/i
8611
8430
  ];
8431
+ var LOW_SIGNAL_CONTEXT_PATTERNS = [
8432
+ /<environment_context\b[\s\S]*<\/environment_context>/i,
8433
+ /<turn_aborted>/i,
8434
+ /^#\s*AGENTS\.md\s+instructions\b[\s\S]*<INSTRUCTIONS>/i,
8435
+ /^\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,
8436
+ /^\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,
8437
+ /^\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,
8438
+ /^\s*---\s*END\s+OF\s+CONTEXT\s+SUMMARY\b/i,
8439
+ /^\s*\[Your\s+active\s+task\s+list\s+was\s+preserved\s+across\s+context\s+compression\]/i,
8440
+ /^➜\s+\S+\s+git:\([^)]*\)\s+/i,
8441
+ /^\$\s+\S+/i
8442
+ ];
8612
8443
  var CONTINUATION_QUERY_PATTERNS = [
8613
8444
  /^\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,
8614
8445
  /^\s*(?:응\s*)?(?:이어서(?:\s*진행(?:해줘)?)?|계속(?:\s*해줘)?|다음\s*(?:단계|작업|추천\s*작업|추천|할\s*일)?(?:은|는)?(?:\s*(?:뭐야|진행(?:해줘)?))?\??|남은\s*(?:추가(?:로)?\s*)?(?:(?:할\s*만한\s*)?(?:작업|일)|할\s*일)?(?:은|는)?\s*(?:있어|있나|있나요|뭐야)\??|추천\s*작업(?:은|는)?(?:\s*뭐야)?\??|진행해줘)\s*$/i
@@ -8620,7 +8451,7 @@ var SHORT_REPAIR_FOLLOW_UP_PATTERNS = [
8620
8451
  var CURRENT_STATE_QUERY_PATTERNS = [
8621
8452
  /\bcurrent\b.*\b(?:state|status|deployment|blocker|pr|pull request)\b/i,
8622
8453
  /\b(?:still|as current|current)\b.*\b(?:unresolved|open|pending|not completed)\b/i,
8623
- /\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|state|status)\b/i,
8454
+ /\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|status)\b/i,
8624
8455
  /(?:현재|아직|이전|오래된|해결된).*(?:상태|미해결|열린|블로커|PR|풀리퀘스트)/i
8625
8456
  ];
8626
8457
  var STALE_CONTENT_PATTERNS = [
@@ -8760,55 +8591,67 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
8760
8591
  ]);
8761
8592
  function isCommandArtifactQuery(query) {
8762
8593
  const trimmed = query.trim();
8763
- if (!trimmed)
8764
- return false;
8594
+ if (!trimmed) return false;
8765
8595
  const normalized = trimmed.toLowerCase();
8766
- if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr"))
8767
- return true;
8768
- if (normalized.includes("command-name") || normalized.includes("command-message"))
8769
- return true;
8596
+ if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
8597
+ if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
8770
8598
  return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
8771
8599
  }
8600
+ function isCommandArtifactContent(content) {
8601
+ const trimmed = content.trim();
8602
+ if (!trimmed) return false;
8603
+ const normalized = trimmed.toLowerCase();
8604
+ if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
8605
+ if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
8606
+ return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
8607
+ }
8608
+ function isLowSignalContextContent(content) {
8609
+ const trimmed = content.trim();
8610
+ if (!trimmed) return true;
8611
+ if (isCommandArtifactContent(trimmed)) return true;
8612
+ if (LOW_SIGNAL_CONTEXT_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
8613
+ return false;
8614
+ }
8772
8615
  function isGenericContinuationQuery(query) {
8773
8616
  const trimmed = query.trim();
8774
- if (!trimmed)
8775
- return false;
8776
- if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed)))
8777
- return false;
8778
- if (extractTechnicalQueryTerms(trimmed).length > 0)
8779
- return false;
8617
+ if (!trimmed) return false;
8618
+ if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
8619
+ if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
8780
8620
  const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
8781
- if (tokens.length > 10)
8782
- return false;
8621
+ if (tokens.length > 10) return false;
8783
8622
  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);
8784
8623
  }
8785
8624
  function isShortRepairFollowUpQuery(query) {
8786
8625
  const trimmed = query.trim();
8787
- if (!trimmed)
8788
- return false;
8789
- if (extractTechnicalQueryTerms(trimmed).length > 0)
8790
- return false;
8626
+ if (!trimmed) return false;
8627
+ if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
8791
8628
  const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
8792
- if (tokens.length > 8)
8793
- return false;
8629
+ if (tokens.length > 8) return false;
8794
8630
  return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
8795
8631
  }
8632
+ function isLowConfidenceContextFallbackQuery(query) {
8633
+ const trimmed = query.trim();
8634
+ if (!trimmed) return false;
8635
+ if (isGenericContinuationQuery(trimmed) || isShortRepairFollowUpQuery(trimmed)) return true;
8636
+ const terms = new Set(tokenizeQualityText(trimmed));
8637
+ if ((terms.has("compacted") || terms.has("compaction")) && terms.has("handoff")) return false;
8638
+ const hasContinuationRecall = /^(?:continue|resume)\b/i.test(trimmed) && (terms.has("work") || terms.has("step") || terms.has("task") || terms.has("last") || terms.has("completed"));
8639
+ 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"));
8640
+ return hasContinuationRecall || hasValidationGateRecall;
8641
+ }
8796
8642
  function isCurrentStateQuery(query) {
8797
8643
  const trimmed = query.trim();
8798
- if (!trimmed)
8799
- return false;
8644
+ if (!trimmed) return false;
8800
8645
  return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
8801
8646
  }
8802
8647
  function isStaleOrSupersededContent(content) {
8803
8648
  const trimmed = content.trim();
8804
- if (!trimmed)
8805
- return false;
8649
+ if (!trimmed) return false;
8806
8650
  return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
8807
8651
  }
8808
8652
  function buildRetrievalQualityQuery(query) {
8809
8653
  const trimmed = query.trim();
8810
- if (!trimmed)
8811
- return query;
8654
+ if (!trimmed) return query;
8812
8655
  if (isRetrievalPrivacyDecisionQuery(trimmed)) {
8813
8656
  return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
8814
8657
  }
@@ -8822,12 +8665,10 @@ function buildRetrievalQualityQuery(query) {
8822
8665
  }
8823
8666
  function isRetrievalPrivacyDecisionQuery(query) {
8824
8667
  const trimmed = query.trim();
8825
- if (!trimmed)
8826
- return false;
8668
+ if (!trimmed) return false;
8827
8669
  const terms = new Set(tokenizeQualityText(trimmed));
8828
8670
  const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
8829
- if (!hasDecisionSignal)
8830
- return false;
8671
+ if (!hasDecisionSignal) return false;
8831
8672
  const hasRawQuerySignal = terms.has("raw") && terms.has("query");
8832
8673
  const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
8833
8674
  const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
@@ -8840,16 +8681,14 @@ function extractTechnicalQueryTerms(query) {
8840
8681
  const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
8841
8682
  const terms = matches.filter((term) => {
8842
8683
  const lower = term.toLowerCase();
8843
- if (GENERIC_TECHNICAL_TERMS.has(lower))
8844
- return false;
8684
+ if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
8845
8685
  return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
8846
8686
  });
8847
8687
  return Array.from(new Set(terms.map((term) => term.toLowerCase())));
8848
8688
  }
8849
8689
  function hasTechnicalTermOverlap(query, content) {
8850
8690
  const terms = extractTechnicalQueryTerms(query);
8851
- if (terms.length === 0)
8852
- return true;
8691
+ if (terms.length === 0) return true;
8853
8692
  const normalizedContent = content.toLowerCase();
8854
8693
  return terms.some((term) => normalizedContent.includes(term));
8855
8694
  }
@@ -8865,15 +8704,12 @@ function hasDiscriminativeTermOverlap(query, content) {
8865
8704
  return topicTerms.some((term) => contentTerms.has(term));
8866
8705
  }
8867
8706
  }
8868
- if (queryTerms.length < 3)
8869
- return true;
8707
+ if (queryTerms.length < 3) return true;
8870
8708
  const requiredHits = queryTerms.length >= 3 ? 2 : 1;
8871
8709
  let hits = 0;
8872
8710
  for (const term of queryTerms) {
8873
- if (contentTerms.has(term))
8874
- hits += 1;
8875
- if (hits >= requiredHits)
8876
- return true;
8711
+ if (contentTerms.has(term)) hits += 1;
8712
+ if (hits >= requiredHits) return true;
8877
8713
  }
8878
8714
  return false;
8879
8715
  }
@@ -8883,17 +8719,14 @@ function shouldApplyTechnicalGuard(query) {
8883
8719
  function hasAnyTerm(terms, expectedTerms) {
8884
8720
  let found = false;
8885
8721
  expectedTerms.forEach((term) => {
8886
- if (terms.has(term))
8887
- found = true;
8722
+ if (terms.has(term)) found = true;
8888
8723
  });
8889
8724
  return found;
8890
8725
  }
8891
8726
  function shouldRequireDecisionTopicOverlap(query) {
8892
- if (isRetrievalPrivacyDecisionQuery(query))
8893
- return false;
8727
+ if (isRetrievalPrivacyDecisionQuery(query)) return false;
8894
8728
  const trimmed = query.trim();
8895
- if (!trimmed)
8896
- return false;
8729
+ if (!trimmed) return false;
8897
8730
  const terms = new Set(tokenizeQualityText(trimmed));
8898
8731
  return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
8899
8732
  }
@@ -8901,12 +8734,9 @@ function extractDiscriminativeQueryTerms(query) {
8901
8734
  const seen = /* @__PURE__ */ new Set();
8902
8735
  const terms = [];
8903
8736
  for (const token of tokenizeQualityText(query)) {
8904
- if (LOW_INFORMATION_QUERY_TERMS.has(token))
8905
- continue;
8906
- if (GENERIC_TECHNICAL_TERMS.has(token))
8907
- continue;
8908
- if (seen.has(token))
8909
- continue;
8737
+ if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
8738
+ if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
8739
+ if (seen.has(token)) continue;
8910
8740
  seen.add(token);
8911
8741
  terms.push(token);
8912
8742
  }
@@ -8921,14 +8751,10 @@ function tokenizeQualityText(text) {
8921
8751
  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);
8922
8752
  }
8923
8753
  function normalizeQualityToken(token) {
8924
- if (token === "apis")
8925
- return "api";
8926
- if (token === "ids")
8927
- return "id";
8928
- if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token))
8929
- return token;
8930
- if (token.length > 4 && token.endsWith("ies"))
8931
- return `${token.slice(0, -3)}y`;
8754
+ if (token === "apis") return "api";
8755
+ if (token === "ids") return "id";
8756
+ if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
8757
+ if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
8932
8758
  if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
8933
8759
  return token.slice(0, -1);
8934
8760
  }
@@ -9080,7 +8906,14 @@ var Retriever = class {
9080
8906
  };
9081
8907
  fallbackTrace.push("fallback:summary");
9082
8908
  }
9083
- const memories = await this.enrichResults(current.results.slice(0, opts.topK), opts);
8909
+ const selectedResults = current.results.slice(0, opts.topK).filter((result) => {
8910
+ if (current.matchResult.confidence !== "none") return true;
8911
+ if (isLowConfidenceContextFallbackQuery(query)) {
8912
+ return (result.semanticScore ?? result.score) >= 0.5 || result.score >= 0.5;
8913
+ }
8914
+ return (result.semanticScore ?? result.score) >= 0.62 || result.score >= 0.62;
8915
+ });
8916
+ const memories = await this.enrichResults(selectedResults, opts, query);
9084
8917
  const context = this.buildContext(memories, opts.maxTokens);
9085
8918
  return {
9086
8919
  memories,
@@ -9088,7 +8921,7 @@ var Retriever = class {
9088
8921
  totalTokens: this.estimateTokens(context),
9089
8922
  context,
9090
8923
  fallbackTrace,
9091
- selectedDebug: current.results.slice(0, opts.topK).map((r) => this.debugDetailForResult(r)),
8924
+ selectedDebug: selectedResults.map((r) => this.debugDetailForResult(r)),
9092
8925
  candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r) => this.debugDetailForResult(r)),
9093
8926
  rawQueryText: current.queryRewriteKind ? query : void 0,
9094
8927
  effectiveQueryText: current.effectiveQueryText,
@@ -9110,8 +8943,7 @@ var Retriever = class {
9110
8943
  const sharedMemories = [];
9111
8944
  for (const result of sharedVectorResults) {
9112
8945
  const entry = await this.sharedStore.get(result.entryId);
9113
- if (!entry)
9114
- continue;
8946
+ if (!entry) continue;
9115
8947
  if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
9116
8948
  sharedMemories.push(entry);
9117
8949
  await this.sharedStore.recordUsage(entry.entryId);
@@ -9184,6 +9016,7 @@ var Retriever = class {
9184
9016
  if (isCurrentStateQuery(options.query)) {
9185
9017
  filtered = filtered.filter((result) => !isStaleOrSupersededContent(result.content));
9186
9018
  }
9019
+ filtered = filtered.filter((result) => !isLowSignalContextContent(result.content));
9187
9020
  filtered = filtered.filter(
9188
9021
  (result) => this.isGraphPathResult(result) || hasDiscriminativeTermOverlap(options.query, result.content)
9189
9022
  );
@@ -9192,18 +9025,15 @@ var Retriever = class {
9192
9025
  (result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
9193
9026
  );
9194
9027
  }
9195
- if (filtered.length <= 2)
9196
- return filtered;
9028
+ if (filtered.length <= 2) return filtered;
9197
9029
  const topScore = filtered[0].score;
9198
- if (topScore < 0.8)
9199
- return filtered;
9030
+ if (topScore < 0.8) return filtered;
9200
9031
  const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
9201
9032
  return filtered.filter((result) => result.score >= cliffThreshold);
9202
9033
  }
9203
9034
  mergeResults(primary, secondary, limit) {
9204
9035
  const byId = /* @__PURE__ */ new Map();
9205
- for (const row of primary)
9206
- byId.set(row.eventId, row);
9036
+ for (const row of primary) byId.set(row.eventId, row);
9207
9037
  for (const row of secondary) {
9208
9038
  const prev = byId.get(row.eventId);
9209
9039
  if (!prev || row.score > prev.score) {
@@ -9214,23 +9044,19 @@ var Retriever = class {
9214
9044
  }
9215
9045
  async expandGraphHops(seeds, opts) {
9216
9046
  const byId = /* @__PURE__ */ new Map();
9217
- for (const s of seeds)
9218
- byId.set(s.eventId, s);
9047
+ for (const s of seeds) byId.set(s.eventId, s);
9219
9048
  let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
9220
9049
  for (let hop = 1; hop <= opts.maxHops; hop += 1) {
9221
9050
  const next = [];
9222
9051
  for (const f of frontier) {
9223
9052
  const ev = await this.eventStore.getEvent(f.row.eventId);
9224
- if (!ev)
9225
- continue;
9053
+ if (!ev) continue;
9226
9054
  const rel = ev.metadata?.relatedEventIds ?? [];
9227
9055
  const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
9228
9056
  for (const rid of relatedIds) {
9229
- if (byId.has(rid))
9230
- continue;
9057
+ if (byId.has(rid)) continue;
9231
9058
  const target = await this.eventStore.getEvent(rid);
9232
- if (!target)
9233
- continue;
9059
+ if (!target) continue;
9234
9060
  const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
9235
9061
  const row = {
9236
9062
  id: `hop-${hop}-${rid}`,
@@ -9244,15 +9070,12 @@ var Retriever = class {
9244
9070
  };
9245
9071
  byId.set(row.eventId, row);
9246
9072
  next.push({ row, hop });
9247
- if (byId.size >= opts.limit)
9248
- break;
9073
+ if (byId.size >= opts.limit) break;
9249
9074
  }
9250
- if (byId.size >= opts.limit)
9251
- break;
9075
+ if (byId.size >= opts.limit) break;
9252
9076
  }
9253
9077
  frontier = next;
9254
- if (frontier.length === 0 || byId.size >= opts.limit)
9255
- break;
9078
+ if (frontier.length === 0 || byId.size >= opts.limit) break;
9256
9079
  }
9257
9080
  if (opts.queryGraphEnabled) {
9258
9081
  await this.expandQueryGraphPaths(opts.query, byId, opts);
@@ -9260,8 +9083,7 @@ var Retriever = class {
9260
9083
  return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9261
9084
  }
9262
9085
  async expandQueryGraphPaths(query, byId, opts) {
9263
- if (!query.trim() || !this.eventStore.getDatabase)
9264
- return;
9086
+ if (!query.trim() || !this.eventStore.getDatabase) return;
9265
9087
  try {
9266
9088
  const db = this.eventStore.getDatabase();
9267
9089
  const extraction = new QueryEntityExtractor(db).extract(query, {
@@ -9270,8 +9092,7 @@ var Retriever = class {
9270
9092
  });
9271
9093
  const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
9272
9094
  const startNodes = uniqueEntityStartNodes(startCandidates);
9273
- if (startNodes.length === 0)
9274
- return;
9095
+ if (startNodes.length === 0) return;
9275
9096
  const expansion = new GraphPathService(db).expand({
9276
9097
  startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
9277
9098
  maxHops: opts.maxHops,
@@ -9280,11 +9101,9 @@ var Retriever = class {
9280
9101
  });
9281
9102
  const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
9282
9103
  for (const path14 of expansion.paths) {
9283
- if (path14.target.type !== "event")
9284
- continue;
9104
+ if (path14.target.type !== "event") continue;
9285
9105
  const target = await this.eventStore.getEvent(path14.target.id);
9286
- if (!target)
9287
- continue;
9106
+ if (!target) continue;
9288
9107
  const graphPath = toRetrievalGraphPathDebug(path14, titleByEntityId);
9289
9108
  const score = graphPathScore(path14, opts.hopPenalty);
9290
9109
  const existing = byId.get(target.id);
@@ -9310,17 +9129,14 @@ var Retriever = class {
9310
9129
  lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
9311
9130
  };
9312
9131
  byId.set(row.eventId, row);
9313
- if (byId.size >= opts.limit)
9314
- break;
9132
+ if (byId.size >= opts.limit) break;
9315
9133
  }
9316
9134
  } catch {
9317
9135
  }
9318
9136
  }
9319
9137
  shouldFallback(matchResult, results) {
9320
- if (results.length === 0)
9321
- return true;
9322
- if (matchResult.confidence === "none")
9323
- return true;
9138
+ if (results.length === 0) return true;
9139
+ if (matchResult.confidence === "none") return true;
9324
9140
  return false;
9325
9141
  }
9326
9142
  async buildSummaryFallback(query, topK) {
@@ -9425,29 +9241,21 @@ var Retriever = class {
9425
9241
  (value) => typeof value === "string" && value.length > 0
9426
9242
  )
9427
9243
  );
9428
- if (!scope && projectScopeMode === "global" && facetFilters === null)
9429
- return results;
9244
+ if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
9430
9245
  const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
9431
9246
  const filtered = [];
9432
9247
  for (const result of results) {
9433
- if (scope?.sessionId && result.sessionId !== scope.sessionId)
9434
- continue;
9435
- if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix))
9436
- continue;
9437
- if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType))
9438
- continue;
9248
+ if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
9249
+ if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
9250
+ if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
9439
9251
  const event = await this.eventStore.getEvent(result.eventId);
9440
- if (!event)
9441
- continue;
9442
- if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
9443
- continue;
9252
+ if (!event) continue;
9253
+ if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
9444
9254
  if (normalizedIncludes.length > 0) {
9445
9255
  const lc = event.content.toLowerCase();
9446
- if (!normalizedIncludes.some((needle) => lc.includes(needle)))
9447
- continue;
9256
+ if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
9448
9257
  }
9449
- if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
9450
- continue;
9258
+ if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
9451
9259
  const projectHash = this.extractProjectHash(event.metadata);
9452
9260
  filtered.push({ result, projectHash });
9453
9261
  }
@@ -9464,27 +9272,21 @@ var Retriever = class {
9464
9272
  });
9465
9273
  }
9466
9274
  normalizeFacetFilters(facets) {
9467
- if (!facets || facets.length === 0)
9468
- return null;
9275
+ if (!facets || facets.length === 0) return null;
9469
9276
  const normalized = [];
9470
9277
  for (const facet of facets) {
9471
9278
  const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
9472
9279
  const value = typeof facet.value === "string" ? facet.value.trim() : "";
9473
- if (!parsedDimension.success || !value)
9474
- return [];
9280
+ if (!parsedDimension.success || !value) return [];
9475
9281
  normalized.push({ dimension: parsedDimension.data, value });
9476
9282
  }
9477
9283
  return normalized;
9478
9284
  }
9479
9285
  async applyFacetFilters(results, options) {
9480
- if (options.facets === null)
9481
- return results;
9482
- if (options.facets.length === 0)
9483
- return [];
9484
- if (!options.projectHash)
9485
- return [];
9486
- if (!this.eventStore.getDatabase)
9487
- return [];
9286
+ if (options.facets === null) return results;
9287
+ if (options.facets.length === 0) return [];
9288
+ if (!options.projectHash) return [];
9289
+ if (!this.eventStore.getDatabase) return [];
9488
9290
  const repo = new FacetRepository(this.eventStore.getDatabase());
9489
9291
  const filtered = [];
9490
9292
  for (const result of results) {
@@ -9541,14 +9343,11 @@ var Retriever = class {
9541
9343
  return (result.graphPaths || []).length > 0;
9542
9344
  }
9543
9345
  extractProjectHash(metadata) {
9544
- if (!metadata || typeof metadata !== "object")
9545
- return void 0;
9346
+ if (!metadata || typeof metadata !== "object") return void 0;
9546
9347
  const scope = metadata.scope;
9547
- if (!scope || typeof scope !== "object")
9548
- return void 0;
9348
+ if (!scope || typeof scope !== "object") return void 0;
9549
9349
  const project = scope.project;
9550
- if (!project || typeof project !== "object")
9551
- return void 0;
9350
+ if (!project || typeof project !== "object") return void 0;
9552
9351
  const hash = project.hash;
9553
9352
  return typeof hash === "string" && hash.length > 0 ? hash : void 0;
9554
9353
  }
@@ -9558,52 +9357,48 @@ var Retriever = class {
9558
9357
  async retrieveRecent(limit = 100) {
9559
9358
  return this.eventStore.getRecentEvents(limit);
9560
9359
  }
9561
- async enrichResults(results, options) {
9360
+ async enrichResults(results, options, query) {
9562
9361
  const memories = [];
9563
9362
  for (const result of results) {
9564
9363
  const event = await this.eventStore.getEvent(result.eventId);
9565
- if (!event)
9566
- continue;
9364
+ if (!event) continue;
9567
9365
  if (this.graduation) {
9568
9366
  this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
9569
9367
  }
9570
9368
  let sessionContext;
9571
9369
  if (options.includeSessionContext) {
9572
- sessionContext = await this.getSessionContext(event.sessionId, event.id);
9370
+ sessionContext = await this.getSessionContext(event.sessionId, event.id, query);
9573
9371
  }
9574
9372
  memories.push({ event, score: result.score, sessionContext });
9575
9373
  }
9576
9374
  return memories;
9577
9375
  }
9578
- async getSessionContext(sessionId, eventId) {
9376
+ async getSessionContext(sessionId, eventId, query) {
9579
9377
  const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9580
9378
  const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
9581
- if (eventIndex === -1)
9582
- return void 0;
9379
+ if (eventIndex === -1) return void 0;
9583
9380
  const start = Math.max(0, eventIndex - 1);
9584
9381
  const end = Math.min(sessionEvents.length, eventIndex + 2);
9585
9382
  const contextEvents = sessionEvents.slice(start, end);
9586
- if (contextEvents.length <= 1)
9587
- return void 0;
9588
- return contextEvents.filter((e) => e.id !== eventId).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`).join("\n");
9383
+ if (contextEvents.length <= 1) return void 0;
9384
+ const suppressStaleState = isCurrentStateQuery(query);
9385
+ 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)}...`);
9386
+ return contextLines.length > 0 ? contextLines.join("\n") : void 0;
9589
9387
  }
9590
9388
  buildUnifiedContext(projectResult, sharedMemories) {
9591
9389
  let context = projectResult.context;
9592
- if (sharedMemories.length === 0)
9593
- return context;
9390
+ if (sharedMemories.length === 0) return context;
9594
9391
  context += "\n\n## Cross-Project Knowledge\n\n";
9595
9392
  for (const memory of sharedMemories.slice(0, 3)) {
9596
9393
  context += `### ${memory.title}
9597
9394
  `;
9598
- if (memory.symptoms.length > 0)
9599
- context += `**Symptoms:** ${memory.symptoms.join(", ")}
9395
+ if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
9600
9396
  `;
9601
9397
  context += `**Root Cause:** ${memory.rootCause}
9602
9398
  `;
9603
9399
  context += `**Solution:** ${memory.solution}
9604
9400
  `;
9605
- if (memory.technologies && memory.technologies.length > 0)
9606
- context += `**Technologies:** ${memory.technologies.join(", ")}
9401
+ if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
9607
9402
  `;
9608
9403
  context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
9609
9404
 
@@ -9617,13 +9412,11 @@ var Retriever = class {
9617
9412
  for (const memory of memories) {
9618
9413
  const memoryText = this.formatMemory(memory);
9619
9414
  const memoryTokens = this.estimateTokens(memoryText);
9620
- if (currentTokens + memoryTokens > maxTokens)
9621
- break;
9415
+ if (currentTokens + memoryTokens > maxTokens) break;
9622
9416
  parts.push(memoryText);
9623
9417
  currentTokens += memoryTokens;
9624
9418
  }
9625
- if (parts.length === 0)
9626
- return "";
9419
+ if (parts.length === 0) return "";
9627
9420
  return `## Relevant Memories
9628
9421
 
9629
9422
  ${parts.join("\n\n---\n\n")}`;
@@ -9633,19 +9426,16 @@ ${parts.join("\n\n---\n\n")}`;
9633
9426
  const date = event.timestamp.toISOString().split("T")[0];
9634
9427
  let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
9635
9428
  ${event.content}`;
9636
- if (sessionContext)
9637
- text += `
9429
+ if (sessionContext) text += `
9638
9430
 
9639
9431
  _Context:_ ${sessionContext}`;
9640
9432
  return text;
9641
9433
  }
9642
9434
  matchesMetadataScope(metadata, expected) {
9643
- if (!metadata)
9644
- return false;
9435
+ if (!metadata) return false;
9645
9436
  return Object.entries(expected).every(([path14, value]) => {
9646
9437
  const actual = path14.split(".").reduce((acc, key) => {
9647
- if (typeof acc !== "object" || acc === null)
9648
- return void 0;
9438
+ if (typeof acc !== "object" || acc === null) return void 0;
9649
9439
  return acc[key];
9650
9440
  }, metadata);
9651
9441
  return actual === value;
@@ -9655,27 +9445,20 @@ _Context:_ ${sessionContext}`;
9655
9445
  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);
9656
9446
  }
9657
9447
  normalizeToken(token) {
9658
- if (token === "apis")
9659
- return "api";
9660
- if (token === "ids")
9661
- return "id";
9662
- if (token === "does")
9663
- return token;
9664
- if (token.length > 4 && token.endsWith("ies"))
9665
- return `${token.slice(0, -3)}y`;
9448
+ if (token === "apis") return "api";
9449
+ if (token === "ids") return "id";
9450
+ if (token === "does") return token;
9451
+ if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
9666
9452
  if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
9667
9453
  return token.slice(0, -1);
9668
9454
  }
9669
9455
  return token;
9670
9456
  }
9671
9457
  keywordOverlap(a, b) {
9672
- if (a.length === 0 || b.length === 0)
9673
- return 0;
9458
+ if (a.length === 0 || b.length === 0) return 0;
9674
9459
  const bs = new Set(b);
9675
9460
  let hit = 0;
9676
- for (const t of a)
9677
- if (bs.has(t))
9678
- hit += 1;
9461
+ for (const t of a) if (bs.has(t)) hit += 1;
9679
9462
  return hit / a.length;
9680
9463
  }
9681
9464
  estimateTokens(text) {
@@ -9696,8 +9479,7 @@ function uniqueEntityStartNodes(candidates) {
9696
9479
  const seen = /* @__PURE__ */ new Set();
9697
9480
  const nodes = [];
9698
9481
  for (const candidate of candidates) {
9699
- if (!candidate.entityId || seen.has(candidate.entityId))
9700
- continue;
9482
+ if (!candidate.entityId || seen.has(candidate.entityId)) continue;
9701
9483
  seen.add(candidate.entityId);
9702
9484
  nodes.push({ entityId: candidate.entityId, title: candidate.text });
9703
9485
  }
@@ -9721,16 +9503,14 @@ function graphPathScore(path14, hopPenalty) {
9721
9503
  return Math.max(0.05, base - hopPenalty * Math.max(0, path14.hops - 1));
9722
9504
  }
9723
9505
  function clampGraphHops(maxHops) {
9724
- if (!Number.isFinite(maxHops))
9725
- return 2;
9506
+ if (!Number.isFinite(maxHops)) return 2;
9726
9507
  return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
9727
9508
  }
9728
9509
  function mergeGraphPaths(existing, incoming) {
9729
9510
  const byKey = /* @__PURE__ */ new Map();
9730
9511
  for (const path14 of [...existing, ...incoming]) {
9731
9512
  const key = [path14.startEntityId, path14.targetType, path14.targetId, path14.hops, ...path14.relationPath].join("\0");
9732
- if (!byKey.has(key))
9733
- byKey.set(key, path14);
9513
+ if (!byKey.has(key)) byKey.set(key, path14);
9734
9514
  }
9735
9515
  return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
9736
9516
  }
@@ -9738,10 +9518,8 @@ function graphPathSignature(path14) {
9738
9518
  return [path14.startEntityId, path14.targetType, path14.targetId, path14.hops, ...path14.relationPath].join("|");
9739
9519
  }
9740
9520
  function compareStable(a, b) {
9741
- if (a < b)
9742
- return -1;
9743
- if (a > b)
9744
- return 1;
9521
+ if (a < b) return -1;
9522
+ if (a > b) return 1;
9745
9523
  return 0;
9746
9524
  }
9747
9525
  function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
@@ -9753,6 +9531,7 @@ var RetrievalAnalyticsService = class {
9753
9531
  constructor(deps) {
9754
9532
  this.deps = deps;
9755
9533
  }
9534
+ deps;
9756
9535
  async getRetrievalTraceStats() {
9757
9536
  await this.deps.initialize();
9758
9537
  return this.deps.retrievalStore.getRetrievalTraceStats();
@@ -9830,6 +9609,7 @@ var RetrievalDisclosureService = class {
9830
9609
  constructor(deps) {
9831
9610
  this.deps = deps;
9832
9611
  }
9612
+ deps;
9833
9613
  async search(query, options) {
9834
9614
  const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
9835
9615
  const debugByEventId = this.buildDebugIndex(result);
@@ -9859,8 +9639,7 @@ var RetrievalDisclosureService = class {
9859
9639
  return this.expandShared(parsedId.entryId);
9860
9640
  }
9861
9641
  const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
9862
- if (!targetEvent)
9863
- return null;
9642
+ if (!targetEvent) return null;
9864
9643
  const windowSize = Math.max(0, options?.windowSize ?? 3);
9865
9644
  const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
9866
9645
  const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
@@ -9884,8 +9663,7 @@ var RetrievalDisclosureService = class {
9884
9663
  return this.sourceShared(parsedId.entryId);
9885
9664
  }
9886
9665
  const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
9887
- if (!rawEvent)
9888
- return null;
9666
+ if (!rawEvent) return null;
9889
9667
  return {
9890
9668
  ...this.sourceReferenceForEvent(rawEvent),
9891
9669
  rawEvents: [rawEvent],
@@ -9894,8 +9672,7 @@ var RetrievalDisclosureService = class {
9894
9672
  }
9895
9673
  async expandShared(entryId) {
9896
9674
  const entry = await this.deps.sharedStore?.get(entryId);
9897
- if (!entry)
9898
- return null;
9675
+ if (!entry) return null;
9899
9676
  return {
9900
9677
  target: this.sharedToEnvelope(entry),
9901
9678
  surroundingFacts: [],
@@ -9906,8 +9683,7 @@ var RetrievalDisclosureService = class {
9906
9683
  }
9907
9684
  async sourceShared(entryId) {
9908
9685
  const entry = await this.deps.sharedStore?.get(entryId);
9909
- if (!entry)
9910
- return null;
9686
+ if (!entry) return null;
9911
9687
  const sourceReference = this.sourceReferenceForShared(entry);
9912
9688
  return {
9913
9689
  ...sourceReference,
@@ -9993,38 +9769,25 @@ var RetrievalDisclosureService = class {
9993
9769
  const reasons = /* @__PURE__ */ new Set();
9994
9770
  const usedVector = this.usedVector(result);
9995
9771
  const usedKeyword = this.usedKeyword(result);
9996
- if (usedVector && (debug?.semanticScore ?? 0) > 0)
9997
- reasons.add("semantic_match");
9998
- if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword)
9999
- reasons.add("keyword_match");
10000
- if ((debug?.recencyScore ?? 0) > 0)
10001
- reasons.add("recent_relevance");
10002
- if ((debug?.facetMatches || []).length > 0)
10003
- reasons.add("facet_match");
10004
- if ((debug?.graphPaths || []).length > 0)
10005
- reasons.add("entity_overlap");
10006
- if ((result.fallbackTrace || []).some((step) => step === "fallback:summary"))
10007
- reasons.add("summary_fallback");
10008
- if (memory.sessionContext)
10009
- reasons.add("continuity_link");
10010
- if (memory.event.eventType === "tool_observation")
10011
- reasons.add("tool_followup");
10012
- if (reasons.size === 0)
10013
- reasons.add(usedVector ? "semantic_match" : "keyword_match");
9772
+ if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
9773
+ if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
9774
+ if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
9775
+ if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
9776
+ if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
9777
+ if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
9778
+ if (memory.sessionContext) reasons.add("continuity_link");
9779
+ if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
9780
+ if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
10014
9781
  return Array.from(reasons);
10015
9782
  }
10016
9783
  reasonsForContextEvent(event) {
10017
- if (event.eventType === "tool_observation")
10018
- return ["tool_followup"];
10019
- if (event.eventType === "session_summary")
10020
- return ["summary_fallback"];
9784
+ if (event.eventType === "tool_observation") return ["tool_followup"];
9785
+ if (event.eventType === "session_summary") return ["summary_fallback"];
10021
9786
  return ["continuity_link"];
10022
9787
  }
10023
9788
  resultTypeForEvent(event) {
10024
- if (event.eventType === "session_summary")
10025
- return "summary";
10026
- if (event.eventType === "tool_observation")
10027
- return "tool_evidence";
9789
+ if (event.eventType === "session_summary") return "summary";
9790
+ if (event.eventType === "tool_observation") return "tool_evidence";
10028
9791
  return "source";
10029
9792
  }
10030
9793
  sourceReferenceForEvent(event) {
@@ -10048,21 +9811,15 @@ var RetrievalDisclosureService = class {
10048
9811
  }
10049
9812
  sourceTypeForEvent(event) {
10050
9813
  const metadata = event.metadata || {};
10051
- if (event.eventType === "tool_observation")
10052
- return "tool_output";
10053
- if (typeof metadata.transcriptPath === "string")
10054
- return "transcript";
10055
- if (typeof metadata.importedFrom === "string")
10056
- return "imported_history";
9814
+ if (event.eventType === "tool_observation") return "tool_output";
9815
+ if (typeof metadata.transcriptPath === "string") return "transcript";
9816
+ if (typeof metadata.importedFrom === "string") return "imported_history";
10057
9817
  return "raw_event";
10058
9818
  }
10059
9819
  titleForEvent(event) {
10060
- if (event.eventType === "session_summary")
10061
- return "Session summary";
10062
- if (event.eventType === "tool_observation")
10063
- return "Tool evidence";
10064
- if (event.eventType === "agent_response")
10065
- return "Agent response";
9820
+ if (event.eventType === "session_summary") return "Session summary";
9821
+ if (event.eventType === "tool_observation") return "Tool evidence";
9822
+ if (event.eventType === "agent_response") return "Agent response";
10066
9823
  return "User prompt";
10067
9824
  }
10068
9825
  usedVector(result) {
@@ -10088,8 +9845,7 @@ var RetrievalDisclosureService = class {
10088
9845
  }
10089
9846
  preview(content, maxLength) {
10090
9847
  const normalized = content.replace(/\s+/g, " ").trim();
10091
- if (normalized.length <= maxLength)
10092
- return normalized;
9848
+ if (normalized.length <= maxLength) return normalized;
10093
9849
  return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
10094
9850
  }
10095
9851
  };
@@ -10118,6 +9874,7 @@ var RetrievalOrchestrator = class {
10118
9874
  this.deps = deps;
10119
9875
  this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
10120
9876
  }
9877
+ deps;
10121
9878
  /**
10122
9879
  * Retrieve relevant memories for a query.
10123
9880
  */
@@ -10199,8 +9956,7 @@ var RetrievalOrchestrator = class {
10199
9956
  * the heavier retrieval/vector initialization path for prompt telemetry.
10200
9957
  */
10201
9958
  async incrementMemoryAccess(eventIds) {
10202
- if (eventIds.length === 0)
10203
- return;
9959
+ if (eventIds.length === 0) return;
10204
9960
  await this.deps.accessStore.incrementAccessCount(eventIds);
10205
9961
  }
10206
9962
  /**
@@ -10213,10 +9969,8 @@ var RetrievalOrchestrator = class {
10213
9969
  resolveGraphHopOptions(callerOptions) {
10214
9970
  const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
10215
9971
  const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
10216
- if (!callerOptions)
10217
- return durableOptions;
10218
- if (!graphExpansion)
10219
- return callerOptions;
9972
+ if (!callerOptions) return durableOptions;
9973
+ if (!graphExpansion) return callerOptions;
10220
9974
  if (graphExpansion.enabled !== true) {
10221
9975
  return {
10222
9976
  ...callerOptions,
@@ -10276,12 +10030,10 @@ var RetrievalOrchestrator = class {
10276
10030
  const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
10277
10031
  const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
10278
10032
  const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
10279
- if (!allFinite)
10280
- return void 0;
10033
+ if (!allFinite) return void 0;
10281
10034
  const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
10282
10035
  const total = semantic + lexical + recency;
10283
- if (!nonNegative || total <= 0)
10284
- return void 0;
10036
+ if (!nonNegative || total <= 0) return void 0;
10285
10037
  return {
10286
10038
  semantic: semantic / total,
10287
10039
  lexical: lexical / total,
@@ -10290,17 +10042,14 @@ var RetrievalOrchestrator = class {
10290
10042
  }
10291
10043
  async getRerankWeights(adaptive) {
10292
10044
  const configured = this.getConfiguredRerankWeights();
10293
- if (configured)
10294
- return configured;
10295
- if (adaptive)
10296
- return this.getAdaptiveRerankWeights();
10045
+ if (configured) return configured;
10046
+ if (adaptive) return this.getAdaptiveRerankWeights();
10297
10047
  return void 0;
10298
10048
  }
10299
10049
  async getAdaptiveRerankWeights() {
10300
10050
  try {
10301
10051
  const stats = await this.deps.traceStore.getHelpfulnessStats();
10302
- if (stats.totalEvaluated < 20)
10303
- return void 0;
10052
+ if (stats.totalEvaluated < 20) return void 0;
10304
10053
  let semantic = 0.7;
10305
10054
  let lexical = 0.2;
10306
10055
  let recency = 0.1;
@@ -10322,11 +10071,9 @@ var RetrievalOrchestrator = class {
10322
10071
  }
10323
10072
  }
10324
10073
  async rewriteQueryIntent(query) {
10325
- if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
10326
- return null;
10074
+ if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
10327
10075
  const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
10328
- if (!apiUrl)
10329
- return null;
10076
+ if (!apiUrl) return null;
10330
10077
  const controller = new AbortController();
10331
10078
  const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
10332
10079
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
@@ -10352,11 +10099,9 @@ var RetrievalOrchestrator = class {
10352
10099
  signal: controller.signal
10353
10100
  });
10354
10101
  const text = (await res.text()).trim();
10355
- if (!text)
10356
- return null;
10102
+ if (!text) return null;
10357
10103
  const oneLine = text.replace(/^data:\s*/gm, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ").slice(0, 240);
10358
- if (!oneLine || oneLine.toLowerCase() === query.toLowerCase())
10359
- return null;
10104
+ if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
10360
10105
  return oneLine;
10361
10106
  } catch {
10362
10107
  return null;
@@ -10498,8 +10243,7 @@ function createMemoryEngineServices(options) {
10498
10243
  };
10499
10244
  }
10500
10245
  function shouldEnablePerspectiveDeriver(options) {
10501
- if (options.readOnly)
10502
- return false;
10246
+ if (options.readOnly) return false;
10503
10247
  const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
10504
10248
  return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
10505
10249
  }
@@ -10533,6 +10277,9 @@ var GraduationWorker = class {
10533
10277
  this.graduation = graduation;
10534
10278
  this.config = config;
10535
10279
  }
10280
+ eventStore;
10281
+ graduation;
10282
+ config;
10536
10283
  running = false;
10537
10284
  timeout = null;
10538
10285
  lastEvaluated = /* @__PURE__ */ new Map();
@@ -10540,8 +10287,7 @@ var GraduationWorker = class {
10540
10287
  * Start the graduation worker
10541
10288
  */
10542
10289
  start() {
10543
- if (this.running)
10544
- return;
10290
+ if (this.running) return;
10545
10291
  this.running = true;
10546
10292
  this.scheduleNext();
10547
10293
  }
@@ -10571,8 +10317,7 @@ var GraduationWorker = class {
10571
10317
  * Schedule the next graduation check
10572
10318
  */
10573
10319
  scheduleNext() {
10574
- if (!this.running)
10575
- return;
10320
+ if (!this.running) return;
10576
10321
  this.timeout = setTimeout(
10577
10322
  () => this.run(),
10578
10323
  this.config.evaluationIntervalMs
@@ -10582,8 +10327,7 @@ var GraduationWorker = class {
10582
10327
  * Run graduation evaluation
10583
10328
  */
10584
10329
  async run() {
10585
- if (!this.running)
10586
- return;
10330
+ if (!this.running) return;
10587
10331
  try {
10588
10332
  await this.runGraduation();
10589
10333
  } catch (error) {
@@ -10647,10 +10391,8 @@ var DEFAULT_CONFIG5 = {
10647
10391
  maxRetries: 3
10648
10392
  };
10649
10393
  function parseJsonArray(value) {
10650
- if (Array.isArray(value))
10651
- return value;
10652
- if (typeof value !== "string" || value.trim().length === 0)
10653
- return [];
10394
+ if (Array.isArray(value)) return value;
10395
+ if (typeof value !== "string" || value.trim().length === 0) return [];
10654
10396
  try {
10655
10397
  const parsed = JSON.parse(value);
10656
10398
  return Array.isArray(parsed) ? parsed : [];
@@ -10680,8 +10422,7 @@ var VectorWorker = class {
10680
10422
  * Start the worker polling loop
10681
10423
  */
10682
10424
  start() {
10683
- if (this.running)
10684
- return;
10425
+ if (this.running) return;
10685
10426
  this.running = true;
10686
10427
  this.stopping = false;
10687
10428
  this.poll();
@@ -10757,8 +10498,7 @@ var VectorWorker = class {
10757
10498
  * Poll for new items
10758
10499
  */
10759
10500
  async poll() {
10760
- if (!this.running || this.stopping)
10761
- return;
10501
+ if (!this.running || this.stopping) return;
10762
10502
  try {
10763
10503
  await this.processBatch();
10764
10504
  } catch (error) {
@@ -10803,6 +10543,7 @@ var DefaultContentProvider = class {
10803
10543
  constructor(db) {
10804
10544
  this.db = db;
10805
10545
  }
10546
+ db;
10806
10547
  async getContent(itemKind, itemId) {
10807
10548
  switch (itemKind) {
10808
10549
  case "entry":
@@ -10823,8 +10564,7 @@ var DefaultContentProvider = class {
10823
10564
  `SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
10824
10565
  [entryId]
10825
10566
  );
10826
- if (rows.length === 0)
10827
- return null;
10567
+ if (rows.length === 0) return null;
10828
10568
  const row = rows[0];
10829
10569
  const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
10830
10570
  return {
@@ -10843,8 +10583,7 @@ ${JSON.stringify(contentJson)}`,
10843
10583
  WHERE entity_id = ? AND entity_type = 'task'`,
10844
10584
  [taskId]
10845
10585
  );
10846
- if (rows.length === 0)
10847
- return null;
10586
+ if (rows.length === 0) return null;
10848
10587
  const row = rows[0];
10849
10588
  return {
10850
10589
  content: row.search_text || row.title,
@@ -10860,8 +10599,7 @@ ${JSON.stringify(contentJson)}`,
10860
10599
  `SELECT content, event_type, session_id FROM events WHERE id = ?`,
10861
10600
  [eventId]
10862
10601
  );
10863
- if (rows.length === 0)
10864
- return null;
10602
+ if (rows.length === 0) return null;
10865
10603
  const row = rows[0];
10866
10604
  return {
10867
10605
  content: row.content,
@@ -10889,8 +10627,7 @@ ${JSON.stringify(contentJson)}`,
10889
10627
  }
10890
10628
  throw error;
10891
10629
  }
10892
- if (rows.length === 0)
10893
- return null;
10630
+ if (rows.length === 0) return null;
10894
10631
  const row = rows[0];
10895
10632
  const sourceEventIds = parseJsonArray(row.source_event_ids_json);
10896
10633
  const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
@@ -10932,8 +10669,7 @@ var VectorWorkerV2 = class {
10932
10669
  * Start the worker polling loop
10933
10670
  */
10934
10671
  start() {
10935
- if (this.running)
10936
- return;
10672
+ if (this.running) return;
10937
10673
  this.running = true;
10938
10674
  this.stopping = false;
10939
10675
  this.poll();
@@ -11003,8 +10739,7 @@ var VectorWorkerV2 = class {
11003
10739
  * Poll for new jobs
11004
10740
  */
11005
10741
  async poll() {
11006
- if (!this.running || this.stopping)
11007
- return;
10742
+ if (!this.running || this.stopping) return;
11008
10743
  try {
11009
10744
  await this.processBatch();
11010
10745
  } catch (error) {
@@ -11071,8 +10806,7 @@ function createMemoryRuntimeService(deps) {
11071
10806
  let graduationWorker = null;
11072
10807
  return {
11073
10808
  async initialize() {
11074
- if (initialized)
11075
- return;
10809
+ if (initialized) return;
11076
10810
  await deps.sqliteStore.initialize();
11077
10811
  if (deps.lightweightMode) {
11078
10812
  initialized = true;
@@ -11166,8 +10900,7 @@ var SharedEventStore = class {
11166
10900
  this.db = createDatabase(dbPath);
11167
10901
  }
11168
10902
  async initialize() {
11169
- if (this.initialized)
11170
- return;
10903
+ if (this.initialized) return;
11171
10904
  await dbRun(this.db, `
11172
10905
  CREATE TABLE IF NOT EXISTS shared_troubleshooting (
11173
10906
  entry_id VARCHAR PRIMARY KEY,
@@ -11257,6 +10990,10 @@ var SharedPromoter = class {
11257
10990
  this.embedder = embedder;
11258
10991
  this.config = config;
11259
10992
  }
10993
+ sharedStore;
10994
+ sharedVectorStore;
10995
+ embedder;
10996
+ config;
11260
10997
  /**
11261
10998
  * Check if an entry is eligible for promotion
11262
10999
  */
@@ -11438,6 +11175,7 @@ var SharedStore = class {
11438
11175
  constructor(sharedEventStore) {
11439
11176
  this.sharedEventStore = sharedEventStore;
11440
11177
  }
11178
+ sharedEventStore;
11441
11179
  get db() {
11442
11180
  return this.sharedEventStore.getDatabase();
11443
11181
  }
@@ -11542,8 +11280,7 @@ var SharedStore = class {
11542
11280
  `SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
11543
11281
  [entryId]
11544
11282
  );
11545
- if (rows.length === 0)
11546
- return null;
11283
+ if (rows.length === 0) return null;
11547
11284
  return this.rowToEntry(rows[0]);
11548
11285
  }
11549
11286
  /**
@@ -11556,8 +11293,7 @@ var SharedStore = class {
11556
11293
  WHERE source_project_hash = ? AND source_entry_id = ?`,
11557
11294
  [projectHash, sourceEntryId]
11558
11295
  );
11559
- if (rows.length === 0)
11560
- return null;
11296
+ if (rows.length === 0) return null;
11561
11297
  return this.rowToEntry(rows[0]);
11562
11298
  }
11563
11299
  /**
@@ -11667,6 +11403,7 @@ var SharedVectorStore = class {
11667
11403
  constructor(dbPath) {
11668
11404
  this.dbPath = dbPath;
11669
11405
  }
11406
+ dbPath;
11670
11407
  db = null;
11671
11408
  table = null;
11672
11409
  tableName = "shared_knowledge";
@@ -11674,8 +11411,7 @@ var SharedVectorStore = class {
11674
11411
  * Initialize LanceDB connection
11675
11412
  */
11676
11413
  async initialize() {
11677
- if (this.db)
11678
- return;
11414
+ if (this.db) return;
11679
11415
  this.db = await lancedb2.connect(this.dbPath);
11680
11416
  try {
11681
11417
  const tables = await this.db.tableNames();
@@ -11717,8 +11453,7 @@ var SharedVectorStore = class {
11717
11453
  * Add multiple records in batch
11718
11454
  */
11719
11455
  async upsertBatch(records) {
11720
- if (records.length === 0)
11721
- return;
11456
+ if (records.length === 0) return;
11722
11457
  await this.initialize();
11723
11458
  if (!this.db) {
11724
11459
  throw new Error("Database not initialized");
@@ -11779,24 +11514,21 @@ var SharedVectorStore = class {
11779
11514
  * Delete vector by entry ID
11780
11515
  */
11781
11516
  async delete(entryId) {
11782
- if (!this.table)
11783
- return;
11517
+ if (!this.table) return;
11784
11518
  await this.table.delete(`entryId = '${entryId}'`);
11785
11519
  }
11786
11520
  /**
11787
11521
  * Get total count
11788
11522
  */
11789
11523
  async count() {
11790
- if (!this.table)
11791
- return 0;
11524
+ if (!this.table) return 0;
11792
11525
  return this.table.countRows();
11793
11526
  }
11794
11527
  /**
11795
11528
  * Check if vector exists for entry
11796
11529
  */
11797
11530
  async exists(entryId) {
11798
- if (!this.table)
11799
- return false;
11531
+ if (!this.table) return false;
11800
11532
  try {
11801
11533
  const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
11802
11534
  return results.length > 0;
@@ -11814,6 +11546,7 @@ var SharedMemoryServices = class {
11814
11546
  constructor(options) {
11815
11547
  this.options = options;
11816
11548
  }
11549
+ options;
11817
11550
  sharedEventStore = null;
11818
11551
  sharedStore = null;
11819
11552
  sharedVectorStore = null;
@@ -11838,8 +11571,7 @@ var SharedMemoryServices = class {
11838
11571
  return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
11839
11572
  }
11840
11573
  async initialize() {
11841
- if (this.options.config?.enabled === false || this.options.readOnly)
11842
- return;
11574
+ if (this.options.config?.enabled === false || this.options.readOnly) return;
11843
11575
  const sharedPath = this.getSharedStoragePath();
11844
11576
  this.ensureDirectory(sharedPath, { allowCreate: true });
11845
11577
  const store = await this.openStore(sharedPath);
@@ -11856,14 +11588,11 @@ var SharedMemoryServices = class {
11856
11588
  this.options.retriever.setSharedStores(store, this.sharedVectorStore);
11857
11589
  }
11858
11590
  async ensureStoreForRead() {
11859
- if (this.options.config?.enabled === false)
11860
- return null;
11861
- if (this.sharedStore)
11862
- return this.sharedStore;
11591
+ if (this.options.config?.enabled === false) return null;
11592
+ if (this.sharedStore) return this.sharedStore;
11863
11593
  const sharedPath = this.getSharedStoragePath();
11864
11594
  const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
11865
- if (!directoryReady)
11866
- return null;
11595
+ if (!directoryReady) return null;
11867
11596
  return this.openStore(sharedPath);
11868
11597
  }
11869
11598
  async getEntryForDisclosure(entryId) {
@@ -11880,13 +11609,11 @@ var SharedMemoryServices = class {
11880
11609
  return this.sharedPromoter.promoteEntry(entry, projectHash);
11881
11610
  }
11882
11611
  async getStats() {
11883
- if (!this.sharedStore)
11884
- return null;
11612
+ if (!this.sharedStore) return null;
11885
11613
  return this.sharedStore.getStats();
11886
11614
  }
11887
11615
  async search(query, options) {
11888
- if (!this.sharedStore)
11889
- return [];
11616
+ if (!this.sharedStore) return [];
11890
11617
  return this.sharedStore.search(query, options);
11891
11618
  }
11892
11619
  async close() {
@@ -11903,8 +11630,7 @@ var SharedMemoryServices = class {
11903
11630
  this.openStorePromise = null;
11904
11631
  }
11905
11632
  async openStore(sharedPath) {
11906
- if (this.sharedStore)
11907
- return this.sharedStore;
11633
+ if (this.sharedStore) return this.sharedStore;
11908
11634
  if (!this.openStorePromise) {
11909
11635
  this.openStorePromise = this.createOpenStorePromise(sharedPath);
11910
11636
  }
@@ -11928,10 +11654,8 @@ var SharedMemoryServices = class {
11928
11654
  return this.sharedStore;
11929
11655
  }
11930
11656
  ensureDirectory(sharedPath, options) {
11931
- if (this.factories.existsSync(sharedPath))
11932
- return true;
11933
- if (!options.allowCreate)
11934
- return false;
11657
+ if (this.factories.existsSync(sharedPath)) return true;
11658
+ if (!options.allowCreate) return false;
11935
11659
  this.factories.mkdirSync(sharedPath);
11936
11660
  return true;
11937
11661
  }
@@ -12721,13 +12445,10 @@ function getLastResponsePath(sessionId) {
12721
12445
  function readLastAssistantSnippet(sessionId) {
12722
12446
  try {
12723
12447
  const filePath = getLastResponsePath(sessionId);
12724
- if (!fs9.existsSync(filePath))
12725
- return null;
12448
+ if (!fs9.existsSync(filePath)) return null;
12726
12449
  const state = JSON.parse(fs9.readFileSync(filePath, "utf-8"));
12727
- if (state.sessionId !== sessionId)
12728
- return null;
12729
- if (Date.now() - new Date(state.createdAt).getTime() > 2 * 60 * 60 * 1e3)
12730
- return null;
12450
+ if (state.sessionId !== sessionId) return null;
12451
+ if (Date.now() - new Date(state.createdAt).getTime() > 2 * 60 * 60 * 1e3) return null;
12731
12452
  return state.snippet || null;
12732
12453
  } catch {
12733
12454
  return null;
@@ -12785,8 +12506,7 @@ function requestFromDaemon(payload, timeoutMs) {
12785
12506
  client.destroy();
12786
12507
  }, timeoutMs);
12787
12508
  const settle = (error, memories) => {
12788
- if (settled)
12789
- return;
12509
+ if (settled) return;
12790
12510
  settled = true;
12791
12511
  clearTimeout(timer);
12792
12512
  if (error) {
@@ -12867,8 +12587,7 @@ function canConnect() {
12867
12587
  let settled = false;
12868
12588
  const client = net.createConnection(DAEMON_SOCKET_PATH);
12869
12589
  const finalize = (ok) => {
12870
- if (settled)
12871
- return;
12590
+ if (settled) return;
12872
12591
  settled = true;
12873
12592
  client.destroy();
12874
12593
  resolve2(ok);
@@ -12914,13 +12633,10 @@ function filterHookInjectableMemories(candidates, policy = getHookInjectionPolic
12914
12633
  }
12915
12634
  function summarizeHookInjectionConfidence(candidates) {
12916
12635
  const scores = candidates.map((candidate) => candidate.score).filter((score) => typeof score === "number" && Number.isFinite(score));
12917
- if (scores.length === 0)
12918
- return "none";
12636
+ if (scores.length === 0) return "none";
12919
12637
  const maxScore = Math.max(...scores);
12920
- if (maxScore >= 0.8)
12921
- return "high";
12922
- if (maxScore >= 0.65)
12923
- return "medium";
12638
+ if (maxScore >= 0.8) return "high";
12639
+ if (maxScore >= 0.65) return "medium";
12924
12640
  return "none";
12925
12641
  }
12926
12642
  function isHookInjectableMemory(candidate, policy) {
@@ -12942,15 +12658,11 @@ function readScoreThreshold(value, fallback) {
12942
12658
  return readNumber(value, fallback, { min: 0, max: 1 });
12943
12659
  }
12944
12660
  function readNumber(value, fallback, bounds) {
12945
- if (value === void 0 || value.trim() === "")
12946
- return fallback;
12661
+ if (value === void 0 || value.trim() === "") return fallback;
12947
12662
  const parsed = Number(value);
12948
- if (!Number.isFinite(parsed))
12949
- return fallback;
12950
- if (bounds?.min !== void 0 && parsed < bounds.min)
12951
- return fallback;
12952
- if (bounds?.max !== void 0 && parsed > bounds.max)
12953
- return fallback;
12663
+ if (!Number.isFinite(parsed)) return fallback;
12664
+ if (bounds?.min !== void 0 && parsed < bounds.min) return fallback;
12665
+ if (bounds?.max !== void 0 && parsed > bounds.max) return fallback;
12954
12666
  return parsed;
12955
12667
  }
12956
12668
 
@@ -12965,25 +12677,19 @@ var ADHERENCE_INTERVAL_TURNS = parseInt(process.env.CLAUDE_MEMORY_ADHERENCE_INTE
12965
12677
  var ADHERENCE_STATE_DIR = path13.join(os8.homedir(), ".claude-code", "memory");
12966
12678
  function shouldStorePrompt(prompt) {
12967
12679
  const trimmed = prompt.trim();
12968
- if (trimmed.startsWith("/"))
12969
- return false;
12970
- if (trimmed.length < 15)
12971
- return false;
12972
- if (!/[a-zA-Z가-힣]{2,}/.test(trimmed))
12973
- return false;
12680
+ if (trimmed.startsWith("/")) return false;
12681
+ if (trimmed.length < 15) return false;
12682
+ if (!/[a-zA-Z가-힣]{2,}/.test(trimmed)) return false;
12974
12683
  return true;
12975
12684
  }
12976
12685
  function getDynamicMinScore(prompt) {
12977
12686
  const len = prompt.trim().length;
12978
- if (len <= 20)
12979
- return Math.min(0.55, BASE_MIN_SCORE + 0.1);
12980
- if (len >= 80)
12981
- return Math.max(0.3, BASE_MIN_SCORE - 0.05);
12687
+ if (len <= 20) return Math.min(0.55, BASE_MIN_SCORE + 0.1);
12688
+ if (len >= 80) return Math.max(0.3, BASE_MIN_SCORE - 0.05);
12982
12689
  return BASE_MIN_SCORE;
12983
12690
  }
12984
12691
  function formatMemoryContext(items) {
12985
- if (items.length === 0)
12986
- return "";
12692
+ if (items.length === 0) return "";
12987
12693
  const lines = items.map((m) => {
12988
12694
  const preview = m.content.length > 300 ? m.content.substring(0, 300) + "..." : m.content;
12989
12695
  return `- [${m.type}] ${preview}`;
@@ -13010,8 +12716,7 @@ function readAdherenceState(sessionId) {
13010
12716
  }
13011
12717
  const data = fs11.readFileSync(filePath, "utf8");
13012
12718
  const parsed = JSON.parse(data);
13013
- if (parsed.sessionId !== sessionId)
13014
- throw new Error("session mismatch");
12719
+ if (parsed.sessionId !== sessionId) throw new Error("session mismatch");
13015
12720
  return parsed;
13016
12721
  } catch {
13017
12722
  return {
@@ -13054,47 +12759,35 @@ function tokenize(text) {
13054
12759
  return text.toLowerCase().replace(/[^a-z0-9가-힣\s]/g, " ").split(/\s+/).filter((w) => w.length >= 2 && !stopwords.has(w));
13055
12760
  }
13056
12761
  function isTopicShift(currentPrompt, lastPrompt) {
13057
- if (!lastPrompt || lastPrompt.length < 10)
13058
- return false;
12762
+ if (!lastPrompt || lastPrompt.length < 10) return false;
13059
12763
  const a = new Set(tokenize(currentPrompt));
13060
12764
  const b = new Set(tokenize(lastPrompt));
13061
- if (a.size === 0 || b.size === 0)
13062
- return false;
12765
+ if (a.size === 0 || b.size === 0) return false;
13063
12766
  let intersection = 0;
13064
12767
  for (const token of a) {
13065
- if (b.has(token))
13066
- intersection++;
12768
+ if (b.has(token)) intersection++;
13067
12769
  }
13068
12770
  const union = a.size + b.size - intersection;
13069
12771
  const similarity = union > 0 ? intersection / union : 0;
13070
12772
  return similarity < 0.2;
13071
12773
  }
13072
12774
  function shouldRunAdherenceCheck(turnCount, prompt, state) {
13073
- if (hasWriteIntent(prompt))
13074
- return { run: true, reason: "write-intent" };
13075
- if (hasContinuationIntent(prompt))
13076
- return { run: true, reason: "continuation-intent" };
13077
- if (hasDecisionRecallIntent(prompt))
13078
- return { run: true, reason: "decision-recall" };
13079
- if (hasProjectCodeSignal(prompt))
13080
- return { run: true, reason: "code-signal" };
13081
- if (turnCount === 1)
13082
- return { run: true, reason: "first-turn" };
13083
- if (isTopicShift(prompt, state.lastPrompt))
13084
- return { run: true, reason: "topic-shift" };
13085
- if (turnCount - state.lastCheckedTurn >= ADHERENCE_INTERVAL_TURNS)
13086
- return { run: true, reason: "interval" };
12775
+ if (hasWriteIntent(prompt)) return { run: true, reason: "write-intent" };
12776
+ if (hasContinuationIntent(prompt)) return { run: true, reason: "continuation-intent" };
12777
+ if (hasDecisionRecallIntent(prompt)) return { run: true, reason: "decision-recall" };
12778
+ if (hasProjectCodeSignal(prompt)) return { run: true, reason: "code-signal" };
12779
+ if (turnCount === 1) return { run: true, reason: "first-turn" };
12780
+ if (isTopicShift(prompt, state.lastPrompt)) return { run: true, reason: "topic-shift" };
12781
+ if (turnCount - state.lastCheckedTurn >= ADHERENCE_INTERVAL_TURNS) return { run: true, reason: "interval" };
13087
12782
  return { run: false, reason: "skip" };
13088
12783
  }
13089
12784
  function isSlashCommandPrompt(prompt) {
13090
12785
  return /^\/[a-z][\w:-]*(?:\s|$)/i.test(prompt);
13091
12786
  }
13092
12787
  function shouldRunMemorySearch(prompt, adherenceDecision) {
13093
- if (!adherenceDecision.run)
13094
- return false;
12788
+ if (!adherenceDecision.run) return false;
13095
12789
  const trimmed = prompt.trim();
13096
- if (isSlashCommandPrompt(trimmed))
13097
- return false;
12790
+ if (isSlashCommandPrompt(trimmed)) return false;
13098
12791
  const strongIntentReasons = /* @__PURE__ */ new Set([
13099
12792
  "write-intent",
13100
12793
  "continuation-intent",
@@ -13106,45 +12799,35 @@ function shouldRunMemorySearch(prompt, adherenceDecision) {
13106
12799
  var MAX_RETRIEVAL_CONTEXT_CHARS = 500;
13107
12800
  function compactRetrievalContext(text) {
13108
12801
  const compacted = (text || "").replace(/\s+/g, " ").trim();
13109
- if (compacted.length <= MAX_RETRIEVAL_CONTEXT_CHARS)
13110
- return compacted;
12802
+ if (compacted.length <= MAX_RETRIEVAL_CONTEXT_CHARS) return compacted;
13111
12803
  return `${compacted.slice(0, MAX_RETRIEVAL_CONTEXT_CHARS)}\u2026`;
13112
12804
  }
13113
12805
  function shouldEnrichRetrievalQuery(input) {
13114
- if (input.currentTurn <= 1)
13115
- return false;
13116
- if (!input.adherenceDecision.run)
13117
- return false;
12806
+ if (input.currentTurn <= 1) return false;
12807
+ if (!input.adherenceDecision.run) return false;
13118
12808
  if (input.adherenceDecision.reason === "topic-shift" || input.adherenceDecision.reason === "first-turn") {
13119
12809
  return false;
13120
12810
  }
13121
12811
  const hasPriorContext = Boolean(compactRetrievalContext(input.previousUserPrompt)) || Boolean(compactRetrievalContext(input.lastAssistantSnippet));
13122
- if (!hasPriorContext)
13123
- return false;
12812
+ if (!hasPriorContext) return false;
13124
12813
  const reason = input.adherenceDecision.reason;
13125
- if (reason === "continuation-intent" || reason === "decision-recall")
13126
- return true;
13127
- if (reason === "write-intent" && input.prompt.trim().length <= 40)
13128
- return true;
12814
+ if (reason === "continuation-intent" || reason === "decision-recall") return true;
12815
+ if (reason === "write-intent" && input.prompt.trim().length <= 40) return true;
13129
12816
  return false;
13130
12817
  }
13131
12818
  function buildRetrievalQuery(input) {
13132
12819
  const currentPrompt = input.prompt.trim();
13133
- if (!shouldEnrichRetrievalQuery(input))
13134
- return currentPrompt;
12820
+ if (!shouldEnrichRetrievalQuery(input)) return currentPrompt;
13135
12821
  const previousUser = compactRetrievalContext(input.previousUserPrompt);
13136
12822
  const previousAssistant = compactRetrievalContext(input.lastAssistantSnippet);
13137
12823
  const parts = [];
13138
- if (previousUser)
13139
- parts.push(`Previous user: ${previousUser}`);
13140
- if (previousAssistant)
13141
- parts.push(`Previous assistant: ${previousAssistant}`);
12824
+ if (previousUser) parts.push(`Previous user: ${previousUser}`);
12825
+ if (previousAssistant) parts.push(`Previous assistant: ${previousAssistant}`);
13142
12826
  parts.push(`Current user: ${currentPrompt}`);
13143
12827
  return parts.join("\n\n");
13144
12828
  }
13145
12829
  function logAdherenceDecision(sessionId, turn, run, reason) {
13146
- if (!process.env.CLAUDE_MEMORY_DEBUG)
13147
- return;
12830
+ if (!process.env.CLAUDE_MEMORY_DEBUG) return;
13148
12831
  const mode = run ? "enforced" : "skipped";
13149
12832
  console.error(`[adherence] session=${sessionId} turn=${turn} mode=${mode} reason=${reason}`);
13150
12833
  }
@@ -13228,8 +12911,7 @@ async function main() {
13228
12911
  }
13229
12912
  const existingIds = new Set(mergedMemories.map((m) => m.id).filter(Boolean));
13230
12913
  for (const r of results) {
13231
- if (existingIds.has(r.event.id))
13232
- continue;
12914
+ if (existingIds.has(r.event.id)) continue;
13233
12915
  mergedMemories.push({
13234
12916
  type: r.event.eventType,
13235
12917
  content: r.event.content,
@@ -13238,8 +12920,7 @@ async function main() {
13238
12920
  source: "keyword",
13239
12921
  fallback: usedFallbackFloor
13240
12922
  });
13241
- if (mergedMemories.length >= MAX_MEMORIES)
13242
- break;
12923
+ if (mergedMemories.length >= MAX_MEMORIES) break;
13243
12924
  }
13244
12925
  }
13245
12926
  const injectableMemories = filterHookInjectableMemories(
@@ -13252,8 +12933,7 @@ async function main() {
13252
12933
  await memoryService.incrementMemoryAccess(eventIds);
13253
12934
  }
13254
12935
  for (const m of injectableMemories) {
13255
- if (!m.id)
13256
- continue;
12936
+ if (!m.id) continue;
13257
12937
  try {
13258
12938
  await memoryService.recordRetrieval(
13259
12939
  m.id,