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.
- package/dist/commands/context.js +4 -2
- package/dist/commands/diff.js +8 -171
- package/dist/commands/extract.js +16 -6
- package/dist/commands/impact.js +21 -3
- package/dist/commands/investigate.js +4 -2
- package/dist/commands/log.js +231 -0
- package/dist/commands/peek.js +16 -11
- package/dist/commands/project.js +8 -7
- package/dist/commands/recent.js +7 -127
- package/dist/commands/related.js +13 -2
- package/dist/commands/remove.js +12 -31
- package/dist/commands/review.js +10 -3
- package/dist/commands/search.js +61 -36
- package/dist/commands/similar.js +13 -2
- package/dist/commands/symbols.js +4 -1
- package/dist/commands/test-find.js +16 -3
- package/dist/commands/trace.js +13 -3
- package/dist/index.js +2 -0
- package/dist/lib/daemon/ipc-handler.js +4 -0
- package/dist/lib/graph/graph-builder.js +10 -4
- package/dist/lib/graph/impact.js +16 -7
- package/dist/lib/search/searcher.js +28 -0
- package/dist/lib/utils/git.js +90 -0
- package/dist/lib/utils/project-registry.js +43 -0
- package/dist/lib/utils/scope-filter.js +104 -0
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
- package/plugins/grepmax/skills/grepmax/SKILL.md +11 -11
|
@@ -48,6 +48,8 @@ exports.getProject = getProject;
|
|
|
48
48
|
exports.removeProject = removeProject;
|
|
49
49
|
exports.getParentProject = getParentProject;
|
|
50
50
|
exports.getChildProjects = getChildProjects;
|
|
51
|
+
exports.resolveRootOrExit = resolveRootOrExit;
|
|
52
|
+
exports.resolveProjectRoot = resolveProjectRoot;
|
|
51
53
|
const fs = __importStar(require("node:fs"));
|
|
52
54
|
const path = __importStar(require("node:path"));
|
|
53
55
|
const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
|
|
@@ -126,3 +128,44 @@ function getChildProjects(root) {
|
|
|
126
128
|
const prefix = root.endsWith("/") ? root : `${root}/`;
|
|
127
129
|
return loadRegistry().filter((e) => e.root !== root && e.root.startsWith(prefix));
|
|
128
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Resolve a `--root` argument with cwd fallback, printing the helper's
|
|
133
|
+
* error message and setting process.exitCode = 1 on failure. Returns
|
|
134
|
+
* null when the caller should bail out. Used at command entry points.
|
|
135
|
+
*/
|
|
136
|
+
function resolveRootOrExit(arg) {
|
|
137
|
+
if (!arg)
|
|
138
|
+
return process.cwd();
|
|
139
|
+
try {
|
|
140
|
+
return resolveProjectRoot(arg);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Resolve a `--root` argument that may be either a path or a registered
|
|
150
|
+
* project name. Throws on no-match or duplicate-name so callers can
|
|
151
|
+
* report a uniform error.
|
|
152
|
+
*/
|
|
153
|
+
function resolveProjectRoot(arg) {
|
|
154
|
+
if (arg.includes("/") || arg.includes("\\"))
|
|
155
|
+
return path.resolve(arg);
|
|
156
|
+
const resolved = path.resolve(arg);
|
|
157
|
+
if (fs.existsSync(resolved))
|
|
158
|
+
return resolved;
|
|
159
|
+
const matches = loadRegistry().filter((p) => p.name === arg);
|
|
160
|
+
if (matches.length === 1)
|
|
161
|
+
return matches[0].root;
|
|
162
|
+
if (matches.length === 0) {
|
|
163
|
+
const all = loadRegistry();
|
|
164
|
+
const list = all.length > 0
|
|
165
|
+
? all.map((p) => ` ${p.name.padEnd(24)} ${p.root}`).join("\n")
|
|
166
|
+
: " (none registered)";
|
|
167
|
+
throw new Error(`No registered project named "${arg}".\nAvailable:\n${list}`);
|
|
168
|
+
}
|
|
169
|
+
const paths = matches.map((p) => ` ${p.root}`).join("\n");
|
|
170
|
+
throw new Error(`Multiple registered projects named "${arg}":\n${paths}\nPass an absolute path to disambiguate.`);
|
|
171
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resolveScope = resolveScope;
|
|
37
|
+
exports.buildScopeWhere = buildScopeWhere;
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const filter_builder_1 = require("./filter-builder");
|
|
40
|
+
function toArray(value) {
|
|
41
|
+
if (value === undefined)
|
|
42
|
+
return [];
|
|
43
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
44
|
+
// Support comma-separated values within each occurrence so agents can pass
|
|
45
|
+
// either `--in a --in b` or `--in a,b` interchangeably.
|
|
46
|
+
return arr
|
|
47
|
+
.flatMap((v) => v.split(","))
|
|
48
|
+
.map((v) => v.trim())
|
|
49
|
+
.filter(Boolean);
|
|
50
|
+
}
|
|
51
|
+
function joinSubpath(projectRoot, sub) {
|
|
52
|
+
const rootWithSlash = projectRoot.endsWith("/") ? projectRoot : `${projectRoot}/`;
|
|
53
|
+
if (path.isAbsolute(sub))
|
|
54
|
+
return sub.endsWith("/") ? sub : `${sub}/`;
|
|
55
|
+
if (sub.startsWith(rootWithSlash))
|
|
56
|
+
return sub.endsWith("/") ? sub : `${sub}/`;
|
|
57
|
+
const joined = path.join(rootWithSlash, sub);
|
|
58
|
+
return joined.endsWith("/") ? joined : `${joined}/`;
|
|
59
|
+
}
|
|
60
|
+
function resolveScope(opts) {
|
|
61
|
+
const { projectRoot } = opts;
|
|
62
|
+
const ins = toArray(opts.in);
|
|
63
|
+
const excludes = toArray(opts.exclude);
|
|
64
|
+
const projectPrefix = projectRoot.endsWith("/")
|
|
65
|
+
? projectRoot
|
|
66
|
+
: `${projectRoot}/`;
|
|
67
|
+
const inPrefixesAll = ins.map((v) => joinSubpath(projectRoot, v));
|
|
68
|
+
const excludePrefixes = excludes.map((v) => joinSubpath(projectRoot, v));
|
|
69
|
+
// Collapse a single --in into pathPrefix to keep WHERE clauses simple.
|
|
70
|
+
if (inPrefixesAll.length === 1) {
|
|
71
|
+
return {
|
|
72
|
+
pathPrefix: inPrefixesAll[0],
|
|
73
|
+
inPrefixes: [],
|
|
74
|
+
excludePrefixes,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
pathPrefix: projectPrefix,
|
|
79
|
+
inPrefixes: inPrefixesAll,
|
|
80
|
+
excludePrefixes,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compose a SQL WHERE clause that AND-applies the resolved scope to an
|
|
85
|
+
* existing condition. Used by symbol commands that build their own table
|
|
86
|
+
* queries (peek/extract/similar/related) instead of going through
|
|
87
|
+
* Searcher.buildWhereClause or GraphBuilder.scopeWhere.
|
|
88
|
+
*/
|
|
89
|
+
function buildScopeWhere(scope, condition) {
|
|
90
|
+
const parts = [];
|
|
91
|
+
if (condition)
|
|
92
|
+
parts.push(condition);
|
|
93
|
+
parts.push(`path LIKE '${(0, filter_builder_1.escapeSqlString)(scope.pathPrefix)}%'`);
|
|
94
|
+
for (const ex of scope.excludePrefixes) {
|
|
95
|
+
parts.push(`path NOT LIKE '${(0, filter_builder_1.escapeSqlString)(ex)}%'`);
|
|
96
|
+
}
|
|
97
|
+
if (scope.inPrefixes.length > 0) {
|
|
98
|
+
const ors = scope.inPrefixes
|
|
99
|
+
.map((p) => `path LIKE '${(0, filter_builder_1.escapeSqlString)(p)}%'`)
|
|
100
|
+
.join(" OR ");
|
|
101
|
+
parts.push(`(${ors})`);
|
|
102
|
+
}
|
|
103
|
+
return parts.join(" AND ");
|
|
104
|
+
}
|
package/package.json
CHANGED
|
@@ -125,9 +125,18 @@ gmax related src/lib/index/syncer.ts # dependencies + dependents
|
|
|
125
125
|
gmax related src/lib/index/syncer.ts --root ~/project
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
###
|
|
128
|
+
### Commit history — `gmax log <path-or-symbol>`
|
|
129
129
|
```
|
|
130
|
-
gmax
|
|
130
|
+
gmax log src/lib/auth.ts # commits touching this file
|
|
131
|
+
gmax log src/lib/ # commits touching this directory
|
|
132
|
+
gmax log handleAuth # commits across all files defining the symbol
|
|
133
|
+
gmax log handleAuth --in src/ # restrict symbol resolution to a sub-path
|
|
134
|
+
gmax log src/lib/auth.ts --limit 5 # last 5 commits
|
|
135
|
+
gmax log src/lib/auth.ts --from main # commits since main (range main..HEAD)
|
|
136
|
+
gmax log src/lib/auth.ts --since "2 weeks ago"
|
|
137
|
+
gmax log src/lib/auth.ts --author Robert
|
|
138
|
+
gmax log src/lib/auth.ts --no-follow # disable rename tracking (default: on for files)
|
|
139
|
+
gmax log src/lib/auth.ts --agent # TSV: hash\tisoDate\tauthor\tsubject\tfilesChanged\tins\tdel\ttouchedFiles
|
|
131
140
|
```
|
|
132
141
|
|
|
133
142
|
### Symbols — `gmax symbols`
|
|
@@ -137,15 +146,6 @@ gmax symbols auth -p src/ --root ~/proj # filter by name, path, project
|
|
|
137
146
|
gmax symbols --agent # compact: symbol\tpath:line\tcount
|
|
138
147
|
```
|
|
139
148
|
|
|
140
|
-
### Diff — `gmax diff [ref]`
|
|
141
|
-
```
|
|
142
|
-
gmax diff # uncommitted changes
|
|
143
|
-
gmax diff HEAD~5 # last 5 commits
|
|
144
|
-
gmax diff main # branch changes vs main
|
|
145
|
-
gmax diff main --query "auth changes" # semantic search within changed files
|
|
146
|
-
gmax diff --agent # compact output
|
|
147
|
-
```
|
|
148
|
-
|
|
149
149
|
### Test — `gmax test <symbol|file>`
|
|
150
150
|
```
|
|
151
151
|
gmax test handleAuth # tests calling handleAuth
|