grepmax 0.7.33 → 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/mcp.js
CHANGED
|
@@ -84,260 +84,110 @@ const watcher_registry_1 = require("../lib/utils/watcher-registry");
|
|
|
84
84
|
const TOOLS = [
|
|
85
85
|
{
|
|
86
86
|
name: "semantic_search",
|
|
87
|
-
description: "Search code by meaning
|
|
87
|
+
description: "Search code by meaning. Use scope:'all' for cross-project. Prefer CLI: gmax \"query\" --plain",
|
|
88
88
|
inputSchema: {
|
|
89
89
|
type: "object",
|
|
90
90
|
properties: {
|
|
91
|
-
query: {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
description: "Output detail: 'pointer' (default, metadata only), 'code' (4-line snippets), or 'full' (complete chunk content with line numbers)",
|
|
110
|
-
},
|
|
111
|
-
min_score: {
|
|
112
|
-
type: "number",
|
|
113
|
-
description: "Minimum relevance score (0-1). Results below this threshold are filtered out. Default: 0 (no filtering)",
|
|
114
|
-
},
|
|
115
|
-
max_per_file: {
|
|
116
|
-
type: "number",
|
|
117
|
-
description: "Max results per file (default: no cap). Useful to get diversity across files.",
|
|
118
|
-
},
|
|
119
|
-
file: {
|
|
120
|
-
type: "string",
|
|
121
|
-
description: "Filter to files matching this name (e.g. 'syncer.ts'). Matches the filename, not the full path.",
|
|
122
|
-
},
|
|
123
|
-
exclude: {
|
|
124
|
-
type: "string",
|
|
125
|
-
description: "Exclude files under this path prefix (e.g. 'tests/' or 'dist/').",
|
|
126
|
-
},
|
|
127
|
-
language: {
|
|
128
|
-
type: "string",
|
|
129
|
-
description: "Filter by file extension (e.g. 'ts', 'py', 'go'). Omit the dot.",
|
|
130
|
-
},
|
|
131
|
-
role: {
|
|
132
|
-
type: "string",
|
|
133
|
-
description: "Filter by chunk role: 'ORCHESTRATION' (logic/flow), 'DEFINITION' (types/classes), or 'IMPLEMENTATION'.",
|
|
134
|
-
},
|
|
135
|
-
context_lines: {
|
|
136
|
-
type: "number",
|
|
137
|
-
description: "Include N lines before and after the chunk (like grep -C). Only with detail 'code' or 'full'. Max 20.",
|
|
138
|
-
},
|
|
139
|
-
mode: {
|
|
140
|
-
type: "string",
|
|
141
|
-
description: "Search mode: 'default' (semantic only) or 'symbol' (semantic + call graph trace appended). Use 'symbol' when query is a function/class name.",
|
|
142
|
-
},
|
|
143
|
-
include_imports: {
|
|
144
|
-
type: "boolean",
|
|
145
|
-
description: "Prepend the file's import/require statements to each result. Deduped per file.",
|
|
146
|
-
},
|
|
147
|
-
name_pattern: {
|
|
148
|
-
type: "string",
|
|
149
|
-
description: "Regex to filter by symbol name (e.g. 'handle.*Auth'). Case-insensitive. Applied after search.",
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
required: ["query"],
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
name: "search_all",
|
|
157
|
-
description: "Search ALL indexed code across every directory. Use when you need to find code that could be anywhere. Returns results with full absolute paths so you know which project each result is from.",
|
|
158
|
-
inputSchema: {
|
|
159
|
-
type: "object",
|
|
160
|
-
properties: {
|
|
161
|
-
query: {
|
|
162
|
-
type: "string",
|
|
163
|
-
description: "Natural language search query.",
|
|
164
|
-
},
|
|
165
|
-
limit: {
|
|
166
|
-
type: "number",
|
|
167
|
-
description: "Max results to return (default 3, max 50)",
|
|
168
|
-
},
|
|
169
|
-
detail: {
|
|
170
|
-
type: "string",
|
|
171
|
-
description: "Output detail: 'pointer' (default), 'code' (snippets), or 'full' (complete content)",
|
|
172
|
-
},
|
|
173
|
-
min_score: {
|
|
174
|
-
type: "number",
|
|
175
|
-
description: "Minimum relevance score (0-1). Default: 0",
|
|
176
|
-
},
|
|
177
|
-
max_per_file: {
|
|
178
|
-
type: "number",
|
|
179
|
-
description: "Max results per file (default: no cap).",
|
|
180
|
-
},
|
|
181
|
-
file: {
|
|
182
|
-
type: "string",
|
|
183
|
-
description: "Filter to files matching this name (e.g. 'syncer.ts').",
|
|
184
|
-
},
|
|
185
|
-
exclude: {
|
|
186
|
-
type: "string",
|
|
187
|
-
description: "Exclude files under this path prefix (e.g. 'tests/').",
|
|
188
|
-
},
|
|
189
|
-
language: {
|
|
190
|
-
type: "string",
|
|
191
|
-
description: "Filter by file extension (e.g. 'ts', 'py').",
|
|
192
|
-
},
|
|
193
|
-
role: {
|
|
194
|
-
type: "string",
|
|
195
|
-
description: "Filter by role: 'ORCHESTRATION', 'DEFINITION', or 'IMPLEMENTATION'.",
|
|
196
|
-
},
|
|
197
|
-
projects: {
|
|
198
|
-
type: "string",
|
|
199
|
-
description: "Comma-separated project names to include (e.g. 'platform,osgrep'). Use index_status to see names.",
|
|
200
|
-
},
|
|
201
|
-
exclude_projects: {
|
|
202
|
-
type: "string",
|
|
203
|
-
description: "Comma-separated project names to exclude (e.g. 'capstone,power').",
|
|
204
|
-
},
|
|
205
|
-
context_lines: {
|
|
206
|
-
type: "number",
|
|
207
|
-
description: "Include N lines before/after chunk. Only with detail 'code' or 'full'. Max 20.",
|
|
208
|
-
},
|
|
209
|
-
include_imports: {
|
|
210
|
-
type: "boolean",
|
|
211
|
-
description: "Prepend file's import statements to each result.",
|
|
212
|
-
},
|
|
213
|
-
name_pattern: {
|
|
214
|
-
type: "string",
|
|
215
|
-
description: "Regex to filter by symbol name (e.g. 'handle.*Auth').",
|
|
216
|
-
},
|
|
91
|
+
query: { type: "string", description: "Natural language query (5+ words recommended)" },
|
|
92
|
+
limit: { type: "number", description: "Max results (default 3, max 50)" },
|
|
93
|
+
root: { type: "string", description: "Search a different directory (absolute path)" },
|
|
94
|
+
path: { type: "string", description: "Path prefix filter (e.g. 'src/auth/')" },
|
|
95
|
+
detail: { type: "string", description: "'pointer' (default), 'code', or 'full'" },
|
|
96
|
+
min_score: { type: "number", description: "Min score 0-1 (default 0)" },
|
|
97
|
+
max_per_file: { type: "number", description: "Max results per file" },
|
|
98
|
+
file: { type: "string", description: "Filename filter (e.g. 'syncer.ts')" },
|
|
99
|
+
exclude: { type: "string", description: "Exclude path prefix (e.g. 'tests/')" },
|
|
100
|
+
language: { type: "string", description: "Extension filter (e.g. 'ts', 'py')" },
|
|
101
|
+
role: { type: "string", description: "'ORCHESTRATION', 'DEFINITION', or 'IMPLEMENTATION'" },
|
|
102
|
+
context_lines: { type: "number", description: "Lines before/after chunk (max 20)" },
|
|
103
|
+
mode: { type: "string", description: "'default' or 'symbol' (appends call graph)" },
|
|
104
|
+
include_imports: { type: "boolean", description: "Prepend file imports to results" },
|
|
105
|
+
name_pattern: { type: "string", description: "Regex filter on symbol name" },
|
|
106
|
+
scope: { type: "string", description: "'project' (default) or 'all' (search everything)" },
|
|
107
|
+
projects: { type: "string", description: "Project names to include (comma-separated)" },
|
|
108
|
+
exclude_projects: { type: "string", description: "Project names to exclude (comma-separated)" },
|
|
217
109
|
},
|
|
218
110
|
required: ["query"],
|
|
219
111
|
},
|
|
220
112
|
},
|
|
221
113
|
{
|
|
222
114
|
name: "code_skeleton",
|
|
223
|
-
description: "
|
|
115
|
+
description: "File structure with bodies collapsed (~4x fewer tokens). Accepts file, directory, or comma-separated paths.",
|
|
224
116
|
inputSchema: {
|
|
225
117
|
type: "object",
|
|
226
118
|
properties: {
|
|
227
|
-
target: {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
},
|
|
231
|
-
limit: {
|
|
232
|
-
type: "number",
|
|
233
|
-
description: "Max files for directory mode (default 10, max 20). Ignored for single files.",
|
|
234
|
-
},
|
|
235
|
-
format: {
|
|
236
|
-
type: "string",
|
|
237
|
-
description: "Output format: 'text' (default) or 'json' (structured symbol list with names, lines, signatures).",
|
|
238
|
-
},
|
|
119
|
+
target: { type: "string", description: "File, directory, or comma-separated paths" },
|
|
120
|
+
limit: { type: "number", description: "Max files for directory mode (default 10)" },
|
|
121
|
+
format: { type: "string", description: "'text' (default) or 'json'" },
|
|
239
122
|
},
|
|
240
123
|
required: ["target"],
|
|
241
124
|
},
|
|
242
125
|
},
|
|
243
126
|
{
|
|
244
127
|
name: "trace_calls",
|
|
245
|
-
description: "
|
|
128
|
+
description: "Call graph: importers, callers (multi-hop), callees with file:line.",
|
|
246
129
|
inputSchema: {
|
|
247
130
|
type: "object",
|
|
248
131
|
properties: {
|
|
249
|
-
symbol: {
|
|
250
|
-
|
|
251
|
-
description: "The function, method, or class name to trace (e.g. 'handleAuth')",
|
|
252
|
-
},
|
|
253
|
-
depth: {
|
|
254
|
-
type: "number",
|
|
255
|
-
description: "Traversal depth for callers (default 1, max 3). depth: 2 shows callers-of-callers.",
|
|
256
|
-
},
|
|
132
|
+
symbol: { type: "string", description: "Function/class name to trace" },
|
|
133
|
+
depth: { type: "number", description: "Caller depth (default 1, max 3)" },
|
|
257
134
|
},
|
|
258
135
|
required: ["symbol"],
|
|
259
136
|
},
|
|
260
137
|
},
|
|
261
138
|
{
|
|
262
139
|
name: "list_symbols",
|
|
263
|
-
description: "List indexed symbols
|
|
140
|
+
description: "List indexed symbols with role and export status.",
|
|
264
141
|
inputSchema: {
|
|
265
142
|
type: "object",
|
|
266
143
|
properties: {
|
|
267
|
-
pattern: {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
},
|
|
271
|
-
limit: {
|
|
272
|
-
type: "number",
|
|
273
|
-
description: "Max symbols to return (default 20, max 100)",
|
|
274
|
-
},
|
|
275
|
-
path: {
|
|
276
|
-
type: "string",
|
|
277
|
-
description: "Only include symbols defined under this path prefix",
|
|
278
|
-
},
|
|
144
|
+
pattern: { type: "string", description: "Name filter (case-insensitive)" },
|
|
145
|
+
limit: { type: "number", description: "Max results (default 20)" },
|
|
146
|
+
path: { type: "string", description: "Path prefix filter" },
|
|
279
147
|
},
|
|
280
148
|
},
|
|
281
149
|
},
|
|
282
150
|
{
|
|
283
151
|
name: "index_status",
|
|
284
|
-
description: "
|
|
285
|
-
inputSchema: {
|
|
286
|
-
type: "object",
|
|
287
|
-
properties: {},
|
|
288
|
-
},
|
|
152
|
+
description: "Index health: chunks, files, projects, watcher status.",
|
|
153
|
+
inputSchema: { type: "object", properties: {} },
|
|
289
154
|
},
|
|
290
155
|
{
|
|
291
156
|
name: "summarize_directory",
|
|
292
|
-
description: "Generate LLM summaries for indexed
|
|
157
|
+
description: "Generate LLM summaries for indexed chunks.",
|
|
293
158
|
inputSchema: {
|
|
294
159
|
type: "object",
|
|
295
160
|
properties: {
|
|
296
|
-
path: {
|
|
297
|
-
|
|
298
|
-
description: "Directory to summarize (absolute or relative). Defaults to current project root.",
|
|
299
|
-
},
|
|
300
|
-
limit: {
|
|
301
|
-
type: "number",
|
|
302
|
-
description: "Max chunks to summarize per call (default 200, max 5000). Run again to continue.",
|
|
303
|
-
},
|
|
161
|
+
path: { type: "string", description: "Directory to summarize (default: project root)" },
|
|
162
|
+
limit: { type: "number", description: "Max chunks (default 200, max 5000)" },
|
|
304
163
|
},
|
|
305
164
|
},
|
|
306
165
|
},
|
|
307
166
|
{
|
|
308
167
|
name: "summarize_project",
|
|
309
|
-
description: "
|
|
168
|
+
description: "Project overview: languages, structure, roles, key symbols, entry points.",
|
|
310
169
|
inputSchema: {
|
|
311
170
|
type: "object",
|
|
312
171
|
properties: {
|
|
313
|
-
root: {
|
|
314
|
-
type: "string",
|
|
315
|
-
description: "Project root (absolute path). Defaults to current project.",
|
|
316
|
-
},
|
|
172
|
+
root: { type: "string", description: "Project root (default: current)" },
|
|
317
173
|
},
|
|
318
174
|
},
|
|
319
175
|
},
|
|
320
176
|
{
|
|
321
177
|
name: "related_files",
|
|
322
|
-
description: "Find
|
|
178
|
+
description: "Find dependencies and dependents of a file by shared symbols.",
|
|
323
179
|
inputSchema: {
|
|
324
180
|
type: "object",
|
|
325
181
|
properties: {
|
|
326
|
-
file: {
|
|
327
|
-
|
|
328
|
-
description: "File path relative to project root (e.g. 'src/lib/index/syncer.ts')",
|
|
329
|
-
},
|
|
330
|
-
limit: {
|
|
331
|
-
type: "number",
|
|
332
|
-
description: "Max related files per direction (default 10)",
|
|
333
|
-
},
|
|
182
|
+
file: { type: "string", description: "File path relative to project root" },
|
|
183
|
+
limit: { type: "number", description: "Max results per direction (default 10)" },
|
|
334
184
|
},
|
|
335
185
|
required: ["file"],
|
|
336
186
|
},
|
|
337
187
|
},
|
|
338
188
|
{
|
|
339
189
|
name: "recent_changes",
|
|
340
|
-
description: "
|
|
190
|
+
description: "Recently modified indexed files with timestamps.",
|
|
341
191
|
inputSchema: {
|
|
342
192
|
type: "object",
|
|
343
193
|
properties: {
|
|
@@ -513,11 +363,12 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
513
363
|
}
|
|
514
364
|
// --- Tool handlers ---
|
|
515
365
|
function handleSemanticSearch(args_1) {
|
|
516
|
-
return __awaiter(this, arguments, void 0, function* (args,
|
|
366
|
+
return __awaiter(this, arguments, void 0, function* (args, isSearchAll = false) {
|
|
517
367
|
var _a;
|
|
518
368
|
const query = String(args.query || "");
|
|
519
369
|
if (!query)
|
|
520
370
|
return err("Missing required parameter: query");
|
|
371
|
+
const searchAll = isSearchAll || args.scope === "all";
|
|
521
372
|
const limit = Math.min(Math.max(Number(args.limit) || 3, 1), 50);
|
|
522
373
|
ensureWatcher();
|
|
523
374
|
if (_indexing) {
|
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));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: grepmax
|
|
3
3
|
description: Semantic code search. Use alongside grep - grep for exact strings, gmax for concepts.
|
|
4
|
-
allowed-tools: "mcp__grepmax__semantic_search,
|
|
4
|
+
allowed-tools: "mcp__grepmax__semantic_search, mcp__grepmax__code_skeleton, mcp__grepmax__trace_calls, mcp__grepmax__list_symbols, mcp__grepmax__index_status, mcp__grepmax__summarize_directory, mcp__grepmax__summarize_project, mcp__grepmax__related_files, mcp__grepmax__recent_changes, Bash(gmax:*), Read"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## What gmax does
|
|
@@ -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
|
```
|
|
@@ -85,18 +85,13 @@ gmax doctor # health check
|
|
|
85
85
|
6. **Context** — `Bash(gmax related <file>)` to see what else to look at
|
|
86
86
|
7. **Changes** — `Bash(gmax recent)` after pulls
|
|
87
87
|
|
|
88
|
-
## MCP tools
|
|
89
|
-
|
|
90
|
-
MCP tools are available but consume more tokens. Use them only for:
|
|
91
|
-
- `index_status` — quick health check (no CLI equivalent that's cheaper)
|
|
92
|
-
- `summarize_directory` — LLM summary generation
|
|
93
|
-
- `semantic_search` with `detail: "pointer"` — when you need the structured pointer format
|
|
88
|
+
## MCP tools
|
|
94
89
|
|
|
95
|
-
|
|
90
|
+
Use MCP only for `index_status` and `summarize_directory`. Use CLI for everything else. For cross-project search, use `scope: "all"` on semantic_search (replaces search_all).
|
|
96
91
|
|
|
97
92
|
## Tips
|
|
98
93
|
|
|
99
|
-
- **Always use `--
|
|
94
|
+
- **Always use `--agent`** on CLI searches — one line per result, most token-efficient.
|
|
100
95
|
- **Be specific.** 5+ words. "auth" returns noise. "where does the server validate JWT tokens" is specific.
|
|
101
96
|
- **Use `--role ORCHESTRATION`** to skip type definitions and find the actual logic.
|
|
102
97
|
- **Use `--symbol`** when the query is a function/class name — gets search + trace in one call.
|