grepmax 0.6.5 → 0.7.2
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/README.md +49 -9
- package/dist/commands/config.js +80 -0
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/index.js +7 -0
- package/dist/commands/mcp.js +38 -4
- package/dist/commands/search.js +10 -3
- package/dist/commands/serve.js +1 -1
- package/dist/commands/skeleton.js +6 -0
- package/dist/index.js +13 -3
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
- package/plugins/grepmax/skills/grepmax/SKILL.md +25 -15
package/README.md
CHANGED
|
@@ -106,6 +106,7 @@ In our public benchmarks, `grepmax` can save about 20% of your LLM tokens and de
|
|
|
106
106
|
| `trace_calls` | Call graph — who calls a symbol and what it calls (unscoped, crosses project boundaries) |
|
|
107
107
|
| `list_symbols` | List indexed functions, classes, and types with definition locations |
|
|
108
108
|
| `index_status` | Check index health: chunk counts, indexed directories, model info |
|
|
109
|
+
| `summarize_directory` | Generate LLM summaries for indexed chunks. Summaries appear in search results. |
|
|
109
110
|
|
|
110
111
|
## Commands
|
|
111
112
|
|
|
@@ -193,6 +194,17 @@ gmax skeleton "auth logic" # Search, skeletonize top matches
|
|
|
193
194
|
|
|
194
195
|
**Supported Languages:** TypeScript, JavaScript, Python, Go, Rust, Java, C#, C++, C, Ruby, PHP, Swift, Kotlin.
|
|
195
196
|
|
|
197
|
+
### `gmax config`
|
|
198
|
+
|
|
199
|
+
View or update configuration without the full interactive setup.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
gmax config # Show current settings
|
|
203
|
+
gmax config --embed-mode cpu # Switch to CPU embeddings
|
|
204
|
+
gmax config --embed-mode gpu # Switch to GPU (MLX)
|
|
205
|
+
gmax config --model-tier standard # Switch to standard model (768d)
|
|
206
|
+
```
|
|
207
|
+
|
|
196
208
|
### `gmax doctor`
|
|
197
209
|
|
|
198
210
|
Checks installation health, model paths, and database integrity.
|
|
@@ -244,9 +256,31 @@ handleAuth [exported ORCH C:8] src/auth/handler.ts:45-90
|
|
|
244
256
|
|
|
245
257
|
## Configuration
|
|
246
258
|
|
|
259
|
+
### Config File
|
|
260
|
+
|
|
261
|
+
Settings are stored in `~/.gmax/config.json`:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"modelTier": "small",
|
|
266
|
+
"vectorDim": 384,
|
|
267
|
+
"embedMode": "gpu",
|
|
268
|
+
"mlxModel": "ibm-granite/granite-embedding-small-english-r2"
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
View and change settings with `gmax config` or run `gmax setup` for interactive configuration.
|
|
273
|
+
|
|
247
274
|
### Ignoring Files
|
|
248
275
|
|
|
249
|
-
gmax respects `.gitignore` and `.gmaxignore` files. Create a `.gmaxignore` in your directory root to exclude additional patterns
|
|
276
|
+
gmax respects `.gitignore` and `.gmaxignore` files. Create a `.gmaxignore` in your directory root to exclude additional patterns:
|
|
277
|
+
|
|
278
|
+
```gitignore
|
|
279
|
+
# .gmaxignore — same syntax as .gitignore
|
|
280
|
+
docs/generated/
|
|
281
|
+
*.test.ts
|
|
282
|
+
fixtures/
|
|
283
|
+
```
|
|
250
284
|
|
|
251
285
|
### Index Management
|
|
252
286
|
|
|
@@ -255,15 +289,21 @@ gmax respects `.gitignore` and `.gmaxignore` files. Create a `.gmaxignore` in yo
|
|
|
255
289
|
- **Clean up:** `gmax index --reset` re-indexes the current directory from scratch
|
|
256
290
|
- **Full reset:** `rm -rf ~/.gmax/lancedb ~/.gmax/cache` to start completely fresh
|
|
257
291
|
|
|
258
|
-
|
|
292
|
+
### Environment Variables
|
|
259
293
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
294
|
+
| Variable | Description | Default |
|
|
295
|
+
| --- | --- | --- |
|
|
296
|
+
| `GMAX_WORKER_THREADS` | Number of worker threads for embedding | 50% of CPU cores |
|
|
297
|
+
| `GMAX_EMBED_MODE` | Force `cpu` or `gpu` embedding mode | Auto-detect |
|
|
298
|
+
| `GMAX_DEBUG` | Enable debug logging (`1` to enable) | Off |
|
|
299
|
+
| `GMAX_VERBOSE` | Enable verbose output (`1` to enable) | Off |
|
|
300
|
+
| `GMAX_WORKER_TASK_TIMEOUT_MS` | Worker task timeout in ms | `120000` |
|
|
301
|
+
| `GMAX_MAX_WORKER_MEMORY_MB` | Max worker memory in MB | 50% of system RAM |
|
|
302
|
+
| `GMAX_MAX_PER_FILE` | Default max results per file in search | `3` |
|
|
303
|
+
|
|
304
|
+
## Contributing
|
|
305
|
+
|
|
306
|
+
See [CLAUDE.md](CLAUDE.md) for development setup, commands, and architecture details.
|
|
267
307
|
|
|
268
308
|
## Troubleshooting
|
|
269
309
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.config = void 0;
|
|
13
|
+
const commander_1 = require("commander");
|
|
14
|
+
const config_1 = require("../config");
|
|
15
|
+
const index_config_1 = require("../lib/index/index-config");
|
|
16
|
+
const exit_1 = require("../lib/utils/exit");
|
|
17
|
+
const project_root_1 = require("../lib/utils/project-root");
|
|
18
|
+
exports.config = new commander_1.Command("config")
|
|
19
|
+
.description("View or update gmax configuration")
|
|
20
|
+
.option("--embed-mode <mode>", "Set embedding mode: cpu or gpu")
|
|
21
|
+
.option("--model-tier <tier>", "Set model tier: small (384d) or standard (768d)")
|
|
22
|
+
.addHelpText("after", `
|
|
23
|
+
Examples:
|
|
24
|
+
gmax config Show current configuration
|
|
25
|
+
gmax config --embed-mode cpu Switch to CPU embeddings
|
|
26
|
+
gmax config --model-tier standard Switch to standard model (768d)
|
|
27
|
+
`)
|
|
28
|
+
.action((_opts, cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
var _a, _b, _c, _d;
|
|
30
|
+
const options = cmd.optsWithGlobals();
|
|
31
|
+
const globalConfig = (0, index_config_1.readGlobalConfig)();
|
|
32
|
+
const paths = (0, project_root_1.ensureProjectPaths)(process.cwd());
|
|
33
|
+
const indexConfig = (0, index_config_1.readIndexConfig)(paths.configPath);
|
|
34
|
+
const hasUpdates = options.embedMode !== undefined || options.modelTier !== undefined;
|
|
35
|
+
if (!hasUpdates) {
|
|
36
|
+
// Show current config
|
|
37
|
+
const tier = (_a = config_1.MODEL_TIERS[globalConfig.modelTier]) !== null && _a !== void 0 ? _a : config_1.MODEL_TIERS.small;
|
|
38
|
+
console.log("gmax configuration (~/.gmax/config.json)\n");
|
|
39
|
+
console.log(` Model tier: ${globalConfig.modelTier} (${tier.vectorDim}d, ${tier.params})`);
|
|
40
|
+
console.log(` Embed mode: ${globalConfig.embedMode}`);
|
|
41
|
+
console.log(` Embed model: ${globalConfig.embedMode === "gpu" ? tier.mlxModel : tier.onnxModel}`);
|
|
42
|
+
if (indexConfig === null || indexConfig === void 0 ? void 0 : indexConfig.indexedAt) {
|
|
43
|
+
console.log(` Last indexed: ${indexConfig.indexedAt}`);
|
|
44
|
+
}
|
|
45
|
+
console.log(`\nTo change: gmax config --embed-mode <cpu|gpu> --model-tier <small|standard>`);
|
|
46
|
+
yield (0, exit_1.gracefulExit)();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Validate inputs
|
|
50
|
+
if (options.embedMode && !["cpu", "gpu"].includes(options.embedMode)) {
|
|
51
|
+
console.error(`Invalid embed mode: ${options.embedMode} (use cpu or gpu)`);
|
|
52
|
+
yield (0, exit_1.gracefulExit)(1);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (options.modelTier && !config_1.MODEL_TIERS[options.modelTier]) {
|
|
56
|
+
console.error(`Invalid model tier: ${options.modelTier} (use ${Object.keys(config_1.MODEL_TIERS).join(" or ")})`);
|
|
57
|
+
yield (0, exit_1.gracefulExit)(1);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const newTier = (_b = options.modelTier) !== null && _b !== void 0 ? _b : globalConfig.modelTier;
|
|
61
|
+
const newMode = (_c = options.embedMode) !== null && _c !== void 0 ? _c : globalConfig.embedMode;
|
|
62
|
+
const tier = (_d = config_1.MODEL_TIERS[newTier]) !== null && _d !== void 0 ? _d : config_1.MODEL_TIERS.small;
|
|
63
|
+
const tierChanged = newTier !== globalConfig.modelTier;
|
|
64
|
+
(0, index_config_1.writeGlobalConfig)({
|
|
65
|
+
modelTier: newTier,
|
|
66
|
+
vectorDim: tier.vectorDim,
|
|
67
|
+
embedMode: newMode,
|
|
68
|
+
mlxModel: newMode === "gpu" ? tier.mlxModel : undefined,
|
|
69
|
+
});
|
|
70
|
+
(0, index_config_1.writeSetupConfig)(paths.configPath, {
|
|
71
|
+
embedMode: newMode,
|
|
72
|
+
mlxModel: newMode === "gpu" ? tier.mlxModel : undefined,
|
|
73
|
+
modelTier: newTier,
|
|
74
|
+
});
|
|
75
|
+
console.log(`Updated: embed-mode=${newMode}, model-tier=${newTier} (${tier.vectorDim}d)`);
|
|
76
|
+
if (tierChanged) {
|
|
77
|
+
console.log("⚠️ Model tier changed — run `gmax index --reset` to rebuild with new dimensions.");
|
|
78
|
+
}
|
|
79
|
+
yield (0, exit_1.gracefulExit)();
|
|
80
|
+
}));
|
package/dist/commands/doctor.js
CHANGED
|
@@ -52,7 +52,7 @@ const index_config_1 = require("../lib/index/index-config");
|
|
|
52
52
|
const exit_1 = require("../lib/utils/exit");
|
|
53
53
|
const project_root_1 = require("../lib/utils/project-root");
|
|
54
54
|
exports.doctor = new commander_1.Command("doctor")
|
|
55
|
-
.description("Check
|
|
55
|
+
.description("Check installation health, models, and index status")
|
|
56
56
|
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
57
|
var _a;
|
|
58
58
|
console.log("🏥 gmax Doctor\n");
|
package/dist/commands/index.js
CHANGED
|
@@ -60,6 +60,13 @@ exports.index = new commander_1.Command("index")
|
|
|
60
60
|
.option("-p, --path <dir>", "Path to index (defaults to current directory)", "")
|
|
61
61
|
.option("-r, --reset", "Remove existing index and re-index from scratch", false)
|
|
62
62
|
.option("-v, --verbose", "Show detailed progress with file names", false)
|
|
63
|
+
.addHelpText("after", `
|
|
64
|
+
Examples:
|
|
65
|
+
gmax index Index current directory
|
|
66
|
+
gmax index --path ~/workspace Index a specific directory
|
|
67
|
+
gmax index --dry-run Preview what would be indexed
|
|
68
|
+
gmax index --reset Full re-index from scratch
|
|
69
|
+
`)
|
|
63
70
|
.action((_args, cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
71
|
var _a;
|
|
65
72
|
const options = cmd.optsWithGlobals();
|
package/dist/commands/mcp.js
CHANGED
|
@@ -239,13 +239,15 @@ function err(text) {
|
|
|
239
239
|
// Command
|
|
240
240
|
// ---------------------------------------------------------------------------
|
|
241
241
|
exports.mcp = new commander_1.Command("mcp")
|
|
242
|
-
.description("Start MCP server
|
|
242
|
+
.description("Start MCP server (stdio, auto-started by plugins)")
|
|
243
243
|
.action((_optsArg, _cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
244
244
|
// --- Lifecycle ---
|
|
245
245
|
let _vectorDb = null;
|
|
246
246
|
let _searcher = null;
|
|
247
247
|
let _skeletonizer = null;
|
|
248
248
|
let _indexReady = false;
|
|
249
|
+
let _indexing = false;
|
|
250
|
+
let _indexProgress = "";
|
|
249
251
|
const cleanup = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
250
252
|
if (_vectorDb) {
|
|
251
253
|
try {
|
|
@@ -310,14 +312,33 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
310
312
|
const db = getVectorDb();
|
|
311
313
|
const hasIndex = yield db.hasRowsForPath(projectRoot);
|
|
312
314
|
if (!hasIndex) {
|
|
315
|
+
if (_indexing)
|
|
316
|
+
return; // Already indexing in background
|
|
317
|
+
_indexing = true;
|
|
318
|
+
_indexProgress = "starting...";
|
|
313
319
|
console.log("[MCP] No index found, running initial sync...");
|
|
314
|
-
|
|
315
|
-
|
|
320
|
+
(0, syncer_1.initialSync)({
|
|
321
|
+
projectRoot,
|
|
322
|
+
onProgress: (info) => {
|
|
323
|
+
_indexProgress = `${info.processed}/${info.total || "?"} files`;
|
|
324
|
+
},
|
|
325
|
+
})
|
|
326
|
+
.then(() => {
|
|
327
|
+
_indexReady = true;
|
|
328
|
+
_indexing = false;
|
|
329
|
+
_indexProgress = "";
|
|
330
|
+
console.log("[MCP] Initial sync complete.");
|
|
331
|
+
})
|
|
332
|
+
.catch((e) => {
|
|
333
|
+
_indexing = false;
|
|
334
|
+
_indexProgress = "";
|
|
335
|
+
console.error("[MCP] Index sync failed:", e);
|
|
336
|
+
});
|
|
316
337
|
}
|
|
317
338
|
else {
|
|
318
339
|
console.log("[MCP] Index exists, ready.");
|
|
340
|
+
_indexReady = true;
|
|
319
341
|
}
|
|
320
|
-
_indexReady = true;
|
|
321
342
|
}
|
|
322
343
|
catch (e) {
|
|
323
344
|
console.error("[MCP] Index sync failed:", e);
|
|
@@ -345,6 +366,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
345
366
|
const limit = Math.min(Math.max(Number(args.limit) || 3, 1), 50);
|
|
346
367
|
yield ensureIndexReady();
|
|
347
368
|
ensureWatcher();
|
|
369
|
+
if (_indexing) {
|
|
370
|
+
return ok(`Indexing in progress (${_indexProgress}). Results may be incomplete or empty — try again shortly.`);
|
|
371
|
+
}
|
|
348
372
|
try {
|
|
349
373
|
const searcher = getSearcher();
|
|
350
374
|
// Determine path prefix and display root for relative paths
|
|
@@ -492,6 +516,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
492
516
|
const symbol = String(args.symbol || "");
|
|
493
517
|
if (!symbol)
|
|
494
518
|
return err("Missing required parameter: symbol");
|
|
519
|
+
if (_indexing) {
|
|
520
|
+
return ok(`Indexing in progress (${_indexProgress}). trace_calls requires a complete index — try again shortly.`);
|
|
521
|
+
}
|
|
495
522
|
try {
|
|
496
523
|
const db = getVectorDb();
|
|
497
524
|
const builder = new graph_builder_1.GraphBuilder(db);
|
|
@@ -534,6 +561,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
534
561
|
const pattern = typeof args.pattern === "string" ? args.pattern : undefined;
|
|
535
562
|
const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
|
|
536
563
|
const pathPrefix = typeof args.path === "string" ? args.path : undefined;
|
|
564
|
+
if (_indexing) {
|
|
565
|
+
return ok(`Indexing in progress (${_indexProgress}). list_symbols requires a complete index — try again shortly.`);
|
|
566
|
+
}
|
|
537
567
|
try {
|
|
538
568
|
const db = getVectorDb();
|
|
539
569
|
const table = yield db.ensureTable();
|
|
@@ -621,6 +651,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
621
651
|
watcherLine += " — search results may be incomplete";
|
|
622
652
|
}
|
|
623
653
|
}
|
|
654
|
+
const indexingLine = _indexing
|
|
655
|
+
? `Indexing: in progress (${_indexProgress})`
|
|
656
|
+
: "";
|
|
624
657
|
const lines = [
|
|
625
658
|
`Index: ~/.gmax/lancedb (${stats.chunks} chunks, ${fileCount} files)`,
|
|
626
659
|
`Model: ${globalConfig.embedMode === "gpu" ? ((_d = (_c = (_b = config_1.MODEL_TIERS[globalConfig.modelTier]) === null || _b === void 0 ? void 0 : _b.mlxModel) !== null && _c !== void 0 ? _c : config === null || config === void 0 ? void 0 : config.embedModel) !== null && _d !== void 0 ? _d : "unknown") : ((_e = config === null || config === void 0 ? void 0 : config.embedModel) !== null && _e !== void 0 ? _e : "unknown")} (${(_f = config === null || config === void 0 ? void 0 : config.vectorDim) !== null && _f !== void 0 ? _f : "?"}d, ${globalConfig.embedMode})`,
|
|
@@ -628,6 +661,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
628
661
|
? `Last indexed: ${config.indexedAt}`
|
|
629
662
|
: "",
|
|
630
663
|
watcherLine,
|
|
664
|
+
indexingLine,
|
|
631
665
|
"",
|
|
632
666
|
"Indexed directories:",
|
|
633
667
|
...projects.map((p) => { var _a; return ` ${p.name}\t${p.root}\t${(_a = p.lastIndexed) !== null && _a !== void 0 ? _a : "unknown"}`; }),
|
package/dist/commands/search.js
CHANGED
|
@@ -325,7 +325,7 @@ function outputSkeletons(results, projectRoot, limit, db) {
|
|
|
325
325
|
});
|
|
326
326
|
}
|
|
327
327
|
exports.search = new commander_1.Command("search")
|
|
328
|
-
.description("
|
|
328
|
+
.description("Search code by meaning (default command)")
|
|
329
329
|
.option("-m <max_count>, --max-count <max_count>", "The maximum number of results to return (total)", "5")
|
|
330
330
|
.option("-c, --content", "Show full chunk content instead of snippets", false)
|
|
331
331
|
.option("--per-file <n>", "Number of matches to show per file", "3")
|
|
@@ -336,8 +336,15 @@ 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
|
-
.argument("<pattern>", "
|
|
340
|
-
.argument("[path]", "
|
|
339
|
+
.argument("<pattern>", "Natural language query (e.g. \"where do we handle auth?\")")
|
|
340
|
+
.argument("[path]", "Restrict search to this path prefix")
|
|
341
|
+
.addHelpText("after", `
|
|
342
|
+
Examples:
|
|
343
|
+
gmax "where do we handle authentication?"
|
|
344
|
+
gmax "database connection pooling" -m 10
|
|
345
|
+
gmax "error handling" --compact --min-score 0.5
|
|
346
|
+
gmax "validation logic" --skeleton
|
|
347
|
+
`)
|
|
341
348
|
.action((pattern, exec_path, _options, cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
342
349
|
var _a, _b, _c;
|
|
343
350
|
const options = cmd.optsWithGlobals();
|
package/dist/commands/serve.js
CHANGED
|
@@ -100,7 +100,7 @@ function startMlxServer(mlxModel) {
|
|
|
100
100
|
return child;
|
|
101
101
|
}
|
|
102
102
|
exports.serve = new commander_1.Command("serve")
|
|
103
|
-
.description("
|
|
103
|
+
.description("HTTP search server with live file watching")
|
|
104
104
|
.option("-p, --port <port>", "Port to listen on", process.env.GMAX_PORT || "4444")
|
|
105
105
|
.option("-b, --background", "Run in background", false)
|
|
106
106
|
.option("--cpu", "Use CPU-only embeddings (skip MLX GPU server)", false)
|
|
@@ -112,6 +112,12 @@ exports.skeleton = new commander_1.Command("skeleton")
|
|
|
112
112
|
.option("--json", "Output as JSON", false)
|
|
113
113
|
.option("--no-summary", "Omit call/complexity summary in bodies", false)
|
|
114
114
|
.option("-s, --sync", "Sync index before searching", false)
|
|
115
|
+
.addHelpText("after", `
|
|
116
|
+
Examples:
|
|
117
|
+
gmax skeleton src/lib/auth.ts Show file structure
|
|
118
|
+
gmax skeleton AuthService Find symbol, show its file
|
|
119
|
+
gmax skeleton "auth logic" Search, skeletonize top matches
|
|
120
|
+
`)
|
|
115
121
|
.action((target, options, _cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
122
|
var _a, _b;
|
|
117
123
|
let vectorDb = null;
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ const path = __importStar(require("node:path"));
|
|
|
39
39
|
const commander_1 = require("commander");
|
|
40
40
|
const claude_code_1 = require("./commands/claude-code");
|
|
41
41
|
const codex_1 = require("./commands/codex");
|
|
42
|
+
const config_1 = require("./commands/config");
|
|
42
43
|
const doctor_1 = require("./commands/doctor");
|
|
43
44
|
const droid_1 = require("./commands/droid");
|
|
44
45
|
const index_1 = require("./commands/index");
|
|
@@ -54,6 +55,8 @@ const symbols_1 = require("./commands/symbols");
|
|
|
54
55
|
const trace_1 = require("./commands/trace");
|
|
55
56
|
const watch_1 = require("./commands/watch");
|
|
56
57
|
commander_1.program
|
|
58
|
+
.name("gmax")
|
|
59
|
+
.description("Semantic code search — finds code by meaning, not just strings")
|
|
57
60
|
.version(JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json"), {
|
|
58
61
|
encoding: "utf-8",
|
|
59
62
|
})).version)
|
|
@@ -67,22 +70,29 @@ if (legacyProjectData) {
|
|
|
67
70
|
console.log(" gmax now uses a centralized index at ~/.gmax/lancedb/.");
|
|
68
71
|
console.log(" Run 'gmax index' to re-index into the centralized store.");
|
|
69
72
|
}
|
|
73
|
+
// Core commands
|
|
70
74
|
commander_1.program.addCommand(search_1.search, { isDefault: true });
|
|
71
75
|
commander_1.program.addCommand(index_1.index);
|
|
72
76
|
commander_1.program.addCommand(list_1.list);
|
|
73
77
|
commander_1.program.addCommand(skeleton_1.skeleton);
|
|
74
78
|
commander_1.program.addCommand(symbols_1.symbols);
|
|
75
79
|
commander_1.program.addCommand(trace_1.trace);
|
|
76
|
-
|
|
80
|
+
// Services
|
|
77
81
|
commander_1.program.addCommand(serve_1.serve);
|
|
78
82
|
commander_1.program.addCommand(watch_1.watch);
|
|
79
83
|
commander_1.program.addCommand(mcp_1.mcp);
|
|
84
|
+
commander_1.program.addCommand(summarize_1.summarize);
|
|
85
|
+
// Setup & diagnostics
|
|
86
|
+
commander_1.program.addCommand(setup_1.setup);
|
|
87
|
+
commander_1.program.addCommand(config_1.config);
|
|
88
|
+
commander_1.program.addCommand(doctor_1.doctor);
|
|
89
|
+
// Plugin installers
|
|
80
90
|
commander_1.program.addCommand(claude_code_1.installClaudeCode);
|
|
81
91
|
commander_1.program.addCommand(codex_1.installCodex);
|
|
82
92
|
commander_1.program.addCommand(droid_1.installDroid);
|
|
93
|
+
droid_1.uninstallDroid._hidden = true;
|
|
83
94
|
commander_1.program.addCommand(droid_1.uninstallDroid);
|
|
84
95
|
commander_1.program.addCommand(opencode_1.installOpencode);
|
|
96
|
+
opencode_1.uninstallOpencode._hidden = true;
|
|
85
97
|
commander_1.program.addCommand(opencode_1.uninstallOpencode);
|
|
86
|
-
commander_1.program.addCommand(summarize_1.summarize);
|
|
87
|
-
commander_1.program.addCommand(doctor_1.doctor);
|
|
88
98
|
commander_1.program.parse();
|
package/package.json
CHANGED
|
@@ -35,10 +35,10 @@ handleAuth [exported ORCH C:8] src/auth/handler.ts:45-90
|
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Parameters:
|
|
38
|
-
- `query` (required): Natural language.
|
|
38
|
+
- `query` (required): Natural language. Be specific — 5+ words gives much better results than 1-2 words.
|
|
39
39
|
- `limit` (optional): Max results (default 3, max 50)
|
|
40
|
-
- `root` (optional):
|
|
41
|
-
- `path` (optional): Restrict to path prefix (e.g. "src/auth/")
|
|
40
|
+
- `root` (optional): Absolute path to search a different indexed directory.
|
|
41
|
+
- `path` (optional): Restrict to path prefix (e.g. "src/auth/"). Relative to the search root.
|
|
42
42
|
- `detail` (optional): `"pointer"` (default) or `"code"`
|
|
43
43
|
- `min_score` (optional): Filter by minimum relevance score (0-1)
|
|
44
44
|
- `max_per_file` (optional): Cap results per file for diversity
|
|
@@ -48,7 +48,9 @@ Parameters:
|
|
|
48
48
|
- `code` — comparing implementations, finding duplicates, checking syntax
|
|
49
49
|
|
|
50
50
|
### search_all
|
|
51
|
-
Search ALL indexed code across every directory. Same
|
|
51
|
+
Search ALL indexed code across every directory. Same parameters as semantic_search (query, limit, detail, min_score, max_per_file) but without `root` or `path` — searches everything.
|
|
52
|
+
|
|
53
|
+
Use sparingly. Prefer `semantic_search` when you know which directory to search.
|
|
52
54
|
|
|
53
55
|
### code_skeleton
|
|
54
56
|
File structure — signatures with bodies collapsed (~4x fewer tokens).
|
|
@@ -60,16 +62,17 @@ Call graph — who calls a symbol and what it calls. Unscoped — follows calls
|
|
|
60
62
|
|
|
61
63
|
### list_symbols
|
|
62
64
|
List indexed symbols with definition locations.
|
|
63
|
-
- `pattern` (optional): Filter by name
|
|
64
|
-
- `limit` (optional): Max results (default 20)
|
|
65
|
+
- `pattern` (optional): Filter by name (case-insensitive substring match)
|
|
66
|
+
- `limit` (optional): Max results (default 20, max 100)
|
|
65
67
|
- `path` (optional): Only symbols under this path prefix
|
|
66
68
|
|
|
67
69
|
### index_status
|
|
68
|
-
Check centralized index health — chunks, files, indexed directories, model info.
|
|
70
|
+
Check centralized index health — chunks, files, indexed directories, model info, watcher status.
|
|
69
71
|
|
|
70
72
|
### summarize_directory
|
|
71
|
-
Generate LLM summaries for indexed code in a directory. Summaries are stored and returned in search results.
|
|
73
|
+
Generate LLM summaries for indexed code in a directory. Summaries are stored and returned in search results. Requires the summarizer server (auto-started by the plugin hook).
|
|
72
74
|
- `path` (optional): Directory to summarize. Defaults to project root.
|
|
75
|
+
- `limit` (optional): Max chunks to summarize per call (default 200, max 5000). Run again to continue.
|
|
73
76
|
|
|
74
77
|
## Workflow
|
|
75
78
|
|
|
@@ -81,15 +84,22 @@ Generate LLM summaries for indexed code in a directory. Summaries are stored and
|
|
|
81
84
|
|
|
82
85
|
## If results seem stale
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
The watcher auto-starts when the MCP server connects — it detects file changes and re-indexes in the background. Usually results are fresh without manual intervention.
|
|
88
|
+
|
|
89
|
+
1. Check `index_status` — if watcher shows "syncing", wait for it to finish.
|
|
90
|
+
2. To force a full re-index: `Bash(gmax index)` (indexes current directory)
|
|
86
91
|
3. To add summaries without re-indexing: `Bash(gmax summarize)`
|
|
87
92
|
4. Do NOT use `gmax reindex` — it doesn't exist.
|
|
88
93
|
|
|
94
|
+
## Search warnings
|
|
95
|
+
|
|
96
|
+
If search results include a warning like "Full-text search unavailable", results may be less precise. This resolves automatically — the index retries FTS every 5 minutes.
|
|
97
|
+
|
|
89
98
|
## Tips
|
|
90
99
|
|
|
91
|
-
-
|
|
92
|
-
- ORCH results contain the logic — prioritize over DEF/IMPL.
|
|
93
|
-
- Summaries tell you what the code does without reading it. Use them to decide what to Read
|
|
94
|
-
- Use `root`
|
|
95
|
-
- Use `
|
|
100
|
+
- **Be specific.** "auth" returns noise. "where does the server validate JWT tokens from the Authorization header" returns exactly what you need. Aim for 5+ words.
|
|
101
|
+
- **ORCH results contain the logic** — prioritize over DEF/IMPL results.
|
|
102
|
+
- **Summaries tell you what the code does** without reading it. Use them to decide what to `Read`.
|
|
103
|
+
- **Use `root` for cross-project search** — absolute path to another indexed directory.
|
|
104
|
+
- **Use `max_per_file`** when results cluster in one file but you need diversity.
|
|
105
|
+
- **Don't search for exact strings** — use grep/Grep for that. gmax finds concepts, not literals.
|