grepmax 0.17.2 → 0.17.4
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/README.md +17 -0
- package/dist/commands/context.js +118 -21
- package/dist/commands/mcp.js +305 -118
- package/dist/commands/search.js +40 -102
- package/dist/eval-graph-sanity.js +225 -0
- package/dist/eval-graph-spotcheck.js +83 -0
- package/dist/eval-graph-totals.js +131 -0
- package/dist/eval-oss.js +244 -0
- package/dist/eval.js +6 -1
- package/dist/lib/output/agent-search-formatter.js +163 -0
- package/dist/lib/search/pagerank.js +267 -0
- package/dist/lib/search/searcher.js +44 -4
- package/mlx-embed-server/server.py +24 -0
- package/package.json +3 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
- package/plugins/grepmax/skills/grepmax/SKILL.md +15 -5
package/dist/commands/search.js
CHANGED
|
@@ -49,6 +49,7 @@ const commander_1 = require("commander");
|
|
|
49
49
|
const grammar_loader_1 = require("../lib/index/grammar-loader");
|
|
50
50
|
const sync_helpers_1 = require("../lib/index/sync-helpers");
|
|
51
51
|
const syncer_1 = require("../lib/index/syncer");
|
|
52
|
+
const agent_search_formatter_1 = require("../lib/output/agent-search-formatter");
|
|
52
53
|
const searcher_1 = require("../lib/search/searcher");
|
|
53
54
|
const setup_helpers_1 = require("../lib/setup/setup-helpers");
|
|
54
55
|
const skeleton_1 = require("../lib/skeleton");
|
|
@@ -346,9 +347,7 @@ function resultCountHeader(results, maxCount) {
|
|
|
346
347
|
if (p)
|
|
347
348
|
files.add(p);
|
|
348
349
|
}
|
|
349
|
-
const showing = results.length < maxCount
|
|
350
|
-
? `${results.length}`
|
|
351
|
-
: `top ${results.length}`;
|
|
350
|
+
const showing = results.length < maxCount ? `${results.length}` : `top ${results.length}`;
|
|
352
351
|
return `Found ${results.length} match${results.length === 1 ? "" : "es"} (showing ${showing}) across ${files.size} file${files.size === 1 ? "" : "s"}`;
|
|
353
352
|
}
|
|
354
353
|
exports.search = new commander_1.Command("search")
|
|
@@ -368,8 +367,8 @@ exports.search = new commander_1.Command("search")
|
|
|
368
367
|
.option("--skeleton", "Show code skeleton for matching files instead of snippets", false)
|
|
369
368
|
.option("--root <dir>", "Search a different project directory")
|
|
370
369
|
.option("--file <name>", "Filter to files matching this name (e.g. 'syncer.ts')")
|
|
371
|
-
.option("--in <subpath>", "Restrict to a sub-path of the project (repeatable; comma-separated also accepted)", (value, prev) =>
|
|
372
|
-
.option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable; e.g. 'tests/')", (value, prev) =>
|
|
370
|
+
.option("--in <subpath>", "Restrict to a sub-path of the project (repeatable; comma-separated also accepted)", (value, prev) => prev ? [...prev, value] : [value])
|
|
371
|
+
.option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable; e.g. 'tests/')", (value, prev) => prev ? [...prev, value] : [value])
|
|
373
372
|
.option("--lang <ext>", "Filter by file extension (e.g. 'ts', 'py')")
|
|
374
373
|
.option("--role <role>", "Filter by role: ORCHESTRATION, DEFINITION, IMPLEMENTATION")
|
|
375
374
|
.option("--symbol", "Append call graph after search results", false)
|
|
@@ -377,7 +376,7 @@ exports.search = new commander_1.Command("search")
|
|
|
377
376
|
.option("--name <regex>", "Filter results by symbol name regex")
|
|
378
377
|
.option("-C, --context <n>", "Include N lines before/after each result")
|
|
379
378
|
.option("--agent", "Ultra-compact output for AI agents (one line per result)", false)
|
|
380
|
-
.argument("<pattern>",
|
|
379
|
+
.argument("<pattern>", 'Natural language query (e.g. "where do we handle auth?")')
|
|
381
380
|
.argument("[path]", "Restrict search to this path prefix")
|
|
382
381
|
.addHelpText("after", `
|
|
383
382
|
Examples:
|
|
@@ -389,7 +388,7 @@ Examples:
|
|
|
389
388
|
gmax "handler" --name "handle.*" --exclude tests/
|
|
390
389
|
`)
|
|
391
390
|
.action((pattern, exec_path, _options, cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
392
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z
|
|
391
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
393
392
|
const options = cmd.optsWithGlobals();
|
|
394
393
|
const root = process.cwd();
|
|
395
394
|
const minScore = Number.isFinite(Number.parseFloat(options.minScore))
|
|
@@ -454,6 +453,24 @@ Examples:
|
|
|
454
453
|
process.exitCode = 1;
|
|
455
454
|
return; // EXIT
|
|
456
455
|
}
|
|
456
|
+
if (options.agent) {
|
|
457
|
+
const importCache = new Map();
|
|
458
|
+
const getImportsForFile = (absPath) => {
|
|
459
|
+
var _a;
|
|
460
|
+
if (!options.imports || !absPath)
|
|
461
|
+
return "";
|
|
462
|
+
if (!importCache.has(absPath)) {
|
|
463
|
+
importCache.set(absPath, (0, import_extractor_1.extractImports)(absPath));
|
|
464
|
+
}
|
|
465
|
+
return (_a = importCache.get(absPath)) !== null && _a !== void 0 ? _a : "";
|
|
466
|
+
};
|
|
467
|
+
console.log((0, agent_search_formatter_1.formatAgentSearchResults)(filteredData, projectRootForServer, {
|
|
468
|
+
includeImports: options.imports,
|
|
469
|
+
getImportsForFile,
|
|
470
|
+
explain: options.explain,
|
|
471
|
+
}));
|
|
472
|
+
return; // EXIT
|
|
473
|
+
}
|
|
457
474
|
const isTTY = process.stdout.isTTY;
|
|
458
475
|
const shouldBePlain = options.plain || !isTTY;
|
|
459
476
|
_searchResultCount = filteredData.length;
|
|
@@ -689,7 +706,7 @@ Examples:
|
|
|
689
706
|
return defs.some((d) => regex.test(d));
|
|
690
707
|
});
|
|
691
708
|
}
|
|
692
|
-
catch (
|
|
709
|
+
catch (_0) {
|
|
693
710
|
// Invalid regex — skip
|
|
694
711
|
}
|
|
695
712
|
}
|
|
@@ -712,90 +729,11 @@ Examples:
|
|
|
712
729
|
process.exitCode = 1;
|
|
713
730
|
}
|
|
714
731
|
else {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
for (const r of filteredData) {
|
|
721
|
-
const absP = (_j = (_g = r.path) !== null && _g !== void 0 ? _g : (_h = r.metadata) === null || _h === void 0 ? void 0 : _h.path) !== null && _j !== void 0 ? _j : "";
|
|
722
|
-
const arr = groups.get(absP);
|
|
723
|
-
if (arr) {
|
|
724
|
-
arr.push(r);
|
|
725
|
-
}
|
|
726
|
-
else {
|
|
727
|
-
groups.set(absP, [r]);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
const seenImportFiles = new Set();
|
|
731
|
-
for (const [absP, members] of groups) {
|
|
732
|
-
const relPath = absP.startsWith(effectiveRoot)
|
|
733
|
-
? absP.slice(effectiveRoot.length + 1)
|
|
734
|
-
: absP;
|
|
735
|
-
if (options.imports && absP && !seenImportFiles.has(absP)) {
|
|
736
|
-
seenImportFiles.add(absP);
|
|
737
|
-
const imports = getImportsForFile(absP);
|
|
738
|
-
if (imports) {
|
|
739
|
-
console.log(`[imports ${relPath}] ${imports.split("\n").join(" | ")}`);
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
const grouped = members.length > 1;
|
|
743
|
-
if (grouped) {
|
|
744
|
-
console.log(`${relPath} (${members.length} hits):`);
|
|
745
|
-
}
|
|
746
|
-
for (const r of members) {
|
|
747
|
-
const startLine = Math.max(1, ((_o = (_l = (_k = r.startLine) !== null && _k !== void 0 ? _k : r.start_line) !== null && _l !== void 0 ? _l : (_m = r.generated_metadata) === null || _m === void 0 ? void 0 : _m.start_line) !== null && _o !== void 0 ? _o : 0) + 1);
|
|
748
|
-
const defs = Array.isArray(r.defined_symbols)
|
|
749
|
-
? r.defined_symbols
|
|
750
|
-
: [];
|
|
751
|
-
const symbol = defs[0] || "";
|
|
752
|
-
const role = ((_p = r.role) !== null && _p !== void 0 ? _p : "")
|
|
753
|
-
.slice(0, 4)
|
|
754
|
-
.toUpperCase();
|
|
755
|
-
let hint = "";
|
|
756
|
-
if (r.summary) {
|
|
757
|
-
hint = ` — ${r.summary}`;
|
|
758
|
-
}
|
|
759
|
-
else {
|
|
760
|
-
// Extract first meaningful signature line from content
|
|
761
|
-
const raw = (_r = (_q = r.content) !== null && _q !== void 0 ? _q : r.text) !== null && _r !== void 0 ? _r : "";
|
|
762
|
-
const lines = raw.split("\n");
|
|
763
|
-
for (const line of lines) {
|
|
764
|
-
const trimmed = line.trim();
|
|
765
|
-
// Skip empty, comments, imports, braces, and mid-line fragments
|
|
766
|
-
if (!trimmed || trimmed.length < 5)
|
|
767
|
-
continue;
|
|
768
|
-
if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*"))
|
|
769
|
-
continue;
|
|
770
|
-
if (trimmed.startsWith("import ") || trimmed.startsWith("#") || trimmed.startsWith("File:"))
|
|
771
|
-
continue;
|
|
772
|
-
if (trimmed === "{" || trimmed === "}")
|
|
773
|
-
continue;
|
|
774
|
-
// Skip lines that look like continuations (start with punctuation, closing braces, or spread)
|
|
775
|
-
if (/^[.),;:}\]|&(+`'"!~]/.test(trimmed))
|
|
776
|
-
continue;
|
|
777
|
-
if (trimmed.startsWith("} ") || trimmed.startsWith("- ") || trimmed.startsWith("..."))
|
|
778
|
-
continue;
|
|
779
|
-
// Skip lines that look like mid-expression fragments (no keyword/declaration prefix)
|
|
780
|
-
if (/^[a-z]/.test(trimmed) && !/^(export|function|class|interface|type|const|let|var|async|return|if|for|while|switch|enum|struct|pub |fn |def |impl |mod |use )/.test(trimmed))
|
|
781
|
-
continue;
|
|
782
|
-
hint = ` — ${trimmed.length > 120 ? trimmed.slice(0, 117) + "..." : trimmed}`;
|
|
783
|
-
break;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
const sym = symbol ? ` ${symbol}` : "";
|
|
787
|
-
const rl = role ? ` [${role}]` : "";
|
|
788
|
-
const score = r.score;
|
|
789
|
-
const scoreCol = typeof score === "number" ? `\ts=${score.toFixed(3)}` : "";
|
|
790
|
-
const explainSuffix = options.explain && r.scoreBreakdown
|
|
791
|
-
? `\texplain:rerank=${r.scoreBreakdown.rerank.toFixed(3)},fused=${r.scoreBreakdown.fused.toFixed(3)},boost=${r.scoreBreakdown.boost.toFixed(2)}x,score=${r.scoreBreakdown.normalized.toFixed(3)}`
|
|
792
|
-
: "";
|
|
793
|
-
const locator = grouped
|
|
794
|
-
? ` :${startLine}`
|
|
795
|
-
: `${relPath}:${startLine}`;
|
|
796
|
-
console.log(`${locator}${scoreCol}${sym}${rl}${hint}${explainSuffix}`);
|
|
797
|
-
}
|
|
798
|
-
}
|
|
732
|
+
console.log((0, agent_search_formatter_1.formatAgentSearchResults)(filteredData, effectiveRoot, {
|
|
733
|
+
includeImports: options.imports,
|
|
734
|
+
getImportsForFile,
|
|
735
|
+
explain: options.explain,
|
|
736
|
+
}));
|
|
799
737
|
}
|
|
800
738
|
// Agent trace (compact)
|
|
801
739
|
if (options.symbol && filteredData.length > 0) {
|
|
@@ -826,7 +764,7 @@ Examples:
|
|
|
826
764
|
}
|
|
827
765
|
}
|
|
828
766
|
}
|
|
829
|
-
catch (
|
|
767
|
+
catch (_1) { }
|
|
830
768
|
}
|
|
831
769
|
return;
|
|
832
770
|
}
|
|
@@ -858,9 +796,9 @@ Examples:
|
|
|
858
796
|
let shown = 0;
|
|
859
797
|
console.log(resultCountHeader(filteredData, parseInt(options.m, 10)));
|
|
860
798
|
for (const r of filteredData) {
|
|
861
|
-
const absP = (
|
|
862
|
-
const startLine = (
|
|
863
|
-
const endLine = (
|
|
799
|
+
const absP = (_j = (_g = r.path) !== null && _g !== void 0 ? _g : (_h = r.metadata) === null || _h === void 0 ? void 0 : _h.path) !== null && _j !== void 0 ? _j : "";
|
|
800
|
+
const startLine = (_o = (_l = (_k = r.startLine) !== null && _k !== void 0 ? _k : r.start_line) !== null && _l !== void 0 ? _l : (_m = r.generated_metadata) === null || _m === void 0 ? void 0 : _m.start_line) !== null && _o !== void 0 ? _o : 0;
|
|
801
|
+
const endLine = (_s = (_q = (_p = r.endLine) !== null && _p !== void 0 ? _p : r.end_line) !== null && _q !== void 0 ? _q : (_r = r.generated_metadata) === null || _r === void 0 ? void 0 : _r.end_line) !== null && _s !== void 0 ? _s : startLine;
|
|
864
802
|
const relPath = absP.startsWith(projectRoot)
|
|
865
803
|
? absP.slice(projectRoot.length + 1)
|
|
866
804
|
: absP;
|
|
@@ -893,7 +831,7 @@ Examples:
|
|
|
893
831
|
tokensUsed += blobTokens;
|
|
894
832
|
shown++;
|
|
895
833
|
}
|
|
896
|
-
catch (
|
|
834
|
+
catch (_2) {
|
|
897
835
|
console.log(`\n--- ${relPath} (file not readable) ---`);
|
|
898
836
|
shown++;
|
|
899
837
|
}
|
|
@@ -910,7 +848,7 @@ Examples:
|
|
|
910
848
|
if (options.imports) {
|
|
911
849
|
const seenFiles = new Set();
|
|
912
850
|
for (const r of filteredData) {
|
|
913
|
-
const absP = (
|
|
851
|
+
const absP = (_v = (_t = r.path) !== null && _t !== void 0 ? _t : (_u = r.metadata) === null || _u === void 0 ? void 0 : _u.path) !== null && _v !== void 0 ? _v : "";
|
|
914
852
|
if (absP && !seenFiles.has(absP)) {
|
|
915
853
|
seenFiles.add(absP);
|
|
916
854
|
const imports = getImportsForFile(absP);
|
|
@@ -937,7 +875,7 @@ Examples:
|
|
|
937
875
|
for (const r of filteredData) {
|
|
938
876
|
const b = r.scoreBreakdown;
|
|
939
877
|
if (b) {
|
|
940
|
-
const absP = (
|
|
878
|
+
const absP = (_y = (_w = r.path) !== null && _w !== void 0 ? _w : (_x = r.metadata) === null || _x === void 0 ? void 0 : _x.path) !== null && _y !== void 0 ? _y : "";
|
|
941
879
|
const relPath = absP.startsWith(projectRoot)
|
|
942
880
|
? absP.slice(projectRoot.length + 1)
|
|
943
881
|
: absP;
|
|
@@ -999,7 +937,7 @@ Examples:
|
|
|
999
937
|
console.log(lines.join("\n"));
|
|
1000
938
|
}
|
|
1001
939
|
}
|
|
1002
|
-
catch (
|
|
940
|
+
catch (_3) {
|
|
1003
941
|
// Trace failed — skip silently
|
|
1004
942
|
}
|
|
1005
943
|
}
|
|
@@ -1019,13 +957,13 @@ Examples:
|
|
|
1019
957
|
source: "cli",
|
|
1020
958
|
tool: "search",
|
|
1021
959
|
query: pattern,
|
|
1022
|
-
project: (
|
|
960
|
+
project: (_z = (0, project_root_1.findProjectRoot)(root)) !== null && _z !== void 0 ? _z : root,
|
|
1023
961
|
results: _searchResultCount,
|
|
1024
962
|
ms: Date.now() - _searchStartMs,
|
|
1025
963
|
error: _searchError,
|
|
1026
964
|
});
|
|
1027
965
|
}
|
|
1028
|
-
catch (
|
|
966
|
+
catch (_4) { }
|
|
1029
967
|
if (vectorDb) {
|
|
1030
968
|
try {
|
|
1031
969
|
yield vectorDb.close();
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase 0 sanity check for Bundle B G1' (graph-as-recall-recovery).
|
|
4
|
+
*
|
|
5
|
+
* For each platform hard-miss case (BeyondError, ErrorCodes, resolveActor,
|
|
6
|
+
* errorHandler), mirror the searcher's dense+FTS+RRF pipeline to produce
|
|
7
|
+
* the post-fusion top-200 candidate pool, then count how many of those
|
|
8
|
+
* 200 chunks have `referenced_symbols` containing the target symbol.
|
|
9
|
+
*
|
|
10
|
+
* ≥1 hit per case = 1-hop outbound graph walk can recover the target
|
|
11
|
+
* (the seed chunk's defined symbol points at the target via the call
|
|
12
|
+
* graph) → worth building the recovery layer.
|
|
13
|
+
*
|
|
14
|
+
* 0 hits across all 4 = the signal isn't in the graph at this seed
|
|
15
|
+
* depth → stop and report the negative result.
|
|
16
|
+
*
|
|
17
|
+
* Run: `npx tsx src/eval-graph-sanity.ts`
|
|
18
|
+
*/
|
|
19
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
26
|
+
}) : (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
o[k2] = m[k];
|
|
29
|
+
}));
|
|
30
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
32
|
+
}) : function(o, v) {
|
|
33
|
+
o["default"] = v;
|
|
34
|
+
});
|
|
35
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
36
|
+
var ownKeys = function(o) {
|
|
37
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
38
|
+
var ar = [];
|
|
39
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
+
return ar;
|
|
41
|
+
};
|
|
42
|
+
return ownKeys(o);
|
|
43
|
+
};
|
|
44
|
+
return function (mod) {
|
|
45
|
+
if (mod && mod.__esModule) return mod;
|
|
46
|
+
var result = {};
|
|
47
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
48
|
+
__setModuleDefault(result, mod);
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
})();
|
|
52
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
53
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
54
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
55
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
56
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
57
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
58
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
var _a, _b;
|
|
62
|
+
var _c;
|
|
63
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
+
(_a = (_c = process.env).GMAX_WORKER_COUNT) !== null && _a !== void 0 ? _a : (_c.GMAX_WORKER_COUNT = "1");
|
|
65
|
+
const path = __importStar(require("node:path"));
|
|
66
|
+
const config_1 = require("./config");
|
|
67
|
+
const vector_db_1 = require("./lib/store/vector-db");
|
|
68
|
+
const exit_1 = require("./lib/utils/exit");
|
|
69
|
+
const pool_1 = require("./lib/workers/pool");
|
|
70
|
+
const filter_builder_1 = require("./lib/utils/filter-builder");
|
|
71
|
+
const PLATFORM_ROOT = path.join((_b = process.env.HOME) !== null && _b !== void 0 ? _b : "", "Development/beyond/platform");
|
|
72
|
+
const HARD_MISS_TARGETS = [
|
|
73
|
+
"BeyondError",
|
|
74
|
+
"ErrorCodes",
|
|
75
|
+
"resolveActor",
|
|
76
|
+
"errorHandler",
|
|
77
|
+
];
|
|
78
|
+
const PRE_K = 500;
|
|
79
|
+
const STAGE1_K = 200;
|
|
80
|
+
const RRF_K = 60;
|
|
81
|
+
function toStringArray(val) {
|
|
82
|
+
if (!val)
|
|
83
|
+
return [];
|
|
84
|
+
if (Array.isArray(val)) {
|
|
85
|
+
return val.filter((v) => typeof v === "string");
|
|
86
|
+
}
|
|
87
|
+
const maybe = val;
|
|
88
|
+
if (typeof maybe.toArray === "function") {
|
|
89
|
+
try {
|
|
90
|
+
const arr = maybe.toArray();
|
|
91
|
+
return Array.isArray(arr)
|
|
92
|
+
? arr.filter((v) => typeof v === "string")
|
|
93
|
+
: [];
|
|
94
|
+
}
|
|
95
|
+
catch (_a) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
function probe(target) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const db = new vector_db_1.VectorDB(config_1.PATHS.lancedbDir);
|
|
104
|
+
const table = yield db.ensureTable();
|
|
105
|
+
const pool = (0, pool_1.getWorkerPool)();
|
|
106
|
+
const { dense } = yield pool.encodeQuery(target);
|
|
107
|
+
const pathPrefix = PLATFORM_ROOT.endsWith("/") ? PLATFORM_ROOT : `${PLATFORM_ROOT}/`;
|
|
108
|
+
const where = `path LIKE '${(0, filter_builder_1.escapeSqlString)(pathPrefix)}%'`;
|
|
109
|
+
const columns = [
|
|
110
|
+
"id",
|
|
111
|
+
"path",
|
|
112
|
+
"chunk_index",
|
|
113
|
+
"start_line",
|
|
114
|
+
"end_line",
|
|
115
|
+
"defined_symbols",
|
|
116
|
+
"referenced_symbols",
|
|
117
|
+
];
|
|
118
|
+
const vectorRows = (yield table
|
|
119
|
+
.vectorSearch(dense)
|
|
120
|
+
.select([...columns, "_distance"])
|
|
121
|
+
.where(where)
|
|
122
|
+
.limit(PRE_K)
|
|
123
|
+
.toArray());
|
|
124
|
+
let ftsRows = [];
|
|
125
|
+
try {
|
|
126
|
+
ftsRows = (yield table
|
|
127
|
+
.search(target)
|
|
128
|
+
.select([...columns, "_score"])
|
|
129
|
+
.where(where)
|
|
130
|
+
.limit(PRE_K)
|
|
131
|
+
.toArray());
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
console.warn(`[sanity] FTS unavailable for "${target}": ${e.message}`);
|
|
135
|
+
}
|
|
136
|
+
const candidateScores = new Map();
|
|
137
|
+
const docMap = new Map();
|
|
138
|
+
vectorRows.forEach((doc, rank) => {
|
|
139
|
+
const key = doc.id ||
|
|
140
|
+
`${doc.path}:${doc.chunk_index}`;
|
|
141
|
+
docMap.set(key, doc);
|
|
142
|
+
candidateScores.set(key, (candidateScores.get(key) || 0) + 1.0 / (RRF_K + rank + 1));
|
|
143
|
+
});
|
|
144
|
+
ftsRows.forEach((doc, rank) => {
|
|
145
|
+
const key = doc.id ||
|
|
146
|
+
`${doc.path}:${doc.chunk_index}`;
|
|
147
|
+
if (!docMap.has(key))
|
|
148
|
+
docMap.set(key, doc);
|
|
149
|
+
candidateScores.set(key, (candidateScores.get(key) || 0) + 1.0 / (RRF_K + rank + 1));
|
|
150
|
+
});
|
|
151
|
+
const fused = Array.from(candidateScores.entries())
|
|
152
|
+
.sort((a, b) => b[1] - a[1])
|
|
153
|
+
.slice(0, STAGE1_K)
|
|
154
|
+
.map(([key]) => docMap.get(key))
|
|
155
|
+
.filter(Boolean);
|
|
156
|
+
let withRef = 0;
|
|
157
|
+
let withDef = 0;
|
|
158
|
+
let rankOfFirstRef = -1;
|
|
159
|
+
let rankOfFirstDef = -1;
|
|
160
|
+
const sampleRefHits = [];
|
|
161
|
+
fused.forEach((doc, i) => {
|
|
162
|
+
const refs = toStringArray(doc.referenced_symbols);
|
|
163
|
+
const defs = toStringArray(doc.defined_symbols);
|
|
164
|
+
if (refs.includes(target)) {
|
|
165
|
+
withRef++;
|
|
166
|
+
if (rankOfFirstRef < 0)
|
|
167
|
+
rankOfFirstRef = i + 1;
|
|
168
|
+
if (sampleRefHits.length < 3) {
|
|
169
|
+
sampleRefHits.push({ rank: i + 1, path: String(doc.path) });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (defs.includes(target)) {
|
|
173
|
+
withDef++;
|
|
174
|
+
if (rankOfFirstDef < 0)
|
|
175
|
+
rankOfFirstDef = i + 1;
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
yield db.close();
|
|
179
|
+
return {
|
|
180
|
+
target,
|
|
181
|
+
poolSize: fused.length,
|
|
182
|
+
vectorRows: vectorRows.length,
|
|
183
|
+
ftsRows: ftsRows.length,
|
|
184
|
+
withRef,
|
|
185
|
+
withDef,
|
|
186
|
+
rankOfFirstRef,
|
|
187
|
+
rankOfFirstDef,
|
|
188
|
+
sampleRefHits,
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function main() {
|
|
193
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
194
|
+
console.log(`Phase 0 sanity check — graph reachability on platform hard-miss cases`);
|
|
195
|
+
console.log(`pathPrefix: ${PLATFORM_ROOT}`);
|
|
196
|
+
console.log(`STAGE1_K=${STAGE1_K}, PRE_K=${PRE_K}\n`);
|
|
197
|
+
let anyReachable = false;
|
|
198
|
+
const summary = [];
|
|
199
|
+
for (const target of HARD_MISS_TARGETS) {
|
|
200
|
+
const res = yield probe(target);
|
|
201
|
+
summary.push(res);
|
|
202
|
+
const refOK = res.withRef > 0 ? "✓" : "✗";
|
|
203
|
+
const defOK = res.withDef > 0 ? "✓" : "✗";
|
|
204
|
+
console.log(`${refOK} ${target.padEnd(16)} pool=${String(res.poolSize).padStart(3)} ` +
|
|
205
|
+
`refs=${String(res.withRef).padStart(3)}/200 defs=${defOK} (${res.withDef}) ` +
|
|
206
|
+
`1st-ref@${res.rankOfFirstRef > 0 ? res.rankOfFirstRef : "—"} ` +
|
|
207
|
+
`1st-def@${res.rankOfFirstDef > 0 ? res.rankOfFirstDef : "—"}`);
|
|
208
|
+
for (const s of res.sampleRefHits) {
|
|
209
|
+
console.log(` ↳ rank ${s.rank}: ${s.path}`);
|
|
210
|
+
}
|
|
211
|
+
if (res.withRef > 0)
|
|
212
|
+
anyReachable = true;
|
|
213
|
+
}
|
|
214
|
+
console.log(`\nVerdict: ${anyReachable ? "BUILD (≥1 case has graph signal in top-200)" : "ABORT (graph is empty at this depth — pick a different mechanism)"}`);
|
|
215
|
+
console.log(`\nJSON:`);
|
|
216
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
217
|
+
yield (0, exit_1.gracefulExit)(0);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
if (require.main === module) {
|
|
221
|
+
main().catch((e) => {
|
|
222
|
+
console.error(e);
|
|
223
|
+
process.exit(1);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pulls the chunks for a known BeyondError-using file out of the index
|
|
4
|
+
* and prints their `referenced_symbols` arrays. Lets us see what the
|
|
5
|
+
* chunker actually extracts vs what's missing — whether BeyondError is
|
|
6
|
+
* absent due to chunker scope (e.g., only same-function refs are tagged)
|
|
7
|
+
* or whether the tagging is just sparse.
|
|
8
|
+
*/
|
|
9
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
10
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
11
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
12
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
13
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
14
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
15
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
var _a;
|
|
19
|
+
var _b;
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
(_a = (_b = process.env).GMAX_WORKER_COUNT) !== null && _a !== void 0 ? _a : (_b.GMAX_WORKER_COUNT = "1");
|
|
22
|
+
const config_1 = require("./config");
|
|
23
|
+
const vector_db_1 = require("./lib/store/vector-db");
|
|
24
|
+
const exit_1 = require("./lib/utils/exit");
|
|
25
|
+
const filter_builder_1 = require("./lib/utils/filter-builder");
|
|
26
|
+
const CANDIDATES = [
|
|
27
|
+
"/Users/reoiv/Development/beyond/platform/packages/api/src/middleware/error.ts",
|
|
28
|
+
"/Users/reoiv/Development/beyond/platform/packages/api/src/graphql/shared/error-mapping.ts",
|
|
29
|
+
"/Users/reoiv/Development/beyond/platform/packages/api/src/lib/service-errors.ts",
|
|
30
|
+
];
|
|
31
|
+
function toStrArr(v) {
|
|
32
|
+
if (!v)
|
|
33
|
+
return [];
|
|
34
|
+
if (Array.isArray(v))
|
|
35
|
+
return v.filter((x) => typeof x === "string");
|
|
36
|
+
const m = v;
|
|
37
|
+
if (typeof m.toArray === "function") {
|
|
38
|
+
try {
|
|
39
|
+
const a = m.toArray();
|
|
40
|
+
return Array.isArray(a) ? a.filter((x) => typeof x === "string") : [];
|
|
41
|
+
}
|
|
42
|
+
catch (_a) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
function main() {
|
|
49
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
const db = new vector_db_1.VectorDB(config_1.PATHS.lancedbDir);
|
|
51
|
+
const table = yield db.ensureTable();
|
|
52
|
+
for (const file of CANDIDATES) {
|
|
53
|
+
console.log(`\n── ${file}`);
|
|
54
|
+
const rows = (yield table
|
|
55
|
+
.query()
|
|
56
|
+
.select(["start_line", "end_line", "chunk_type", "defined_symbols", "referenced_symbols"])
|
|
57
|
+
.where(`path = '${(0, filter_builder_1.escapeSqlString)(file)}'`)
|
|
58
|
+
.limit(20)
|
|
59
|
+
.toArray());
|
|
60
|
+
if (rows.length === 0) {
|
|
61
|
+
console.log(" (no chunks indexed for this path)");
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
for (const r of rows) {
|
|
65
|
+
const defs = toStrArr(r.defined_symbols);
|
|
66
|
+
const refs = toStrArr(r.referenced_symbols);
|
|
67
|
+
const hasBE = refs.includes("BeyondError");
|
|
68
|
+
console.log(` lines ${r.start_line}-${r.end_line} (${r.chunk_type}) ` +
|
|
69
|
+
`defs=[${defs.slice(0, 4).join(",")}${defs.length > 4 ? "…" : ""}] ` +
|
|
70
|
+
`refs(${refs.length})=[${refs.slice(0, 8).join(",")}${refs.length > 8 ? "…" : ""}] ` +
|
|
71
|
+
`BeyondError-ref=${hasBE ? "✓" : "✗"}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
yield db.close();
|
|
75
|
+
yield (0, exit_1.gracefulExit)(0);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (require.main === module) {
|
|
79
|
+
main().catch((e) => {
|
|
80
|
+
console.error(e);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
});
|
|
83
|
+
}
|