@loreai/core 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/bun/agents-file.d.ts.map +1 -1
  2. package/dist/bun/config.d.ts.map +1 -1
  3. package/dist/bun/db.d.ts +13 -1
  4. package/dist/bun/db.d.ts.map +1 -1
  5. package/dist/bun/embedding.d.ts.map +1 -1
  6. package/dist/bun/git.d.ts.map +1 -1
  7. package/dist/bun/gradient.d.ts +4 -1
  8. package/dist/bun/gradient.d.ts.map +1 -1
  9. package/dist/bun/hosted.d.ts +36 -0
  10. package/dist/bun/hosted.d.ts.map +1 -0
  11. package/dist/bun/index.d.ts +3 -2
  12. package/dist/bun/index.d.ts.map +1 -1
  13. package/dist/bun/index.js +236 -152
  14. package/dist/bun/index.js.map +4 -4
  15. package/dist/bun/lat-reader.d.ts.map +1 -1
  16. package/dist/node/agents-file.d.ts.map +1 -1
  17. package/dist/node/config.d.ts.map +1 -1
  18. package/dist/node/db.d.ts +13 -1
  19. package/dist/node/db.d.ts.map +1 -1
  20. package/dist/node/embedding.d.ts.map +1 -1
  21. package/dist/node/git.d.ts.map +1 -1
  22. package/dist/node/gradient.d.ts +4 -1
  23. package/dist/node/gradient.d.ts.map +1 -1
  24. package/dist/node/hosted.d.ts +36 -0
  25. package/dist/node/hosted.d.ts.map +1 -0
  26. package/dist/node/index.d.ts +3 -2
  27. package/dist/node/index.d.ts.map +1 -1
  28. package/dist/node/index.js +236 -152
  29. package/dist/node/index.js.map +4 -4
  30. package/dist/node/lat-reader.d.ts.map +1 -1
  31. package/dist/types/agents-file.d.ts.map +1 -1
  32. package/dist/types/config.d.ts.map +1 -1
  33. package/dist/types/db.d.ts +13 -1
  34. package/dist/types/db.d.ts.map +1 -1
  35. package/dist/types/embedding.d.ts.map +1 -1
  36. package/dist/types/git.d.ts.map +1 -1
  37. package/dist/types/gradient.d.ts +4 -1
  38. package/dist/types/gradient.d.ts.map +1 -1
  39. package/dist/types/hosted.d.ts +36 -0
  40. package/dist/types/hosted.d.ts.map +1 -0
  41. package/dist/types/index.d.ts +3 -2
  42. package/dist/types/index.d.ts.map +1 -1
  43. package/dist/types/lat-reader.d.ts.map +1 -1
  44. package/package.json +2 -1
  45. package/src/agents-file.ts +12 -0
  46. package/src/config.ts +10 -5
  47. package/src/db.ts +39 -6
  48. package/src/embedding.ts +43 -5
  49. package/src/git.ts +4 -0
  50. package/src/gradient.ts +44 -0
  51. package/src/hosted.ts +46 -0
  52. package/src/index.ts +4 -0
  53. package/src/lat-reader.ts +4 -0
@@ -168,6 +168,17 @@ import { mkdirSync } from "fs";
168
168
 
169
169
  // src/git.ts
170
170
  import { execSync } from "child_process";
171
+
172
+ // src/hosted.ts
173
+ var _hostedMode = false;
174
+ function enableHostedMode() {
175
+ _hostedMode = true;
176
+ }
177
+ function isHostedMode() {
178
+ return _hostedMode;
179
+ }
180
+
181
+ // src/git.ts
171
182
  function normalizeRemoteUrl(url2) {
172
183
  let normalized = url2.trim();
173
184
  const sshMatch = normalized.match(/^[\w.-]+@([\w.-]+):(.+)$/);
@@ -192,6 +203,7 @@ function clearGitRemoteCache() {
192
203
  gitRemoteCache.clear();
193
204
  }
194
205
  function getGitRemote(path) {
206
+ if (isHostedMode()) return null;
195
207
  const cached2 = gitRemoteCache.get(path);
196
208
  if (cached2 !== void 0) return cached2;
197
209
  try {
@@ -939,7 +951,7 @@ function close() {
939
951
  instance = void 0;
940
952
  }
941
953
  }
942
- function ensureProject(path, name) {
954
+ function ensureProject(path, name, suppliedGitRemote) {
943
955
  if (!process.env.LORE_DB_PATH && /^\/test\//.test(path)) {
944
956
  throw new Error(
945
957
  `Refusing to create project with test path "${path}" in the production DB. Set LORE_DB_PATH to a temp path, or run tests via \`bun test\` from the repo root.`
@@ -948,22 +960,22 @@ function ensureProject(path, name) {
948
960
  const existing = db().query("SELECT id, git_remote FROM projects WHERE path = ?").get(path);
949
961
  if (existing) {
950
962
  if (!existing.git_remote) {
951
- const gitRemote2 = getGitRemote(path);
952
- if (gitRemote2) {
963
+ const resolvedRemote = suppliedGitRemote ?? getGitRemote(path);
964
+ if (resolvedRemote) {
953
965
  const conflict = db().query(
954
966
  "SELECT id FROM projects WHERE git_remote = ? AND id != ? LIMIT 1"
955
- ).get(gitRemote2, existing.id);
967
+ ).get(resolvedRemote, existing.id);
956
968
  if (conflict) {
957
969
  mergeProjectInternal(conflict.id, existing.id);
958
970
  }
959
- db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(gitRemote2, existing.id);
971
+ db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(resolvedRemote, existing.id);
960
972
  }
961
973
  }
962
974
  return existing.id;
963
975
  }
964
976
  const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
965
977
  if (alias) return alias.project_id;
966
- const gitRemote = getGitRemote(path);
978
+ const gitRemote = suppliedGitRemote ?? getGitRemote(path);
967
979
  if (gitRemote) {
968
980
  const byRemote = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
969
981
  if (byRemote) {
@@ -991,6 +1003,20 @@ function projectId(path) {
991
1003
  const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
992
1004
  return alias?.project_id;
993
1005
  }
1006
+ function resolveProjectByRemoteOrPath(gitRemote, path) {
1007
+ if (gitRemote) {
1008
+ const row = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
1009
+ if (row) return row.id;
1010
+ }
1011
+ if (path) {
1012
+ return projectId(path) ?? null;
1013
+ }
1014
+ return null;
1015
+ }
1016
+ function projectPath(id) {
1017
+ const row = db().query("SELECT path FROM projects WHERE id = ?").get(id);
1018
+ return row?.path ?? null;
1019
+ }
994
1020
  function projectName(id) {
995
1021
  const row = db().query("SELECT name FROM projects WHERE id = ?").get(id);
996
1022
  return row?.name ?? null;
@@ -999,13 +1025,13 @@ function isFirstRun() {
999
1025
  const row = db().query("SELECT COUNT(*) as count FROM projects").get();
1000
1026
  return row.count === 0;
1001
1027
  }
1002
- function getLastImportAt(projectPath) {
1003
- const id = ensureProject(projectPath);
1028
+ function getLastImportAt(projectPath2) {
1029
+ const id = ensureProject(projectPath2);
1004
1030
  const row = db().query("SELECT last_import_at FROM projects WHERE id = ?").get(id);
1005
1031
  return row?.last_import_at ?? null;
1006
1032
  }
1007
- function setLastImportAt(projectPath, timestamp) {
1008
- const id = ensureProject(projectPath);
1033
+ function setLastImportAt(projectPath2, timestamp) {
1034
+ const id = ensureProject(projectPath2);
1009
1035
  db().query("UPDATE projects SET last_import_at = ? WHERE id = ?").run(timestamp, id);
1010
1036
  }
1011
1037
  function loadForceMinLayer(sessionID) {
@@ -26791,11 +26817,13 @@ function config2() {
26791
26817
  return current;
26792
26818
  }
26793
26819
  async function load(directory) {
26794
- const path = join5(directory, ".lore.json");
26795
- if (existsSync2(path)) {
26796
- const raw = JSON.parse(readFileSync(path, "utf8"));
26797
- current = LoreConfig.parse(raw);
26798
- return current;
26820
+ if (!isHostedMode()) {
26821
+ const path = join5(directory, ".lore.json");
26822
+ if (existsSync2(path)) {
26823
+ const raw = JSON.parse(readFileSync(path, "utf8"));
26824
+ current = LoreConfig.parse(raw);
26825
+ return current;
26826
+ }
26799
26827
  }
26800
26828
  current = LoreConfig.parse({});
26801
26829
  return current;
@@ -26835,6 +26863,14 @@ function vendorRegistration() {
26835
26863
 
26836
26864
  // src/embedding.ts
26837
26865
  var EMBED_TIMEOUT_MS = 1e4;
26866
+ var LOCAL_MAX_CHARS = 4096 * 4;
26867
+ function safeLocalTruncate(text4) {
26868
+ if (text4.length <= LOCAL_MAX_CHARS) return text4;
26869
+ let end = LOCAL_MAX_CHARS;
26870
+ const code2 = text4.charCodeAt(end - 1);
26871
+ if (code2 >= 55296 && code2 <= 56319) end--;
26872
+ return text4.slice(0, end);
26873
+ }
26838
26874
  var VOYAGE_API_URL = "https://api.voyageai.com/v1/embeddings";
26839
26875
  var VoyageProvider = class {
26840
26876
  maxBatchSize = 128;
@@ -27017,8 +27053,9 @@ var LocalProvider = class {
27017
27053
  localProviderKnownBroken = true;
27018
27054
  if (!localProviderErrorLogged) {
27019
27055
  localProviderErrorLogged = true;
27020
- info(
27021
- `local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`
27056
+ error(
27057
+ `local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`,
27058
+ new Error(`embedding worker init failed: ${msg.error}`)
27022
27059
  );
27023
27060
  }
27024
27061
  for (const [, p2] of this.pendingRequests) {
@@ -27033,6 +27070,7 @@ var LocalProvider = class {
27033
27070
  this.worker.on("error", (err) => {
27034
27071
  this.workerInitError = err.message;
27035
27072
  this.workerReady = false;
27073
+ error("embedding worker crashed:", err);
27036
27074
  for (const [, p2] of this.pendingRequests) {
27037
27075
  p2.reject(new LocalProviderUnavailableError(err));
27038
27076
  }
@@ -27042,6 +27080,10 @@ var LocalProvider = class {
27042
27080
  this.worker.on("exit", (code2) => {
27043
27081
  if (code2 !== 0 && !this.workerInitError) {
27044
27082
  this.workerInitError = `embedding worker exited with code ${code2}`;
27083
+ error(
27084
+ this.workerInitError,
27085
+ new Error(this.workerInitError)
27086
+ );
27045
27087
  }
27046
27088
  this.workerReady = false;
27047
27089
  for (const [, p2] of this.pendingRequests) {
@@ -27072,8 +27114,9 @@ var LocalProvider = class {
27072
27114
  }
27073
27115
  async embed(texts, inputType) {
27074
27116
  await this.ensureWorker();
27117
+ const truncated = texts.map(safeLocalTruncate);
27075
27118
  const prefix = inputType === "document" ? "search_document: " : "search_query: ";
27076
- const prefixed = texts.map((t2) => prefix + t2);
27119
+ const prefixed = truncated.map((t2) => prefix + t2);
27077
27120
  const id = this.nextRequestId++;
27078
27121
  const priority = inputType === "query" && texts.length === 1 ? "high" : "normal";
27079
27122
  return new Promise((resolve, reject) => {
@@ -27301,27 +27344,30 @@ function vectorSearchAllDistillations(queryEmbedding, projectId2, limit = 20) {
27301
27344
  return scored.slice(0, limit);
27302
27345
  }
27303
27346
  function embedKnowledgeEntry(id, title, content3) {
27347
+ if (!isAvailable()) return;
27304
27348
  const text4 = `${title}
27305
27349
  ${content3}`;
27306
27350
  embed([text4], "document").then(([vec]) => {
27307
27351
  db().query("UPDATE knowledge SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
27308
27352
  }).catch((err) => {
27309
- info("embedding failed for knowledge entry", id, ":", err);
27353
+ error("embedding failed for knowledge entry", id, ":", err);
27310
27354
  });
27311
27355
  }
27312
27356
  function embedDistillation(id, observations) {
27357
+ if (!isAvailable()) return;
27313
27358
  embed([observations], "document").then(([vec]) => {
27314
27359
  db().query("UPDATE distillations SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
27315
27360
  }).catch((err) => {
27316
- info("embedding failed for distillation", id, ":", err);
27361
+ error("embedding failed for distillation", id, ":", err);
27317
27362
  });
27318
27363
  }
27319
27364
  function embedTemporalMessage(id, content3) {
27365
+ if (!isAvailable()) return;
27320
27366
  if (content3.length < 50) return;
27321
27367
  embed([content3], "document").then(([vec]) => {
27322
27368
  db().query("UPDATE temporal_messages SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
27323
27369
  }).catch((err) => {
27324
- info("embedding failed for temporal message", id, ":", err);
27370
+ error("embedding failed for temporal message", id, ":", err);
27325
27371
  });
27326
27372
  }
27327
27373
  function vectorSearchTemporal(queryEmbedding, projectId2, limit = 10, sessionId) {
@@ -27441,6 +27487,7 @@ ${r.content}` }));
27441
27487
  }
27442
27488
  } catch (err) {
27443
27489
  error(`embedding backfill batch failed (${batch.length} items):`, err);
27490
+ if (err instanceof LocalProviderUnavailableError) break;
27444
27491
  }
27445
27492
  }
27446
27493
  if (embedded > 0) {
@@ -27474,6 +27521,7 @@ async function backfillDistillationEmbeddings() {
27474
27521
  }
27475
27522
  } catch (err) {
27476
27523
  error(`distillation embedding backfill batch failed (${batch.length} items):`, err);
27524
+ if (err instanceof LocalProviderUnavailableError) break;
27477
27525
  }
27478
27526
  if (embedded >= nextProgressAt) {
27479
27527
  info(`embedding distillations: ${embedded}/${rows.length}\u2026`);
@@ -27563,14 +27611,14 @@ function store(input) {
27563
27611
  embedTemporalMessage(input.info.id, content3);
27564
27612
  }
27565
27613
  }
27566
- function undistilled(projectPath, sessionID) {
27567
- const pid = ensureProject(projectPath);
27614
+ function undistilled(projectPath2, sessionID) {
27615
+ const pid = ensureProject(projectPath2);
27568
27616
  const query = sessionID ? "SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? AND distilled = 0 ORDER BY created_at ASC" : "SELECT * FROM temporal_messages WHERE project_id = ? AND distilled = 0 ORDER BY created_at ASC";
27569
27617
  const params = sessionID ? [pid, sessionID] : [pid];
27570
27618
  return db().query(query).all(...params);
27571
27619
  }
27572
- function bySession(projectPath, sessionID) {
27573
- const pid = ensureProject(projectPath);
27620
+ function bySession(projectPath2, sessionID) {
27621
+ const pid = ensureProject(projectPath2);
27574
27622
  return db().query(
27575
27623
  "SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC"
27576
27624
  ).all(pid, sessionID);
@@ -27646,26 +27694,26 @@ function temporalCnorm(timestamps, now = Date.now()) {
27646
27694
  const maxVariance = (n - 1) / (n * n);
27647
27695
  return maxVariance === 0 ? 0 : variance / maxVariance;
27648
27696
  }
27649
- function count(projectPath, sessionID) {
27650
- const pid = ensureProject(projectPath);
27697
+ function count(projectPath2, sessionID) {
27698
+ const pid = ensureProject(projectPath2);
27651
27699
  const query = sessionID ? "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ? AND session_id = ?" : "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ?";
27652
27700
  const params = sessionID ? [pid, sessionID] : [pid];
27653
27701
  return db().query(query).get(...params).count;
27654
27702
  }
27655
- function hasMessages(projectPath, sessionID) {
27656
- const pid = ensureProject(projectPath);
27703
+ function hasMessages(projectPath2, sessionID) {
27704
+ const pid = ensureProject(projectPath2);
27657
27705
  return !!db().query(
27658
27706
  "SELECT 1 FROM temporal_messages WHERE project_id = ? AND session_id = ? LIMIT 1"
27659
27707
  ).get(pid, sessionID);
27660
27708
  }
27661
- function undistilledCount(projectPath, sessionID) {
27662
- const pid = ensureProject(projectPath);
27709
+ function undistilledCount(projectPath2, sessionID) {
27710
+ const pid = ensureProject(projectPath2);
27663
27711
  const query = sessionID ? "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ? AND session_id = ? AND distilled = 0" : "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ? AND distilled = 0";
27664
27712
  const params = sessionID ? [pid, sessionID] : [pid];
27665
27713
  return db().query(query).get(...params).count;
27666
27714
  }
27667
- function undistilledTokens(projectPath, sessionID) {
27668
- const pid = ensureProject(projectPath);
27715
+ function undistilledTokens(projectPath2, sessionID) {
27716
+ const pid = ensureProject(projectPath2);
27669
27717
  const query = sessionID ? "SELECT COALESCE(SUM(tokens), 0) as total FROM temporal_messages WHERE project_id = ? AND session_id = ? AND distilled = 0" : "SELECT COALESCE(SUM(tokens), 0) as total FROM temporal_messages WHERE project_id = ? AND distilled = 0";
27670
27718
  const params = sessionID ? [pid, sessionID] : [pid];
27671
27719
  return db().query(query).get(...params).total;
@@ -28186,14 +28234,16 @@ function listMarkdownFiles(dir) {
28186
28234
  function contentHash(content3) {
28187
28235
  return sha256(content3);
28188
28236
  }
28189
- function hasLatDir(projectPath) {
28190
- const latDir = join6(projectPath, "lat.md");
28237
+ function hasLatDir(projectPath2) {
28238
+ if (isHostedMode()) return false;
28239
+ const latDir = join6(projectPath2, "lat.md");
28191
28240
  return existsSync3(latDir) && statSync2(latDir).isDirectory();
28192
28241
  }
28193
- function refresh(projectPath) {
28194
- const latDir = join6(projectPath, "lat.md");
28242
+ function refresh(projectPath2) {
28243
+ if (isHostedMode()) return 0;
28244
+ const latDir = join6(projectPath2, "lat.md");
28195
28245
  if (!existsSync3(latDir) || !statSync2(latDir).isDirectory()) return 0;
28196
- const pid = ensureProject(projectPath);
28246
+ const pid = ensureProject(projectPath2);
28197
28247
  const files = listMarkdownFiles(latDir);
28198
28248
  let upserted = 0;
28199
28249
  const seenFiles = /* @__PURE__ */ new Set();
@@ -28208,7 +28258,7 @@ function refresh(projectPath) {
28208
28258
  } catch {
28209
28259
  continue;
28210
28260
  }
28211
- const fileRel = relative(projectPath, filePath);
28261
+ const fileRel = relative(projectPath2, filePath);
28212
28262
  seenFiles.add(fileRel);
28213
28263
  const hash2 = contentHash(content3);
28214
28264
  const existing = db().query("SELECT content_hash FROM lat_sections WHERE project_id = ? AND file = ? LIMIT 1").get(pid, fileRel.replace(/\.md$/, ""));
@@ -28216,7 +28266,7 @@ function refresh(projectPath) {
28216
28266
  continue;
28217
28267
  }
28218
28268
  db().query("DELETE FROM lat_sections WHERE project_id = ? AND file = ?").run(pid, fileRel.replace(/\.md$/, ""));
28219
- const sections = parseSections(filePath, content3, projectPath);
28269
+ const sections = parseSections(filePath, content3, projectPath2);
28220
28270
  const now = Date.now();
28221
28271
  for (const section of sections) {
28222
28272
  upsertStmt.run(
@@ -28266,9 +28316,9 @@ function searchScored2(input) {
28266
28316
  return [];
28267
28317
  }
28268
28318
  }
28269
- function scoreForSession(projectPath, sessionContext, maxTokens) {
28270
- if (!hasLatDir(projectPath)) return [];
28271
- const pid = ensureProject(projectPath);
28319
+ function scoreForSession(projectPath2, sessionContext, maxTokens) {
28320
+ if (!hasLatDir(projectPath2)) return [];
28321
+ const pid = ensureProject(projectPath2);
28272
28322
  const terms = extractTopTerms(sessionContext);
28273
28323
  if (!terms.length) return [];
28274
28324
  const q = terms.map((t2) => `${t2}*`).join(" OR ");
@@ -28300,8 +28350,8 @@ function scoreForSession(projectPath, sessionContext, maxTokens) {
28300
28350
  }
28301
28351
  return packed;
28302
28352
  }
28303
- function count2(projectPath) {
28304
- const pid = ensureProject(projectPath);
28353
+ function count2(projectPath2) {
28354
+ const pid = ensureProject(projectPath2);
28305
28355
  const row = db().query("SELECT COUNT(*) as cnt FROM lat_sections WHERE project_id = ?").get(pid);
28306
28356
  return row.cnt;
28307
28357
  }
@@ -28428,8 +28478,8 @@ function findFuzzyDuplicate(input) {
28428
28478
  }
28429
28479
  return null;
28430
28480
  }
28431
- function forProject(projectPath, includeCross = true) {
28432
- const pid = ensureProject(projectPath);
28481
+ function forProject(projectPath2, includeCross = true) {
28482
+ const pid = ensureProject(projectPath2);
28433
28483
  if (includeCross) {
28434
28484
  return db().query(
28435
28485
  `SELECT ${KNOWLEDGE_COLS} FROM knowledge
@@ -28477,8 +28527,8 @@ function scoreEntriesFTS(sessionContext) {
28477
28527
  return /* @__PURE__ */ new Map();
28478
28528
  }
28479
28529
  }
28480
- async function forSession(projectPath, sessionID, maxTokens, options) {
28481
- const pid = ensureProject(projectPath);
28530
+ async function forSession(projectPath2, sessionID, maxTokens, options) {
28531
+ const pid = ensureProject(projectPath2);
28482
28532
  const categoryFilter = options?.categories;
28483
28533
  const excludeFilter = options?.excludeCategories;
28484
28534
  let categoryClause = "";
@@ -28582,9 +28632,9 @@ async function forSession(projectPath, sessionID, maxTokens, options) {
28582
28632
  result.push(entry);
28583
28633
  used += cost;
28584
28634
  }
28585
- if (hasLatDir(projectPath) && used < maxTokens) {
28635
+ if (hasLatDir(projectPath2) && used < maxTokens) {
28586
28636
  const latSections = scoreForSession(
28587
- projectPath,
28637
+ projectPath2,
28588
28638
  sessionContext,
28589
28639
  maxTokens - used
28590
28640
  );
@@ -28807,8 +28857,8 @@ function cleanDeadRefs() {
28807
28857
  }
28808
28858
  return cleaned;
28809
28859
  }
28810
- function check2(projectPath) {
28811
- const entries = forProject(projectPath, false);
28860
+ function check2(projectPath2) {
28861
+ const entries = forProject(projectPath2, false);
28812
28862
  const issues = [];
28813
28863
  for (const entry of entries) {
28814
28864
  if (entry.content.length > 1200) {
@@ -28963,10 +29013,10 @@ function _dedup(entries, dryRun, embeddingThreshold = EMBEDDING_DEDUP_THRESHOLD)
28963
29013
  const entryTitles = new Map(entries.map((e) => [e.id, e.title]));
28964
29014
  return { clusters: result, totalRemoved, pairSimilarities, entryTitles };
28965
29015
  }
28966
- async function deduplicate(projectPath, opts) {
28967
- const pid = ensureProject(projectPath);
29016
+ async function deduplicate(projectPath2, opts) {
29017
+ const pid = ensureProject(projectPath2);
28968
29018
  const threshold = loadCalibratedThreshold(pid) ?? EMBEDDING_DEDUP_THRESHOLD;
28969
- const entries = forProject(projectPath, false);
29019
+ const entries = forProject(projectPath2, false);
28970
29020
  return _dedup(entries, opts?.dryRun ?? true, threshold);
28971
29021
  }
28972
29022
  async function deduplicateGlobal(opts) {
@@ -29191,8 +29241,8 @@ function setCache(fp, entry) {
29191
29241
  "INSERT INTO kv_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = ?"
29192
29242
  ).run(key, value, value);
29193
29243
  }
29194
- function clearLoreFileCache(projectPath) {
29195
- db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath, LORE_FILE));
29244
+ function clearLoreFileCache(projectPath2) {
29245
+ db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath2, LORE_FILE));
29196
29246
  }
29197
29247
  function splitFile(fileContent) {
29198
29248
  const spans = [];
@@ -29268,8 +29318,8 @@ function hashSection(section) {
29268
29318
  }
29269
29319
  return (h3 >>> 0).toString(16).padStart(8, "0");
29270
29320
  }
29271
- function buildSection(projectPath) {
29272
- const entries = forProject(projectPath, false);
29321
+ function buildSection(projectPath2) {
29322
+ const entries = forProject(projectPath2, false);
29273
29323
  if (!entries.length) {
29274
29324
  return "\n";
29275
29325
  }
@@ -29301,6 +29351,7 @@ function buildSection(projectPath) {
29301
29351
  return out.join("\n");
29302
29352
  }
29303
29353
  function exportToFile(input) {
29354
+ if (isHostedMode()) return;
29304
29355
  exportLoreFile(input.projectPath);
29305
29356
  const pointerBody = "\n## Long-term Knowledge\n\nFor long-term knowledge entries managed by [lore](https://github.com/BYK/loreai) (gotchas, patterns, decisions, architecture), see [`.lore.md`](.lore.md) in the project root.\n";
29306
29357
  const newSection = LORE_SECTION_START + pointerBody + LORE_SECTION_END + "\n";
@@ -29318,6 +29369,7 @@ function exportToFile(input) {
29318
29369
  writeFileSync(input.filePath, result, "utf8");
29319
29370
  }
29320
29371
  function shouldImport(input) {
29372
+ if (isHostedMode()) return false;
29321
29373
  if (!existsSync4(input.filePath)) return false;
29322
29374
  const fileContent = readFileSync3(input.filePath, "utf8");
29323
29375
  const { section } = splitFile(fileContent);
@@ -29327,7 +29379,7 @@ function shouldImport(input) {
29327
29379
  const expected = buildSection(input.projectPath);
29328
29380
  return hashSection(section) !== hashSection(expected);
29329
29381
  }
29330
- function _importEntries(entries, projectPath) {
29382
+ function _importEntries(entries, projectPath2) {
29331
29383
  const seenIds = /* @__PURE__ */ new Set();
29332
29384
  for (const entry of entries) {
29333
29385
  if (entry.id !== null) {
@@ -29339,7 +29391,7 @@ function _importEntries(entries, projectPath) {
29339
29391
  update(entry.id, { content: entry.content });
29340
29392
  }
29341
29393
  } else {
29342
- const pid = ensureProject(projectPath);
29394
+ const pid = ensureProject(projectPath2);
29343
29395
  const fuzzyMatch = findFuzzyDuplicate({ title: entry.title, projectId: pid });
29344
29396
  if (fuzzyMatch) {
29345
29397
  if (fuzzyMatch.title !== entry.title || get(fuzzyMatch.id)?.content !== entry.content) {
@@ -29347,7 +29399,7 @@ function _importEntries(entries, projectPath) {
29347
29399
  }
29348
29400
  } else {
29349
29401
  create({
29350
- projectPath,
29402
+ projectPath: projectPath2,
29351
29403
  category: entry.category,
29352
29404
  title: entry.title,
29353
29405
  content: entry.content,
@@ -29358,13 +29410,13 @@ function _importEntries(entries, projectPath) {
29358
29410
  }
29359
29411
  }
29360
29412
  } else {
29361
- const existing = forProject(projectPath, false);
29413
+ const existing = forProject(projectPath2, false);
29362
29414
  const titleMatch = existing.find(
29363
29415
  (e) => e.title.toLowerCase() === entry.title.toLowerCase()
29364
29416
  );
29365
29417
  if (!titleMatch) {
29366
29418
  create({
29367
- projectPath,
29419
+ projectPath: projectPath2,
29368
29420
  category: entry.category,
29369
29421
  title: entry.title,
29370
29422
  content: entry.content,
@@ -29376,6 +29428,7 @@ function _importEntries(entries, projectPath) {
29376
29428
  }
29377
29429
  }
29378
29430
  function importFromFile(input) {
29431
+ if (isHostedMode()) return;
29379
29432
  if (!existsSync4(input.filePath)) return;
29380
29433
  const fileContent = readFileSync3(input.filePath, "utf8");
29381
29434
  const { section } = splitFile(fileContent);
@@ -29384,14 +29437,16 @@ function importFromFile(input) {
29384
29437
  if (!fileEntries.length) return;
29385
29438
  _importEntries(fileEntries, input.projectPath);
29386
29439
  }
29387
- function loreFileExists(projectPath) {
29388
- return existsSync4(join7(projectPath, LORE_FILE));
29440
+ function loreFileExists(projectPath2) {
29441
+ if (isHostedMode()) return false;
29442
+ return existsSync4(join7(projectPath2, LORE_FILE));
29389
29443
  }
29390
- function exportLoreFile(projectPath) {
29391
- const sectionBody = buildSection(projectPath);
29444
+ function exportLoreFile(projectPath2) {
29445
+ if (isHostedMode()) return;
29446
+ const sectionBody = buildSection(projectPath2);
29392
29447
  const content3 = LORE_FILE_HEADER + "\n" + sectionBody;
29393
29448
  const contentHash2 = hashSection(content3);
29394
- const fp = join7(projectPath, LORE_FILE);
29449
+ const fp = join7(projectPath2, LORE_FILE);
29395
29450
  const cached2 = getCache(fp);
29396
29451
  if (cached2 && cached2.hash === contentHash2) {
29397
29452
  return;
@@ -29400,8 +29455,9 @@ function exportLoreFile(projectPath) {
29400
29455
  const { mtimeMs } = statSync3(fp);
29401
29456
  setCache(fp, { mtimeMs, hash: contentHash2 });
29402
29457
  }
29403
- function shouldImportLoreFile(projectPath) {
29404
- const fp = join7(projectPath, LORE_FILE);
29458
+ function shouldImportLoreFile(projectPath2) {
29459
+ if (isHostedMode()) return false;
29460
+ const fp = join7(projectPath2, LORE_FILE);
29405
29461
  if (!existsSync4(fp)) return false;
29406
29462
  const { mtimeMs } = statSync3(fp);
29407
29463
  const cached2 = getCache(fp);
@@ -29410,7 +29466,7 @@ function shouldImportLoreFile(projectPath) {
29410
29466
  }
29411
29467
  const fileContent = readFileSync3(fp, "utf8");
29412
29468
  const fileHash = hashSection(fileContent);
29413
- const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath);
29469
+ const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath2);
29414
29470
  const expectedHash = hashSection(expected);
29415
29471
  if (fileHash === expectedHash) {
29416
29472
  setCache(fp, { mtimeMs, hash: fileHash });
@@ -29418,13 +29474,14 @@ function shouldImportLoreFile(projectPath) {
29418
29474
  }
29419
29475
  return true;
29420
29476
  }
29421
- function importLoreFile(projectPath) {
29422
- const fp = join7(projectPath, LORE_FILE);
29477
+ function importLoreFile(projectPath2) {
29478
+ if (isHostedMode()) return;
29479
+ const fp = join7(projectPath2, LORE_FILE);
29423
29480
  if (!existsSync4(fp)) return;
29424
29481
  const fileContent = readFileSync3(fp, "utf8");
29425
29482
  const fileEntries = parseEntriesFromSection(fileContent);
29426
29483
  if (!fileEntries.length) return;
29427
- _importEntries(fileEntries, projectPath);
29484
+ _importEntries(fileEntries, projectPath2);
29428
29485
  try {
29429
29486
  const { mtimeMs } = statSync3(fp);
29430
29487
  setCache(fp, { mtimeMs, hash: hashSection(fileContent) });
@@ -29443,8 +29500,8 @@ function listProjects() {
29443
29500
  FROM projects p ORDER BY p.created_at DESC`
29444
29501
  ).all();
29445
29502
  }
29446
- function listSessions(projectPath, limit = 50) {
29447
- const pid = ensureProject(projectPath);
29503
+ function listSessions(projectPath2, limit = 50) {
29504
+ const pid = ensureProject(projectPath2);
29448
29505
  return db().query(
29449
29506
  `SELECT
29450
29507
  session_id,
@@ -29463,8 +29520,8 @@ function listSessions(projectPath, limit = 50) {
29463
29520
  LIMIT ?`
29464
29521
  ).all(pid, limit);
29465
29522
  }
29466
- function listDistillations(projectPath, opts) {
29467
- const pid = ensureProject(projectPath);
29523
+ function listDistillations(projectPath2, opts) {
29524
+ const pid = ensureProject(projectPath2);
29468
29525
  const limit = opts?.limit ?? 50;
29469
29526
  if (opts?.sessionId) {
29470
29527
  return db().query(
@@ -29513,8 +29570,8 @@ function globalStats() {
29513
29570
  }
29514
29571
  return { ...row, db_size_bytes };
29515
29572
  }
29516
- function countForProject(projectPath) {
29517
- const pid = projectId(projectPath);
29573
+ function countForProject(projectPath2) {
29574
+ const pid = projectId(projectPath2);
29518
29575
  if (!pid)
29519
29576
  return { knowledge: 0, messages: 0, distillations: 0, sessions: 0 };
29520
29577
  const row = db().query(
@@ -29526,8 +29583,8 @@ function countForProject(projectPath) {
29526
29583
  ).get(pid, pid, pid, pid);
29527
29584
  return row;
29528
29585
  }
29529
- function clearProject(projectPath) {
29530
- const pid = ensureProject(projectPath);
29586
+ function clearProject(projectPath2) {
29587
+ const pid = ensureProject(projectPath2);
29531
29588
  const database = db();
29532
29589
  const counts = {
29533
29590
  knowledge: database.query(
@@ -29558,9 +29615,9 @@ function clearProject(projectPath) {
29558
29615
  database.exec("ROLLBACK");
29559
29616
  throw e;
29560
29617
  }
29561
- if (existsSync5(projectPath)) {
29618
+ if (existsSync5(projectPath2)) {
29562
29619
  try {
29563
- exportLoreFile(projectPath);
29620
+ exportLoreFile(projectPath2);
29564
29621
  } catch {
29565
29622
  }
29566
29623
  }
@@ -29623,30 +29680,30 @@ function renameProject(projectId2, newName) {
29623
29680
  const result = db().query("UPDATE projects SET name = ? WHERE id = ?").run(newName.trim(), projectId2);
29624
29681
  return result.changes > 0;
29625
29682
  }
29626
- function clearKnowledge(projectPath) {
29627
- const pid = ensureProject(projectPath);
29683
+ function clearKnowledge(projectPath2) {
29684
+ const pid = ensureProject(projectPath2);
29628
29685
  const count3 = db().query(
29629
29686
  "SELECT COUNT(*) as c FROM knowledge WHERE project_id = ?"
29630
29687
  ).get(pid).c;
29631
29688
  db().query("DELETE FROM knowledge WHERE project_id = ?").run(pid);
29632
- if (existsSync5(projectPath)) {
29689
+ if (existsSync5(projectPath2)) {
29633
29690
  try {
29634
- exportLoreFile(projectPath);
29691
+ exportLoreFile(projectPath2);
29635
29692
  } catch {
29636
29693
  }
29637
29694
  }
29638
29695
  return count3;
29639
29696
  }
29640
- function clearTemporal(projectPath) {
29641
- const pid = ensureProject(projectPath);
29697
+ function clearTemporal(projectPath2) {
29698
+ const pid = ensureProject(projectPath2);
29642
29699
  const count3 = db().query(
29643
29700
  "SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ?"
29644
29701
  ).get(pid).c;
29645
29702
  db().query("DELETE FROM temporal_messages WHERE project_id = ?").run(pid);
29646
29703
  return count3;
29647
29704
  }
29648
- function clearDistillations(projectPath) {
29649
- const pid = ensureProject(projectPath);
29705
+ function clearDistillations(projectPath2) {
29706
+ const pid = ensureProject(projectPath2);
29650
29707
  const count3 = db().query(
29651
29708
  "SELECT COUNT(*) as c FROM distillations WHERE project_id = ?"
29652
29709
  ).get(pid).c;
@@ -29665,8 +29722,8 @@ function deleteDistillation(id) {
29665
29722
  db().query("DELETE FROM distillations WHERE id = ?").run(id);
29666
29723
  return true;
29667
29724
  }
29668
- function deleteSession(projectPath, sessionId) {
29669
- const pid = ensureProject(projectPath);
29725
+ function deleteSession(projectPath2, sessionId) {
29726
+ const pid = ensureProject(projectPath2);
29670
29727
  const database = db();
29671
29728
  const msgCount = database.query(
29672
29729
  "SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ? AND session_id = ?"
@@ -29910,9 +29967,22 @@ function setMaxContextTokens(tokens) {
29910
29967
  function getMaxContextTokens() {
29911
29968
  return maxContextTokensCeiling;
29912
29969
  }
29913
- function updateBustRate(cacheWrite, cacheRead, sessionID) {
29970
+ function updateBustRate(cacheWrite, cacheRead, sessionID, lastLayer) {
29914
29971
  if (!sessionID) return;
29915
29972
  const state = getSessionState(sessionID);
29973
+ if (lastLayer === 4) {
29974
+ state.consecutiveLayer4++;
29975
+ if (state.consecutiveLayer4 >= 5 && state.dynamicContextCap > 0 && maxContextTokensCeiling > 0) {
29976
+ state.dynamicContextCap = Math.min(
29977
+ maxContextTokensCeiling,
29978
+ Math.floor(state.dynamicContextCap * 1.1)
29979
+ );
29980
+ }
29981
+ return;
29982
+ }
29983
+ if (lastLayer !== void 0) {
29984
+ state.consecutiveLayer4 = 0;
29985
+ }
29916
29986
  const total = cacheWrite + cacheRead;
29917
29987
  if (total === 0) return;
29918
29988
  const bustRatio = cacheWrite / total;
@@ -29967,6 +30037,7 @@ function makeSessionState() {
29967
30037
  cameOutOfIdle: false,
29968
30038
  postIdleCompact: false,
29969
30039
  consecutiveHighLayer: 0,
30040
+ consecutiveLayer4: 0,
29970
30041
  bustRateEMA: -1,
29971
30042
  interBustIntervalEMA: -1,
29972
30043
  lastBustAt: 0,
@@ -30069,6 +30140,11 @@ function getLastTransformedCount(sessionID) {
30069
30140
  function getLastTransformEstimate(sessionID) {
30070
30141
  return sessionStates.get(sessionID)?.lastTransformEstimate ?? 0;
30071
30142
  }
30143
+ function getLastLayer(sessionID) {
30144
+ if (sessionID) return sessionStates.get(sessionID)?.lastLayer ?? 0;
30145
+ const first = sessionStates.values().next().value;
30146
+ return first?.lastLayer ?? 0;
30147
+ }
30072
30148
  function setForceMinLayer(layer, sessionID) {
30073
30149
  if (sessionID) {
30074
30150
  getSessionState(sessionID).forceMinLayer = layer;
@@ -30089,7 +30165,10 @@ function inspectSessionState(sessionID) {
30089
30165
  cameOutOfIdle: state.cameOutOfIdle,
30090
30166
  postIdleCompact: state.postIdleCompact,
30091
30167
  lastTurnAt: state.lastTurnAt,
30092
- distillationSnapshot: state.distillationSnapshot
30168
+ distillationSnapshot: state.distillationSnapshot,
30169
+ bustRateEMA: state.bustRateEMA,
30170
+ dynamicContextCap: state.dynamicContextCap,
30171
+ consecutiveLayer4: state.consecutiveLayer4
30093
30172
  };
30094
30173
  }
30095
30174
  function setLastTurnAtForTest(sessionID, ms) {
@@ -30108,13 +30187,13 @@ function saveGradientState(sessionID) {
30108
30187
  lastBustAt: state.lastBustAt
30109
30188
  });
30110
30189
  }
30111
- function loadDistillations(projectPath, sessionID) {
30112
- const pid = ensureProject(projectPath);
30190
+ function loadDistillations(projectPath2, sessionID) {
30191
+ const pid = ensureProject(projectPath2);
30113
30192
  const query = sessionID ? "SELECT id, observations, generation, token_count, created_at, session_id FROM distillations WHERE project_id = ? AND session_id = ? AND archived = 0 ORDER BY created_at ASC" : "SELECT id, observations, generation, token_count, created_at, session_id FROM distillations WHERE project_id = ? AND archived = 0 ORDER BY created_at ASC";
30114
30193
  const params = sessionID ? [pid, sessionID] : [pid];
30115
30194
  return db().query(query).all(...params);
30116
30195
  }
30117
- function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
30196
+ function loadDistillationsCached(projectPath2, sessionID, messages, sessState) {
30118
30197
  let lastUserMsgId = null;
30119
30198
  for (let i = messages.length - 1; i >= 0; i--) {
30120
30199
  if (messages[i].info.role === "user") {
@@ -30126,7 +30205,7 @@ function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
30126
30205
  if (snapshot && snapshot.lastUserMsgId === lastUserMsgId) {
30127
30206
  return snapshot.rows;
30128
30207
  }
30129
- const rows = loadDistillations(projectPath, sessionID);
30208
+ const rows = loadDistillations(projectPath2, sessionID);
30130
30209
  sessState.distillationSnapshot = { rows, lastUserMsgId };
30131
30210
  info(
30132
30211
  `distillation refresh: ${rows.length} rows (user msg ${lastUserMsgId?.substring(0, 16) ?? "none"})`
@@ -31110,18 +31189,18 @@ function parseDistillationResult(text4) {
31110
31189
  if (!observations) return null;
31111
31190
  return { observations };
31112
31191
  }
31113
- function latestObservations(projectPath, sessionID) {
31114
- const pid = ensureProject(projectPath);
31192
+ function latestObservations(projectPath2, sessionID) {
31193
+ const pid = ensureProject(projectPath2);
31115
31194
  const row = db().query(
31116
31195
  "SELECT observations FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1"
31117
31196
  ).get(pid, sessionID);
31118
31197
  return row?.observations || void 0;
31119
31198
  }
31120
- function latestMetaObservations(projectPath, sessionID) {
31121
- return latestMeta(projectPath, sessionID)?.observations;
31199
+ function latestMetaObservations(projectPath2, sessionID) {
31200
+ return latestMeta(projectPath2, sessionID)?.observations;
31122
31201
  }
31123
- function latestMeta(projectPath, sessionID) {
31124
- const pid = ensureProject(projectPath);
31202
+ function latestMeta(projectPath2, sessionID) {
31203
+ const pid = ensureProject(projectPath2);
31125
31204
  const row = db().query(
31126
31205
  `SELECT observations, generation FROM distillations
31127
31206
  WHERE project_id = ? AND session_id = ? AND generation > 0
@@ -31139,8 +31218,8 @@ function parseSourceIds(raw) {
31139
31218
  return [];
31140
31219
  }
31141
31220
  }
31142
- function loadForSession(projectPath, sessionID, includeArchived = false) {
31143
- const pid = ensureProject(projectPath);
31221
+ function loadForSession(projectPath2, sessionID, includeArchived = false) {
31222
+ const pid = ensureProject(projectPath2);
31144
31223
  const sql = includeArchived ? "SELECT id, project_id, session_id, observations, source_ids, generation, token_count, created_at, r_compression, c_norm FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC" : "SELECT id, project_id, session_id, observations, source_ids, generation, token_count, created_at, r_compression, c_norm FROM distillations WHERE project_id = ? AND session_id = ? AND archived = 0 ORDER BY created_at ASC";
31145
31224
  const rows = db().query(sql).all(pid, sessionID);
31146
31225
  return rows.map((r) => ({
@@ -31175,14 +31254,14 @@ function storeDistillation(input) {
31175
31254
  );
31176
31255
  return id;
31177
31256
  }
31178
- function gen0Count(projectPath, sessionID) {
31179
- const pid = ensureProject(projectPath);
31257
+ function gen0Count(projectPath2, sessionID) {
31258
+ const pid = ensureProject(projectPath2);
31180
31259
  return db().query(
31181
31260
  "SELECT COUNT(*) as count FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0"
31182
31261
  ).get(pid, sessionID).count;
31183
31262
  }
31184
- function loadGen0(projectPath, sessionID) {
31185
- const pid = ensureProject(projectPath);
31263
+ function loadGen0(projectPath2, sessionID) {
31264
+ const pid = ensureProject(projectPath2);
31186
31265
  const rows = db().query(
31187
31266
  "SELECT id, project_id, session_id, observations, source_ids, generation, token_count, created_at, r_compression, c_norm FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0 ORDER BY created_at ASC"
31188
31267
  ).all(pid, sessionID);
@@ -31198,8 +31277,8 @@ function archiveDistillations(ids) {
31198
31277
  `UPDATE distillations SET archived = 1 WHERE id IN (${placeholders})`
31199
31278
  ).run(...ids);
31200
31279
  }
31201
- function resetOrphans(projectPath, sessionID) {
31202
- const pid = ensureProject(projectPath);
31280
+ function resetOrphans(projectPath2, sessionID) {
31281
+ const pid = ensureProject(projectPath2);
31203
31282
  const rows = db().query(
31204
31283
  "SELECT source_ids FROM distillations WHERE project_id = ? AND session_id = ?"
31205
31284
  ).all(pid, sessionID);
@@ -31831,11 +31910,11 @@ function clearProviders() {
31831
31910
  }
31832
31911
 
31833
31912
  // src/import/detect.ts
31834
- function detectAll(projectPath) {
31913
+ function detectAll(projectPath2) {
31835
31914
  const results = [];
31836
31915
  for (const provider of getProviders()) {
31837
31916
  try {
31838
- const sessions = provider.detect(projectPath);
31917
+ const sessions = provider.detect(projectPath2);
31839
31918
  if (sessions.length > 0) {
31840
31919
  results.push({
31841
31920
  agentName: provider.name,
@@ -31924,8 +32003,8 @@ async function extractKnowledge(input) {
31924
32003
  }
31925
32004
 
31926
32005
  // src/import/history.ts
31927
- function isImported(projectPath, agentName, sourceId, sourceHash) {
31928
- const projectId2 = ensureProject(projectPath);
32006
+ function isImported(projectPath2, agentName, sourceId, sourceHash) {
32007
+ const projectId2 = ensureProject(projectPath2);
31929
32008
  const row = db().query(
31930
32009
  `SELECT * FROM import_history
31931
32010
  WHERE project_id = ? AND agent_name = ? AND source_id = ?`
@@ -31934,8 +32013,8 @@ function isImported(projectPath, agentName, sourceId, sourceHash) {
31934
32013
  if (row.source_hash !== sourceHash) return null;
31935
32014
  return row;
31936
32015
  }
31937
- function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
31938
- const projectId2 = ensureProject(projectPath);
32016
+ function recordImport(projectPath2, agentName, sourceId, sourceHash, stats) {
32017
+ const projectId2 = ensureProject(projectPath2);
31939
32018
  db().query(
31940
32019
  `INSERT OR REPLACE INTO import_history
31941
32020
  (id, project_id, agent_name, source_id, source_hash, entries_created, entries_updated, imported_at)
@@ -31951,8 +32030,8 @@ function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
31951
32030
  Date.now()
31952
32031
  );
31953
32032
  }
31954
- function listImports(projectPath) {
31955
- const projectId2 = ensureProject(projectPath);
32033
+ function listImports(projectPath2) {
32034
+ const projectId2 = ensureProject(projectPath2);
31956
32035
  return db().query(
31957
32036
  `SELECT * FROM import_history
31958
32037
  WHERE project_id = ? AND source_id != '__declined__'
@@ -31970,8 +32049,8 @@ import { homedir as homedir2 } from "os";
31970
32049
  var CLAUDE_DIR = join8(homedir2(), ".claude", "projects");
31971
32050
  var MAX_TOOL_OUTPUT_CHARS = 500;
31972
32051
  var DEFAULT_MAX_TOKENS = 12288;
31973
- function manglePath(projectPath) {
31974
- return projectPath.replace(/\//g, "-");
32052
+ function manglePath(projectPath2) {
32053
+ return projectPath2.replace(/\//g, "-");
31975
32054
  }
31976
32055
  function estimateTokens4(text4) {
31977
32056
  return Math.ceil(text4.length / 3);
@@ -32085,8 +32164,8 @@ function getSessionMetadata(filePath) {
32085
32164
  var claudeCodeProvider = {
32086
32165
  name: "claude-code",
32087
32166
  displayName: "Claude Code",
32088
- detect(projectPath) {
32089
- const mangled = manglePath(projectPath);
32167
+ detect(projectPath2) {
32168
+ const mangled = manglePath(projectPath2);
32090
32169
  const dir = join8(CLAUDE_DIR, mangled);
32091
32170
  let entries;
32092
32171
  try {
@@ -32284,7 +32363,7 @@ function getSessionMeta(filePath) {
32284
32363
  var codexProvider = {
32285
32364
  name: "codex",
32286
32365
  displayName: "Codex",
32287
- detect(projectPath) {
32366
+ detect(projectPath2) {
32288
32367
  const sessions = [];
32289
32368
  const allFiles = [
32290
32369
  ...findJsonlFiles(SESSIONS_DIR),
@@ -32293,7 +32372,7 @@ var codexProvider = {
32293
32372
  for (const filePath of allFiles) {
32294
32373
  const meta3 = getSessionMeta(filePath);
32295
32374
  if (!meta3) continue;
32296
- if (meta3.cwd !== projectPath) continue;
32375
+ if (meta3.cwd !== projectPath2) continue;
32297
32376
  if (meta3.messageCount < 3) continue;
32298
32377
  const ts = new Date(meta3.timestamp).getTime();
32299
32378
  const estimatedTokens = Math.ceil(meta3.fileSize / 5);
@@ -32425,14 +32504,14 @@ function partsToConversationText(parts) {
32425
32504
  var opencodeProvider = {
32426
32505
  name: "opencode",
32427
32506
  displayName: "OpenCode",
32428
- detect(projectPath) {
32507
+ detect(projectPath2) {
32429
32508
  const database = openDB();
32430
32509
  if (!database) return [];
32431
32510
  try {
32432
32511
  if (!tableExists(database, "project") || !tableExists(database, "session") || !tableExists(database, "message")) {
32433
32512
  return [];
32434
32513
  }
32435
- const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath);
32514
+ const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath2);
32436
32515
  if (!project) return [];
32437
32516
  const sessions = database.query(
32438
32517
  `SELECT s.id, s.title, s.time_created, s.time_updated,
@@ -32597,7 +32676,7 @@ function findGlobalStorageDirs() {
32597
32676
  }
32598
32677
  return dirs;
32599
32678
  }
32600
- function loadTaskHistory(storageDir, projectPath) {
32679
+ function loadTaskHistory(storageDir, projectPath2) {
32601
32680
  const paths = [
32602
32681
  join11(storageDir, "state", "taskHistory.json"),
32603
32682
  join11(storageDir, "taskHistory.json")
@@ -32609,7 +32688,7 @@ function loadTaskHistory(storageDir, projectPath) {
32609
32688
  const items = JSON.parse(raw);
32610
32689
  if (!Array.isArray(items)) continue;
32611
32690
  return items.filter(
32612
- (item) => item.cwdOnTaskInitialization === projectPath
32691
+ (item) => item.cwdOnTaskInitialization === projectPath2
32613
32692
  );
32614
32693
  } catch {
32615
32694
  continue;
@@ -32662,11 +32741,11 @@ function messageToText(msg) {
32662
32741
  var clineProvider = {
32663
32742
  name: "cline",
32664
32743
  displayName: "Cline",
32665
- detect(projectPath) {
32744
+ detect(projectPath2) {
32666
32745
  const sessions = [];
32667
32746
  const storageDirs = findGlobalStorageDirs();
32668
32747
  for (const storageDir of storageDirs) {
32669
- const tasks = loadTaskHistory(storageDir, projectPath);
32748
+ const tasks = loadTaskHistory(storageDir, projectPath2);
32670
32749
  for (const task of tasks) {
32671
32750
  const taskDir = join11(storageDir, "tasks", task.id);
32672
32751
  if (!existsSync8(taskDir)) continue;
@@ -32814,11 +32893,11 @@ function historyItemToText(item) {
32814
32893
  var continueProvider = {
32815
32894
  name: "continue",
32816
32895
  displayName: "Continue",
32817
- detect(projectPath) {
32896
+ detect(projectPath2) {
32818
32897
  const sessions = [];
32819
32898
  const index2 = loadSessionIndex();
32820
32899
  for (const meta3 of index2) {
32821
- if (meta3.workspaceDirectory !== projectPath) continue;
32900
+ if (meta3.workspaceDirectory !== projectPath2) continue;
32822
32901
  const session = loadSession(meta3.sessionId);
32823
32902
  if (!session || !session.history || session.history.length < 3) continue;
32824
32903
  const ts = new Date(meta3.dateCreated).getTime();
@@ -32850,7 +32929,7 @@ var continueProvider = {
32850
32929
  if (existingIds.has(sessionId)) continue;
32851
32930
  const session = loadSession(sessionId);
32852
32931
  if (!session) continue;
32853
- if (session.workspaceDirectory !== projectPath) continue;
32932
+ if (session.workspaceDirectory !== projectPath2) continue;
32854
32933
  if (!session.history || session.history.length < 3) continue;
32855
32934
  const dateStr = session.title ? truncate5(session.title, 60) : sessionId.slice(0, 8);
32856
32935
  sessions.push({
@@ -32999,8 +33078,8 @@ function getSessionMeta2(filePath) {
32999
33078
  var piProvider = {
33000
33079
  name: "pi",
33001
33080
  displayName: "Pi",
33002
- detect(projectPath) {
33003
- const encoded = encodeCwd(projectPath);
33081
+ detect(projectPath2) {
33082
+ const encoded = encodeCwd(projectPath2);
33004
33083
  const dir = join13(PI_DIR, encoded);
33005
33084
  let entries;
33006
33085
  try {
@@ -33138,8 +33217,8 @@ function parseAiderHistory(content3) {
33138
33217
  var aiderProvider = {
33139
33218
  name: "aider",
33140
33219
  displayName: "Aider",
33141
- detect(projectPath) {
33142
- const filePath = join14(projectPath, HISTORY_FILE);
33220
+ detect(projectPath2) {
33221
+ const filePath = join14(projectPath2, HISTORY_FILE);
33143
33222
  if (!existsSync11(filePath)) return [];
33144
33223
  let stat;
33145
33224
  try {
@@ -33168,7 +33247,7 @@ var aiderProvider = {
33168
33247
  }
33169
33248
  ];
33170
33249
  },
33171
- readChunks(projectPath, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
33250
+ readChunks(projectPath2, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
33172
33251
  const chunks = [];
33173
33252
  for (const filePath of sessionIds) {
33174
33253
  let content3;
@@ -33463,7 +33542,7 @@ async function searchRecall(input) {
33463
33542
  const {
33464
33543
  query,
33465
33544
  scope = "all",
33466
- projectPath,
33545
+ projectPath: projectPath2,
33467
33546
  sessionID,
33468
33547
  knowledgeEnabled = true,
33469
33548
  llm,
@@ -33490,7 +33569,7 @@ async function searchRecall(input) {
33490
33569
  if (knowledgeEnabled && scope !== "session") {
33491
33570
  try {
33492
33571
  knowledgeResults.push(
33493
- ...searchScored3({ query: q, projectPath, limit })
33572
+ ...searchScored3({ query: q, projectPath: projectPath2, limit })
33494
33573
  );
33495
33574
  } catch (err) {
33496
33575
  error("recall: knowledge search failed:", err);
@@ -33501,7 +33580,7 @@ async function searchRecall(input) {
33501
33580
  try {
33502
33581
  distillationResults.push(
33503
33582
  ...searchDistillationsScored({
33504
- projectPath,
33583
+ projectPath: projectPath2,
33505
33584
  query: q,
33506
33585
  sessionID: scope === "session" ? sessionID : void 0,
33507
33586
  limit
@@ -33516,7 +33595,7 @@ async function searchRecall(input) {
33516
33595
  try {
33517
33596
  temporalResults.push(
33518
33597
  ...searchScored({
33519
- projectPath,
33598
+ projectPath: projectPath2,
33520
33599
  query: q,
33521
33600
  sessionID: scope === "session" ? sessionID : void 0,
33522
33601
  limit
@@ -33610,7 +33689,7 @@ async function searchRecall(input) {
33610
33689
  }
33611
33690
  }
33612
33691
  if (scope !== "knowledge") {
33613
- const pid = ensureProject(projectPath);
33692
+ const pid = ensureProject(projectPath2);
33614
33693
  const temporalVectorHits = vectorSearchTemporal(
33615
33694
  queryVec,
33616
33695
  pid,
@@ -33638,11 +33717,11 @@ async function searchRecall(input) {
33638
33717
  info("recall: vector search failed:", err);
33639
33718
  }
33640
33719
  }
33641
- if (scope !== "session" && hasLatDir(projectPath)) {
33720
+ if (scope !== "session" && hasLatDir(projectPath2)) {
33642
33721
  try {
33643
33722
  const latResults = searchScored2({
33644
33723
  query,
33645
- projectPath,
33724
+ projectPath: projectPath2,
33646
33725
  limit
33647
33726
  });
33648
33727
  if (latResults.length) {
@@ -33662,7 +33741,7 @@ async function searchRecall(input) {
33662
33741
  try {
33663
33742
  const crossProjectResults = searchScoredOtherProjects({
33664
33743
  query,
33665
- excludeProjectPath: projectPath,
33744
+ excludeProjectPath: projectPath2,
33666
33745
  limit
33667
33746
  });
33668
33747
  if (crossProjectResults.length) {
@@ -33868,6 +33947,7 @@ export {
33868
33947
  distillationUser,
33869
33948
  embedding_exports as embedding,
33870
33949
  embedding_vendor_exports as embeddingVendor,
33950
+ enableHostedMode,
33871
33951
  ensureProject,
33872
33952
  exactTermMatchRank,
33873
33953
  expandQuery,
@@ -33883,6 +33963,7 @@ export {
33883
33963
  getInstanceId,
33884
33964
  getKV,
33885
33965
  getLastImportAt,
33966
+ getLastLayer,
33886
33967
  getLastTransformEstimate,
33887
33968
  getLastTransformedCount,
33888
33969
  getLastTurnAt,
@@ -33897,6 +33978,7 @@ export {
33897
33978
  inspectSessionState,
33898
33979
  instruction_detect_exports as instructionDetect,
33899
33980
  isFirstRun,
33981
+ isHostedMode,
33900
33982
  isReasoningPart,
33901
33983
  isTextPart,
33902
33984
  isToolPart,
@@ -33922,10 +34004,12 @@ export {
33922
34004
  pattern_extract_exports as patternExtract,
33923
34005
  projectId,
33924
34006
  projectName,
34007
+ projectPath,
33925
34008
  recallById,
33926
34009
  reciprocalRankFusion,
33927
34010
  recursiveUser,
33928
34011
  renderMarkdown,
34012
+ resolveProjectByRemoteOrPath,
33929
34013
  root2 as root,
33930
34014
  runRecall,
33931
34015
  sanitizeSurrogates,