grepmax 0.7.17 → 0.7.19
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
|
@@ -41,6 +41,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
41
41
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
45
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
46
|
+
var m = o[Symbol.asyncIterator], i;
|
|
47
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
48
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
49
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
50
|
+
};
|
|
44
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
52
|
exports.mcp = void 0;
|
|
46
53
|
exports.toStringArray = toStringArray;
|
|
@@ -57,6 +64,7 @@ const config_1 = require("../config");
|
|
|
57
64
|
const graph_builder_1 = require("../lib/graph/graph-builder");
|
|
58
65
|
const index_config_1 = require("../lib/index/index-config");
|
|
59
66
|
const syncer_1 = require("../lib/index/syncer");
|
|
67
|
+
const meta_cache_1 = require("../lib/store/meta-cache");
|
|
60
68
|
const searcher_1 = require("../lib/search/searcher");
|
|
61
69
|
const retriever_1 = require("../lib/skeleton/retriever");
|
|
62
70
|
const skeletonizer_1 = require("../lib/skeleton/skeletonizer");
|
|
@@ -132,6 +140,10 @@ const TOOLS = [
|
|
|
132
140
|
type: "boolean",
|
|
133
141
|
description: "Prepend the file's import/require statements to each result. Deduped per file.",
|
|
134
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
|
+
},
|
|
135
147
|
},
|
|
136
148
|
required: ["query"],
|
|
137
149
|
},
|
|
@@ -194,6 +206,10 @@ const TOOLS = [
|
|
|
194
206
|
type: "boolean",
|
|
195
207
|
description: "Prepend file's import statements to each result.",
|
|
196
208
|
},
|
|
209
|
+
name_pattern: {
|
|
210
|
+
type: "string",
|
|
211
|
+
description: "Regex to filter by symbol name (e.g. 'handle.*Auth').",
|
|
212
|
+
},
|
|
197
213
|
},
|
|
198
214
|
required: ["query"],
|
|
199
215
|
},
|
|
@@ -315,6 +331,23 @@ const TOOLS = [
|
|
|
315
331
|
required: ["file"],
|
|
316
332
|
},
|
|
317
333
|
},
|
|
334
|
+
{
|
|
335
|
+
name: "recent_changes",
|
|
336
|
+
description: "Show recently modified files in the index. Useful after pulls or merges to see what changed.",
|
|
337
|
+
inputSchema: {
|
|
338
|
+
type: "object",
|
|
339
|
+
properties: {
|
|
340
|
+
limit: {
|
|
341
|
+
type: "number",
|
|
342
|
+
description: "Max files to return (default 20)",
|
|
343
|
+
},
|
|
344
|
+
root: {
|
|
345
|
+
type: "string",
|
|
346
|
+
description: "Project root (defaults to current project)",
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
},
|
|
318
351
|
];
|
|
319
352
|
// ---------------------------------------------------------------------------
|
|
320
353
|
// Helpers
|
|
@@ -699,6 +732,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
699
732
|
absPath,
|
|
700
733
|
text,
|
|
701
734
|
score: typeof r.score === "number" ? r.score : 0,
|
|
735
|
+
symbols: defs,
|
|
702
736
|
};
|
|
703
737
|
});
|
|
704
738
|
if (minScore > 0) {
|
|
@@ -714,6 +748,18 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
714
748
|
return true;
|
|
715
749
|
});
|
|
716
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
|
+
}
|
|
717
763
|
let output = results.map((r) => r.text).join("\n\n");
|
|
718
764
|
// Symbol mode: append call graph
|
|
719
765
|
const mode = typeof args.mode === "string" ? args.mode : "default";
|
|
@@ -754,7 +800,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
754
800
|
output += `\n${traceLines.join("\n")}`;
|
|
755
801
|
}
|
|
756
802
|
}
|
|
757
|
-
catch (
|
|
803
|
+
catch (_c) {
|
|
758
804
|
// Trace failed — return search results without trace
|
|
759
805
|
}
|
|
760
806
|
}
|
|
@@ -1405,6 +1451,76 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1405
1451
|
}
|
|
1406
1452
|
});
|
|
1407
1453
|
}
|
|
1454
|
+
function formatTimeAgo(ms) {
|
|
1455
|
+
const sec = Math.floor(ms / 1000);
|
|
1456
|
+
if (sec < 60)
|
|
1457
|
+
return `${sec}s ago`;
|
|
1458
|
+
const min = Math.floor(sec / 60);
|
|
1459
|
+
if (min < 60)
|
|
1460
|
+
return `${min}m ago`;
|
|
1461
|
+
const hr = Math.floor(min / 60);
|
|
1462
|
+
if (hr < 24)
|
|
1463
|
+
return `${hr}h ago`;
|
|
1464
|
+
const days = Math.floor(hr / 24);
|
|
1465
|
+
return `${days}d ago`;
|
|
1466
|
+
}
|
|
1467
|
+
function handleRecentChanges(args) {
|
|
1468
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1469
|
+
var _a, e_1, _b, _c;
|
|
1470
|
+
const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 50);
|
|
1471
|
+
const root = typeof args.root === "string"
|
|
1472
|
+
? path.resolve(args.root)
|
|
1473
|
+
: projectRoot;
|
|
1474
|
+
const prefix = root.endsWith("/") ? root : `${root}/`;
|
|
1475
|
+
try {
|
|
1476
|
+
const metaCache = new meta_cache_1.MetaCache(config_1.PATHS.lmdbPath);
|
|
1477
|
+
try {
|
|
1478
|
+
const files = [];
|
|
1479
|
+
try {
|
|
1480
|
+
for (var _d = true, _e = __asyncValues(metaCache.entries()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
|
1481
|
+
_c = _f.value;
|
|
1482
|
+
_d = false;
|
|
1483
|
+
const { path: p, entry, } = _c;
|
|
1484
|
+
if (p.startsWith(prefix)) {
|
|
1485
|
+
files.push({ path: p, mtimeMs: entry.mtimeMs });
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1490
|
+
finally {
|
|
1491
|
+
try {
|
|
1492
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
1493
|
+
}
|
|
1494
|
+
finally { if (e_1) throw e_1.error; }
|
|
1495
|
+
}
|
|
1496
|
+
files.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
1497
|
+
const top = files.slice(0, limit);
|
|
1498
|
+
if (top.length === 0) {
|
|
1499
|
+
return ok(`No indexed files found for ${root}`);
|
|
1500
|
+
}
|
|
1501
|
+
const now = Date.now();
|
|
1502
|
+
const lines = [
|
|
1503
|
+
`Recent changes in ${path.basename(root)} (${top.length} most recent):\n`,
|
|
1504
|
+
];
|
|
1505
|
+
for (const f of top) {
|
|
1506
|
+
const rel = f.path.startsWith(prefix)
|
|
1507
|
+
? f.path.slice(prefix.length)
|
|
1508
|
+
: f.path;
|
|
1509
|
+
const ago = formatTimeAgo(now - f.mtimeMs);
|
|
1510
|
+
lines.push(` ${ago.padEnd(10)} ${rel}`);
|
|
1511
|
+
}
|
|
1512
|
+
return ok(lines.join("\n"));
|
|
1513
|
+
}
|
|
1514
|
+
finally {
|
|
1515
|
+
yield metaCache.close();
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
catch (e) {
|
|
1519
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1520
|
+
return err(`Recent changes failed: ${msg}`);
|
|
1521
|
+
}
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1408
1524
|
// --- MCP server setup ---
|
|
1409
1525
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
1410
1526
|
const server = new index_js_1.Server({
|
|
@@ -1442,6 +1558,8 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1442
1558
|
return handleSummarizeProject(toolArgs);
|
|
1443
1559
|
case "related_files":
|
|
1444
1560
|
return handleRelatedFiles(toolArgs);
|
|
1561
|
+
case "recent_changes":
|
|
1562
|
+
return handleRecentChanges(toolArgs);
|
|
1445
1563
|
default:
|
|
1446
1564
|
return err(`Unknown tool: ${name}`);
|
|
1447
1565
|
}
|
package/package.json
CHANGED
|
@@ -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, Bash(gmax:*), Read"
|
|
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"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## What gmax does
|
|
@@ -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
|
|
@@ -93,6 +94,11 @@ Find files related to a given file by shared symbol references. Shows dependenci
|
|
|
93
94
|
- `file` (required): File path relative to project root
|
|
94
95
|
- `limit` (optional): Max results per direction (default 10)
|
|
95
96
|
|
|
97
|
+
### recent_changes
|
|
98
|
+
Show recently modified files in the index. Useful after pulls or merges to see what changed.
|
|
99
|
+
- `limit` (optional): Max files (default 20)
|
|
100
|
+
- `root` (optional): Project root (defaults to current project)
|
|
101
|
+
|
|
96
102
|
### index_status
|
|
97
103
|
Check centralized index health — chunks, files, indexed directories, model info, watcher status.
|
|
98
104
|
|
|
@@ -103,11 +109,13 @@ Generate LLM summaries for indexed code in a directory. Summaries are stored and
|
|
|
103
109
|
|
|
104
110
|
## Workflow
|
|
105
111
|
|
|
106
|
-
1. **
|
|
107
|
-
2. **
|
|
108
|
-
3. **
|
|
109
|
-
4. **
|
|
110
|
-
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
|
|
111
119
|
|
|
112
120
|
## If results seem stale
|
|
113
121
|
|