@inerrata-corporation/errata 2.0.20-dev.3690 → 2.0.20-dev.3704
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.
package/consolidate-worker.mjs
CHANGED
|
@@ -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
|
-
|
|
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 } : {}
|
package/errata.mjs
CHANGED
|
@@ -18597,6 +18597,11 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
18597
18597
|
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
18598
18598
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
18599
18599
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
18600
|
+
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
18601
|
+
-- tool response (the enrichment piggyback), so it must not parse every
|
|
18602
|
+
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
18603
|
+
-- closed versions too.
|
|
18604
|
+
CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
|
|
18600
18605
|
`;
|
|
18601
18606
|
FINGERPRINT_INDEXED_LABELS = ["Problem", "Vulnerability", "Solution", "RootCause"];
|
|
18602
18607
|
NODE_LABELS_CHUNK = 256;
|
|
@@ -19197,7 +19202,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
19197
19202
|
}));
|
|
19198
19203
|
}
|
|
19199
19204
|
findAllVersionsByLabel(label, attribute) {
|
|
19200
|
-
|
|
19205
|
+
if (attribute && !/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attribute.path)) {
|
|
19206
|
+
throw new Error(`invalid attr path: ${attribute.path}`);
|
|
19207
|
+
}
|
|
19208
|
+
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);
|
|
19201
19209
|
return rows.map(rowToNode);
|
|
19202
19210
|
}
|
|
19203
19211
|
searchNodes(opts) {
|
|
@@ -19222,6 +19230,21 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
19222
19230
|
const rows = this.db.prepare(sql).all(params);
|
|
19223
19231
|
return rows.map(rowToNode);
|
|
19224
19232
|
}
|
|
19233
|
+
searchDescriptionTerms(terms, limit) {
|
|
19234
|
+
if (terms.length === 0) return [];
|
|
19235
|
+
const score2 = terms.map(() => "(description LIKE ?)").join(" + ");
|
|
19236
|
+
const rows = this.db.prepare(
|
|
19237
|
+
`SELECT n.*, h.m AS matched
|
|
19238
|
+
FROM (SELECT rowid AS rid, ${score2} AS m
|
|
19239
|
+
FROM nodes INDEXED BY nodes_live_description
|
|
19240
|
+
WHERE valid_to IS NULL) h
|
|
19241
|
+
JOIN nodes n ON n.rowid = h.rid
|
|
19242
|
+
WHERE h.m > 0
|
|
19243
|
+
ORDER BY h.m DESC, n.page_rank DESC, n.last_updated_at DESC
|
|
19244
|
+
LIMIT ?`
|
|
19245
|
+
).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
|
|
19246
|
+
return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
|
|
19247
|
+
}
|
|
19225
19248
|
typedEdgeStmt(sql) {
|
|
19226
19249
|
let stmt = this.typedEdgeStmts.get(sql);
|
|
19227
19250
|
if (!stmt) {
|
|
@@ -34444,6 +34467,19 @@ function buildSymbolLexicon(store) {
|
|
|
34444
34467
|
}
|
|
34445
34468
|
return lex;
|
|
34446
34469
|
}
|
|
34470
|
+
function codeGraphKey(store) {
|
|
34471
|
+
const files = store.labelFingerprint?.(["File"]);
|
|
34472
|
+
if (files === void 0) return null;
|
|
34473
|
+
return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
|
|
34474
|
+
}
|
|
34475
|
+
function lexiconsFor(store) {
|
|
34476
|
+
const key = codeGraphKey(store);
|
|
34477
|
+
const hit = key !== null ? lexiconCache.get(store) : void 0;
|
|
34478
|
+
if (hit && hit.key === key) return hit;
|
|
34479
|
+
const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
|
|
34480
|
+
if (key !== null) lexiconCache.set(store, { key, ...built });
|
|
34481
|
+
return built;
|
|
34482
|
+
}
|
|
34447
34483
|
function replaceWithPhrase(text, before, escapedKey, after, phrase2) {
|
|
34448
34484
|
if (!RE_LEADING_ARTICLE2.test(phrase2)) {
|
|
34449
34485
|
return text.replace(new RegExp(`${before}${escapedKey}${after}`, "g"), phrase2);
|
|
@@ -34609,7 +34645,7 @@ function registerRenderedContributorLabels(labels) {
|
|
|
34609
34645
|
if (trimmed.length >= 3) renderedContributorLabels.add(trimmed);
|
|
34610
34646
|
}
|
|
34611
34647
|
}
|
|
34612
|
-
var SYMBOL_LABELS2, KIND_PHRASE, BUILTIN_TYPE_NAMES, DOC_COMMENT_KINDS, MAX_DOC_CHARS, RE_RESERVED2, escapeRe4, RE_LEADING_ARTICLE2, CONVENTION_FILENAMES, CONVENTION_BASENAME_MIN_FILES, CONVENTION_STEMS, FILE_TOKEN_RE, STEM_TOKEN_RE, SOURCE_EXTENSIONS, TOKEN_RE3, renderedContributorLabels;
|
|
34648
|
+
var SYMBOL_LABELS2, KIND_PHRASE, BUILTIN_TYPE_NAMES, DOC_COMMENT_KINDS, MAX_DOC_CHARS, LEXICON_SYMBOL_LABELS, lexiconCache, RE_RESERVED2, escapeRe4, RE_LEADING_ARTICLE2, CONVENTION_FILENAMES, CONVENTION_BASENAME_MIN_FILES, CONVENTION_STEMS, FILE_TOKEN_RE, STEM_TOKEN_RE, SOURCE_EXTENSIONS, TOKEN_RE3, renderedContributorLabels;
|
|
34613
34649
|
var init_generalize_graph = __esm({
|
|
34614
34650
|
"src/generalize-graph.ts"() {
|
|
34615
34651
|
"use strict";
|
|
@@ -34659,6 +34695,8 @@ var init_generalize_graph = __esm({
|
|
|
34659
34695
|
]);
|
|
34660
34696
|
DOC_COMMENT_KINDS = /* @__PURE__ */ new Set(["docstring", "explanation"]);
|
|
34661
34697
|
MAX_DOC_CHARS = 600;
|
|
34698
|
+
LEXICON_SYMBOL_LABELS = ["Function", "Method", "Class", "Interface", "Const", "Comment"];
|
|
34699
|
+
lexiconCache = /* @__PURE__ */ new WeakMap();
|
|
34662
34700
|
RE_RESERVED2 = /[.*+?^${}()|[\]\\]/g;
|
|
34663
34701
|
escapeRe4 = (s) => s.replace(RE_RESERVED2, "\\$&");
|
|
34664
34702
|
RE_LEADING_ARTICLE2 = /^(?:an?|the)\s/i;
|
|
@@ -34867,13 +34905,12 @@ async function dualAugment(opts) {
|
|
|
34867
34905
|
let seedProvenance = "local";
|
|
34868
34906
|
const calls = [];
|
|
34869
34907
|
try {
|
|
34870
|
-
const lexicon = buildSymbolLexicon(store);
|
|
34871
34908
|
const hardIds = [.../* @__PURE__ */ new Set([...seedNode ? [seedNode.id] : [], ...localHits.map((h) => h.id)])].filter((nid) => {
|
|
34872
34909
|
const n = seedNode && nid === seedNode.id ? seedNode : store.getNode(nid);
|
|
34873
34910
|
return !!n && isHardBridge(n);
|
|
34874
34911
|
});
|
|
34875
34912
|
const softText = queryText ?? (seedNode && BRIDGE_LABELS.has(seedNode.label) ? seedNode.description : void 0);
|
|
34876
|
-
const softQ = softText ? generalizeSymbols(softText,
|
|
34913
|
+
const softQ = softText ? generalizeSymbols(softText, lexiconsFor(store).symbols, 1) : void 0;
|
|
34877
34914
|
if (seedNode?.label === "Package") {
|
|
34878
34915
|
calls.push(
|
|
34879
34916
|
cloud.packages(seedNode.id).then((pn) => {
|
|
@@ -43927,7 +43964,7 @@ __export(mcp_exports, {
|
|
|
43927
43964
|
import { existsSync as existsSync17, readFileSync as readFileSync16 } from "node:fs";
|
|
43928
43965
|
import { resolve as resolve4 } from "node:path";
|
|
43929
43966
|
function collectEnrichmentPulls(store, opts = {}) {
|
|
43930
|
-
const pending = store.
|
|
43967
|
+
const pending = store.findLiveNodesByAttr("Solution", "enrichmentPending", 1).filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
|
|
43931
43968
|
const byEpisode = /* @__PURE__ */ new Map();
|
|
43932
43969
|
for (const s of pending) {
|
|
43933
43970
|
const ep = s.attrs["episodeId"] ?? s.id;
|
|
@@ -44044,20 +44081,8 @@ function searchGraph(store, query, limit) {
|
|
|
44044
44081
|
const terms = q.split(/\s+/).filter((t) => t.length >= 2);
|
|
44045
44082
|
const pool = Math.max(limit * 3, 60);
|
|
44046
44083
|
const raw2 = /* @__PURE__ */ new Map();
|
|
44047
|
-
const
|
|
44048
|
-
|
|
44049
|
-
const e = raw2.get(n.id);
|
|
44050
|
-
if (e) e.matched++;
|
|
44051
|
-
else raw2.set(n.id, { node: n, matched: 1 });
|
|
44052
|
-
}
|
|
44053
|
-
};
|
|
44054
|
-
if (terms.length <= 1) {
|
|
44055
|
-
collect2(store.searchNodes({ descriptionLike: q, limit: pool }));
|
|
44056
|
-
} else {
|
|
44057
|
-
for (const term of terms) {
|
|
44058
|
-
collect2(store.searchNodes({ descriptionLike: term, limit: 200 }));
|
|
44059
|
-
}
|
|
44060
|
-
}
|
|
44084
|
+
const scored = !q ? store.searchNodes({ limit: pool }).map((node2) => ({ node: node2, matched: 1 })) : terms.length <= 1 ? store.searchDescriptionTerms([q], pool) : store.searchDescriptionTerms(terms, Math.max(pool, 600));
|
|
44085
|
+
for (const hit of scored) raw2.set(hit.node.id, hit);
|
|
44061
44086
|
const merged = /* @__PURE__ */ new Map();
|
|
44062
44087
|
const add = (node2, matched, via) => {
|
|
44063
44088
|
const e = merged.get(node2.id);
|
|
@@ -82779,7 +82804,7 @@ function createWatchBreaker(deps) {
|
|
|
82779
82804
|
}
|
|
82780
82805
|
|
|
82781
82806
|
// src/engine.ts
|
|
82782
|
-
var DAEMON_VERSION = true ? "2.0.20-dev.
|
|
82807
|
+
var DAEMON_VERSION = true ? "2.0.20-dev.3704" : "2.0.0-alpha.0";
|
|
82783
82808
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
82784
82809
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
82785
82810
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -86810,21 +86835,7 @@ function liveBackoffMs(failures) {
|
|
|
86810
86835
|
|
|
86811
86836
|
// src/drain-build.ts
|
|
86812
86837
|
init_generalize_graph();
|
|
86813
|
-
|
|
86814
|
-
function codeGraphKey(store) {
|
|
86815
|
-
const files = store.labelFingerprint?.(["File"]);
|
|
86816
|
-
if (files === void 0) return null;
|
|
86817
|
-
return [files, ...LEXICON_SYMBOL_LABELS.map((l) => store.countNodesByLabel(l))].join("|");
|
|
86818
|
-
}
|
|
86819
|
-
var lexiconCache = /* @__PURE__ */ new WeakMap();
|
|
86820
|
-
function lexiconsFor(store) {
|
|
86821
|
-
const key = codeGraphKey(store);
|
|
86822
|
-
const hit = key !== null ? lexiconCache.get(store) : void 0;
|
|
86823
|
-
if (hit && hit.key === key) return hit;
|
|
86824
|
-
const built = { symbols: buildSymbolLexicon(store), files: buildFileLexicon(store) };
|
|
86825
|
-
if (key !== null) lexiconCache.set(store, { key, ...built });
|
|
86826
|
-
return built;
|
|
86827
|
-
}
|
|
86838
|
+
init_generalize_graph();
|
|
86828
86839
|
function buildDrainContext(store, input) {
|
|
86829
86840
|
return buildContextIngest(store, input.profile, input.daemonVersion, input.ignorePatterns, {
|
|
86830
86841
|
...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {}
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -25581,6 +25581,11 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
25581
25581
|
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
25582
25582
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
25583
25583
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
25584
|
+
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
25585
|
+
-- tool response (the enrichment piggyback), so it must not parse every
|
|
25586
|
+
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
25587
|
+
-- closed versions too.
|
|
25588
|
+
CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
|
|
25584
25589
|
`;
|
|
25585
25590
|
function encodeEmbedding(emb) {
|
|
25586
25591
|
if (!emb || emb.length === 0) return null;
|
|
@@ -26238,7 +26243,10 @@ var SqliteGraphStore = class {
|
|
|
26238
26243
|
}));
|
|
26239
26244
|
}
|
|
26240
26245
|
findAllVersionsByLabel(label, attribute) {
|
|
26241
|
-
|
|
26246
|
+
if (attribute && !/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attribute.path)) {
|
|
26247
|
+
throw new Error(`invalid attr path: ${attribute.path}`);
|
|
26248
|
+
}
|
|
26249
|
+
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);
|
|
26242
26250
|
return rows.map(rowToNode);
|
|
26243
26251
|
}
|
|
26244
26252
|
searchNodes(opts) {
|
|
@@ -26263,6 +26271,21 @@ var SqliteGraphStore = class {
|
|
|
26263
26271
|
const rows = this.db.prepare(sql).all(params);
|
|
26264
26272
|
return rows.map(rowToNode);
|
|
26265
26273
|
}
|
|
26274
|
+
searchDescriptionTerms(terms, limit) {
|
|
26275
|
+
if (terms.length === 0) return [];
|
|
26276
|
+
const score2 = terms.map(() => "(description LIKE ?)").join(" + ");
|
|
26277
|
+
const rows = this.db.prepare(
|
|
26278
|
+
`SELECT n.*, h.m AS matched
|
|
26279
|
+
FROM (SELECT rowid AS rid, ${score2} AS m
|
|
26280
|
+
FROM nodes INDEXED BY nodes_live_description
|
|
26281
|
+
WHERE valid_to IS NULL) h
|
|
26282
|
+
JOIN nodes n ON n.rowid = h.rid
|
|
26283
|
+
WHERE h.m > 0
|
|
26284
|
+
ORDER BY h.m DESC, n.page_rank DESC, n.last_updated_at DESC
|
|
26285
|
+
LIMIT ?`
|
|
26286
|
+
).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
|
|
26287
|
+
return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
|
|
26288
|
+
}
|
|
26266
26289
|
typedEdgeStmt(sql) {
|
|
26267
26290
|
let stmt = this.typedEdgeStmts.get(sql);
|
|
26268
26291
|
if (!stmt) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
afb5db840916d7c565672ed92c16364144acdada84a9eceaa9ae0b1204277214 .codex-plugin/plugin.json
|
|
2
2
|
a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
|
|
3
3
|
fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
|
|
4
4
|
73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js
|