grepmax 0.7.34 → 0.7.35
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/search.js
CHANGED
|
@@ -345,6 +345,7 @@ exports.search = new commander_1.Command("search")
|
|
|
345
345
|
.option("--imports", "Prepend file imports to each result", false)
|
|
346
346
|
.option("--name <regex>", "Filter results by symbol name regex")
|
|
347
347
|
.option("-C, --context <n>", "Include N lines before/after each result")
|
|
348
|
+
.option("--agent", "Ultra-compact output for AI agents (one line per result)", false)
|
|
348
349
|
.argument("<pattern>", "Natural language query (e.g. \"where do we handle auth?\")")
|
|
349
350
|
.argument("[path]", "Restrict search to this path prefix")
|
|
350
351
|
.addHelpText("after", `
|
|
@@ -357,7 +358,7 @@ Examples:
|
|
|
357
358
|
gmax "handler" --name "handle.*" --exclude tests/
|
|
358
359
|
`)
|
|
359
360
|
.action((pattern, exec_path, _options, cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
360
|
-
var _a, _b, _c, _d, _e;
|
|
361
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
361
362
|
const options = cmd.optsWithGlobals();
|
|
362
363
|
const root = process.cwd();
|
|
363
364
|
const minScore = Number.isFinite(Number.parseFloat(options.minScore))
|
|
@@ -451,8 +452,7 @@ Examples:
|
|
|
451
452
|
process.env.GMAX_PROJECT_ROOT = projectRoot;
|
|
452
453
|
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
453
454
|
// Check for active indexing lock and warn if present
|
|
454
|
-
|
|
455
|
-
if ((0, lock_1.isLocked)(paths.dataDir)) {
|
|
455
|
+
if (!options.agent && (0, lock_1.isLocked)(paths.dataDir)) {
|
|
456
456
|
console.warn("⚠️ Warning: Indexing in progress... search results may be incomplete.");
|
|
457
457
|
}
|
|
458
458
|
const hasRows = yield vectorDb.hasAnyRows();
|
|
@@ -506,7 +506,7 @@ Examples:
|
|
|
506
506
|
stdio: "ignore",
|
|
507
507
|
});
|
|
508
508
|
}
|
|
509
|
-
catch (
|
|
509
|
+
catch (_p) {
|
|
510
510
|
// Watcher may already be running — ignore
|
|
511
511
|
}
|
|
512
512
|
}
|
|
@@ -532,7 +532,7 @@ Examples:
|
|
|
532
532
|
if (options.role)
|
|
533
533
|
searchFilters.role = options.role;
|
|
534
534
|
const searchResult = yield searcher.search(pattern, parseInt(options.m, 10), { rerank: true }, Object.keys(searchFilters).length > 0 ? searchFilters : undefined, pathFilter);
|
|
535
|
-
if ((_e = searchResult.warnings) === null || _e === void 0 ? void 0 : _e.length) {
|
|
535
|
+
if (!options.agent && ((_e = searchResult.warnings) === null || _e === void 0 ? void 0 : _e.length)) {
|
|
536
536
|
for (const w of searchResult.warnings) {
|
|
537
537
|
console.warn(`Warning: ${w}`);
|
|
538
538
|
}
|
|
@@ -549,10 +549,65 @@ Examples:
|
|
|
549
549
|
return defs.some((d) => regex.test(d));
|
|
550
550
|
});
|
|
551
551
|
}
|
|
552
|
-
catch (
|
|
552
|
+
catch (_q) {
|
|
553
553
|
// Invalid regex — skip
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
|
+
// Agent mode: ultra-compact one-line-per-result output
|
|
557
|
+
if (options.agent) {
|
|
558
|
+
if (!filteredData.length) {
|
|
559
|
+
console.log("(none)");
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
for (const r of filteredData) {
|
|
563
|
+
const absP = (_h = (_f = r.path) !== null && _f !== void 0 ? _f : (_g = r.metadata) === null || _g === void 0 ? void 0 : _g.path) !== null && _h !== void 0 ? _h : "";
|
|
564
|
+
const relPath = absP.startsWith(effectiveRoot)
|
|
565
|
+
? absP.slice(effectiveRoot.length + 1)
|
|
566
|
+
: absP;
|
|
567
|
+
const startLine = Math.max(1, ((_m = (_k = (_j = r.startLine) !== null && _j !== void 0 ? _j : r.start_line) !== null && _k !== void 0 ? _k : (_l = r.generated_metadata) === null || _l === void 0 ? void 0 : _l.start_line) !== null && _m !== void 0 ? _m : 0) + 1);
|
|
568
|
+
const defs = Array.isArray(r.defined_symbols)
|
|
569
|
+
? r.defined_symbols
|
|
570
|
+
: [];
|
|
571
|
+
const symbol = defs[0] || "";
|
|
572
|
+
const role = ((_o = r.role) !== null && _o !== void 0 ? _o : "")
|
|
573
|
+
.slice(0, 4)
|
|
574
|
+
.toUpperCase();
|
|
575
|
+
const summary = r.summary
|
|
576
|
+
? ` — ${r.summary}`
|
|
577
|
+
: "";
|
|
578
|
+
const sym = symbol ? ` ${symbol}` : "";
|
|
579
|
+
const rl = role ? ` [${role}]` : "";
|
|
580
|
+
console.log(`${relPath}:${startLine}${sym}${rl}${summary}`);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
// Agent trace (compact)
|
|
584
|
+
if (options.symbol && vectorDb && filteredData.length > 0) {
|
|
585
|
+
try {
|
|
586
|
+
const { GraphBuilder } = yield Promise.resolve().then(() => __importStar(require("../lib/graph/graph-builder")));
|
|
587
|
+
const builder = new GraphBuilder(vectorDb);
|
|
588
|
+
const graph = yield builder.buildGraphMultiHop(pattern, 1);
|
|
589
|
+
if (graph.center) {
|
|
590
|
+
console.log("---");
|
|
591
|
+
for (const t of graph.callerTree) {
|
|
592
|
+
const rel = t.node.file.startsWith(effectiveRoot)
|
|
593
|
+
? t.node.file.slice(effectiveRoot.length + 1)
|
|
594
|
+
: t.node.file;
|
|
595
|
+
console.log(`<- ${t.node.symbol} ${rel}:${t.node.line + 1}`);
|
|
596
|
+
}
|
|
597
|
+
for (const c of graph.callees.slice(0, 10)) {
|
|
598
|
+
if (c.file) {
|
|
599
|
+
const rel = c.file.startsWith(effectiveRoot)
|
|
600
|
+
? c.file.slice(effectiveRoot.length + 1)
|
|
601
|
+
: c.file;
|
|
602
|
+
console.log(`-> ${c.symbol} ${rel}:${c.line + 1}`);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
catch (_r) { }
|
|
608
|
+
}
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
556
611
|
if (options.skeleton) {
|
|
557
612
|
yield outputSkeletons(filteredData, projectRoot, parseInt(options.m, 10), vectorDb);
|
|
558
613
|
return;
|
|
@@ -634,7 +689,7 @@ Examples:
|
|
|
634
689
|
console.log(lines.join("\n"));
|
|
635
690
|
}
|
|
636
691
|
}
|
|
637
|
-
catch (
|
|
692
|
+
catch (_s) {
|
|
638
693
|
// Trace failed — skip silently
|
|
639
694
|
}
|
|
640
695
|
}
|
package/package.json
CHANGED
|
@@ -89,7 +89,7 @@ async function main() {
|
|
|
89
89
|
hookSpecificOutput: {
|
|
90
90
|
hookEventName: "SessionStart",
|
|
91
91
|
additionalContext:
|
|
92
|
-
'gmax ready. PREFER CLI over MCP
|
|
92
|
+
'gmax ready. PREFER CLI over MCP — use Bash(gmax "query" --agent) for search (one line per result, 89% fewer tokens). Bash(gmax trace <symbol>) for call graphs. Bash(gmax skeleton <path>) for structure. Always use --agent flag.',
|
|
93
93
|
},
|
|
94
94
|
};
|
|
95
95
|
process.stdout.write(JSON.stringify(response));
|
|
@@ -13,29 +13,29 @@ Semantic code search — finds code by meaning, not just strings.
|
|
|
13
13
|
|
|
14
14
|
## IMPORTANT: Use CLI, not MCP tools
|
|
15
15
|
|
|
16
|
-
**Always prefer `Bash(gmax ...)` over MCP tool calls.**
|
|
16
|
+
**Always prefer `Bash(gmax ...)` over MCP tool calls.** Use `--agent` for the most token-efficient output (one line per result, ~89% fewer tokens than default).
|
|
17
17
|
|
|
18
18
|
```
|
|
19
|
-
Bash(gmax "auth handler" --role ORCHESTRATION --lang ts --
|
|
19
|
+
Bash(gmax "auth handler" --role ORCHESTRATION --lang ts --agent -m 3)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
**Only use MCP tools** for `index_status`
|
|
22
|
+
**Only use MCP tools** for `index_status` or `summarize_directory`. For everything else, use CLI with `--agent`.
|
|
23
23
|
|
|
24
24
|
## CLI commands (use these)
|
|
25
25
|
|
|
26
|
-
### Search — `gmax "query" --
|
|
26
|
+
### Search — `gmax "query" --agent`
|
|
27
27
|
```
|
|
28
|
-
gmax "where do we handle authentication" --
|
|
29
|
-
gmax "database connection pooling" --role ORCHESTRATION --
|
|
30
|
-
gmax "error handling" --lang ts --exclude tests/ --
|
|
31
|
-
gmax "VectorDB" --symbol --
|
|
32
|
-
gmax "handler" --name "handle.*" --
|
|
33
|
-
gmax "auth" --file handler.ts --
|
|
34
|
-
gmax "query" -C 5 --plain # include context lines
|
|
35
|
-
gmax "query" --imports --plain # show file imports
|
|
28
|
+
gmax "where do we handle authentication" --agent
|
|
29
|
+
gmax "database connection pooling" --role ORCHESTRATION --agent -m 5
|
|
30
|
+
gmax "error handling" --lang ts --exclude tests/ --agent
|
|
31
|
+
gmax "VectorDB" --symbol --agent # search + call graph in one shot
|
|
32
|
+
gmax "handler" --name "handle.*" --agent # regex filter on symbol names
|
|
33
|
+
gmax "auth" --file handler.ts --agent # filter by filename
|
|
36
34
|
```
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
Output format: `file:line symbol [role] — summary` (one line per result, no headers/footers)
|
|
37
|
+
|
|
38
|
+
All flags: `--agent --plain -m <n> --per-file <n> --min-score <n> --root <dir> --file <name> --exclude <prefix> --lang <ext> --role <role> --symbol --imports --name <regex> -C <n> --compact --content --scores --skeleton`
|
|
39
39
|
|
|
40
40
|
### Trace — `gmax trace <symbol>`
|
|
41
41
|
```
|
|
@@ -91,7 +91,7 @@ Use MCP only for `index_status` and `summarize_directory`. Use CLI for everythin
|
|
|
91
91
|
|
|
92
92
|
## Tips
|
|
93
93
|
|
|
94
|
-
- **Always use `--
|
|
94
|
+
- **Always use `--agent`** on CLI searches — one line per result, most token-efficient.
|
|
95
95
|
- **Be specific.** 5+ words. "auth" returns noise. "where does the server validate JWT tokens" is specific.
|
|
96
96
|
- **Use `--role ORCHESTRATION`** to skip type definitions and find the actual logic.
|
|
97
97
|
- **Use `--symbol`** when the query is a function/class name — gets search + trace in one call.
|