@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
package/dist/bun/index.js CHANGED
@@ -151,6 +151,17 @@ import { mkdirSync } from "fs";
151
151
 
152
152
  // src/git.ts
153
153
  import { execSync } from "child_process";
154
+
155
+ // src/hosted.ts
156
+ var _hostedMode = false;
157
+ function enableHostedMode() {
158
+ _hostedMode = true;
159
+ }
160
+ function isHostedMode() {
161
+ return _hostedMode;
162
+ }
163
+
164
+ // src/git.ts
154
165
  function normalizeRemoteUrl(url2) {
155
166
  let normalized = url2.trim();
156
167
  const sshMatch = normalized.match(/^[\w.-]+@([\w.-]+):(.+)$/);
@@ -175,6 +186,7 @@ function clearGitRemoteCache() {
175
186
  gitRemoteCache.clear();
176
187
  }
177
188
  function getGitRemote(path) {
189
+ if (isHostedMode()) return null;
178
190
  const cached2 = gitRemoteCache.get(path);
179
191
  if (cached2 !== void 0) return cached2;
180
192
  try {
@@ -922,7 +934,7 @@ function close() {
922
934
  instance = void 0;
923
935
  }
924
936
  }
925
- function ensureProject(path, name) {
937
+ function ensureProject(path, name, suppliedGitRemote) {
926
938
  if (!process.env.LORE_DB_PATH && /^\/test\//.test(path)) {
927
939
  throw new Error(
928
940
  `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.`
@@ -931,22 +943,22 @@ function ensureProject(path, name) {
931
943
  const existing = db().query("SELECT id, git_remote FROM projects WHERE path = ?").get(path);
932
944
  if (existing) {
933
945
  if (!existing.git_remote) {
934
- const gitRemote2 = getGitRemote(path);
935
- if (gitRemote2) {
946
+ const resolvedRemote = suppliedGitRemote ?? getGitRemote(path);
947
+ if (resolvedRemote) {
936
948
  const conflict = db().query(
937
949
  "SELECT id FROM projects WHERE git_remote = ? AND id != ? LIMIT 1"
938
- ).get(gitRemote2, existing.id);
950
+ ).get(resolvedRemote, existing.id);
939
951
  if (conflict) {
940
952
  mergeProjectInternal(conflict.id, existing.id);
941
953
  }
942
- db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(gitRemote2, existing.id);
954
+ db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(resolvedRemote, existing.id);
943
955
  }
944
956
  }
945
957
  return existing.id;
946
958
  }
947
959
  const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
948
960
  if (alias) return alias.project_id;
949
- const gitRemote = getGitRemote(path);
961
+ const gitRemote = suppliedGitRemote ?? getGitRemote(path);
950
962
  if (gitRemote) {
951
963
  const byRemote = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
952
964
  if (byRemote) {
@@ -974,6 +986,20 @@ function projectId(path) {
974
986
  const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
975
987
  return alias?.project_id;
976
988
  }
989
+ function resolveProjectByRemoteOrPath(gitRemote, path) {
990
+ if (gitRemote) {
991
+ const row = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
992
+ if (row) return row.id;
993
+ }
994
+ if (path) {
995
+ return projectId(path) ?? null;
996
+ }
997
+ return null;
998
+ }
999
+ function projectPath(id) {
1000
+ const row = db().query("SELECT path FROM projects WHERE id = ?").get(id);
1001
+ return row?.path ?? null;
1002
+ }
977
1003
  function projectName(id) {
978
1004
  const row = db().query("SELECT name FROM projects WHERE id = ?").get(id);
979
1005
  return row?.name ?? null;
@@ -982,13 +1008,13 @@ function isFirstRun() {
982
1008
  const row = db().query("SELECT COUNT(*) as count FROM projects").get();
983
1009
  return row.count === 0;
984
1010
  }
985
- function getLastImportAt(projectPath) {
986
- const id = ensureProject(projectPath);
1011
+ function getLastImportAt(projectPath2) {
1012
+ const id = ensureProject(projectPath2);
987
1013
  const row = db().query("SELECT last_import_at FROM projects WHERE id = ?").get(id);
988
1014
  return row?.last_import_at ?? null;
989
1015
  }
990
- function setLastImportAt(projectPath, timestamp) {
991
- const id = ensureProject(projectPath);
1016
+ function setLastImportAt(projectPath2, timestamp) {
1017
+ const id = ensureProject(projectPath2);
992
1018
  db().query("UPDATE projects SET last_import_at = ? WHERE id = ?").run(timestamp, id);
993
1019
  }
994
1020
  function loadForceMinLayer(sessionID) {
@@ -26774,11 +26800,13 @@ function config2() {
26774
26800
  return current;
26775
26801
  }
26776
26802
  async function load(directory) {
26777
- const path = join5(directory, ".lore.json");
26778
- if (existsSync2(path)) {
26779
- const raw = JSON.parse(readFileSync(path, "utf8"));
26780
- current = LoreConfig.parse(raw);
26781
- return current;
26803
+ if (!isHostedMode()) {
26804
+ const path = join5(directory, ".lore.json");
26805
+ if (existsSync2(path)) {
26806
+ const raw = JSON.parse(readFileSync(path, "utf8"));
26807
+ current = LoreConfig.parse(raw);
26808
+ return current;
26809
+ }
26782
26810
  }
26783
26811
  current = LoreConfig.parse({});
26784
26812
  return current;
@@ -26818,6 +26846,14 @@ function vendorRegistration() {
26818
26846
 
26819
26847
  // src/embedding.ts
26820
26848
  var EMBED_TIMEOUT_MS = 1e4;
26849
+ var LOCAL_MAX_CHARS = 4096 * 4;
26850
+ function safeLocalTruncate(text4) {
26851
+ if (text4.length <= LOCAL_MAX_CHARS) return text4;
26852
+ let end = LOCAL_MAX_CHARS;
26853
+ const code2 = text4.charCodeAt(end - 1);
26854
+ if (code2 >= 55296 && code2 <= 56319) end--;
26855
+ return text4.slice(0, end);
26856
+ }
26821
26857
  var VOYAGE_API_URL = "https://api.voyageai.com/v1/embeddings";
26822
26858
  var VoyageProvider = class {
26823
26859
  maxBatchSize = 128;
@@ -27000,8 +27036,9 @@ var LocalProvider = class {
27000
27036
  localProviderKnownBroken = true;
27001
27037
  if (!localProviderErrorLogged) {
27002
27038
  localProviderErrorLogged = true;
27003
- info(
27004
- `local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`
27039
+ error(
27040
+ `local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`,
27041
+ new Error(`embedding worker init failed: ${msg.error}`)
27005
27042
  );
27006
27043
  }
27007
27044
  for (const [, p2] of this.pendingRequests) {
@@ -27016,6 +27053,7 @@ var LocalProvider = class {
27016
27053
  this.worker.on("error", (err) => {
27017
27054
  this.workerInitError = err.message;
27018
27055
  this.workerReady = false;
27056
+ error("embedding worker crashed:", err);
27019
27057
  for (const [, p2] of this.pendingRequests) {
27020
27058
  p2.reject(new LocalProviderUnavailableError(err));
27021
27059
  }
@@ -27025,6 +27063,10 @@ var LocalProvider = class {
27025
27063
  this.worker.on("exit", (code2) => {
27026
27064
  if (code2 !== 0 && !this.workerInitError) {
27027
27065
  this.workerInitError = `embedding worker exited with code ${code2}`;
27066
+ error(
27067
+ this.workerInitError,
27068
+ new Error(this.workerInitError)
27069
+ );
27028
27070
  }
27029
27071
  this.workerReady = false;
27030
27072
  for (const [, p2] of this.pendingRequests) {
@@ -27055,8 +27097,9 @@ var LocalProvider = class {
27055
27097
  }
27056
27098
  async embed(texts, inputType) {
27057
27099
  await this.ensureWorker();
27100
+ const truncated = texts.map(safeLocalTruncate);
27058
27101
  const prefix = inputType === "document" ? "search_document: " : "search_query: ";
27059
- const prefixed = texts.map((t2) => prefix + t2);
27102
+ const prefixed = truncated.map((t2) => prefix + t2);
27060
27103
  const id = this.nextRequestId++;
27061
27104
  const priority = inputType === "query" && texts.length === 1 ? "high" : "normal";
27062
27105
  return new Promise((resolve, reject) => {
@@ -27284,27 +27327,30 @@ function vectorSearchAllDistillations(queryEmbedding, projectId2, limit = 20) {
27284
27327
  return scored.slice(0, limit);
27285
27328
  }
27286
27329
  function embedKnowledgeEntry(id, title, content3) {
27330
+ if (!isAvailable()) return;
27287
27331
  const text4 = `${title}
27288
27332
  ${content3}`;
27289
27333
  embed([text4], "document").then(([vec]) => {
27290
27334
  db().query("UPDATE knowledge SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
27291
27335
  }).catch((err) => {
27292
- info("embedding failed for knowledge entry", id, ":", err);
27336
+ error("embedding failed for knowledge entry", id, ":", err);
27293
27337
  });
27294
27338
  }
27295
27339
  function embedDistillation(id, observations) {
27340
+ if (!isAvailable()) return;
27296
27341
  embed([observations], "document").then(([vec]) => {
27297
27342
  db().query("UPDATE distillations SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
27298
27343
  }).catch((err) => {
27299
- info("embedding failed for distillation", id, ":", err);
27344
+ error("embedding failed for distillation", id, ":", err);
27300
27345
  });
27301
27346
  }
27302
27347
  function embedTemporalMessage(id, content3) {
27348
+ if (!isAvailable()) return;
27303
27349
  if (content3.length < 50) return;
27304
27350
  embed([content3], "document").then(([vec]) => {
27305
27351
  db().query("UPDATE temporal_messages SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
27306
27352
  }).catch((err) => {
27307
- info("embedding failed for temporal message", id, ":", err);
27353
+ error("embedding failed for temporal message", id, ":", err);
27308
27354
  });
27309
27355
  }
27310
27356
  function vectorSearchTemporal(queryEmbedding, projectId2, limit = 10, sessionId) {
@@ -27424,6 +27470,7 @@ ${r.content}` }));
27424
27470
  }
27425
27471
  } catch (err) {
27426
27472
  error(`embedding backfill batch failed (${batch.length} items):`, err);
27473
+ if (err instanceof LocalProviderUnavailableError) break;
27427
27474
  }
27428
27475
  }
27429
27476
  if (embedded > 0) {
@@ -27457,6 +27504,7 @@ async function backfillDistillationEmbeddings() {
27457
27504
  }
27458
27505
  } catch (err) {
27459
27506
  error(`distillation embedding backfill batch failed (${batch.length} items):`, err);
27507
+ if (err instanceof LocalProviderUnavailableError) break;
27460
27508
  }
27461
27509
  if (embedded >= nextProgressAt) {
27462
27510
  info(`embedding distillations: ${embedded}/${rows.length}\u2026`);
@@ -27546,14 +27594,14 @@ function store(input) {
27546
27594
  embedTemporalMessage(input.info.id, content3);
27547
27595
  }
27548
27596
  }
27549
- function undistilled(projectPath, sessionID) {
27550
- const pid = ensureProject(projectPath);
27597
+ function undistilled(projectPath2, sessionID) {
27598
+ const pid = ensureProject(projectPath2);
27551
27599
  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";
27552
27600
  const params = sessionID ? [pid, sessionID] : [pid];
27553
27601
  return db().query(query).all(...params);
27554
27602
  }
27555
- function bySession(projectPath, sessionID) {
27556
- const pid = ensureProject(projectPath);
27603
+ function bySession(projectPath2, sessionID) {
27604
+ const pid = ensureProject(projectPath2);
27557
27605
  return db().query(
27558
27606
  "SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC"
27559
27607
  ).all(pid, sessionID);
@@ -27629,26 +27677,26 @@ function temporalCnorm(timestamps, now = Date.now()) {
27629
27677
  const maxVariance = (n - 1) / (n * n);
27630
27678
  return maxVariance === 0 ? 0 : variance / maxVariance;
27631
27679
  }
27632
- function count(projectPath, sessionID) {
27633
- const pid = ensureProject(projectPath);
27680
+ function count(projectPath2, sessionID) {
27681
+ const pid = ensureProject(projectPath2);
27634
27682
  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 = ?";
27635
27683
  const params = sessionID ? [pid, sessionID] : [pid];
27636
27684
  return db().query(query).get(...params).count;
27637
27685
  }
27638
- function hasMessages(projectPath, sessionID) {
27639
- const pid = ensureProject(projectPath);
27686
+ function hasMessages(projectPath2, sessionID) {
27687
+ const pid = ensureProject(projectPath2);
27640
27688
  return !!db().query(
27641
27689
  "SELECT 1 FROM temporal_messages WHERE project_id = ? AND session_id = ? LIMIT 1"
27642
27690
  ).get(pid, sessionID);
27643
27691
  }
27644
- function undistilledCount(projectPath, sessionID) {
27645
- const pid = ensureProject(projectPath);
27692
+ function undistilledCount(projectPath2, sessionID) {
27693
+ const pid = ensureProject(projectPath2);
27646
27694
  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";
27647
27695
  const params = sessionID ? [pid, sessionID] : [pid];
27648
27696
  return db().query(query).get(...params).count;
27649
27697
  }
27650
- function undistilledTokens(projectPath, sessionID) {
27651
- const pid = ensureProject(projectPath);
27698
+ function undistilledTokens(projectPath2, sessionID) {
27699
+ const pid = ensureProject(projectPath2);
27652
27700
  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";
27653
27701
  const params = sessionID ? [pid, sessionID] : [pid];
27654
27702
  return db().query(query).get(...params).total;
@@ -28169,14 +28217,16 @@ function listMarkdownFiles(dir) {
28169
28217
  function contentHash(content3) {
28170
28218
  return sha256(content3);
28171
28219
  }
28172
- function hasLatDir(projectPath) {
28173
- const latDir = join6(projectPath, "lat.md");
28220
+ function hasLatDir(projectPath2) {
28221
+ if (isHostedMode()) return false;
28222
+ const latDir = join6(projectPath2, "lat.md");
28174
28223
  return existsSync3(latDir) && statSync2(latDir).isDirectory();
28175
28224
  }
28176
- function refresh(projectPath) {
28177
- const latDir = join6(projectPath, "lat.md");
28225
+ function refresh(projectPath2) {
28226
+ if (isHostedMode()) return 0;
28227
+ const latDir = join6(projectPath2, "lat.md");
28178
28228
  if (!existsSync3(latDir) || !statSync2(latDir).isDirectory()) return 0;
28179
- const pid = ensureProject(projectPath);
28229
+ const pid = ensureProject(projectPath2);
28180
28230
  const files = listMarkdownFiles(latDir);
28181
28231
  let upserted = 0;
28182
28232
  const seenFiles = /* @__PURE__ */ new Set();
@@ -28191,7 +28241,7 @@ function refresh(projectPath) {
28191
28241
  } catch {
28192
28242
  continue;
28193
28243
  }
28194
- const fileRel = relative(projectPath, filePath);
28244
+ const fileRel = relative(projectPath2, filePath);
28195
28245
  seenFiles.add(fileRel);
28196
28246
  const hash2 = contentHash(content3);
28197
28247
  const existing = db().query("SELECT content_hash FROM lat_sections WHERE project_id = ? AND file = ? LIMIT 1").get(pid, fileRel.replace(/\.md$/, ""));
@@ -28199,7 +28249,7 @@ function refresh(projectPath) {
28199
28249
  continue;
28200
28250
  }
28201
28251
  db().query("DELETE FROM lat_sections WHERE project_id = ? AND file = ?").run(pid, fileRel.replace(/\.md$/, ""));
28202
- const sections = parseSections(filePath, content3, projectPath);
28252
+ const sections = parseSections(filePath, content3, projectPath2);
28203
28253
  const now = Date.now();
28204
28254
  for (const section of sections) {
28205
28255
  upsertStmt.run(
@@ -28249,9 +28299,9 @@ function searchScored2(input) {
28249
28299
  return [];
28250
28300
  }
28251
28301
  }
28252
- function scoreForSession(projectPath, sessionContext, maxTokens) {
28253
- if (!hasLatDir(projectPath)) return [];
28254
- const pid = ensureProject(projectPath);
28302
+ function scoreForSession(projectPath2, sessionContext, maxTokens) {
28303
+ if (!hasLatDir(projectPath2)) return [];
28304
+ const pid = ensureProject(projectPath2);
28255
28305
  const terms = extractTopTerms(sessionContext);
28256
28306
  if (!terms.length) return [];
28257
28307
  const q = terms.map((t2) => `${t2}*`).join(" OR ");
@@ -28283,8 +28333,8 @@ function scoreForSession(projectPath, sessionContext, maxTokens) {
28283
28333
  }
28284
28334
  return packed;
28285
28335
  }
28286
- function count2(projectPath) {
28287
- const pid = ensureProject(projectPath);
28336
+ function count2(projectPath2) {
28337
+ const pid = ensureProject(projectPath2);
28288
28338
  const row = db().query("SELECT COUNT(*) as cnt FROM lat_sections WHERE project_id = ?").get(pid);
28289
28339
  return row.cnt;
28290
28340
  }
@@ -28411,8 +28461,8 @@ function findFuzzyDuplicate(input) {
28411
28461
  }
28412
28462
  return null;
28413
28463
  }
28414
- function forProject(projectPath, includeCross = true) {
28415
- const pid = ensureProject(projectPath);
28464
+ function forProject(projectPath2, includeCross = true) {
28465
+ const pid = ensureProject(projectPath2);
28416
28466
  if (includeCross) {
28417
28467
  return db().query(
28418
28468
  `SELECT ${KNOWLEDGE_COLS} FROM knowledge
@@ -28460,8 +28510,8 @@ function scoreEntriesFTS(sessionContext) {
28460
28510
  return /* @__PURE__ */ new Map();
28461
28511
  }
28462
28512
  }
28463
- async function forSession(projectPath, sessionID, maxTokens, options) {
28464
- const pid = ensureProject(projectPath);
28513
+ async function forSession(projectPath2, sessionID, maxTokens, options) {
28514
+ const pid = ensureProject(projectPath2);
28465
28515
  const categoryFilter = options?.categories;
28466
28516
  const excludeFilter = options?.excludeCategories;
28467
28517
  let categoryClause = "";
@@ -28565,9 +28615,9 @@ async function forSession(projectPath, sessionID, maxTokens, options) {
28565
28615
  result.push(entry);
28566
28616
  used += cost;
28567
28617
  }
28568
- if (hasLatDir(projectPath) && used < maxTokens) {
28618
+ if (hasLatDir(projectPath2) && used < maxTokens) {
28569
28619
  const latSections = scoreForSession(
28570
- projectPath,
28620
+ projectPath2,
28571
28621
  sessionContext,
28572
28622
  maxTokens - used
28573
28623
  );
@@ -28790,8 +28840,8 @@ function cleanDeadRefs() {
28790
28840
  }
28791
28841
  return cleaned;
28792
28842
  }
28793
- function check2(projectPath) {
28794
- const entries = forProject(projectPath, false);
28843
+ function check2(projectPath2) {
28844
+ const entries = forProject(projectPath2, false);
28795
28845
  const issues = [];
28796
28846
  for (const entry of entries) {
28797
28847
  if (entry.content.length > 1200) {
@@ -28946,10 +28996,10 @@ function _dedup(entries, dryRun, embeddingThreshold = EMBEDDING_DEDUP_THRESHOLD)
28946
28996
  const entryTitles = new Map(entries.map((e) => [e.id, e.title]));
28947
28997
  return { clusters: result, totalRemoved, pairSimilarities, entryTitles };
28948
28998
  }
28949
- async function deduplicate(projectPath, opts) {
28950
- const pid = ensureProject(projectPath);
28999
+ async function deduplicate(projectPath2, opts) {
29000
+ const pid = ensureProject(projectPath2);
28951
29001
  const threshold = loadCalibratedThreshold(pid) ?? EMBEDDING_DEDUP_THRESHOLD;
28952
- const entries = forProject(projectPath, false);
29002
+ const entries = forProject(projectPath2, false);
28953
29003
  return _dedup(entries, opts?.dryRun ?? true, threshold);
28954
29004
  }
28955
29005
  async function deduplicateGlobal(opts) {
@@ -29174,8 +29224,8 @@ function setCache(fp, entry) {
29174
29224
  "INSERT INTO kv_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = ?"
29175
29225
  ).run(key, value, value);
29176
29226
  }
29177
- function clearLoreFileCache(projectPath) {
29178
- db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath, LORE_FILE));
29227
+ function clearLoreFileCache(projectPath2) {
29228
+ db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath2, LORE_FILE));
29179
29229
  }
29180
29230
  function splitFile(fileContent) {
29181
29231
  const spans = [];
@@ -29251,8 +29301,8 @@ function hashSection(section) {
29251
29301
  }
29252
29302
  return (h3 >>> 0).toString(16).padStart(8, "0");
29253
29303
  }
29254
- function buildSection(projectPath) {
29255
- const entries = forProject(projectPath, false);
29304
+ function buildSection(projectPath2) {
29305
+ const entries = forProject(projectPath2, false);
29256
29306
  if (!entries.length) {
29257
29307
  return "\n";
29258
29308
  }
@@ -29284,6 +29334,7 @@ function buildSection(projectPath) {
29284
29334
  return out.join("\n");
29285
29335
  }
29286
29336
  function exportToFile(input) {
29337
+ if (isHostedMode()) return;
29287
29338
  exportLoreFile(input.projectPath);
29288
29339
  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";
29289
29340
  const newSection = LORE_SECTION_START + pointerBody + LORE_SECTION_END + "\n";
@@ -29301,6 +29352,7 @@ function exportToFile(input) {
29301
29352
  writeFileSync(input.filePath, result, "utf8");
29302
29353
  }
29303
29354
  function shouldImport(input) {
29355
+ if (isHostedMode()) return false;
29304
29356
  if (!existsSync4(input.filePath)) return false;
29305
29357
  const fileContent = readFileSync3(input.filePath, "utf8");
29306
29358
  const { section } = splitFile(fileContent);
@@ -29310,7 +29362,7 @@ function shouldImport(input) {
29310
29362
  const expected = buildSection(input.projectPath);
29311
29363
  return hashSection(section) !== hashSection(expected);
29312
29364
  }
29313
- function _importEntries(entries, projectPath) {
29365
+ function _importEntries(entries, projectPath2) {
29314
29366
  const seenIds = /* @__PURE__ */ new Set();
29315
29367
  for (const entry of entries) {
29316
29368
  if (entry.id !== null) {
@@ -29322,7 +29374,7 @@ function _importEntries(entries, projectPath) {
29322
29374
  update(entry.id, { content: entry.content });
29323
29375
  }
29324
29376
  } else {
29325
- const pid = ensureProject(projectPath);
29377
+ const pid = ensureProject(projectPath2);
29326
29378
  const fuzzyMatch = findFuzzyDuplicate({ title: entry.title, projectId: pid });
29327
29379
  if (fuzzyMatch) {
29328
29380
  if (fuzzyMatch.title !== entry.title || get(fuzzyMatch.id)?.content !== entry.content) {
@@ -29330,7 +29382,7 @@ function _importEntries(entries, projectPath) {
29330
29382
  }
29331
29383
  } else {
29332
29384
  create({
29333
- projectPath,
29385
+ projectPath: projectPath2,
29334
29386
  category: entry.category,
29335
29387
  title: entry.title,
29336
29388
  content: entry.content,
@@ -29341,13 +29393,13 @@ function _importEntries(entries, projectPath) {
29341
29393
  }
29342
29394
  }
29343
29395
  } else {
29344
- const existing = forProject(projectPath, false);
29396
+ const existing = forProject(projectPath2, false);
29345
29397
  const titleMatch = existing.find(
29346
29398
  (e) => e.title.toLowerCase() === entry.title.toLowerCase()
29347
29399
  );
29348
29400
  if (!titleMatch) {
29349
29401
  create({
29350
- projectPath,
29402
+ projectPath: projectPath2,
29351
29403
  category: entry.category,
29352
29404
  title: entry.title,
29353
29405
  content: entry.content,
@@ -29359,6 +29411,7 @@ function _importEntries(entries, projectPath) {
29359
29411
  }
29360
29412
  }
29361
29413
  function importFromFile(input) {
29414
+ if (isHostedMode()) return;
29362
29415
  if (!existsSync4(input.filePath)) return;
29363
29416
  const fileContent = readFileSync3(input.filePath, "utf8");
29364
29417
  const { section } = splitFile(fileContent);
@@ -29367,14 +29420,16 @@ function importFromFile(input) {
29367
29420
  if (!fileEntries.length) return;
29368
29421
  _importEntries(fileEntries, input.projectPath);
29369
29422
  }
29370
- function loreFileExists(projectPath) {
29371
- return existsSync4(join7(projectPath, LORE_FILE));
29423
+ function loreFileExists(projectPath2) {
29424
+ if (isHostedMode()) return false;
29425
+ return existsSync4(join7(projectPath2, LORE_FILE));
29372
29426
  }
29373
- function exportLoreFile(projectPath) {
29374
- const sectionBody = buildSection(projectPath);
29427
+ function exportLoreFile(projectPath2) {
29428
+ if (isHostedMode()) return;
29429
+ const sectionBody = buildSection(projectPath2);
29375
29430
  const content3 = LORE_FILE_HEADER + "\n" + sectionBody;
29376
29431
  const contentHash2 = hashSection(content3);
29377
- const fp = join7(projectPath, LORE_FILE);
29432
+ const fp = join7(projectPath2, LORE_FILE);
29378
29433
  const cached2 = getCache(fp);
29379
29434
  if (cached2 && cached2.hash === contentHash2) {
29380
29435
  return;
@@ -29383,8 +29438,9 @@ function exportLoreFile(projectPath) {
29383
29438
  const { mtimeMs } = statSync3(fp);
29384
29439
  setCache(fp, { mtimeMs, hash: contentHash2 });
29385
29440
  }
29386
- function shouldImportLoreFile(projectPath) {
29387
- const fp = join7(projectPath, LORE_FILE);
29441
+ function shouldImportLoreFile(projectPath2) {
29442
+ if (isHostedMode()) return false;
29443
+ const fp = join7(projectPath2, LORE_FILE);
29388
29444
  if (!existsSync4(fp)) return false;
29389
29445
  const { mtimeMs } = statSync3(fp);
29390
29446
  const cached2 = getCache(fp);
@@ -29393,7 +29449,7 @@ function shouldImportLoreFile(projectPath) {
29393
29449
  }
29394
29450
  const fileContent = readFileSync3(fp, "utf8");
29395
29451
  const fileHash = hashSection(fileContent);
29396
- const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath);
29452
+ const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath2);
29397
29453
  const expectedHash = hashSection(expected);
29398
29454
  if (fileHash === expectedHash) {
29399
29455
  setCache(fp, { mtimeMs, hash: fileHash });
@@ -29401,13 +29457,14 @@ function shouldImportLoreFile(projectPath) {
29401
29457
  }
29402
29458
  return true;
29403
29459
  }
29404
- function importLoreFile(projectPath) {
29405
- const fp = join7(projectPath, LORE_FILE);
29460
+ function importLoreFile(projectPath2) {
29461
+ if (isHostedMode()) return;
29462
+ const fp = join7(projectPath2, LORE_FILE);
29406
29463
  if (!existsSync4(fp)) return;
29407
29464
  const fileContent = readFileSync3(fp, "utf8");
29408
29465
  const fileEntries = parseEntriesFromSection(fileContent);
29409
29466
  if (!fileEntries.length) return;
29410
- _importEntries(fileEntries, projectPath);
29467
+ _importEntries(fileEntries, projectPath2);
29411
29468
  try {
29412
29469
  const { mtimeMs } = statSync3(fp);
29413
29470
  setCache(fp, { mtimeMs, hash: hashSection(fileContent) });
@@ -29426,8 +29483,8 @@ function listProjects() {
29426
29483
  FROM projects p ORDER BY p.created_at DESC`
29427
29484
  ).all();
29428
29485
  }
29429
- function listSessions(projectPath, limit = 50) {
29430
- const pid = ensureProject(projectPath);
29486
+ function listSessions(projectPath2, limit = 50) {
29487
+ const pid = ensureProject(projectPath2);
29431
29488
  return db().query(
29432
29489
  `SELECT
29433
29490
  session_id,
@@ -29446,8 +29503,8 @@ function listSessions(projectPath, limit = 50) {
29446
29503
  LIMIT ?`
29447
29504
  ).all(pid, limit);
29448
29505
  }
29449
- function listDistillations(projectPath, opts) {
29450
- const pid = ensureProject(projectPath);
29506
+ function listDistillations(projectPath2, opts) {
29507
+ const pid = ensureProject(projectPath2);
29451
29508
  const limit = opts?.limit ?? 50;
29452
29509
  if (opts?.sessionId) {
29453
29510
  return db().query(
@@ -29496,8 +29553,8 @@ function globalStats() {
29496
29553
  }
29497
29554
  return { ...row, db_size_bytes };
29498
29555
  }
29499
- function countForProject(projectPath) {
29500
- const pid = projectId(projectPath);
29556
+ function countForProject(projectPath2) {
29557
+ const pid = projectId(projectPath2);
29501
29558
  if (!pid)
29502
29559
  return { knowledge: 0, messages: 0, distillations: 0, sessions: 0 };
29503
29560
  const row = db().query(
@@ -29509,8 +29566,8 @@ function countForProject(projectPath) {
29509
29566
  ).get(pid, pid, pid, pid);
29510
29567
  return row;
29511
29568
  }
29512
- function clearProject(projectPath) {
29513
- const pid = ensureProject(projectPath);
29569
+ function clearProject(projectPath2) {
29570
+ const pid = ensureProject(projectPath2);
29514
29571
  const database = db();
29515
29572
  const counts = {
29516
29573
  knowledge: database.query(
@@ -29541,9 +29598,9 @@ function clearProject(projectPath) {
29541
29598
  database.exec("ROLLBACK");
29542
29599
  throw e;
29543
29600
  }
29544
- if (existsSync5(projectPath)) {
29601
+ if (existsSync5(projectPath2)) {
29545
29602
  try {
29546
- exportLoreFile(projectPath);
29603
+ exportLoreFile(projectPath2);
29547
29604
  } catch {
29548
29605
  }
29549
29606
  }
@@ -29606,30 +29663,30 @@ function renameProject(projectId2, newName) {
29606
29663
  const result = db().query("UPDATE projects SET name = ? WHERE id = ?").run(newName.trim(), projectId2);
29607
29664
  return result.changes > 0;
29608
29665
  }
29609
- function clearKnowledge(projectPath) {
29610
- const pid = ensureProject(projectPath);
29666
+ function clearKnowledge(projectPath2) {
29667
+ const pid = ensureProject(projectPath2);
29611
29668
  const count3 = db().query(
29612
29669
  "SELECT COUNT(*) as c FROM knowledge WHERE project_id = ?"
29613
29670
  ).get(pid).c;
29614
29671
  db().query("DELETE FROM knowledge WHERE project_id = ?").run(pid);
29615
- if (existsSync5(projectPath)) {
29672
+ if (existsSync5(projectPath2)) {
29616
29673
  try {
29617
- exportLoreFile(projectPath);
29674
+ exportLoreFile(projectPath2);
29618
29675
  } catch {
29619
29676
  }
29620
29677
  }
29621
29678
  return count3;
29622
29679
  }
29623
- function clearTemporal(projectPath) {
29624
- const pid = ensureProject(projectPath);
29680
+ function clearTemporal(projectPath2) {
29681
+ const pid = ensureProject(projectPath2);
29625
29682
  const count3 = db().query(
29626
29683
  "SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ?"
29627
29684
  ).get(pid).c;
29628
29685
  db().query("DELETE FROM temporal_messages WHERE project_id = ?").run(pid);
29629
29686
  return count3;
29630
29687
  }
29631
- function clearDistillations(projectPath) {
29632
- const pid = ensureProject(projectPath);
29688
+ function clearDistillations(projectPath2) {
29689
+ const pid = ensureProject(projectPath2);
29633
29690
  const count3 = db().query(
29634
29691
  "SELECT COUNT(*) as c FROM distillations WHERE project_id = ?"
29635
29692
  ).get(pid).c;
@@ -29648,8 +29705,8 @@ function deleteDistillation(id) {
29648
29705
  db().query("DELETE FROM distillations WHERE id = ?").run(id);
29649
29706
  return true;
29650
29707
  }
29651
- function deleteSession(projectPath, sessionId) {
29652
- const pid = ensureProject(projectPath);
29708
+ function deleteSession(projectPath2, sessionId) {
29709
+ const pid = ensureProject(projectPath2);
29653
29710
  const database = db();
29654
29711
  const msgCount = database.query(
29655
29712
  "SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ? AND session_id = ?"
@@ -29893,9 +29950,22 @@ function setMaxContextTokens(tokens) {
29893
29950
  function getMaxContextTokens() {
29894
29951
  return maxContextTokensCeiling;
29895
29952
  }
29896
- function updateBustRate(cacheWrite, cacheRead, sessionID) {
29953
+ function updateBustRate(cacheWrite, cacheRead, sessionID, lastLayer) {
29897
29954
  if (!sessionID) return;
29898
29955
  const state = getSessionState(sessionID);
29956
+ if (lastLayer === 4) {
29957
+ state.consecutiveLayer4++;
29958
+ if (state.consecutiveLayer4 >= 5 && state.dynamicContextCap > 0 && maxContextTokensCeiling > 0) {
29959
+ state.dynamicContextCap = Math.min(
29960
+ maxContextTokensCeiling,
29961
+ Math.floor(state.dynamicContextCap * 1.1)
29962
+ );
29963
+ }
29964
+ return;
29965
+ }
29966
+ if (lastLayer !== void 0) {
29967
+ state.consecutiveLayer4 = 0;
29968
+ }
29899
29969
  const total = cacheWrite + cacheRead;
29900
29970
  if (total === 0) return;
29901
29971
  const bustRatio = cacheWrite / total;
@@ -29950,6 +30020,7 @@ function makeSessionState() {
29950
30020
  cameOutOfIdle: false,
29951
30021
  postIdleCompact: false,
29952
30022
  consecutiveHighLayer: 0,
30023
+ consecutiveLayer4: 0,
29953
30024
  bustRateEMA: -1,
29954
30025
  interBustIntervalEMA: -1,
29955
30026
  lastBustAt: 0,
@@ -30052,6 +30123,11 @@ function getLastTransformedCount(sessionID) {
30052
30123
  function getLastTransformEstimate(sessionID) {
30053
30124
  return sessionStates.get(sessionID)?.lastTransformEstimate ?? 0;
30054
30125
  }
30126
+ function getLastLayer(sessionID) {
30127
+ if (sessionID) return sessionStates.get(sessionID)?.lastLayer ?? 0;
30128
+ const first = sessionStates.values().next().value;
30129
+ return first?.lastLayer ?? 0;
30130
+ }
30055
30131
  function setForceMinLayer(layer, sessionID) {
30056
30132
  if (sessionID) {
30057
30133
  getSessionState(sessionID).forceMinLayer = layer;
@@ -30072,7 +30148,10 @@ function inspectSessionState(sessionID) {
30072
30148
  cameOutOfIdle: state.cameOutOfIdle,
30073
30149
  postIdleCompact: state.postIdleCompact,
30074
30150
  lastTurnAt: state.lastTurnAt,
30075
- distillationSnapshot: state.distillationSnapshot
30151
+ distillationSnapshot: state.distillationSnapshot,
30152
+ bustRateEMA: state.bustRateEMA,
30153
+ dynamicContextCap: state.dynamicContextCap,
30154
+ consecutiveLayer4: state.consecutiveLayer4
30076
30155
  };
30077
30156
  }
30078
30157
  function setLastTurnAtForTest(sessionID, ms) {
@@ -30091,13 +30170,13 @@ function saveGradientState(sessionID) {
30091
30170
  lastBustAt: state.lastBustAt
30092
30171
  });
30093
30172
  }
30094
- function loadDistillations(projectPath, sessionID) {
30095
- const pid = ensureProject(projectPath);
30173
+ function loadDistillations(projectPath2, sessionID) {
30174
+ const pid = ensureProject(projectPath2);
30096
30175
  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";
30097
30176
  const params = sessionID ? [pid, sessionID] : [pid];
30098
30177
  return db().query(query).all(...params);
30099
30178
  }
30100
- function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
30179
+ function loadDistillationsCached(projectPath2, sessionID, messages, sessState) {
30101
30180
  let lastUserMsgId = null;
30102
30181
  for (let i = messages.length - 1; i >= 0; i--) {
30103
30182
  if (messages[i].info.role === "user") {
@@ -30109,7 +30188,7 @@ function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
30109
30188
  if (snapshot && snapshot.lastUserMsgId === lastUserMsgId) {
30110
30189
  return snapshot.rows;
30111
30190
  }
30112
- const rows = loadDistillations(projectPath, sessionID);
30191
+ const rows = loadDistillations(projectPath2, sessionID);
30113
30192
  sessState.distillationSnapshot = { rows, lastUserMsgId };
30114
30193
  info(
30115
30194
  `distillation refresh: ${rows.length} rows (user msg ${lastUserMsgId?.substring(0, 16) ?? "none"})`
@@ -31093,18 +31172,18 @@ function parseDistillationResult(text4) {
31093
31172
  if (!observations) return null;
31094
31173
  return { observations };
31095
31174
  }
31096
- function latestObservations(projectPath, sessionID) {
31097
- const pid = ensureProject(projectPath);
31175
+ function latestObservations(projectPath2, sessionID) {
31176
+ const pid = ensureProject(projectPath2);
31098
31177
  const row = db().query(
31099
31178
  "SELECT observations FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1"
31100
31179
  ).get(pid, sessionID);
31101
31180
  return row?.observations || void 0;
31102
31181
  }
31103
- function latestMetaObservations(projectPath, sessionID) {
31104
- return latestMeta(projectPath, sessionID)?.observations;
31182
+ function latestMetaObservations(projectPath2, sessionID) {
31183
+ return latestMeta(projectPath2, sessionID)?.observations;
31105
31184
  }
31106
- function latestMeta(projectPath, sessionID) {
31107
- const pid = ensureProject(projectPath);
31185
+ function latestMeta(projectPath2, sessionID) {
31186
+ const pid = ensureProject(projectPath2);
31108
31187
  const row = db().query(
31109
31188
  `SELECT observations, generation FROM distillations
31110
31189
  WHERE project_id = ? AND session_id = ? AND generation > 0
@@ -31122,8 +31201,8 @@ function parseSourceIds(raw) {
31122
31201
  return [];
31123
31202
  }
31124
31203
  }
31125
- function loadForSession(projectPath, sessionID, includeArchived = false) {
31126
- const pid = ensureProject(projectPath);
31204
+ function loadForSession(projectPath2, sessionID, includeArchived = false) {
31205
+ const pid = ensureProject(projectPath2);
31127
31206
  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";
31128
31207
  const rows = db().query(sql).all(pid, sessionID);
31129
31208
  return rows.map((r) => ({
@@ -31158,14 +31237,14 @@ function storeDistillation(input) {
31158
31237
  );
31159
31238
  return id;
31160
31239
  }
31161
- function gen0Count(projectPath, sessionID) {
31162
- const pid = ensureProject(projectPath);
31240
+ function gen0Count(projectPath2, sessionID) {
31241
+ const pid = ensureProject(projectPath2);
31163
31242
  return db().query(
31164
31243
  "SELECT COUNT(*) as count FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0"
31165
31244
  ).get(pid, sessionID).count;
31166
31245
  }
31167
- function loadGen0(projectPath, sessionID) {
31168
- const pid = ensureProject(projectPath);
31246
+ function loadGen0(projectPath2, sessionID) {
31247
+ const pid = ensureProject(projectPath2);
31169
31248
  const rows = db().query(
31170
31249
  "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"
31171
31250
  ).all(pid, sessionID);
@@ -31181,8 +31260,8 @@ function archiveDistillations(ids) {
31181
31260
  `UPDATE distillations SET archived = 1 WHERE id IN (${placeholders})`
31182
31261
  ).run(...ids);
31183
31262
  }
31184
- function resetOrphans(projectPath, sessionID) {
31185
- const pid = ensureProject(projectPath);
31263
+ function resetOrphans(projectPath2, sessionID) {
31264
+ const pid = ensureProject(projectPath2);
31186
31265
  const rows = db().query(
31187
31266
  "SELECT source_ids FROM distillations WHERE project_id = ? AND session_id = ?"
31188
31267
  ).all(pid, sessionID);
@@ -31814,11 +31893,11 @@ function clearProviders() {
31814
31893
  }
31815
31894
 
31816
31895
  // src/import/detect.ts
31817
- function detectAll(projectPath) {
31896
+ function detectAll(projectPath2) {
31818
31897
  const results = [];
31819
31898
  for (const provider of getProviders()) {
31820
31899
  try {
31821
- const sessions = provider.detect(projectPath);
31900
+ const sessions = provider.detect(projectPath2);
31822
31901
  if (sessions.length > 0) {
31823
31902
  results.push({
31824
31903
  agentName: provider.name,
@@ -31907,8 +31986,8 @@ async function extractKnowledge(input) {
31907
31986
  }
31908
31987
 
31909
31988
  // src/import/history.ts
31910
- function isImported(projectPath, agentName, sourceId, sourceHash) {
31911
- const projectId2 = ensureProject(projectPath);
31989
+ function isImported(projectPath2, agentName, sourceId, sourceHash) {
31990
+ const projectId2 = ensureProject(projectPath2);
31912
31991
  const row = db().query(
31913
31992
  `SELECT * FROM import_history
31914
31993
  WHERE project_id = ? AND agent_name = ? AND source_id = ?`
@@ -31917,8 +31996,8 @@ function isImported(projectPath, agentName, sourceId, sourceHash) {
31917
31996
  if (row.source_hash !== sourceHash) return null;
31918
31997
  return row;
31919
31998
  }
31920
- function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
31921
- const projectId2 = ensureProject(projectPath);
31999
+ function recordImport(projectPath2, agentName, sourceId, sourceHash, stats) {
32000
+ const projectId2 = ensureProject(projectPath2);
31922
32001
  db().query(
31923
32002
  `INSERT OR REPLACE INTO import_history
31924
32003
  (id, project_id, agent_name, source_id, source_hash, entries_created, entries_updated, imported_at)
@@ -31934,8 +32013,8 @@ function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
31934
32013
  Date.now()
31935
32014
  );
31936
32015
  }
31937
- function listImports(projectPath) {
31938
- const projectId2 = ensureProject(projectPath);
32016
+ function listImports(projectPath2) {
32017
+ const projectId2 = ensureProject(projectPath2);
31939
32018
  return db().query(
31940
32019
  `SELECT * FROM import_history
31941
32020
  WHERE project_id = ? AND source_id != '__declined__'
@@ -31953,8 +32032,8 @@ import { homedir as homedir2 } from "os";
31953
32032
  var CLAUDE_DIR = join8(homedir2(), ".claude", "projects");
31954
32033
  var MAX_TOOL_OUTPUT_CHARS = 500;
31955
32034
  var DEFAULT_MAX_TOKENS = 12288;
31956
- function manglePath(projectPath) {
31957
- return projectPath.replace(/\//g, "-");
32035
+ function manglePath(projectPath2) {
32036
+ return projectPath2.replace(/\//g, "-");
31958
32037
  }
31959
32038
  function estimateTokens4(text4) {
31960
32039
  return Math.ceil(text4.length / 3);
@@ -32068,8 +32147,8 @@ function getSessionMetadata(filePath) {
32068
32147
  var claudeCodeProvider = {
32069
32148
  name: "claude-code",
32070
32149
  displayName: "Claude Code",
32071
- detect(projectPath) {
32072
- const mangled = manglePath(projectPath);
32150
+ detect(projectPath2) {
32151
+ const mangled = manglePath(projectPath2);
32073
32152
  const dir = join8(CLAUDE_DIR, mangled);
32074
32153
  let entries;
32075
32154
  try {
@@ -32267,7 +32346,7 @@ function getSessionMeta(filePath) {
32267
32346
  var codexProvider = {
32268
32347
  name: "codex",
32269
32348
  displayName: "Codex",
32270
- detect(projectPath) {
32349
+ detect(projectPath2) {
32271
32350
  const sessions = [];
32272
32351
  const allFiles = [
32273
32352
  ...findJsonlFiles(SESSIONS_DIR),
@@ -32276,7 +32355,7 @@ var codexProvider = {
32276
32355
  for (const filePath of allFiles) {
32277
32356
  const meta3 = getSessionMeta(filePath);
32278
32357
  if (!meta3) continue;
32279
- if (meta3.cwd !== projectPath) continue;
32358
+ if (meta3.cwd !== projectPath2) continue;
32280
32359
  if (meta3.messageCount < 3) continue;
32281
32360
  const ts = new Date(meta3.timestamp).getTime();
32282
32361
  const estimatedTokens = Math.ceil(meta3.fileSize / 5);
@@ -32408,14 +32487,14 @@ function partsToConversationText(parts) {
32408
32487
  var opencodeProvider = {
32409
32488
  name: "opencode",
32410
32489
  displayName: "OpenCode",
32411
- detect(projectPath) {
32490
+ detect(projectPath2) {
32412
32491
  const database = openDB();
32413
32492
  if (!database) return [];
32414
32493
  try {
32415
32494
  if (!tableExists(database, "project") || !tableExists(database, "session") || !tableExists(database, "message")) {
32416
32495
  return [];
32417
32496
  }
32418
- const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath);
32497
+ const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath2);
32419
32498
  if (!project) return [];
32420
32499
  const sessions = database.query(
32421
32500
  `SELECT s.id, s.title, s.time_created, s.time_updated,
@@ -32580,7 +32659,7 @@ function findGlobalStorageDirs() {
32580
32659
  }
32581
32660
  return dirs;
32582
32661
  }
32583
- function loadTaskHistory(storageDir, projectPath) {
32662
+ function loadTaskHistory(storageDir, projectPath2) {
32584
32663
  const paths = [
32585
32664
  join11(storageDir, "state", "taskHistory.json"),
32586
32665
  join11(storageDir, "taskHistory.json")
@@ -32592,7 +32671,7 @@ function loadTaskHistory(storageDir, projectPath) {
32592
32671
  const items = JSON.parse(raw);
32593
32672
  if (!Array.isArray(items)) continue;
32594
32673
  return items.filter(
32595
- (item) => item.cwdOnTaskInitialization === projectPath
32674
+ (item) => item.cwdOnTaskInitialization === projectPath2
32596
32675
  );
32597
32676
  } catch {
32598
32677
  continue;
@@ -32645,11 +32724,11 @@ function messageToText(msg) {
32645
32724
  var clineProvider = {
32646
32725
  name: "cline",
32647
32726
  displayName: "Cline",
32648
- detect(projectPath) {
32727
+ detect(projectPath2) {
32649
32728
  const sessions = [];
32650
32729
  const storageDirs = findGlobalStorageDirs();
32651
32730
  for (const storageDir of storageDirs) {
32652
- const tasks = loadTaskHistory(storageDir, projectPath);
32731
+ const tasks = loadTaskHistory(storageDir, projectPath2);
32653
32732
  for (const task of tasks) {
32654
32733
  const taskDir = join11(storageDir, "tasks", task.id);
32655
32734
  if (!existsSync8(taskDir)) continue;
@@ -32797,11 +32876,11 @@ function historyItemToText(item) {
32797
32876
  var continueProvider = {
32798
32877
  name: "continue",
32799
32878
  displayName: "Continue",
32800
- detect(projectPath) {
32879
+ detect(projectPath2) {
32801
32880
  const sessions = [];
32802
32881
  const index2 = loadSessionIndex();
32803
32882
  for (const meta3 of index2) {
32804
- if (meta3.workspaceDirectory !== projectPath) continue;
32883
+ if (meta3.workspaceDirectory !== projectPath2) continue;
32805
32884
  const session = loadSession(meta3.sessionId);
32806
32885
  if (!session || !session.history || session.history.length < 3) continue;
32807
32886
  const ts = new Date(meta3.dateCreated).getTime();
@@ -32833,7 +32912,7 @@ var continueProvider = {
32833
32912
  if (existingIds.has(sessionId)) continue;
32834
32913
  const session = loadSession(sessionId);
32835
32914
  if (!session) continue;
32836
- if (session.workspaceDirectory !== projectPath) continue;
32915
+ if (session.workspaceDirectory !== projectPath2) continue;
32837
32916
  if (!session.history || session.history.length < 3) continue;
32838
32917
  const dateStr = session.title ? truncate5(session.title, 60) : sessionId.slice(0, 8);
32839
32918
  sessions.push({
@@ -32982,8 +33061,8 @@ function getSessionMeta2(filePath) {
32982
33061
  var piProvider = {
32983
33062
  name: "pi",
32984
33063
  displayName: "Pi",
32985
- detect(projectPath) {
32986
- const encoded = encodeCwd(projectPath);
33064
+ detect(projectPath2) {
33065
+ const encoded = encodeCwd(projectPath2);
32987
33066
  const dir = join13(PI_DIR, encoded);
32988
33067
  let entries;
32989
33068
  try {
@@ -33121,8 +33200,8 @@ function parseAiderHistory(content3) {
33121
33200
  var aiderProvider = {
33122
33201
  name: "aider",
33123
33202
  displayName: "Aider",
33124
- detect(projectPath) {
33125
- const filePath = join14(projectPath, HISTORY_FILE);
33203
+ detect(projectPath2) {
33204
+ const filePath = join14(projectPath2, HISTORY_FILE);
33126
33205
  if (!existsSync11(filePath)) return [];
33127
33206
  let stat;
33128
33207
  try {
@@ -33151,7 +33230,7 @@ var aiderProvider = {
33151
33230
  }
33152
33231
  ];
33153
33232
  },
33154
- readChunks(projectPath, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
33233
+ readChunks(projectPath2, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
33155
33234
  const chunks = [];
33156
33235
  for (const filePath of sessionIds) {
33157
33236
  let content3;
@@ -33446,7 +33525,7 @@ async function searchRecall(input) {
33446
33525
  const {
33447
33526
  query,
33448
33527
  scope = "all",
33449
- projectPath,
33528
+ projectPath: projectPath2,
33450
33529
  sessionID,
33451
33530
  knowledgeEnabled = true,
33452
33531
  llm,
@@ -33473,7 +33552,7 @@ async function searchRecall(input) {
33473
33552
  if (knowledgeEnabled && scope !== "session") {
33474
33553
  try {
33475
33554
  knowledgeResults.push(
33476
- ...searchScored3({ query: q, projectPath, limit })
33555
+ ...searchScored3({ query: q, projectPath: projectPath2, limit })
33477
33556
  );
33478
33557
  } catch (err) {
33479
33558
  error("recall: knowledge search failed:", err);
@@ -33484,7 +33563,7 @@ async function searchRecall(input) {
33484
33563
  try {
33485
33564
  distillationResults.push(
33486
33565
  ...searchDistillationsScored({
33487
- projectPath,
33566
+ projectPath: projectPath2,
33488
33567
  query: q,
33489
33568
  sessionID: scope === "session" ? sessionID : void 0,
33490
33569
  limit
@@ -33499,7 +33578,7 @@ async function searchRecall(input) {
33499
33578
  try {
33500
33579
  temporalResults.push(
33501
33580
  ...searchScored({
33502
- projectPath,
33581
+ projectPath: projectPath2,
33503
33582
  query: q,
33504
33583
  sessionID: scope === "session" ? sessionID : void 0,
33505
33584
  limit
@@ -33593,7 +33672,7 @@ async function searchRecall(input) {
33593
33672
  }
33594
33673
  }
33595
33674
  if (scope !== "knowledge") {
33596
- const pid = ensureProject(projectPath);
33675
+ const pid = ensureProject(projectPath2);
33597
33676
  const temporalVectorHits = vectorSearchTemporal(
33598
33677
  queryVec,
33599
33678
  pid,
@@ -33621,11 +33700,11 @@ async function searchRecall(input) {
33621
33700
  info("recall: vector search failed:", err);
33622
33701
  }
33623
33702
  }
33624
- if (scope !== "session" && hasLatDir(projectPath)) {
33703
+ if (scope !== "session" && hasLatDir(projectPath2)) {
33625
33704
  try {
33626
33705
  const latResults = searchScored2({
33627
33706
  query,
33628
- projectPath,
33707
+ projectPath: projectPath2,
33629
33708
  limit
33630
33709
  });
33631
33710
  if (latResults.length) {
@@ -33645,7 +33724,7 @@ async function searchRecall(input) {
33645
33724
  try {
33646
33725
  const crossProjectResults = searchScoredOtherProjects({
33647
33726
  query,
33648
- excludeProjectPath: projectPath,
33727
+ excludeProjectPath: projectPath2,
33649
33728
  limit
33650
33729
  });
33651
33730
  if (crossProjectResults.length) {
@@ -33851,6 +33930,7 @@ export {
33851
33930
  distillationUser,
33852
33931
  embedding_exports as embedding,
33853
33932
  embedding_vendor_exports as embeddingVendor,
33933
+ enableHostedMode,
33854
33934
  ensureProject,
33855
33935
  exactTermMatchRank,
33856
33936
  expandQuery,
@@ -33866,6 +33946,7 @@ export {
33866
33946
  getInstanceId,
33867
33947
  getKV,
33868
33948
  getLastImportAt,
33949
+ getLastLayer,
33869
33950
  getLastTransformEstimate,
33870
33951
  getLastTransformedCount,
33871
33952
  getLastTurnAt,
@@ -33880,6 +33961,7 @@ export {
33880
33961
  inspectSessionState,
33881
33962
  instruction_detect_exports as instructionDetect,
33882
33963
  isFirstRun,
33964
+ isHostedMode,
33883
33965
  isReasoningPart,
33884
33966
  isTextPart,
33885
33967
  isToolPart,
@@ -33905,10 +33987,12 @@ export {
33905
33987
  pattern_extract_exports as patternExtract,
33906
33988
  projectId,
33907
33989
  projectName,
33990
+ projectPath,
33908
33991
  recallById,
33909
33992
  reciprocalRankFusion,
33910
33993
  recursiveUser,
33911
33994
  renderMarkdown,
33995
+ resolveProjectByRemoteOrPath,
33912
33996
  root2 as root,
33913
33997
  runRecall,
33914
33998
  sanitizeSurrogates,