grepmax 0.16.1 → 0.16.3

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.
@@ -44,13 +44,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.peek = void 0;
46
46
  const fs = __importStar(require("node:fs"));
47
- const path = __importStar(require("node:path"));
48
47
  const commander_1 = require("commander");
49
48
  const graph_builder_1 = require("../lib/graph/graph-builder");
50
49
  const vector_db_1 = require("../lib/store/vector-db");
51
50
  const exit_1 = require("../lib/utils/exit");
52
51
  const filter_builder_1 = require("../lib/utils/filter-builder");
53
52
  const language_1 = require("../lib/utils/language");
53
+ const project_registry_1 = require("../lib/utils/project-registry");
54
54
  const project_root_1 = require("../lib/utils/project-root");
55
55
  const useColors = process.stdout.isTTY && !process.env.NO_COLOR;
56
56
  const style = {
@@ -95,29 +95,37 @@ exports.peek = new commander_1.Command("peek")
95
95
  .argument("<symbol>", "The symbol to peek at")
96
96
  .option("-d, --depth <n>", "Caller traversal depth (default 1, max 3)", "1")
97
97
  .option("--root <dir>", "Project root directory")
98
+ .option("--in <subpath>", "Restrict to a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
99
+ .option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
98
100
  .option("--agent", "Compact output for AI agents", false)
99
101
  .action((symbol, opts) => __awaiter(void 0, void 0, void 0, function* () {
100
102
  var _a;
101
103
  let vectorDb = null;
102
- const root = opts.root ? path.resolve(opts.root) : process.cwd();
104
+ const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
105
+ if (root === null)
106
+ return;
103
107
  const depth = Math.min(Math.max(Number.parseInt(opts.depth || "1", 10), 1), 3);
104
108
  try {
105
109
  const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
106
110
  const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
107
111
  vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
112
+ const { resolveScope, buildScopeWhere } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
113
+ const scope = resolveScope({
114
+ projectRoot,
115
+ in: opts.in,
116
+ exclude: opts.exclude,
117
+ });
118
+ const scopeWhere = (cond) => buildScopeWhere(scope, cond);
108
119
  // Cross-language disambiguation: when the symbol is defined in 2+
109
120
  // languages, refuse to silently pick one. The graph builder otherwise
110
121
  // picks one chunk arbitrarily and lists callers from a different
111
122
  // language — verified failure mode.
112
123
  {
113
124
  const tableForCheck = yield vectorDb.ensureTable();
114
- const prefixForCheck = projectRoot.endsWith("/")
115
- ? projectRoot
116
- : `${projectRoot}/`;
117
125
  const allDefs = yield tableForCheck
118
126
  .query()
119
127
  .select(["path", "start_line"])
120
- .where(`array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(symbol)}') AND path LIKE '${(0, filter_builder_1.escapeSqlString)(prefixForCheck)}%'`)
128
+ .where(scopeWhere(`array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(symbol)}')`))
121
129
  .limit(20)
122
130
  .toArray();
123
131
  const chunks = allDefs.map((row) => ({
@@ -140,7 +148,7 @@ exports.peek = new commander_1.Command("peek")
140
148
  return;
141
149
  }
142
150
  }
143
- const graphBuilder = new graph_builder_1.GraphBuilder(vectorDb, projectRoot);
151
+ const graphBuilder = new graph_builder_1.GraphBuilder(vectorDb, scope.pathPrefix, scope.excludePrefixes);
144
152
  const graph = yield graphBuilder.buildGraph(symbol);
145
153
  if (!graph.center) {
146
154
  const lines = [
@@ -159,13 +167,10 @@ exports.peek = new commander_1.Command("peek")
159
167
  : p;
160
168
  // Get chunk metadata for is_exported and end_line
161
169
  const table = yield vectorDb.ensureTable();
162
- const prefix = projectRoot.endsWith("/")
163
- ? projectRoot
164
- : `${projectRoot}/`;
165
170
  const metaRows = yield table
166
171
  .query()
167
172
  .select(["is_exported", "start_line", "end_line"])
168
- .where(`array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(symbol)}') AND path LIKE '${(0, filter_builder_1.escapeSqlString)(prefix)}%'`)
173
+ .where(scopeWhere(`array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(symbol)}')`))
169
174
  .limit(1)
170
175
  .toArray();
171
176
  const exported = metaRows.length > 0 && Boolean(metaRows[0].is_exported);
@@ -56,12 +56,13 @@ exports.project = new commander_1.Command("project")
56
56
  .option("--root <dir>", "Project root (defaults to current directory)")
57
57
  .option("--agent", "Compact output for AI agents", false)
58
58
  .action((opts) => __awaiter(void 0, void 0, void 0, function* () {
59
- var _a, _b, _c, _d;
59
+ var _a, _b, _c;
60
60
  let vectorDb = null;
61
61
  try {
62
- const root = opts.root
63
- ? (_a = (0, project_root_1.findProjectRoot)(path.resolve(opts.root))) !== null && _a !== void 0 ? _a : path.resolve(opts.root)
64
- : (_b = (0, project_root_1.findProjectRoot)(process.cwd())) !== null && _b !== void 0 ? _b : process.cwd();
62
+ const resolvedRoot = (0, project_registry_1.resolveRootOrExit)(opts.root);
63
+ if (resolvedRoot === null)
64
+ return;
65
+ const root = (_a = (0, project_root_1.findProjectRoot)(resolvedRoot)) !== null && _a !== void 0 ? _a : resolvedRoot;
65
66
  const prefix = root.endsWith("/") ? root : `${root}/`;
66
67
  const projectName = path.basename(root);
67
68
  const paths = (0, project_root_1.ensureProjectPaths)(root);
@@ -136,7 +137,7 @@ exports.project = new commander_1.Command("project")
136
137
  console.log(`root\t${root}`);
137
138
  console.log(`chunks\t${rows.length}`);
138
139
  console.log(`files\t${files.size}`);
139
- console.log(`last_indexed\t${(_c = proj === null || proj === void 0 ? void 0 : proj.lastIndexed) !== null && _c !== void 0 ? _c : "unknown"}`);
140
+ console.log(`last_indexed\t${(_b = proj === null || proj === void 0 ? void 0 : proj.lastIndexed) !== null && _b !== void 0 ? _b : "unknown"}`);
140
141
  console.log(`languages\t${extEntries.map(([ext]) => ext).join(",")}`);
141
142
  console.log(`top_dirs\t${Array.from(dirCounts.entries()).sort((a, b) => b[1].chunks - a[1].chunks).slice(0, 8).map(([d]) => d).join(",")}`);
142
143
  if (topSymbols.length > 0) {
@@ -148,7 +149,7 @@ exports.project = new commander_1.Command("project")
148
149
  }
149
150
  else {
150
151
  console.log(`Project: ${projectName} (${root})`);
151
- console.log(`Last indexed: ${(_d = proj === null || proj === void 0 ? void 0 : proj.lastIndexed) !== null && _d !== void 0 ? _d : "unknown"} • ${rows.length} chunks • ${files.size} files\n`);
152
+ console.log(`Last indexed: ${(_c = proj === null || proj === void 0 ? void 0 : proj.lastIndexed) !== null && _c !== void 0 ? _c : "unknown"} • ${rows.length} chunks • ${files.size} files\n`);
152
153
  console.log(`Languages: ${extEntries.map(([ext, count]) => `${ext} (${Math.round((count / rows.length) * 100)}%)`).join(", ")}\n`);
153
154
  console.log("Directory structure:");
154
155
  for (const [dir, data] of Array.from(dirCounts.entries())
@@ -182,7 +183,7 @@ exports.project = new commander_1.Command("project")
182
183
  try {
183
184
  yield vectorDb.close();
184
185
  }
185
- catch (_e) { }
186
+ catch (_d) { }
186
187
  }
187
188
  yield (0, exit_1.gracefulExit)();
188
189
  }
@@ -1,132 +1,12 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
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
- };
51
2
  Object.defineProperty(exports, "__esModule", { value: true });
52
3
  exports.recent = void 0;
53
- const path = __importStar(require("node:path"));
54
4
  const commander_1 = require("commander");
55
- const config_1 = require("../config");
56
- const meta_cache_1 = require("../lib/store/meta-cache");
57
- const exit_1 = require("../lib/utils/exit");
58
- const format_helpers_1 = require("../lib/utils/format-helpers");
59
- const project_root_1 = require("../lib/utils/project-root");
60
5
  exports.recent = new commander_1.Command("recent")
61
- .description("Show recently modified indexed files")
62
- .option("-l, --limit <n>", "Max files (default 20)", "20")
63
- .option("--root <dir>", "Project root (defaults to current directory)")
64
- .option("--agent", "Compact output for AI agents", false)
65
- .action((opts) => __awaiter(void 0, void 0, void 0, function* () {
66
- var _a, e_1, _b, _c;
67
- var _d, _e;
68
- const limit = Math.min(Math.max(Number.parseInt(opts.limit || "20", 10), 1), 50);
69
- try {
70
- const root = opts.root
71
- ? (_d = (0, project_root_1.findProjectRoot)(path.resolve(opts.root))) !== null && _d !== void 0 ? _d : path.resolve(opts.root)
72
- : (_e = (0, project_root_1.findProjectRoot)(process.cwd())) !== null && _e !== void 0 ? _e : process.cwd();
73
- const prefix = root.endsWith("/") ? root : `${root}/`;
74
- const metaCache = new meta_cache_1.MetaCache(config_1.PATHS.lmdbPath);
75
- try {
76
- const files = [];
77
- try {
78
- for (var _f = true, _g = __asyncValues(metaCache.entries()), _h; _h = yield _g.next(), _a = _h.done, !_a; _f = true) {
79
- _c = _h.value;
80
- _f = false;
81
- const { path: p, entry } = _c;
82
- if (p.startsWith(prefix)) {
83
- files.push({ path: p, mtimeMs: entry.mtimeMs });
84
- }
85
- }
86
- }
87
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
88
- finally {
89
- try {
90
- if (!_f && !_a && (_b = _g.return)) yield _b.call(_g);
91
- }
92
- finally { if (e_1) throw e_1.error; }
93
- }
94
- files.sort((a, b) => b.mtimeMs - a.mtimeMs);
95
- const top = files.slice(0, limit);
96
- if (top.length === 0) {
97
- console.log(`No indexed files found for ${root}`);
98
- console.log("\nTry: `gmax add` to register and index this project, or `gmax status` to see what's indexed.");
99
- process.exitCode = 1;
100
- return;
101
- }
102
- const now = Date.now();
103
- if (opts.agent) {
104
- for (const f of top) {
105
- const rel = f.path.startsWith(prefix)
106
- ? f.path.slice(prefix.length)
107
- : f.path;
108
- console.log(`${rel}\t${(0, format_helpers_1.formatTimeAgo)(now - f.mtimeMs)}`);
109
- }
110
- }
111
- else {
112
- console.log(`Recent changes in ${path.basename(root)} (${top.length} most recent):\n`);
113
- for (const f of top) {
114
- const rel = f.path.startsWith(prefix)
115
- ? f.path.slice(prefix.length)
116
- : f.path;
117
- const ago = (0, format_helpers_1.formatTimeAgo)(now - f.mtimeMs);
118
- console.log(` ${ago.padEnd(10)} ${rel}`);
119
- }
120
- }
121
- }
122
- finally {
123
- yield metaCache.close();
124
- }
125
- }
126
- catch (error) {
127
- const msg = error instanceof Error ? error.message : "Unknown error";
128
- console.error("Recent changes failed:", msg);
129
- process.exitCode = 1;
130
- }
131
- yield (0, exit_1.gracefulExit)();
132
- }));
6
+ .description("[deprecated] Use 'gmax log' instead")
7
+ .allowUnknownOption(true)
8
+ .allowExcessArguments(true)
9
+ .action(() => {
10
+ console.error("gmax recent is deprecated; use 'gmax log <path-or-symbol>' instead");
11
+ process.exitCode = 1;
12
+ });
@@ -48,6 +48,7 @@ const commander_1 = require("commander");
48
48
  const vector_db_1 = require("../lib/store/vector-db");
49
49
  const filter_builder_1 = require("../lib/utils/filter-builder");
50
50
  const exit_1 = require("../lib/utils/exit");
51
+ const project_registry_1 = require("../lib/utils/project-registry");
51
52
  const project_root_1 = require("../lib/utils/project-root");
52
53
  const arrow_1 = require("../lib/utils/arrow");
53
54
  exports.related = new commander_1.Command("related")
@@ -55,19 +56,29 @@ exports.related = new commander_1.Command("related")
55
56
  .argument("<file>", "File path relative to project root")
56
57
  .option("-l, --limit <n>", "Max results per direction (default 10)", "10")
57
58
  .option("--root <dir>", "Project root directory")
59
+ .option("--in <subpath>", "Restrict to a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
60
+ .option("--exclude <subpath>", "Exclude a sub-path of the project (repeatable)", (value, prev) => (prev ? [...prev, value] : [value]))
58
61
  .option("--agent", "Compact output for AI agents", false)
59
62
  .action((file, opts) => __awaiter(void 0, void 0, void 0, function* () {
60
63
  var _a;
61
64
  const limit = Math.min(Math.max(Number.parseInt(opts.limit || "10", 10), 1), 25);
62
65
  let vectorDb = null;
63
66
  try {
64
- const root = opts.root ? path.resolve(opts.root) : process.cwd();
67
+ const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
68
+ if (root === null)
69
+ return;
65
70
  const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
66
71
  const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
67
72
  vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
68
73
  const absPath = path.resolve(projectRoot, file);
69
74
  const table = yield vectorDb.ensureTable();
70
- const pathScope = `path LIKE '${(0, filter_builder_1.escapeSqlString)(projectRoot)}/%'`;
75
+ const { resolveScope, buildScopeWhere } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
76
+ const scope = resolveScope({
77
+ projectRoot,
78
+ in: opts.in,
79
+ exclude: opts.exclude,
80
+ });
81
+ const pathScope = buildScopeWhere(scope);
71
82
  const fileChunks = yield table
72
83
  .query()
73
84
  .select(["defined_symbols", "referenced_symbols"])
@@ -43,7 +43,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.remove = void 0;
46
- const fs = __importStar(require("node:fs"));
47
46
  const path = __importStar(require("node:path"));
48
47
  const readline = __importStar(require("node:readline"));
49
48
  const commander_1 = require("commander");
@@ -83,41 +82,23 @@ Examples:
83
82
  let vectorDb = null;
84
83
  let metaCache = null;
85
84
  try {
86
- // Resolve name → registered root when arg has no path separator and isn't a dir.
87
- // Avoids the footgun where a typo'd name silently removed the cwd project.
88
- let resolvedDir = dir;
89
- if (dir &&
90
- !dir.includes("/") &&
91
- !dir.includes("\\") &&
92
- !fs.existsSync(path.resolve(dir))) {
93
- const matches = (0, project_registry_1.listProjects)().filter((p) => p.name === dir);
94
- if (matches.length === 0) {
95
- console.error(`No registered project named "${dir}".`);
96
- const all = (0, project_registry_1.listProjects)();
97
- if (all.length > 0) {
98
- console.error("Available projects:");
99
- for (const p of all) {
100
- console.error(` ${p.name.padEnd(24)} ${p.root}`);
101
- }
102
- }
103
- else {
104
- console.error("No projects are currently registered.");
105
- }
106
- process.exitCode = 1;
107
- return;
85
+ // Resolve name → registered root when arg has no path separator and
86
+ // isn't a dir. Avoids the footgun where a typo'd name silently removed
87
+ // the cwd project.
88
+ let targetDir;
89
+ if (dir) {
90
+ try {
91
+ targetDir = (0, project_registry_1.resolveProjectRoot)(dir);
108
92
  }
109
- if (matches.length > 1) {
110
- console.error(`Multiple registered projects named "${dir}":`);
111
- for (const p of matches) {
112
- console.error(` ${p.root}`);
113
- }
114
- console.error("Pass an absolute path to disambiguate.");
93
+ catch (err) {
94
+ console.error(err instanceof Error ? err.message : String(err));
115
95
  process.exitCode = 1;
116
96
  return;
117
97
  }
118
- resolvedDir = matches[0].root;
119
98
  }
120
- const targetDir = resolvedDir ? path.resolve(resolvedDir) : process.cwd();
99
+ else {
100
+ targetDir = process.cwd();
101
+ }
121
102
  const projectRoot = (_a = (0, project_root_1.findProjectRoot)(targetDir)) !== null && _a !== void 0 ? _a : targetDir;
122
103
  const projectName = path.basename(projectRoot);
123
104
  const project = (0, project_registry_1.getProject)(projectRoot);
@@ -48,6 +48,7 @@ const fs = __importStar(require("node:fs"));
48
48
  const path = __importStar(require("node:path"));
49
49
  const commander_1 = require("commander");
50
50
  const exit_1 = require("../lib/utils/exit");
51
+ const project_registry_1 = require("../lib/utils/project-registry");
51
52
  const project_root_1 = require("../lib/utils/project-root");
52
53
  exports.review = new commander_1.Command("review")
53
54
  .description("Review code changes using local LLM + codebase context")
@@ -69,7 +70,9 @@ Subcommands:
69
70
  .action((opts) => __awaiter(void 0, void 0, void 0, function* () {
70
71
  var _a;
71
72
  try {
72
- const root = opts.root ? path.resolve(opts.root) : process.cwd();
73
+ const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
74
+ if (root === null)
75
+ return;
73
76
  const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
74
77
  const commitRef = opts.commit;
75
78
  if (opts.background) {
@@ -135,7 +138,9 @@ exports.review
135
138
  .action((opts) => __awaiter(void 0, void 0, void 0, function* () {
136
139
  var _a;
137
140
  try {
138
- const root = opts.root ? path.resolve(opts.root) : process.cwd();
141
+ const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
142
+ if (root === null)
143
+ return;
139
144
  const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
140
145
  const { readReport, formatReportText } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/report")));
141
146
  const report = readReport(projectRoot);
@@ -166,7 +171,9 @@ exports.review
166
171
  .action((opts) => __awaiter(void 0, void 0, void 0, function* () {
167
172
  var _a;
168
173
  try {
169
- const root = opts.root ? path.resolve(opts.root) : process.cwd();
174
+ const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
175
+ if (root === null)
176
+ return;
170
177
  const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
171
178
  const { clearReport } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/report")));
172
179
  clearReport(projectRoot);