grepmax 0.7.18 → 0.7.20
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/dist/commands/mcp.js
CHANGED
|
@@ -140,6 +140,10 @@ const TOOLS = [
|
|
|
140
140
|
type: "boolean",
|
|
141
141
|
description: "Prepend the file's import/require statements to each result. Deduped per file.",
|
|
142
142
|
},
|
|
143
|
+
name_pattern: {
|
|
144
|
+
type: "string",
|
|
145
|
+
description: "Regex to filter by symbol name (e.g. 'handle.*Auth'). Case-insensitive. Applied after search.",
|
|
146
|
+
},
|
|
143
147
|
},
|
|
144
148
|
required: ["query"],
|
|
145
149
|
},
|
|
@@ -202,6 +206,10 @@ const TOOLS = [
|
|
|
202
206
|
type: "boolean",
|
|
203
207
|
description: "Prepend file's import statements to each result.",
|
|
204
208
|
},
|
|
209
|
+
name_pattern: {
|
|
210
|
+
type: "string",
|
|
211
|
+
description: "Regex to filter by symbol name (e.g. 'handle.*Auth').",
|
|
212
|
+
},
|
|
205
213
|
},
|
|
206
214
|
required: ["query"],
|
|
207
215
|
},
|
|
@@ -724,6 +732,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
724
732
|
absPath,
|
|
725
733
|
text,
|
|
726
734
|
score: typeof r.score === "number" ? r.score : 0,
|
|
735
|
+
symbols: defs,
|
|
727
736
|
};
|
|
728
737
|
});
|
|
729
738
|
if (minScore > 0) {
|
|
@@ -739,6 +748,18 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
739
748
|
return true;
|
|
740
749
|
});
|
|
741
750
|
}
|
|
751
|
+
const namePattern = typeof args.name_pattern === "string"
|
|
752
|
+
? args.name_pattern
|
|
753
|
+
: "";
|
|
754
|
+
if (namePattern) {
|
|
755
|
+
try {
|
|
756
|
+
const regex = new RegExp(namePattern, "i");
|
|
757
|
+
results = results.filter((r) => r.symbols.some((s) => regex.test(s)));
|
|
758
|
+
}
|
|
759
|
+
catch (_b) {
|
|
760
|
+
// Invalid regex — skip filter
|
|
761
|
+
}
|
|
762
|
+
}
|
|
742
763
|
let output = results.map((r) => r.text).join("\n\n");
|
|
743
764
|
// Symbol mode: append call graph
|
|
744
765
|
const mode = typeof args.mode === "string" ? args.mode : "default";
|
|
@@ -779,7 +800,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
779
800
|
output += `\n${traceLines.join("\n")}`;
|
|
780
801
|
}
|
|
781
802
|
}
|
|
782
|
-
catch (
|
|
803
|
+
catch (_c) {
|
|
783
804
|
// Trace failed — return search results without trace
|
|
784
805
|
}
|
|
785
806
|
}
|
package/dist/commands/search.js
CHANGED
|
@@ -336,17 +336,28 @@ exports.search = new commander_1.Command("search")
|
|
|
336
336
|
.option("-s, --sync", "Syncs the local files to the store before searching", false)
|
|
337
337
|
.option("-d, --dry-run", "Show what would be indexed without actually indexing", false)
|
|
338
338
|
.option("--skeleton", "Show code skeleton for matching files instead of snippets", false)
|
|
339
|
+
.option("--root <dir>", "Search a different project directory")
|
|
340
|
+
.option("--file <name>", "Filter to files matching this name (e.g. 'syncer.ts')")
|
|
341
|
+
.option("--exclude <prefix>", "Exclude files under this path prefix (e.g. 'tests/')")
|
|
342
|
+
.option("--lang <ext>", "Filter by file extension (e.g. 'ts', 'py')")
|
|
343
|
+
.option("--role <role>", "Filter by role: ORCHESTRATION, DEFINITION, IMPLEMENTATION")
|
|
344
|
+
.option("--symbol", "Append call graph after search results", false)
|
|
345
|
+
.option("--imports", "Prepend file imports to each result", false)
|
|
346
|
+
.option("--name <regex>", "Filter results by symbol name regex")
|
|
347
|
+
.option("-C, --context <n>", "Include N lines before/after each result")
|
|
339
348
|
.argument("<pattern>", "Natural language query (e.g. \"where do we handle auth?\")")
|
|
340
349
|
.argument("[path]", "Restrict search to this path prefix")
|
|
341
350
|
.addHelpText("after", `
|
|
342
351
|
Examples:
|
|
343
352
|
gmax "where do we handle authentication?"
|
|
344
|
-
gmax "
|
|
345
|
-
gmax "
|
|
346
|
-
gmax "
|
|
353
|
+
gmax "auth handler" --role ORCHESTRATION --lang ts --plain
|
|
354
|
+
gmax "database" --file syncer.ts --plain
|
|
355
|
+
gmax "VectorDB" --symbol --plain
|
|
356
|
+
gmax "error handling" -C 5 --imports --plain
|
|
357
|
+
gmax "handler" --name "handle.*" --exclude tests/
|
|
347
358
|
`)
|
|
348
359
|
.action((pattern, exec_path, _options, cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
349
|
-
var _a, _b, _c;
|
|
360
|
+
var _a, _b, _c, _d;
|
|
350
361
|
const options = cmd.optsWithGlobals();
|
|
351
362
|
const root = process.cwd();
|
|
352
363
|
const minScore = Number.isFinite(Number.parseFloat(options.minScore))
|
|
@@ -487,20 +498,48 @@ Examples:
|
|
|
487
498
|
}
|
|
488
499
|
}
|
|
489
500
|
const searcher = new searcher_1.Searcher(vectorDb);
|
|
490
|
-
// Use
|
|
501
|
+
// Use --root or fall back to project root
|
|
502
|
+
const effectiveRoot = options.root
|
|
503
|
+
? (_c = (0, project_root_1.findProjectRoot)(path.resolve(options.root))) !== null && _c !== void 0 ? _c : path.resolve(options.root)
|
|
504
|
+
: projectRoot;
|
|
491
505
|
const searchPathPrefix = exec_path
|
|
492
506
|
? path.resolve(exec_path)
|
|
493
|
-
:
|
|
507
|
+
: effectiveRoot;
|
|
494
508
|
const pathFilter = searchPathPrefix.endsWith("/")
|
|
495
509
|
? searchPathPrefix
|
|
496
510
|
: `${searchPathPrefix}/`;
|
|
497
|
-
|
|
498
|
-
|
|
511
|
+
// Build filters from CLI options
|
|
512
|
+
const searchFilters = {};
|
|
513
|
+
if (options.file)
|
|
514
|
+
searchFilters.file = options.file;
|
|
515
|
+
if (options.exclude)
|
|
516
|
+
searchFilters.exclude = options.exclude;
|
|
517
|
+
if (options.lang)
|
|
518
|
+
searchFilters.language = options.lang;
|
|
519
|
+
if (options.role)
|
|
520
|
+
searchFilters.role = options.role;
|
|
521
|
+
const searchResult = yield searcher.search(pattern, parseInt(options.m, 10), { rerank: true }, Object.keys(searchFilters).length > 0 ? searchFilters : undefined, pathFilter);
|
|
522
|
+
if ((_d = searchResult.warnings) === null || _d === void 0 ? void 0 : _d.length) {
|
|
499
523
|
for (const w of searchResult.warnings) {
|
|
500
524
|
console.warn(`Warning: ${w}`);
|
|
501
525
|
}
|
|
502
526
|
}
|
|
503
|
-
|
|
527
|
+
let filteredData = searchResult.data.filter((r) => typeof r.score !== "number" || r.score >= minScore);
|
|
528
|
+
// Post-filter by symbol name regex
|
|
529
|
+
if (options.name) {
|
|
530
|
+
try {
|
|
531
|
+
const regex = new RegExp(options.name, "i");
|
|
532
|
+
filteredData = filteredData.filter((r) => {
|
|
533
|
+
const defs = Array.isArray(r.defined_symbols)
|
|
534
|
+
? r.defined_symbols
|
|
535
|
+
: [];
|
|
536
|
+
return defs.some((d) => regex.test(d));
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
catch (_e) {
|
|
540
|
+
// Invalid regex — skip
|
|
541
|
+
}
|
|
542
|
+
}
|
|
504
543
|
if (options.skeleton) {
|
|
505
544
|
yield outputSkeletons(filteredData, projectRoot, parseInt(options.m, 10), vectorDb);
|
|
506
545
|
return;
|
|
@@ -543,6 +582,49 @@ Examples:
|
|
|
543
582
|
});
|
|
544
583
|
console.log(output);
|
|
545
584
|
}
|
|
585
|
+
// Symbol mode: append call graph
|
|
586
|
+
if (options.symbol && vectorDb) {
|
|
587
|
+
try {
|
|
588
|
+
const { GraphBuilder } = yield Promise.resolve().then(() => __importStar(require("../lib/graph/graph-builder")));
|
|
589
|
+
const builder = new GraphBuilder(vectorDb);
|
|
590
|
+
const graph = yield builder.buildGraphMultiHop(pattern, 1);
|
|
591
|
+
if (graph.center) {
|
|
592
|
+
const lines = ["\n--- Call graph ---"];
|
|
593
|
+
const centerRel = path.relative(effectiveRoot, graph.center.file);
|
|
594
|
+
lines.push(`${graph.center.symbol} [${graph.center.role}] ${centerRel}:${graph.center.line + 1}`);
|
|
595
|
+
if (graph.importers.length > 0) {
|
|
596
|
+
const filtered = graph.importers.filter((p) => p !== graph.center.file);
|
|
597
|
+
if (filtered.length > 0) {
|
|
598
|
+
lines.push("Imported by:");
|
|
599
|
+
for (const imp of filtered.slice(0, 10)) {
|
|
600
|
+
lines.push(` ${path.relative(effectiveRoot, imp)}`);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (graph.callerTree.length > 0) {
|
|
605
|
+
lines.push("Callers:");
|
|
606
|
+
for (const t of graph.callerTree) {
|
|
607
|
+
lines.push(` <- ${t.node.symbol} ${path.relative(effectiveRoot, t.node.file)}:${t.node.line + 1}`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (graph.callees.length > 0) {
|
|
611
|
+
lines.push("Calls:");
|
|
612
|
+
for (const c of graph.callees.slice(0, 15)) {
|
|
613
|
+
if (c.file) {
|
|
614
|
+
lines.push(` -> ${c.symbol} ${path.relative(effectiveRoot, c.file)}:${c.line + 1}`);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
lines.push(` -> ${c.symbol} (not indexed)`);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
console.log(lines.join("\n"));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
catch (_f) {
|
|
625
|
+
// Trace failed — skip silently
|
|
626
|
+
}
|
|
627
|
+
}
|
|
546
628
|
}
|
|
547
629
|
catch (error) {
|
|
548
630
|
const message = error instanceof Error ? error.message : "Unknown error";
|
package/package.json
CHANGED
|
@@ -49,6 +49,7 @@ Parameters:
|
|
|
49
49
|
- `role` (optional): Filter by chunk role: "ORCHESTRATION" (logic/flow), "DEFINITION" (types), or "IMPLEMENTATION"
|
|
50
50
|
- `mode` (optional): `"default"` (semantic only) or `"symbol"` (semantic + call graph appended). Use "symbol" when query is a function or class name — gets search results + callers/callees in one call.
|
|
51
51
|
- `include_imports` (optional): Prepend file's import/require statements to each result. Deduped per file — see dependencies at a glance.
|
|
52
|
+
- `name_pattern` (optional): Regex to filter by symbol name (e.g. "handle.*Auth"). Case-insensitive. Applied after search.
|
|
52
53
|
|
|
53
54
|
**When to use which mode:**
|
|
54
55
|
- `pointer` — navigation, finding locations, understanding architecture
|
|
@@ -108,11 +109,13 @@ Generate LLM summaries for indexed code in a directory. Summaries are stored and
|
|
|
108
109
|
|
|
109
110
|
## Workflow
|
|
110
111
|
|
|
111
|
-
1. **
|
|
112
|
-
2. **
|
|
113
|
-
3. **
|
|
114
|
-
4. **
|
|
115
|
-
5. **
|
|
112
|
+
1. **Explore** — `summarize_project` for high-level overview of a new codebase
|
|
113
|
+
2. **Search** — `semantic_search` to find relevant code (pointers by default). Use `mode: "symbol"` for function/class names.
|
|
114
|
+
3. **Read** — `Read file:line` for the specific ranges you need
|
|
115
|
+
4. **Skeleton** — `code_skeleton` before reading large files or directories
|
|
116
|
+
5. **Trace** — `trace_calls` to understand call flow, imports, and callers (use `depth: 2` for full chains)
|
|
117
|
+
6. **Context** — `related_files` to see what else you need to look at when editing
|
|
118
|
+
7. **Changes** — `recent_changes` after pulls to see what's been modified
|
|
116
119
|
|
|
117
120
|
## If results seem stale
|
|
118
121
|
|