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.
@@ -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 within a directory. Use natural language queries like 'where do we validate permissions'. Searches the current project by default. Use `root` to search a different directory's index (e.g. a parent directory).",
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
- type: "string",
93
- description: "Natural language search query. Be specific more words give better results.",
94
- },
95
- limit: {
96
- type: "number",
97
- description: "Max results to return (default 3, max 50)",
98
- },
99
- root: {
100
- type: "string",
101
- description: "Directory to search (absolute or relative path). Defaults to the current project root. Use to search a parent or sibling directory's indexed code.",
102
- },
103
- path: {
104
- type: "string",
105
- description: "Restrict search to files under this path prefix (e.g. 'src/auth/'). Relative to the search root.",
106
- },
107
- detail: {
108
- type: "string",
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: "Show the structure of source files — signatures with bodies collapsed (~4x fewer tokens). Accepts a file path, a directory path, or comma-separated file paths.",
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
- type: "string",
229
- description: "File path, directory path (e.g. 'src/lib/search/'), or comma-separated files (e.g. 'src/a.ts,src/b.ts'). Relative to project root.",
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: "Trace the call graph for a symbol — who calls it (callers) and what it calls (callees). Searches across ALL indexed code to follow calls across project boundaries.",
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
- type: "string",
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 (functions, classes, types) with their definition locations. Useful for finding where things are defined without knowing exact names.",
140
+ description: "List indexed symbols with role and export status.",
264
141
  inputSchema: {
265
142
  type: "object",
266
143
  properties: {
267
- pattern: {
268
- type: "string",
269
- description: "Filter symbols by name (case-insensitive substring match)",
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: "Check the status of the gmax index. Returns indexed directories, chunk counts, embed mode, index age, and watcher status.",
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 code in a directory. Run after indexing. Summaries are stored and returned in search results. Requires the summarizer server on port 8101.",
157
+ description: "Generate LLM summaries for indexed chunks.",
293
158
  inputSchema: {
294
159
  type: "object",
295
160
  properties: {
296
- path: {
297
- type: "string",
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: "High-level overview of an indexed project — languages, directory structure, role distribution, key symbols, and entry points. Use when first exploring a codebase.",
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 files related to a given file by shared symbol references. Shows dependencies (what this file calls) and dependents (what calls this file).",
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
- type: "string",
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: "Show recently modified files in the index. Useful after pulls or merges to see what changed.",
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, searchAll = false) {
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) {
@@ -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
- // This allows agents (via shim) to know results might be partial.
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 (_f) {
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 (_g) {
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 (_h) {
692
+ catch (_s) {
638
693
  // Trace failed — skip silently
639
694
  }
640
695
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.7.33",
3
+ "version": "0.7.35",
4
4
  "author": "Robert Owens <robowens@me.com>",
5
5
  "homepage": "https://github.com/reowens/grepmax",
6
6
  "bugs": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.7.33",
3
+ "version": "0.7.35",
4
4
  "description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
5
5
  "author": {
6
6
  "name": "Robert Owens",
@@ -89,7 +89,7 @@ async function main() {
89
89
  hookSpecificOutput: {
90
90
  hookEventName: "SessionStart",
91
91
  additionalContext:
92
- 'gmax ready. PREFER CLI over MCP tools — use Bash(gmax "query" --plain) for search, Bash(gmax trace <symbol>) for call graphs, Bash(gmax skeleton <path>) for file structure. CLI is 2x more token-efficient than MCP tool calls. Always add --plain flag.',
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, mcp__grepmax__search_all, 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"
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.** The CLI is ~2x more token-efficient because MCP tool schemas add ~800 tokens of overhead per call. The CLI has full feature parity with every MCP tool.
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 --plain -m 3)
19
+ Bash(gmax "auth handler" --role ORCHESTRATION --lang ts --agent -m 3)
20
20
  ```
21
21
 
22
- **Only use MCP tools** for `index_status` (quick health check) or `summarize_directory` (LLM summaries). For everything else, use CLI.
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" --plain`
26
+ ### Search — `gmax "query" --agent`
27
27
  ```
28
- gmax "where do we handle authentication" --plain
29
- gmax "database connection pooling" --role ORCHESTRATION --plain -m 5
30
- gmax "error handling" --lang ts --exclude tests/ --plain
31
- gmax "VectorDB" --symbol --plain # search + call graph in one shot
32
- gmax "handler" --name "handle.*" --plain # regex filter on symbol names
33
- gmax "auth" --file handler.ts --plain # filter by filename
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
- All flags: `--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`
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 (only when CLI isn't suitable)
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
- Full MCP tool documentation: semantic_search (16 params), search_all, code_skeleton, trace_calls, list_symbols, index_status, summarize_project, related_files, recent_changes, summarize_directory.
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 `--plain`** on CLI searches — agent-friendly output without ANSI codes.
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.