lens-engine 0.1.15 → 0.1.16

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 (2) hide show
  1. package/daemon.js +81 -8
  2. package/package.json +1 -1
package/daemon.js CHANGED
@@ -7717,6 +7717,11 @@ function openDb(customPath) {
7717
7717
  sqlite.pragma("foreign_keys = ON");
7718
7718
  const db = drizzle(sqlite, { schema: schema_exports });
7719
7719
  sqlite.exec(createTablesSql());
7720
+ const cols = new Set(
7721
+ sqlite.pragma("table_info(file_metadata)").map((c) => c.name)
7722
+ );
7723
+ if (!cols.has("sections")) sqlite.exec("ALTER TABLE file_metadata ADD COLUMN sections TEXT DEFAULT '[]'");
7724
+ if (!cols.has("internals")) sqlite.exec("ALTER TABLE file_metadata ADD COLUMN internals TEXT DEFAULT '[]'");
7720
7725
  _db = db;
7721
7726
  _raw = sqlite;
7722
7727
  return db;
@@ -7781,6 +7786,8 @@ function createTablesSql() {
7781
7786
  exports TEXT DEFAULT '[]',
7782
7787
  imports TEXT DEFAULT '[]',
7783
7788
  docstring TEXT DEFAULT '',
7789
+ sections TEXT DEFAULT '[]',
7790
+ internals TEXT DEFAULT '[]',
7784
7791
  purpose TEXT DEFAULT '',
7785
7792
  purpose_hash TEXT DEFAULT '',
7786
7793
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
@@ -8238,13 +8245,59 @@ function extractDocstring(content, language) {
8238
8245
  if (!m) return "";
8239
8246
  return m[1]?.replace(/\s*\*\s*/g, " ").trim().slice(0, 200) ?? "";
8240
8247
  }
8248
+ function extractSections(content) {
8249
+ const seen = /* @__PURE__ */ new Set();
8250
+ const sections = [];
8251
+ for (const re of [SECTION_SINGLE_RE, SECTION_BLOCK_RE]) {
8252
+ const pattern = new RegExp(re.source, re.flags);
8253
+ for (const m of content.matchAll(pattern)) {
8254
+ const label = m[1]?.trim();
8255
+ if (label && !seen.has(label)) {
8256
+ seen.add(label);
8257
+ sections.push(label);
8258
+ }
8259
+ }
8260
+ }
8261
+ return sections.slice(0, 15);
8262
+ }
8263
+ function extractInternals(content, language, exports) {
8264
+ switch (language) {
8265
+ case "typescript":
8266
+ case "javascript":
8267
+ case "tsx":
8268
+ case "jsx":
8269
+ break;
8270
+ default:
8271
+ return [];
8272
+ }
8273
+ const exportSet = new Set(exports);
8274
+ const seen = /* @__PURE__ */ new Set();
8275
+ const internals = [];
8276
+ for (const line of content.split("\n")) {
8277
+ if (line.trimStart().startsWith("export")) continue;
8278
+ for (const re of [TS_INTERNAL_FN_RE, TS_INTERNAL_CONST_RE]) {
8279
+ const pattern = new RegExp(re.source, re.flags);
8280
+ for (const m of line.matchAll(pattern)) {
8281
+ const name = m[1];
8282
+ if (name && name.length >= 6 && !exportSet.has(name) && !seen.has(name)) {
8283
+ seen.add(name);
8284
+ internals.push(name);
8285
+ }
8286
+ }
8287
+ }
8288
+ }
8289
+ return internals.slice(0, 20);
8290
+ }
8241
8291
  function extractFileMetadata(path, content, language) {
8292
+ const exports = extractExports(content, language);
8242
8293
  return {
8243
8294
  path,
8244
8295
  language,
8245
- exports: extractExports(content, language),
8296
+ exports,
8246
8297
  imports: extractImportSpecifiers(content, language),
8247
- docstring: extractDocstring(content, language)
8298
+ docstring: extractDocstring(content, language),
8299
+ sections: extractSections(content),
8300
+ internals: extractInternals(content, language, exports)
8248
8301
  };
8249
8302
  }
8250
8303
  function extractAndPersistMetadata(db, repoId) {
@@ -8264,7 +8317,7 @@ function extractAndPersistMetadata(db, repoId) {
8264
8317
  let count = 0;
8265
8318
  for (const [path, { content, language }] of files) {
8266
8319
  const meta = extractFileMetadata(path, content, language);
8267
- metadataQueries.upsert(db, repoId, path, language, meta.exports, meta.imports, meta.docstring);
8320
+ metadataQueries.upsert(db, repoId, path, language, meta.exports, meta.imports, meta.docstring, meta.sections, meta.internals);
8268
8321
  count++;
8269
8322
  }
8270
8323
  return count;
@@ -9063,7 +9116,7 @@ function buildTermWeights(words, metadata) {
9063
9116
  for (const w of words) {
9064
9117
  let df = 0;
9065
9118
  for (const f of metadata) {
9066
- const haystack = `${f.path} ${(f.exports ?? []).join(" ")} ${f.docstring ?? ""} ${f.purpose ?? ""}`.toLowerCase();
9119
+ const haystack = `${f.path} ${(f.exports ?? []).join(" ")} ${f.docstring ?? ""} ${f.purpose ?? ""} ${(f.sections ?? []).join(" ")} ${(f.internals ?? []).join(" ")}`.toLowerCase();
9067
9120
  if (haystack.includes(w)) df++;
9068
9121
  }
9069
9122
  const idf = df > 0 ? Math.min(10, Math.max(1, Math.log(N / df))) : 10;
@@ -9083,6 +9136,8 @@ function interpretQuery(query, metadata, fileStats2, vocabClusters, indegrees, m
9083
9136
  const exportsLower = (f.exports ?? []).join(" ").toLowerCase();
9084
9137
  const docLower = (f.docstring ?? "").toLowerCase();
9085
9138
  const purposeLower = (f.purpose ?? "").toLowerCase();
9139
+ const sectionsLower = (f.sections ?? []).join(" ").toLowerCase();
9140
+ const internalsLower = (f.internals ?? []).join(" ").toLowerCase();
9086
9141
  const pathSegments = pathLower.split("/");
9087
9142
  const fileName = pathSegments[pathSegments.length - 1].replace(/\.[^.]+$/, "");
9088
9143
  const fileTokens = fileName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[._-]/g, " ").toLowerCase().split(/\s+/).filter((t) => t.length >= 2);
@@ -9095,6 +9150,8 @@ function interpretQuery(query, metadata, fileStats2, vocabClusters, indegrees, m
9095
9150
  else if (pathTokenSet.has(w)) termScore += 2 * weight;
9096
9151
  if (exportsLower.includes(w)) termScore += 2 * weight;
9097
9152
  if (docLower.includes(w) || purposeLower.includes(w)) termScore += 1 * weight;
9153
+ if (sectionsLower.includes(w)) termScore += 1 * weight;
9154
+ if (internalsLower.includes(w)) termScore += 1.5 * weight;
9098
9155
  if (termScore > 0) matchedTerms++;
9099
9156
  score += termScore;
9100
9157
  }
@@ -9103,6 +9160,8 @@ function interpretQuery(query, metadata, fileStats2, vocabClusters, indegrees, m
9103
9160
  let termScore = 0;
9104
9161
  if (exportsLower.includes(w)) termScore += 2 * weight;
9105
9162
  if (docLower.includes(w) || purposeLower.includes(w)) termScore += 1 * weight;
9163
+ if (sectionsLower.includes(w)) termScore += 1 * weight;
9164
+ if (internalsLower.includes(w)) termScore += 1.5 * weight;
9106
9165
  if (termScore > 0) matchedTerms++;
9107
9166
  score += termScore;
9108
9167
  }
@@ -9404,7 +9463,7 @@ Context generation failed.`,
9404
9463
  };
9405
9464
  }
9406
9465
  }
9407
- var __defProp2, __getOwnPropNames2, __esm2, __export2, schema_exports, uuid, now, updatedAt, repos, chunks, fileMetadata, fileImports, fileStats, fileCochanges, usageCounters, requestLogs, telemetryEvents, init_schema, queries_exports, repoQueries, chunkQueries, metadataQueries, importQueries, statsQueries, cochangeQueries, logQueries, usageQueries, telemetryQueries, init_queries, _db, _raw, execFileAsync, MAX_FILE_SIZE, BINARY_EXTENSIONS, DOCS_EXTENSIONS, LANG_MAP, DEFAULT_CHUNKING_PARAMS, TS_IMPORT_RE, PY_IMPORT_RE, GO_IMPORT_RE, RUST_USE_RE, TS_EXTENSIONS, PY_EXTENSIONS, TS_EXPORT_RE, PY_EXPORT_RE, GO_EXPORT_RE, RUST_EXPORT_RE, CSHARP_EXPORT_RE, JAVA_EXPORT_RE, JSDOC_RE, PY_DOCSTRING_RE, CSHARP_DOC_RE, GO_PKG_RE, TERM_BATCH_SIZE, SIMILARITY_THRESHOLD, MAX_TERMS, MAX_CLUSTERS, MAX_CLUSTER_SIZE, STOPWORDS, execFileAsync2, MAX_COMMITS, MAX_FILES_PER_COMMIT, RECENT_DAYS, _enabled, MAX_CHUNKS_PER_REPO, locks, MAX_API_CALLS, POOL_SIZE, MAX_BATCH_TOKENS, CHARS_PER_TOKEN, PURPOSE_BATCH_LIMIT, PURPOSE_CONCURRENCY, watchers, debounceTimers, IGNORED, DEBOUNCE_MS, STOPWORDS2, NOISE_EXTENSIONS, NOISE_PATHS, CONCEPT_SYNONYMS, CACHE_TTL, CACHE_MAX, cache;
9466
+ var __defProp2, __getOwnPropNames2, __esm2, __export2, schema_exports, uuid, now, updatedAt, repos, chunks, fileMetadata, fileImports, fileStats, fileCochanges, usageCounters, requestLogs, telemetryEvents, init_schema, queries_exports, repoQueries, chunkQueries, metadataQueries, importQueries, statsQueries, cochangeQueries, logQueries, usageQueries, telemetryQueries, init_queries, _db, _raw, execFileAsync, MAX_FILE_SIZE, BINARY_EXTENSIONS, DOCS_EXTENSIONS, LANG_MAP, DEFAULT_CHUNKING_PARAMS, TS_IMPORT_RE, PY_IMPORT_RE, GO_IMPORT_RE, RUST_USE_RE, TS_EXTENSIONS, PY_EXTENSIONS, TS_EXPORT_RE, PY_EXPORT_RE, GO_EXPORT_RE, RUST_EXPORT_RE, CSHARP_EXPORT_RE, JAVA_EXPORT_RE, JSDOC_RE, PY_DOCSTRING_RE, CSHARP_DOC_RE, GO_PKG_RE, SECTION_SINGLE_RE, SECTION_BLOCK_RE, TS_INTERNAL_FN_RE, TS_INTERNAL_CONST_RE, TERM_BATCH_SIZE, SIMILARITY_THRESHOLD, MAX_TERMS, MAX_CLUSTERS, MAX_CLUSTER_SIZE, STOPWORDS, execFileAsync2, MAX_COMMITS, MAX_FILES_PER_COMMIT, RECENT_DAYS, _enabled, MAX_CHUNKS_PER_REPO, locks, MAX_API_CALLS, POOL_SIZE, MAX_BATCH_TOKENS, CHARS_PER_TOKEN, PURPOSE_BATCH_LIMIT, PURPOSE_CONCURRENCY, watchers, debounceTimers, IGNORED, DEBOUNCE_MS, STOPWORDS2, NOISE_EXTENSIONS, NOISE_PATHS, CONCEPT_SYNONYMS, CACHE_TTL, CACHE_MAX, cache;
9408
9467
  var init_dist = __esm({
9409
9468
  "packages/engine/dist/index.js"() {
9410
9469
  "use strict";
@@ -9493,6 +9552,8 @@ var init_dist = __esm({
9493
9552
  exports: text("exports").default("[]"),
9494
9553
  imports: text("imports").default("[]"),
9495
9554
  docstring: text("docstring").default(""),
9555
+ sections: text("sections").default("[]"),
9556
+ internals: text("internals").default("[]"),
9496
9557
  purpose: text("purpose").default(""),
9497
9558
  purpose_hash: text("purpose_hash").default(""),
9498
9559
  updated_at: updatedAt()
@@ -9785,7 +9846,7 @@ var init_dist = __esm({
9785
9846
  }
9786
9847
  };
9787
9848
  metadataQueries = {
9788
- upsert(db, repoId, path, language, exports, imports, docstring) {
9849
+ upsert(db, repoId, path, language, exports, imports, docstring, sections, internals) {
9789
9850
  db.insert(fileMetadata).values({
9790
9851
  id: randomUUID(),
9791
9852
  repo_id: repoId,
@@ -9793,7 +9854,9 @@ var init_dist = __esm({
9793
9854
  language,
9794
9855
  exports: JSON.stringify(exports),
9795
9856
  imports: JSON.stringify(imports),
9796
- docstring
9857
+ docstring,
9858
+ sections: JSON.stringify(sections),
9859
+ internals: JSON.stringify(internals)
9797
9860
  }).onConflictDoUpdate({
9798
9861
  target: [fileMetadata.repo_id, fileMetadata.path],
9799
9862
  set: {
@@ -9801,6 +9864,8 @@ var init_dist = __esm({
9801
9864
  exports: JSON.stringify(exports),
9802
9865
  imports: JSON.stringify(imports),
9803
9866
  docstring,
9867
+ sections: JSON.stringify(sections),
9868
+ internals: JSON.stringify(internals),
9804
9869
  updated_at: sql`datetime('now')`
9805
9870
  }
9806
9871
  }).run();
@@ -9811,11 +9876,15 @@ var init_dist = __esm({
9811
9876
  language: fileMetadata.language,
9812
9877
  exports: fileMetadata.exports,
9813
9878
  docstring: fileMetadata.docstring,
9879
+ sections: fileMetadata.sections,
9880
+ internals: fileMetadata.internals,
9814
9881
  purpose: fileMetadata.purpose
9815
9882
  }).from(fileMetadata).where(eq(fileMetadata.repo_id, repoId)).orderBy(fileMetadata.path).all().map((r) => ({
9816
9883
  ...r,
9817
9884
  exports: jsonParse(r.exports, []),
9818
9885
  docstring: r.docstring ?? "",
9886
+ sections: jsonParse(r.sections, []),
9887
+ internals: jsonParse(r.internals, []),
9819
9888
  purpose: r.purpose ?? ""
9820
9889
  }));
9821
9890
  },
@@ -10184,6 +10253,10 @@ var init_dist = __esm({
10184
10253
  PY_DOCSTRING_RE = /^(?:["']{3})([\s\S]*?)(?:["']{3})/m;
10185
10254
  CSHARP_DOC_RE = /^(?:\s*\/\/\/\s*(.*))+/m;
10186
10255
  GO_PKG_RE = /^\/\/\s*Package\s+\w+\s+(.*)/m;
10256
+ SECTION_SINGLE_RE = /^(?:\/\/|#)\s*[-=]{3,}\s*(.+?)\s*[-=]{3,}\s*$/gm;
10257
+ SECTION_BLOCK_RE = /^\/\*\s*[-=]{3,}\s*(.+?)\s*[-=]{3,}\s*\*\/$/gm;
10258
+ TS_INTERNAL_FN_RE = /^(?:async\s+)?function\s+(\w+)/gm;
10259
+ TS_INTERNAL_CONST_RE = /^(?:const|let)\s+(\w+)\s*=/gm;
10187
10260
  init_queries();
10188
10261
  init_queries();
10189
10262
  TERM_BATCH_SIZE = 32;
@@ -34525,7 +34598,7 @@ function createApp(db, dashboardDist, initialCaps, initialPlanData) {
34525
34598
  const duration3 = Math.round(performance.now() - start);
34526
34599
  const path = new URL(c.req.url).pathname;
34527
34600
  const source = deriveSource(c.req.raw, path);
34528
- if (path.startsWith("/dashboard/") && !path.startsWith("/api/")) return;
34601
+ if (path.startsWith("/dashboard/") || path.startsWith("/api/dashboard/")) return;
34529
34602
  if (path === "/health") return;
34530
34603
  try {
34531
34604
  logQueries.insert(db, c.req.method, path, c.res.status, duration3, source);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lens-engine",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "LENS — Local-first repo context engine for AI agents",
5
5
  "type": "module",
6
6
  "bin": {