@inerrata-corporation/errata 2.0.20 → 2.0.21-dev.3716

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.
@@ -16552,6 +16552,11 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
16552
16552
  -- Problems by the file their anchor hint names: the harvest upgrades hints for
16553
16553
  -- every edited file of every turn, and a scan parses every Problem's attrs.
16554
16554
  CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
16555
+ -- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
16556
+ -- tool response (the enrichment piggyback), so it must not parse every
16557
+ -- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
16558
+ -- closed versions too.
16559
+ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
16555
16560
  `;
16556
16561
  function encodeEmbedding(emb) {
16557
16562
  if (!emb || emb.length === 0) return null;
@@ -17209,7 +17214,10 @@ var SqliteGraphStore = class {
17209
17214
  }));
17210
17215
  }
17211
17216
  findAllVersionsByLabel(label, attribute) {
17212
- const rows = attribute ? this.db.prepare("SELECT * FROM nodes WHERE label = ? AND json_extract(attrs_json, ?) = ?").all(label, `$.${attribute.path}`, attribute.value) : this.stmts.findByLabelAll.all(label);
17217
+ if (attribute && !/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attribute.path)) {
17218
+ throw new Error(`invalid attr path: ${attribute.path}`);
17219
+ }
17220
+ const rows = attribute ? this.db.prepare(`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attribute.path}') = ? AND label = ?`).all(attribute.value, label) : this.stmts.findByLabelAll.all(label);
17213
17221
  return rows.map(rowToNode);
17214
17222
  }
17215
17223
  searchNodes(opts) {
@@ -17234,6 +17242,21 @@ var SqliteGraphStore = class {
17234
17242
  const rows = this.db.prepare(sql).all(params);
17235
17243
  return rows.map(rowToNode);
17236
17244
  }
17245
+ searchDescriptionTerms(terms, limit) {
17246
+ if (terms.length === 0) return [];
17247
+ const score = terms.map(() => "(description LIKE ?)").join(" + ");
17248
+ const rows = this.db.prepare(
17249
+ `SELECT n.*, h.m AS matched
17250
+ FROM (SELECT rowid AS rid, ${score} AS m
17251
+ FROM nodes INDEXED BY nodes_live_description
17252
+ WHERE valid_to IS NULL) h
17253
+ JOIN nodes n ON n.rowid = h.rid
17254
+ WHERE h.m > 0
17255
+ ORDER BY h.m DESC, n.page_rank DESC, n.last_updated_at DESC
17256
+ LIMIT ?`
17257
+ ).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
17258
+ return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
17259
+ }
17237
17260
  typedEdgeStmt(sql) {
17238
17261
  let stmt = this.typedEdgeStmts.get(sql);
17239
17262
  if (!stmt) {
@@ -19383,6 +19406,21 @@ function buildSymbolLexicon(store) {
19383
19406
  }
19384
19407
  return lex;
19385
19408
  }
19409
+ var LEXICON_SYMBOL_LABELS = ["Function", "Method", "Class", "Interface", "Const", "Comment"];
19410
+ function codeGraphKey(store) {
19411
+ const files = store.labelFingerprint?.(["File"]);
19412
+ if (files === void 0) return null;
19413
+ return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
19414
+ }
19415
+ var lexiconCache = /* @__PURE__ */ new WeakMap();
19416
+ function lexiconsFor(store) {
19417
+ const key = codeGraphKey(store);
19418
+ const hit = key !== null ? lexiconCache.get(store) : void 0;
19419
+ if (hit && hit.key === key) return hit;
19420
+ const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
19421
+ if (key !== null) lexiconCache.set(store, { key, ...built });
19422
+ return built;
19423
+ }
19386
19424
  var RE_RESERVED = /[.*+?^${}()|[\]\\]/g;
19387
19425
  var escapeRe2 = (s) => s.replace(RE_RESERVED, "\\$&");
19388
19426
  var RE_LEADING_ARTICLE = /^(?:an?|the)\s/i;
@@ -20126,21 +20164,6 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
20126
20164
  }
20127
20165
 
20128
20166
  // src/drain-build.ts
20129
- var LEXICON_SYMBOL_LABELS = ["Function", "Method", "Class", "Interface", "Const", "Comment"];
20130
- function codeGraphKey(store) {
20131
- const files = store.labelFingerprint?.(["File"]);
20132
- if (files === void 0) return null;
20133
- return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
20134
- }
20135
- var lexiconCache = /* @__PURE__ */ new WeakMap();
20136
- function lexiconsFor(store) {
20137
- const key = codeGraphKey(store);
20138
- const hit = key !== null ? lexiconCache.get(store) : void 0;
20139
- if (hit && hit.key === key) return hit;
20140
- const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
20141
- if (key !== null) lexiconCache.set(store, { key, ...built });
20142
- return built;
20143
- }
20144
20167
  function buildDrainContext(store, input) {
20145
20168
  return buildContextIngest(store, input.profile, input.daemonVersion, input.ignorePatterns, {
20146
20169
  ...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {}