grepmax 0.26.44 → 0.26.45
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.
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "grepmax",
|
|
11
11
|
"source": "./plugins/grepmax",
|
|
12
12
|
"description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
|
|
13
|
-
"version": "0.26.
|
|
13
|
+
"version": "0.26.45",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Robert Owens",
|
|
16
16
|
"email": "robowens@me.com"
|
package/README.md
CHANGED
|
@@ -130,6 +130,8 @@ MCP is local-only: the client spawns it and communicates through stdin/stdout pi
|
|
|
130
130
|
|
|
131
131
|
`gmax mcp` starts a stdio-based MCP server for clients that support MCP but can't run shell commands (Cursor, Windsurf, custom agents). Search-backed tools use the singleton daemon when available, avoiding a separate embedding worker per MCP session, and use an in-process worker for supported offline/secondary-store access. An unsupported daemon command requires `gmax watch restart`.
|
|
132
132
|
|
|
133
|
+
`semantic_search`, `trace_calls`, `dead`, and `index_status` also advertise output schemas and return `structuredContent` with `schemaVersion: 1`, alongside the existing text. Search matches follow the same scope and display filters and include paths, one-based start/end lines, symbols, scores (null when unavailable), and warnings. Trace results preserve caller ancestry and edge confidence; unresolved callees have no location, and omitted callee/importer counts are explicit. Graph conclusions carry `approximate: true`. Index health includes embedding identity, watcher/reconciliation state, and the last compaction result; unavailable health is null or unobserved. These four tools advertise read-only, non-destructive, closed-world annotations. Other tools retain their current contracts.
|
|
134
|
+
|
|
133
135
|
| Tool | Description |
|
|
134
136
|
| --- | --- |
|
|
135
137
|
| `semantic_search` | Search by meaning. Pointer mode matches CLI `--agent` output; `detail=code/full` returns snippets. |
|
package/dist/commands/mcp.js
CHANGED
|
@@ -85,6 +85,7 @@ const index_config_1 = require("../lib/index/index-config");
|
|
|
85
85
|
const syncer_1 = require("../lib/index/syncer");
|
|
86
86
|
const agent_search_formatter_1 = require("../lib/output/agent-search-formatter");
|
|
87
87
|
const index_state_footer_1 = require("../lib/output/index-state-footer");
|
|
88
|
+
const mcp_results_1 = require("../lib/output/mcp-results");
|
|
88
89
|
const searcher_1 = require("../lib/search/searcher");
|
|
89
90
|
const annotator_1 = require("../lib/skeleton/annotator");
|
|
90
91
|
const skeletonizer_1 = require("../lib/skeleton/skeletonizer");
|
|
@@ -123,8 +124,8 @@ function toStringArray(val) {
|
|
|
123
124
|
}
|
|
124
125
|
return [];
|
|
125
126
|
}
|
|
126
|
-
function ok(text) {
|
|
127
|
-
return { content: [{ type: "text", text }] };
|
|
127
|
+
function ok(text, structuredContent) {
|
|
128
|
+
return Object.assign({ content: [{ type: "text", text }] }, (structuredContent ? { structuredContent } : {}));
|
|
128
129
|
}
|
|
129
130
|
function err(text) {
|
|
130
131
|
return { content: [{ type: "text", text }], isError: true };
|
|
@@ -256,13 +257,13 @@ function searchResultPath(r) {
|
|
|
256
257
|
}
|
|
257
258
|
function searchResultStartLine(r) {
|
|
258
259
|
var _a;
|
|
259
|
-
var _b, _c;
|
|
260
|
-
return Number((_c = (_b = r === null || r === void 0 ? void 0 : r.
|
|
260
|
+
var _b, _c, _d;
|
|
261
|
+
return Number((_d = (_c = (_b = r === null || r === void 0 ? void 0 : r.startLine) !== null && _b !== void 0 ? _b : r === null || r === void 0 ? void 0 : r.start_line) !== null && _c !== void 0 ? _c : (_a = r === null || r === void 0 ? void 0 : r.generated_metadata) === null || _a === void 0 ? void 0 : _a.start_line) !== null && _d !== void 0 ? _d : 0);
|
|
261
262
|
}
|
|
262
263
|
function searchResultEndLine(r, fallbackStart = 0) {
|
|
263
264
|
var _a;
|
|
264
|
-
var _b, _c;
|
|
265
|
-
return Number((_c = (_b = r === null || r === void 0 ? void 0 : r.
|
|
265
|
+
var _b, _c, _d;
|
|
266
|
+
return Number((_d = (_c = (_b = r === null || r === void 0 ? void 0 : r.endLine) !== null && _b !== void 0 ? _b : r === null || r === void 0 ? void 0 : r.end_line) !== null && _c !== void 0 ? _c : (_a = r === null || r === void 0 ? void 0 : r.generated_metadata) === null || _a === void 0 ? void 0 : _a.end_line) !== null && _d !== void 0 ? _d : fallbackStart);
|
|
266
267
|
}
|
|
267
268
|
function filterMcpSearchResults(data, options = {}) {
|
|
268
269
|
var _a, _b;
|
|
@@ -772,6 +773,26 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
772
773
|
return (candidate.length > 0 &&
|
|
773
774
|
allowedRoots.some((root) => (0, path_containment_1.isPathWithin)(root, candidate)));
|
|
774
775
|
});
|
|
776
|
+
const structuredSearch = (matches) => { var _a; return ({
|
|
777
|
+
schemaVersion: 1,
|
|
778
|
+
query,
|
|
779
|
+
roots: allowedRoots,
|
|
780
|
+
warnings: ((_a = result.warnings) !== null && _a !== void 0 ? _a : []).filter(Boolean),
|
|
781
|
+
matches: matches.map((r) => {
|
|
782
|
+
var _a;
|
|
783
|
+
const startLine = searchResultStartLine(r);
|
|
784
|
+
return {
|
|
785
|
+
path: chunkAbsPath(r),
|
|
786
|
+
startLine: startLine + 1,
|
|
787
|
+
endLine: searchResultEndLine(r, startLine) + 1,
|
|
788
|
+
symbols: chunkSymbols(r),
|
|
789
|
+
role: String((_a = r.role) !== null && _a !== void 0 ? _a : "IMPLEMENTATION"),
|
|
790
|
+
score: typeof r.score === "number" && Number.isFinite(r.score)
|
|
791
|
+
? r.score
|
|
792
|
+
: null,
|
|
793
|
+
};
|
|
794
|
+
}),
|
|
795
|
+
}); };
|
|
775
796
|
// Prepend any searcher warnings to whatever body we return.
|
|
776
797
|
const prefixNotes = (body) => {
|
|
777
798
|
var _a;
|
|
@@ -779,7 +800,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
779
800
|
return notes.length ? `${notes.join("\n")}\n\n${body}` : body;
|
|
780
801
|
};
|
|
781
802
|
if (!result.data || result.data.length === 0) {
|
|
782
|
-
return ok(prefixNotes("No matches found. Try broadening your query, using fewer keywords, or check `gmax status` to verify the project is indexed."));
|
|
803
|
+
return ok(prefixNotes("No matches found. Try broadening your query, using fewer keywords, or check `gmax status` to verify the project is indexed."), structuredSearch([]));
|
|
783
804
|
}
|
|
784
805
|
const minScore = typeof args.min_score === "number" ? args.min_score : 0;
|
|
785
806
|
const maxPerFile = typeof args.max_per_file === "number" ? args.max_per_file : 0;
|
|
@@ -809,21 +830,25 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
809
830
|
getImportsForFile,
|
|
810
831
|
query,
|
|
811
832
|
});
|
|
812
|
-
return ok(prefixNotes(output)
|
|
833
|
+
return ok(prefixNotes(output), structuredSearch(filterMcpSearchResults(result.data, {
|
|
834
|
+
minScore,
|
|
835
|
+
maxPerFile,
|
|
836
|
+
namePattern,
|
|
837
|
+
})));
|
|
813
838
|
}
|
|
814
839
|
let results = result.data.map((r) => {
|
|
815
|
-
var _a
|
|
816
|
-
var
|
|
817
|
-
const absPath = (
|
|
840
|
+
var _a;
|
|
841
|
+
var _b, _c, _d, _e, _f;
|
|
842
|
+
const absPath = (_c = (_b = r.path) !== null && _b !== void 0 ? _b : (_a = r.metadata) === null || _a === void 0 ? void 0 : _a.path) !== null && _c !== void 0 ? _c : "";
|
|
818
843
|
const relPath = absPath.startsWith(displayRoot)
|
|
819
844
|
? absPath.slice(displayRoot.length + 1)
|
|
820
845
|
: absPath;
|
|
821
|
-
const startLine = (
|
|
822
|
-
const endLine = (
|
|
823
|
-
const defs = toStringArray((
|
|
824
|
-
const refs = toStringArray((
|
|
846
|
+
const startLine = searchResultStartLine(r);
|
|
847
|
+
const endLine = searchResultEndLine(r, startLine);
|
|
848
|
+
const defs = toStringArray((_d = r.definedSymbols) !== null && _d !== void 0 ? _d : r.defined_symbols);
|
|
849
|
+
const refs = toStringArray((_e = r.referenced_symbols) !== null && _e !== void 0 ? _e : r.referencedSymbols);
|
|
825
850
|
const symbol = defs[0] || "(anonymous)";
|
|
826
|
-
const role = ((
|
|
851
|
+
const role = ((_f = r.role) !== null && _f !== void 0 ? _f : "IMPL").slice(0, 4).toUpperCase();
|
|
827
852
|
const exported = r.is_exported ? "exported " : "";
|
|
828
853
|
const complexity = typeof r.complexity === "number" && r.complexity > 0
|
|
829
854
|
? ` C:${Math.round(r.complexity)}`
|
|
@@ -855,7 +880,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
855
880
|
.map((l, i) => `${ctxStart + i + 1}│${l}`)
|
|
856
881
|
.join("\n");
|
|
857
882
|
}
|
|
858
|
-
catch (
|
|
883
|
+
catch (_g) {
|
|
859
884
|
// Fall through to chunk content
|
|
860
885
|
}
|
|
861
886
|
}
|
|
@@ -885,6 +910,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
885
910
|
}
|
|
886
911
|
}
|
|
887
912
|
return {
|
|
913
|
+
row: r,
|
|
888
914
|
absPath,
|
|
889
915
|
text,
|
|
890
916
|
score: typeof r.score === "number" ? r.score : 0,
|
|
@@ -957,7 +983,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
957
983
|
// Trace failed — return search results without trace
|
|
958
984
|
}
|
|
959
985
|
}
|
|
960
|
-
return ok(prefixNotes(output));
|
|
986
|
+
return ok(prefixNotes(output), structuredSearch(results.map((r) => r.row)));
|
|
961
987
|
}
|
|
962
988
|
catch (e) {
|
|
963
989
|
return toolError("Search failed", e);
|
|
@@ -1105,8 +1131,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1105
1131
|
render: (resp) => resp.graph,
|
|
1106
1132
|
inProcess: () => localStore((deps) => (0, graph_handler_1.runGraphTrace)(deps.vectorDb, { symbol, hops: depth, scope })),
|
|
1107
1133
|
});
|
|
1134
|
+
const structured = (0, mcp_results_1.traceResult)(symbol, root, graph);
|
|
1108
1135
|
if (!graph.center) {
|
|
1109
|
-
return ok(`Symbol '${symbol}' not found in the index. Check \`gmax status\` to see which projects are indexed, or try \`gmax search ${symbol}\` to find similar symbols
|
|
1136
|
+
return ok(`Symbol '${symbol}' not found in the index. Check \`gmax status\` to see which projects are indexed, or try \`gmax search ${symbol}\` to find similar symbols.`, structured);
|
|
1110
1137
|
}
|
|
1111
1138
|
const lines = [];
|
|
1112
1139
|
// Center
|
|
@@ -1165,7 +1192,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1165
1192
|
else {
|
|
1166
1193
|
lines.push("Calls: none");
|
|
1167
1194
|
}
|
|
1168
|
-
return ok(lines.join("\n"));
|
|
1195
|
+
return ok(lines.join("\n"), structured);
|
|
1169
1196
|
}
|
|
1170
1197
|
catch (e) {
|
|
1171
1198
|
return toolError("Trace failed", e);
|
|
@@ -1406,16 +1433,17 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1406
1433
|
render: (resp) => resp.dead,
|
|
1407
1434
|
inProcess: () => localStore((deps) => (0, graph_handler_1.runGraphDead)(deps.vectorDb, { symbol, scope })),
|
|
1408
1435
|
});
|
|
1436
|
+
const structured = (0, mcp_results_1.deadResult)(symbol, root, facts);
|
|
1409
1437
|
if (!facts.found) {
|
|
1410
|
-
return ok(`Symbol '${symbol}' not found in the index. Check \`gmax status\` to see which projects are indexed, or try \`gmax search ${symbol}\` to find similar symbols
|
|
1438
|
+
return ok(`Symbol '${symbol}' not found in the index. Check \`gmax status\` to see which projects are indexed, or try \`gmax search ${symbol}\` to find similar symbols.`, structured);
|
|
1411
1439
|
}
|
|
1412
1440
|
const rel = (p) => p.startsWith(root) ? p.slice(root.length + 1) : p;
|
|
1413
1441
|
const defLoc = `${rel(facts.defPath)}:${facts.defLine + 1}`;
|
|
1414
1442
|
if (facts.callerCount === 0) {
|
|
1415
1443
|
if (facts.isExported) {
|
|
1416
|
-
return ok(`PUBLIC EXPORT ${defLoc} defines ${symbol} — no internal callers found; check external usage
|
|
1444
|
+
return ok(`PUBLIC EXPORT ${defLoc} defines ${symbol} — no internal callers found; check external usage`, structured);
|
|
1417
1445
|
}
|
|
1418
|
-
return ok(`DEAD ${defLoc} defines ${symbol}
|
|
1446
|
+
return ok(`DEAD ${defLoc} defines ${symbol}`, structured);
|
|
1419
1447
|
}
|
|
1420
1448
|
const top = facts.topCallers;
|
|
1421
1449
|
const lines = [
|
|
@@ -1424,7 +1452,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1424
1452
|
for (const c of top) {
|
|
1425
1453
|
lines.push(` ${rel(c.file)}:${c.line + 1}`);
|
|
1426
1454
|
}
|
|
1427
|
-
return ok(lines.join("\n"));
|
|
1455
|
+
return ok(lines.join("\n"), structured);
|
|
1428
1456
|
}
|
|
1429
1457
|
catch (e) {
|
|
1430
1458
|
return toolError("Dead check failed", e);
|
|
@@ -1782,7 +1810,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1782
1810
|
}
|
|
1783
1811
|
function handleIndexStatus() {
|
|
1784
1812
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1785
|
-
var _a, _b;
|
|
1813
|
+
var _a, _b, _c, _d, _e;
|
|
1786
1814
|
try {
|
|
1787
1815
|
const globalConfig = storeConfig();
|
|
1788
1816
|
const projects = storeProjects();
|
|
@@ -1834,7 +1862,36 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1834
1862
|
(0, compaction_result_1.formatCompactionStatus)(daemonStatus.compaction),
|
|
1835
1863
|
`Projects: ${projects.length} indexed (call list_projects for names + per-project chunk counts)`,
|
|
1836
1864
|
].filter(Boolean);
|
|
1837
|
-
|
|
1865
|
+
const compaction = mcp_results_1.compactionSchema.safeParse(daemonStatus.compaction);
|
|
1866
|
+
return ok(lines.join("\n"), {
|
|
1867
|
+
schemaVersion: 1,
|
|
1868
|
+
root: currentRoot(),
|
|
1869
|
+
store: storeDir(),
|
|
1870
|
+
secondary: secondary(),
|
|
1871
|
+
chunks,
|
|
1872
|
+
files,
|
|
1873
|
+
projects: projects.length,
|
|
1874
|
+
embedding: {
|
|
1875
|
+
state: identity.state,
|
|
1876
|
+
configured: {
|
|
1877
|
+
tier: identity.configured.tier,
|
|
1878
|
+
vectorDim: identity.configured.vectorDim,
|
|
1879
|
+
fingerprint: identity.configured.fingerprint,
|
|
1880
|
+
},
|
|
1881
|
+
built: identity.built
|
|
1882
|
+
? {
|
|
1883
|
+
tier: identity.built.tier,
|
|
1884
|
+
vectorDim: identity.built.vectorDim,
|
|
1885
|
+
fingerprint: identity.built.fingerprint,
|
|
1886
|
+
}
|
|
1887
|
+
: null,
|
|
1888
|
+
},
|
|
1889
|
+
watcher: {
|
|
1890
|
+
status: (_d = (_c = daemonProject === null || daemonProject === void 0 ? void 0 : daemonProject.status) !== null && _c !== void 0 ? _c : watcher === null || watcher === void 0 ? void 0 : watcher.status) !== null && _d !== void 0 ? _d : (secondary() || !daemonStatus.ok ? "unobserved" : "not_running"),
|
|
1891
|
+
indexState: (_e = daemonProject === null || daemonProject === void 0 ? void 0 : daemonProject.indexState) !== null && _e !== void 0 ? _e : null,
|
|
1892
|
+
},
|
|
1893
|
+
compaction: compaction.success ? compaction.data : null,
|
|
1894
|
+
});
|
|
1838
1895
|
}
|
|
1839
1896
|
catch (e) {
|
|
1840
1897
|
return toolError("Status check failed", e);
|
|
@@ -2620,7 +2677,16 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2620
2677
|
// shapes give us free input validation (the SDK rejects calls that violate
|
|
2621
2678
|
// the schema before the handler runs); handlers stay defensively coded.
|
|
2622
2679
|
function tool(name, config, handler) {
|
|
2623
|
-
server.registerTool(name, Object.assign(Object.assign(
|
|
2680
|
+
server.registerTool(name, Object.assign(Object.assign(Object.assign({}, config), (mcp_results_1.MCP_READ_OUTPUT_SCHEMAS[name]
|
|
2681
|
+
? {
|
|
2682
|
+
outputSchema: mcp_results_1.MCP_READ_OUTPUT_SCHEMAS[name],
|
|
2683
|
+
annotations: {
|
|
2684
|
+
readOnlyHint: true,
|
|
2685
|
+
destructiveHint: false,
|
|
2686
|
+
openWorldHint: false,
|
|
2687
|
+
},
|
|
2688
|
+
}
|
|
2689
|
+
: {})), { inputSchema: Object.assign({ root: zod_1.z.string().optional() }, config.inputSchema) }), (rawArgs) => __awaiter(this, void 0, void 0, function* () {
|
|
2624
2690
|
let args = (rawArgs !== null && rawArgs !== void 0 ? rawArgs : {});
|
|
2625
2691
|
const startMs = Date.now();
|
|
2626
2692
|
let target = projectRoot;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MCP_READ_OUTPUT_SCHEMAS = exports.compactionSchema = void 0;
|
|
4
|
+
exports.traceResult = traceResult;
|
|
5
|
+
exports.deadResult = deadResult;
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const location = zod_1.z.object({
|
|
8
|
+
path: zod_1.z.string(),
|
|
9
|
+
line: zod_1.z.number().int().positive().describe("One-based source line"),
|
|
10
|
+
});
|
|
11
|
+
const graphNode = zod_1.z.object({
|
|
12
|
+
symbol: zod_1.z.string(),
|
|
13
|
+
location: location.nullable(),
|
|
14
|
+
role: zod_1.z.string(),
|
|
15
|
+
resolution: zod_1.z.enum(["indexed", "not_indexed", "ambiguous_member"]),
|
|
16
|
+
edgeKind: zod_1.z.enum(["free", "member", "type"]).optional(),
|
|
17
|
+
confidence: zod_1.z.enum(["EXTRACTED", "INFERRED"]).optional(),
|
|
18
|
+
});
|
|
19
|
+
const search = {
|
|
20
|
+
schemaVersion: zod_1.z.literal(1),
|
|
21
|
+
query: zod_1.z.string(),
|
|
22
|
+
roots: zod_1.z.array(zod_1.z.string()),
|
|
23
|
+
warnings: zod_1.z.array(zod_1.z.string()),
|
|
24
|
+
matches: zod_1.z
|
|
25
|
+
.array(zod_1.z.object({
|
|
26
|
+
path: zod_1.z.string(),
|
|
27
|
+
startLine: zod_1.z.number().int().positive(),
|
|
28
|
+
endLine: zod_1.z.number().int().positive(),
|
|
29
|
+
symbols: zod_1.z.array(zod_1.z.string()),
|
|
30
|
+
role: zod_1.z.string(),
|
|
31
|
+
score: zod_1.z
|
|
32
|
+
.number()
|
|
33
|
+
.nullable()
|
|
34
|
+
.describe("Search score; null when unavailable"),
|
|
35
|
+
}))
|
|
36
|
+
.max(50),
|
|
37
|
+
};
|
|
38
|
+
exports.compactionSchema = zod_1.z.object({
|
|
39
|
+
status: zod_1.z.enum(["completed", "skipped", "failed"]),
|
|
40
|
+
at: zod_1.z.number(),
|
|
41
|
+
attempts: zod_1.z.number(),
|
|
42
|
+
elapsedMs: zod_1.z.number(),
|
|
43
|
+
reason: zod_1.z.string().optional(),
|
|
44
|
+
logicalBytes: zod_1.z.number().optional(),
|
|
45
|
+
diskBytesBefore: zod_1.z.number().optional(),
|
|
46
|
+
diskBytesAfter: zod_1.z.number().optional(),
|
|
47
|
+
freeBytesBefore: zod_1.z.number().optional(),
|
|
48
|
+
freeBytesAfter: zod_1.z.number().optional(),
|
|
49
|
+
bytesReclaimed: zod_1.z.number().optional(),
|
|
50
|
+
});
|
|
51
|
+
const embedding = zod_1.z.object({
|
|
52
|
+
tier: zod_1.z.string(),
|
|
53
|
+
vectorDim: zod_1.z.number(),
|
|
54
|
+
fingerprint: zod_1.z.string(),
|
|
55
|
+
});
|
|
56
|
+
/** Only tools with a complete success contract advertise an output schema. */
|
|
57
|
+
exports.MCP_READ_OUTPUT_SCHEMAS = {
|
|
58
|
+
semantic_search: search,
|
|
59
|
+
trace_calls: {
|
|
60
|
+
schemaVersion: zod_1.z.literal(1),
|
|
61
|
+
symbol: zod_1.z.string(),
|
|
62
|
+
root: zod_1.z.string(),
|
|
63
|
+
found: zod_1.z.boolean(),
|
|
64
|
+
center: graphNode.nullable(),
|
|
65
|
+
callers: zod_1.z.array(zod_1.z.object({
|
|
66
|
+
node: graphNode,
|
|
67
|
+
depth: zod_1.z.number().int().positive(),
|
|
68
|
+
parentIndex: zod_1.z
|
|
69
|
+
.number()
|
|
70
|
+
.int()
|
|
71
|
+
.nonnegative()
|
|
72
|
+
.nullable()
|
|
73
|
+
.describe("Index of the parent in callers; null for a direct caller of center"),
|
|
74
|
+
})),
|
|
75
|
+
callees: zod_1.z.array(graphNode).max(15),
|
|
76
|
+
importers: zod_1.z.array(zod_1.z.string()).max(10),
|
|
77
|
+
omittedCallees: zod_1.z.number().int().nonnegative(),
|
|
78
|
+
omittedImporters: zod_1.z.number().int().nonnegative(),
|
|
79
|
+
approximate: zod_1.z.literal(true),
|
|
80
|
+
},
|
|
81
|
+
dead: {
|
|
82
|
+
schemaVersion: zod_1.z.literal(1),
|
|
83
|
+
symbol: zod_1.z.string(),
|
|
84
|
+
root: zod_1.z.string(),
|
|
85
|
+
status: zod_1.z.enum(["not_found", "public_export", "dead", "live"]),
|
|
86
|
+
definition: location.nullable(),
|
|
87
|
+
isExported: zod_1.z.boolean(),
|
|
88
|
+
callerCount: zod_1.z.number().int().nonnegative(),
|
|
89
|
+
callers: zod_1.z.array(location),
|
|
90
|
+
approximate: zod_1.z.literal(true),
|
|
91
|
+
},
|
|
92
|
+
index_status: {
|
|
93
|
+
schemaVersion: zod_1.z.literal(1),
|
|
94
|
+
root: zod_1.z.string(),
|
|
95
|
+
store: zod_1.z.string(),
|
|
96
|
+
secondary: zod_1.z.boolean(),
|
|
97
|
+
chunks: zod_1.z.number().int().nonnegative(),
|
|
98
|
+
files: zod_1.z.number().int().nonnegative(),
|
|
99
|
+
projects: zod_1.z.number().int().nonnegative(),
|
|
100
|
+
embedding: zod_1.z.object({
|
|
101
|
+
state: zod_1.z.string(),
|
|
102
|
+
configured: embedding,
|
|
103
|
+
built: embedding.nullable(),
|
|
104
|
+
}),
|
|
105
|
+
watcher: zod_1.z.object({
|
|
106
|
+
status: zod_1.z.string(),
|
|
107
|
+
indexState: zod_1.z
|
|
108
|
+
.object({
|
|
109
|
+
indexing: zod_1.z.boolean(),
|
|
110
|
+
pendingFiles: zod_1.z.number(),
|
|
111
|
+
verifying: zod_1.z.boolean().optional(),
|
|
112
|
+
failedFiles: zod_1.z.number().optional(),
|
|
113
|
+
degraded: zod_1.z.boolean().optional(),
|
|
114
|
+
watcherMode: zod_1.z.enum(["native", "polling", "recovering"]).optional(),
|
|
115
|
+
catchupRunning: zod_1.z.boolean().optional(),
|
|
116
|
+
lastReconciledAt: zod_1.z.number().optional(),
|
|
117
|
+
overflowCount: zod_1.z.number().optional(),
|
|
118
|
+
catchupMs: zod_1.z.number().optional(),
|
|
119
|
+
})
|
|
120
|
+
.nullable(),
|
|
121
|
+
}),
|
|
122
|
+
compaction: exports.compactionSchema.nullable(),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
function nodeResult(node) {
|
|
126
|
+
return Object.assign(Object.assign({ symbol: node.symbol, location: node.file ? { path: node.file, line: node.line + 1 } : null, role: node.role, resolution: node.file
|
|
127
|
+
? "indexed"
|
|
128
|
+
: node.resolution === "ambiguous-member"
|
|
129
|
+
? "ambiguous_member"
|
|
130
|
+
: "not_indexed" }, (node.edgeKind ? { edgeKind: node.edgeKind } : {})), (node.confidence ? { confidence: node.confidence } : {}));
|
|
131
|
+
}
|
|
132
|
+
function traceResult(symbol, root, graph) {
|
|
133
|
+
const callers = [];
|
|
134
|
+
function visit(trees, depth, parentIndex) {
|
|
135
|
+
for (const tree of trees) {
|
|
136
|
+
const index = callers.length;
|
|
137
|
+
callers.push({ node: nodeResult(tree.node), depth, parentIndex });
|
|
138
|
+
visit(tree.callers, depth + 1, index);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
visit(graph.callerTree, 1, null);
|
|
142
|
+
const importers = graph.importers.filter((p) => { var _a; return p !== ((_a = graph.center) === null || _a === void 0 ? void 0 : _a.file); });
|
|
143
|
+
return {
|
|
144
|
+
schemaVersion: 1,
|
|
145
|
+
symbol,
|
|
146
|
+
root,
|
|
147
|
+
found: graph.center !== null,
|
|
148
|
+
center: graph.center ? nodeResult(graph.center) : null,
|
|
149
|
+
callers,
|
|
150
|
+
callees: graph.callees.slice(0, 15).map(nodeResult),
|
|
151
|
+
importers: importers.slice(0, 10),
|
|
152
|
+
omittedCallees: Math.max(0, graph.callees.length - 15),
|
|
153
|
+
omittedImporters: Math.max(0, importers.length - 10),
|
|
154
|
+
approximate: true,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function deadResult(symbol, root, facts) {
|
|
158
|
+
return {
|
|
159
|
+
schemaVersion: 1,
|
|
160
|
+
symbol,
|
|
161
|
+
root,
|
|
162
|
+
status: !facts.found
|
|
163
|
+
? "not_found"
|
|
164
|
+
: facts.callerCount > 0
|
|
165
|
+
? "live"
|
|
166
|
+
: facts.isExported
|
|
167
|
+
? "public_export"
|
|
168
|
+
: "dead",
|
|
169
|
+
definition: facts.found
|
|
170
|
+
? { path: facts.defPath, line: facts.defLine + 1 }
|
|
171
|
+
: null,
|
|
172
|
+
isExported: facts.isExported,
|
|
173
|
+
callerCount: facts.callerCount,
|
|
174
|
+
callers: facts.topCallers.map((c) => ({ path: c.file, line: c.line + 1 })),
|
|
175
|
+
approximate: true,
|
|
176
|
+
};
|
|
177
|
+
}
|
package/package.json
CHANGED