grepmax 0.7.6 → 0.7.8

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.
@@ -94,7 +94,7 @@ const TOOLS = [
94
94
  },
95
95
  detail: {
96
96
  type: "string",
97
- description: "Output detail: 'pointer' (default, metadata only — symbol, location, role, calls) or 'code' (include 4-line code snippets)",
97
+ description: "Output detail: 'pointer' (default, metadata only), 'code' (4-line snippets), or 'full' (complete chunk content with line numbers)",
98
98
  },
99
99
  min_score: {
100
100
  type: "number",
@@ -112,6 +112,14 @@ const TOOLS = [
112
112
  type: "string",
113
113
  description: "Exclude files under this path prefix (e.g. 'tests/' or 'dist/').",
114
114
  },
115
+ language: {
116
+ type: "string",
117
+ description: "Filter by file extension (e.g. 'ts', 'py', 'go'). Omit the dot.",
118
+ },
119
+ role: {
120
+ type: "string",
121
+ description: "Filter by chunk role: 'ORCHESTRATION' (logic/flow), 'DEFINITION' (types/classes), or 'IMPLEMENTATION'.",
122
+ },
115
123
  },
116
124
  required: ["query"],
117
125
  },
@@ -132,7 +140,7 @@ const TOOLS = [
132
140
  },
133
141
  detail: {
134
142
  type: "string",
135
- description: "Output detail: 'pointer' (default) or 'code' (include snippets)",
143
+ description: "Output detail: 'pointer' (default), 'code' (snippets), or 'full' (complete content)",
136
144
  },
137
145
  min_score: {
138
146
  type: "number",
@@ -150,6 +158,22 @@ const TOOLS = [
150
158
  type: "string",
151
159
  description: "Exclude files under this path prefix (e.g. 'tests/').",
152
160
  },
161
+ language: {
162
+ type: "string",
163
+ description: "Filter by file extension (e.g. 'ts', 'py').",
164
+ },
165
+ role: {
166
+ type: "string",
167
+ description: "Filter by role: 'ORCHESTRATION', 'DEFINITION', or 'IMPLEMENTATION'.",
168
+ },
169
+ projects: {
170
+ type: "string",
171
+ description: "Comma-separated project names to include (e.g. 'platform,osgrep'). Use index_status to see names.",
172
+ },
173
+ exclude_projects: {
174
+ type: "string",
175
+ description: "Comma-separated project names to exclude (e.g. 'capstone,power').",
176
+ },
153
177
  },
154
178
  required: ["query"],
155
179
  },
@@ -450,6 +474,38 @@ exports.mcp = new commander_1.Command("mcp")
450
474
  if (typeof args.exclude === "string" && args.exclude) {
451
475
  filters.exclude = args.exclude;
452
476
  }
477
+ if (typeof args.language === "string" && args.language) {
478
+ filters.language = args.language;
479
+ }
480
+ if (typeof args.role === "string" && args.role) {
481
+ filters.role = args.role;
482
+ }
483
+ if (searchAll) {
484
+ const allProjects = (0, project_registry_1.listProjects)();
485
+ if (typeof args.projects === "string" && args.projects) {
486
+ const names = args.projects
487
+ .split(",")
488
+ .map((s) => s.trim());
489
+ const roots = names
490
+ .map((n) => { var _a; return (_a = allProjects.find((p) => p.name === n)) === null || _a === void 0 ? void 0 : _a.root; })
491
+ .filter(Boolean);
492
+ if (roots.length > 0) {
493
+ filters.project_roots = roots.join(",");
494
+ }
495
+ }
496
+ if (typeof args.exclude_projects === "string" &&
497
+ args.exclude_projects) {
498
+ const names = args.exclude_projects
499
+ .split(",")
500
+ .map((s) => s.trim());
501
+ const roots = names
502
+ .map((n) => { var _a; return (_a = allProjects.find((p) => p.name === n)) === null || _a === void 0 ? void 0 : _a.root; })
503
+ .filter(Boolean);
504
+ if (roots.length > 0) {
505
+ filters.exclude_project_roots = roots.join(",");
506
+ }
507
+ }
508
+ }
453
509
  const result = yield searcher.search(query, limit, { rerank: true }, Object.keys(filters).length > 0 ? filters : undefined, pathPrefix);
454
510
  if (!result.data || result.data.length === 0) {
455
511
  return ok("No matches found.");
@@ -485,16 +541,17 @@ exports.mcp = new commander_1.Command("mcp")
485
541
  ? ` ${parentStr}${callsStr}`
486
542
  : "";
487
543
  let snippet = "";
488
- if (detail === "code") {
544
+ if (detail === "code" || detail === "full") {
489
545
  const raw = typeof r.content === "string"
490
546
  ? r.content
491
547
  : typeof r.text === "string"
492
548
  ? r.text
493
549
  : "";
494
- const lines = raw.split("\n").slice(0, 4);
550
+ const allLines = raw.split("\n");
551
+ const linesToShow = detail === "full" ? allLines : allLines.slice(0, 4);
495
552
  snippet =
496
553
  "\n" +
497
- lines
554
+ linesToShow
498
555
  .map((l, i) => `${startLine + i + 1}│${l}`)
499
556
  .join("\n");
500
557
  }
@@ -290,6 +290,35 @@ class Searcher {
290
290
  : excludeFilter;
291
291
  whereClauseParts.push(`path NOT LIKE '${(0, filter_builder_1.escapeSqlString)(absExclude)}%'`);
292
292
  }
293
+ // Handle language filter (by file extension)
294
+ const langFilter = _filters === null || _filters === void 0 ? void 0 : _filters.language;
295
+ if (typeof langFilter === "string" && langFilter) {
296
+ const ext = langFilter.startsWith(".") ? langFilter : `.${langFilter}`;
297
+ whereClauseParts.push(`path LIKE '%${(0, filter_builder_1.escapeSqlString)(ext)}'`);
298
+ }
299
+ // Handle role filter
300
+ const roleFilter = _filters === null || _filters === void 0 ? void 0 : _filters.role;
301
+ if (typeof roleFilter === "string" && roleFilter) {
302
+ whereClauseParts.push(`role = '${(0, filter_builder_1.escapeSqlString)(roleFilter)}'`);
303
+ }
304
+ // Handle project roots filter (from search_all projects param)
305
+ const projectRoots = _filters === null || _filters === void 0 ? void 0 : _filters.project_roots;
306
+ if (typeof projectRoots === "string" && projectRoots) {
307
+ const roots = projectRoots.split(",");
308
+ const clauses = roots.map((r) => {
309
+ const prefix = r.endsWith("/") ? r : `${r}/`;
310
+ return `path LIKE '${(0, filter_builder_1.escapeSqlString)(prefix)}%'`;
311
+ });
312
+ whereClauseParts.push(`(${clauses.join(" OR ")})`);
313
+ }
314
+ // Handle exclude project roots filter
315
+ const excludeRoots = _filters === null || _filters === void 0 ? void 0 : _filters.exclude_project_roots;
316
+ if (typeof excludeRoots === "string" && excludeRoots) {
317
+ for (const r of excludeRoots.split(",")) {
318
+ const prefix = r.endsWith("/") ? r : `${r}/`;
319
+ whereClauseParts.push(`path NOT LIKE '${(0, filter_builder_1.escapeSqlString)(prefix)}%'`);
320
+ }
321
+ }
293
322
  // Handle --def (definition) filter
294
323
  const defFilter = _filters === null || _filters === void 0 ? void 0 : _filters.def;
295
324
  if (typeof defFilter === "string" && defFilter) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.7.6",
3
+ "version": "0.7.8",
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.6",
3
+ "version": "0.7.8",
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",
@@ -39,18 +39,24 @@ Parameters:
39
39
  - `limit` (optional): Max results (default 3, max 50)
40
40
  - `root` (optional): Absolute path to search a different indexed directory.
41
41
  - `path` (optional): Restrict to path prefix (e.g. "src/auth/"). Relative to the search root.
42
- - `detail` (optional): `"pointer"` (default) or `"code"`
42
+ - `detail` (optional): `"pointer"` (default), `"code"` (4-line snippets), or `"full"` (complete chunk with line numbers)
43
43
  - `min_score` (optional): Filter by minimum relevance score (0-1)
44
44
  - `max_per_file` (optional): Cap results per file for diversity
45
45
  - `file` (optional): Filter to files matching this name (e.g. "syncer.ts"). Matches filename, not full path.
46
46
  - `exclude` (optional): Exclude files under this path prefix (e.g. "tests/" or "dist/")
47
+ - `language` (optional): Filter by file extension (e.g. "ts", "py", "go"). Omit the dot.
48
+ - `role` (optional): Filter by chunk role: "ORCHESTRATION" (logic/flow), "DEFINITION" (types), or "IMPLEMENTATION"
47
49
 
48
50
  **When to use which mode:**
49
51
  - `pointer` — navigation, finding locations, understanding architecture
50
52
  - `code` — comparing implementations, finding duplicates, checking syntax
51
53
 
52
54
  ### search_all
53
- 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.
55
+ Search ALL indexed code across every directory. Same parameters as semantic_search (query, limit, detail, min_score, max_per_file, file, exclude, language, role) but without `root` or `path`.
56
+
57
+ Additional parameters:
58
+ - `projects` (optional): Comma-separated project names to include (e.g. "platform,osgrep"). Use `index_status` to see names.
59
+ - `exclude_projects` (optional): Comma-separated project names to exclude (e.g. "capstone,power")
54
60
 
55
61
  Use sparingly. Prefer `semantic_search` when you know which directory to search.
56
62