grepmax 0.26.27 → 0.26.28
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/.claude-plugin/marketplace.json +1 -1
- package/README.md +40 -0
- package/dist/commands/audit.js +28 -260
- package/dist/commands/context.js +42 -26
- package/dist/commands/dead.js +37 -35
- package/dist/commands/doctor.js +280 -10
- package/dist/commands/extract.js +79 -49
- package/dist/commands/impact.js +74 -20
- package/dist/commands/log.js +25 -25
- package/dist/commands/mcp.js +622 -474
- package/dist/commands/peek.js +49 -47
- package/dist/commands/project.js +29 -107
- package/dist/commands/related.js +43 -52
- package/dist/commands/search-run.js +23 -8
- package/dist/commands/search.js +7 -2
- package/dist/commands/similar.js +50 -76
- package/dist/commands/skeleton.js +137 -83
- package/dist/commands/status.js +90 -25
- package/dist/commands/surprises.js +73 -16
- package/dist/commands/symbols.js +58 -77
- package/dist/commands/test-find.js +51 -17
- package/dist/commands/trace.js +26 -11
- package/dist/lib/daemon/daemon.js +26 -0
- package/dist/lib/daemon/graph-handler.js +853 -0
- package/dist/lib/daemon/ipc-handler.js +19 -2
- package/dist/lib/daemon/read-verbs.js +105 -0
- package/dist/lib/daemon/rows-handler.js +665 -0
- package/dist/lib/daemon/vector-handler.js +199 -0
- package/dist/lib/utils/daemon-client.js +11 -0
- package/dist/lib/utils/store-access.js +381 -0
- package/dist/lib/utils/tests-footer.js +19 -2
- package/dist/lib/utils/watcher-launcher.js +10 -0
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
|
@@ -1,4 +1,37 @@
|
|
|
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
|
+
})();
|
|
2
35
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
36
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
37
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -12,11 +45,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
45
|
exports.surprises = void 0;
|
|
13
46
|
const commander_1 = require("commander");
|
|
14
47
|
const surprising_connections_1 = require("../lib/analysis/surprising-connections");
|
|
15
|
-
const
|
|
48
|
+
const rows_handler_1 = require("../lib/daemon/rows-handler");
|
|
49
|
+
const vector_handler_1 = require("../lib/daemon/vector-handler");
|
|
50
|
+
const daemon_client_1 = require("../lib/utils/daemon-client");
|
|
16
51
|
const exit_1 = require("../lib/utils/exit");
|
|
17
52
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
18
53
|
const project_root_1 = require("../lib/utils/project-root");
|
|
19
54
|
const stale_hint_1 = require("../lib/utils/stale-hint");
|
|
55
|
+
const store_access_1 = require("../lib/utils/store-access");
|
|
20
56
|
const useColors = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
21
57
|
const style = {
|
|
22
58
|
bold: (s) => (useColors ? `\x1b[1m${s}\x1b[22m` : s),
|
|
@@ -108,7 +144,6 @@ exports.surprises = new commander_1.Command("surprises")
|
|
|
108
144
|
process.exitCode = 1;
|
|
109
145
|
return;
|
|
110
146
|
}
|
|
111
|
-
let vectorDb = null;
|
|
112
147
|
try {
|
|
113
148
|
const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
|
|
114
149
|
if (root === null)
|
|
@@ -117,10 +152,27 @@ exports.surprises = new commander_1.Command("surprises")
|
|
|
117
152
|
(0, stale_hint_1.maybeWarnStaleChunker)(projectRoot, { agent: opts.agent });
|
|
118
153
|
(0, stale_hint_1.maybeWarnStaleEmbedding)(projectRoot, { agent: opts.agent });
|
|
119
154
|
const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
|
|
120
|
-
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
121
|
-
const table = yield vectorDb.ensureTable();
|
|
122
155
|
const top = parseIntOption(opts.top, 20, 100);
|
|
123
|
-
|
|
156
|
+
// --in/--exclude resolve against this process's cwd and filesystem, so
|
|
157
|
+
// they are resolved here and shipped as absolute prefixes.
|
|
158
|
+
// analyzeSurprisingConnections re-resolves them daemon-side; absolute
|
|
159
|
+
// input makes that a no-op, so both paths scan under the same scope.
|
|
160
|
+
const { resolveScope } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
|
|
161
|
+
const scope = resolveScope({
|
|
162
|
+
projectRoot,
|
|
163
|
+
in: opts.in,
|
|
164
|
+
exclude: opts.exclude,
|
|
165
|
+
});
|
|
166
|
+
const projectPrefix = projectRoot.endsWith("/")
|
|
167
|
+
? projectRoot
|
|
168
|
+
: `${projectRoot}/`;
|
|
169
|
+
const analysisIn = scope.inPrefixes.length > 0
|
|
170
|
+
? scope.inPrefixes
|
|
171
|
+
: scope.pathPrefix !== projectPrefix
|
|
172
|
+
? [scope.pathPrefix]
|
|
173
|
+
: undefined;
|
|
174
|
+
const analysisExclude = scope.excludePrefixes.length > 0 ? scope.excludePrefixes : undefined;
|
|
175
|
+
const options = {
|
|
124
176
|
sample: parseIntOption(opts.sample, surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.sample),
|
|
125
177
|
neighbors: parseIntOption(opts.neighbors, surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.neighbors, 200),
|
|
126
178
|
dirDepth: parseIntOption(opts.dirDepth, surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.dirDepth, 20),
|
|
@@ -128,23 +180,28 @@ exports.surprises = new commander_1.Command("surprises")
|
|
|
128
180
|
maxRows: parseIntOption(opts.maxRows, surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.maxRows, surprising_connections_1.MAX_SURPRISE_ROWS),
|
|
129
181
|
includeTests: Boolean(opts.includeTests),
|
|
130
182
|
includeEval: Boolean(opts.includeEval),
|
|
131
|
-
in:
|
|
132
|
-
exclude:
|
|
183
|
+
in: analysisIn,
|
|
184
|
+
exclude: analysisExclude,
|
|
185
|
+
};
|
|
186
|
+
// The scan reads up to MAX_SURPRISE_ROWS rows with their vectors; the
|
|
187
|
+
// daemon runs it against its warm store and returns the summary plus the
|
|
188
|
+
// findings that will actually be printed.
|
|
189
|
+
const result = yield (0, store_access_1.withStoreRead)("surprises", {
|
|
190
|
+
daemon: () => (0, daemon_client_1.sendDaemonCommand)({ cmd: "vector.surprises", projectRoot, options, top }, { timeoutMs: 300000 }),
|
|
191
|
+
render: (resp) => resp,
|
|
192
|
+
inProcess: () => (0, rows_handler_1.withLocalStore)(paths.lancedbDir, (deps) => (0, vector_handler_1.runSurprises)(deps, { projectRoot, options, top })),
|
|
193
|
+
fallbackOnUnknownVerb: true,
|
|
133
194
|
});
|
|
134
195
|
console.log(opts.agent ? formatAgent(result, top) : formatHuman(result, top));
|
|
135
196
|
}
|
|
136
197
|
catch (error) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
198
|
+
if (!(0, store_access_1.reportStoreAccessRefusal)(error)) {
|
|
199
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
200
|
+
console.error("Surprises failed:", msg);
|
|
201
|
+
process.exitCode = 1;
|
|
202
|
+
}
|
|
140
203
|
}
|
|
141
204
|
finally {
|
|
142
|
-
if (vectorDb) {
|
|
143
|
-
try {
|
|
144
|
-
yield vectorDb.close();
|
|
145
|
-
}
|
|
146
|
-
catch (_b) { }
|
|
147
|
-
}
|
|
148
205
|
yield (0, exit_1.gracefulExit)();
|
|
149
206
|
}
|
|
150
207
|
}));
|
package/dist/commands/symbols.js
CHANGED
|
@@ -45,81 +45,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
45
45
|
exports.symbols = void 0;
|
|
46
46
|
const path = __importStar(require("node:path"));
|
|
47
47
|
const commander_1 = require("commander");
|
|
48
|
-
const
|
|
48
|
+
const rows_handler_1 = require("../lib/daemon/rows-handler");
|
|
49
|
+
const daemon_client_1 = require("../lib/utils/daemon-client");
|
|
49
50
|
const exit_1 = require("../lib/utils/exit");
|
|
50
|
-
const filter_builder_1 = require("../lib/utils/filter-builder");
|
|
51
51
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
52
52
|
const project_root_1 = require("../lib/utils/project-root");
|
|
53
|
+
const store_access_1 = require("../lib/utils/store-access");
|
|
53
54
|
const style = {
|
|
54
55
|
bold: (s) => `\x1b[1m${s}\x1b[22m`,
|
|
55
56
|
dim: (s) => `\x1b[2m${s}\x1b[22m`,
|
|
56
57
|
green: (s) => `\x1b[32m${s}\x1b[39m`,
|
|
57
58
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const arr = val.toArray();
|
|
64
|
-
return Array.isArray(arr) ? arr.filter((v) => typeof v === "string") : [];
|
|
65
|
-
}
|
|
66
|
-
catch (_a) {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return [];
|
|
71
|
-
}
|
|
59
|
+
/**
|
|
60
|
+
* Ask the daemon for the symbol table; open the store only when no daemon is
|
|
61
|
+
* listening. Both branches run the same `runSymbols`, so the two paths cannot
|
|
62
|
+
* disagree — only the process the query runs in changes.
|
|
63
|
+
*/
|
|
72
64
|
function collectSymbols(options) {
|
|
73
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
74
66
|
const paths = (0, project_root_1.ensureProjectPaths)(options.projectRoot);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
.
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
!sym.toLowerCase().includes(options.pattern.toLowerCase())) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
const existing = map.get(sym);
|
|
103
|
-
if (existing) {
|
|
104
|
-
existing.count += 1;
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
map.set(sym, { symbol: sym, count: 1, path, line });
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return Array.from(map.values())
|
|
112
|
-
.sort((a, b) => {
|
|
113
|
-
// Sort by count desc, then symbol asc
|
|
114
|
-
if (b.count !== a.count)
|
|
115
|
-
return b.count - a.count;
|
|
116
|
-
return a.symbol.localeCompare(b.symbol);
|
|
117
|
-
})
|
|
118
|
-
.slice(0, options.limit);
|
|
119
|
-
}
|
|
120
|
-
finally {
|
|
121
|
-
yield db.close();
|
|
122
|
-
}
|
|
67
|
+
// Resolve to absolute for the centralized index. No trailing slash: the
|
|
68
|
+
// query has always matched starts_with on the bare prefix.
|
|
69
|
+
const absPrefix = options.pathPrefix
|
|
70
|
+
? path.isAbsolute(options.pathPrefix)
|
|
71
|
+
? options.pathPrefix
|
|
72
|
+
: path.resolve(options.projectRoot, options.pathPrefix)
|
|
73
|
+
: undefined;
|
|
74
|
+
return (0, store_access_1.withStoreRead)("symbols", {
|
|
75
|
+
daemon: () => (0, daemon_client_1.sendDaemonCommand)({
|
|
76
|
+
cmd: "rows.symbols",
|
|
77
|
+
projectRoot: options.projectRoot,
|
|
78
|
+
pathPrefix: absPrefix,
|
|
79
|
+
pattern: options.pattern,
|
|
80
|
+
limit: options.limit,
|
|
81
|
+
}, { timeoutMs: 60000 }),
|
|
82
|
+
render: (resp) => { var _a; return ((_a = resp.entries) !== null && _a !== void 0 ? _a : []); },
|
|
83
|
+
inProcess: () => (0, rows_handler_1.withLocalStore)(paths.lancedbDir, (deps) => (0, rows_handler_1.runSymbols)(deps, {
|
|
84
|
+
projectRoot: options.projectRoot,
|
|
85
|
+
pathPrefix: absPrefix,
|
|
86
|
+
pattern: options.pattern,
|
|
87
|
+
limit: options.limit,
|
|
88
|
+
})),
|
|
89
|
+
fallbackOnUnknownVerb: true,
|
|
90
|
+
});
|
|
123
91
|
});
|
|
124
92
|
}
|
|
125
93
|
function formatTable(entries) {
|
|
@@ -182,20 +150,33 @@ exports.symbols = new commander_1.Command("symbols")
|
|
|
182
150
|
const limit = Number.parseInt(cmd.limit, 10);
|
|
183
151
|
// Auto-scope to project root; --path narrows further within it
|
|
184
152
|
const pathPrefix = (_b = cmd.path) !== null && _b !== void 0 ? _b : projectRoot;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
153
|
+
try {
|
|
154
|
+
const entries = yield collectSymbols({
|
|
155
|
+
projectRoot,
|
|
156
|
+
limit: Number.isFinite(limit) && limit > 0 ? limit : 20,
|
|
157
|
+
pathPrefix,
|
|
158
|
+
pattern: pattern,
|
|
159
|
+
});
|
|
160
|
+
if (cmd.agent) {
|
|
161
|
+
console.log(formatAgent(entries, projectRoot));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.log(`${style.bold("Project")}: ${style.green(projectRoot)}\n${formatTable(entries)}`);
|
|
165
|
+
}
|
|
166
|
+
if (entries.length === 0) {
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
}
|
|
193
169
|
}
|
|
194
|
-
|
|
195
|
-
|
|
170
|
+
catch (error) {
|
|
171
|
+
// `symbols` was the one read command with no catch at all, so a denied
|
|
172
|
+
// lease escaped as a raw node:fs stack trace instead of the one-line hint.
|
|
173
|
+
if (!(0, store_access_1.reportStoreAccessRefusal)(error)) {
|
|
174
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
175
|
+
console.error("Symbols failed:", msg);
|
|
176
|
+
process.exitCode = 1;
|
|
177
|
+
}
|
|
196
178
|
}
|
|
197
|
-
|
|
198
|
-
|
|
179
|
+
finally {
|
|
180
|
+
yield (0, exit_1.gracefulExit)();
|
|
199
181
|
}
|
|
200
|
-
yield (0, exit_1.gracefulExit)();
|
|
201
182
|
}));
|
|
@@ -44,13 +44,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.testFind = void 0;
|
|
46
46
|
const commander_1 = require("commander");
|
|
47
|
-
const
|
|
47
|
+
const graph_handler_1 = require("../lib/daemon/graph-handler");
|
|
48
48
|
const test_hits_1 = require("../lib/graph/test-hits");
|
|
49
49
|
const vector_db_1 = require("../lib/store/vector-db");
|
|
50
50
|
const exit_1 = require("../lib/utils/exit");
|
|
51
51
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
52
52
|
const project_root_1 = require("../lib/utils/project-root");
|
|
53
53
|
const stale_hint_1 = require("../lib/utils/stale-hint");
|
|
54
|
+
const store_access_1 = require("../lib/utils/store-access");
|
|
54
55
|
exports.testFind = new commander_1.Command("test")
|
|
55
56
|
.description("Find tests that exercise a symbol or file")
|
|
56
57
|
.argument("<target>", "Symbol name or file path")
|
|
@@ -62,7 +63,8 @@ exports.testFind = new commander_1.Command("test")
|
|
|
62
63
|
.action((target, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
64
|
var _a;
|
|
64
65
|
const depth = Math.min(Math.max(Number.parseInt(opts.depth || "1", 10), 1), 3);
|
|
65
|
-
|
|
66
|
+
// Opened only if the daemon is unreachable; withStoreRead decides.
|
|
67
|
+
const local = { db: null };
|
|
66
68
|
try {
|
|
67
69
|
const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
|
|
68
70
|
if (root === null)
|
|
@@ -70,9 +72,31 @@ exports.testFind = new commander_1.Command("test")
|
|
|
70
72
|
const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
|
|
71
73
|
(0, stale_hint_1.maybeWarnStaleChunker)(projectRoot, { agent: opts.agent });
|
|
72
74
|
(0, stale_hint_1.maybeWarnStaleEmbedding)(projectRoot, { agent: opts.agent });
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
const localDb = () => {
|
|
76
|
+
var _a;
|
|
77
|
+
(_a = local.db) !== null && _a !== void 0 ? _a : (local.db = new vector_db_1.VectorDB((0, project_root_1.ensureProjectPaths)(projectRoot).lancedbDir));
|
|
78
|
+
return local.db;
|
|
79
|
+
};
|
|
80
|
+
const { resolveScope } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
|
|
81
|
+
const scope = resolveScope({
|
|
82
|
+
projectRoot,
|
|
83
|
+
in: opts.in,
|
|
84
|
+
exclude: opts.exclude,
|
|
85
|
+
});
|
|
86
|
+
const { symbols, resolvedAsFile, symbolFamilies } = yield (0, graph_handler_1.callGraphVerb)("graph.resolve", {
|
|
87
|
+
projectRoot,
|
|
88
|
+
scope,
|
|
89
|
+
payload: { target },
|
|
90
|
+
render: (resp) => {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
return ({
|
|
93
|
+
symbols: (_a = resp.symbols) !== null && _a !== void 0 ? _a : [],
|
|
94
|
+
resolvedAsFile: resp.resolvedAsFile === true,
|
|
95
|
+
symbolFamilies: (_b = resp.symbolFamilies) !== null && _b !== void 0 ? _b : null,
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
inProcess: () => (0, graph_handler_1.runGraphResolve)(localDb(), { target, projectRoot }),
|
|
99
|
+
});
|
|
76
100
|
if (symbols.length === 0) {
|
|
77
101
|
console.log(resolvedAsFile
|
|
78
102
|
? `No symbols found in file: ${target}`
|
|
@@ -80,16 +104,22 @@ exports.testFind = new commander_1.Command("test")
|
|
|
80
104
|
process.exitCode = 1;
|
|
81
105
|
return;
|
|
82
106
|
}
|
|
83
|
-
const { resolveScope } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
|
|
84
|
-
const scope = resolveScope({
|
|
85
|
-
projectRoot,
|
|
86
|
-
in: opts.in,
|
|
87
|
-
exclude: opts.exclude,
|
|
88
|
-
});
|
|
89
107
|
const queryRoot = opts.in && opts.in.length > 0
|
|
90
108
|
? scope.pathPrefix.replace(/\/$/, "")
|
|
91
109
|
: projectRoot;
|
|
92
|
-
const tests = yield (0,
|
|
110
|
+
const tests = yield (0, graph_handler_1.callGraphVerb)("graph.tests", {
|
|
111
|
+
projectRoot,
|
|
112
|
+
scope,
|
|
113
|
+
payload: { symbols, depth, families: symbolFamilies },
|
|
114
|
+
render: (resp) => { var _a; return (_a = resp.hits) !== null && _a !== void 0 ? _a : []; },
|
|
115
|
+
inProcess: () => (0, graph_handler_1.runGraphTests)(localDb(), {
|
|
116
|
+
symbols,
|
|
117
|
+
queryRoot,
|
|
118
|
+
depth,
|
|
119
|
+
excludePrefixes: scope.excludePrefixes,
|
|
120
|
+
families: (0, graph_handler_1.decodeSymbolFamilies)(symbolFamilies),
|
|
121
|
+
}),
|
|
122
|
+
});
|
|
93
123
|
if (tests.length === 0) {
|
|
94
124
|
console.log(`No tests found for ${target}.`);
|
|
95
125
|
return;
|
|
@@ -111,14 +141,18 @@ exports.testFind = new commander_1.Command("test")
|
|
|
111
141
|
}
|
|
112
142
|
}
|
|
113
143
|
catch (error) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
144
|
+
// A sandbox refusal is already one actionable line; a "Test find failed:"
|
|
145
|
+
// prefix would bury the settings key that fixes it.
|
|
146
|
+
if (!(0, store_access_1.reportStoreAccessRefusal)(error)) {
|
|
147
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
148
|
+
console.error("Test find failed:", msg);
|
|
149
|
+
process.exitCode = 1;
|
|
150
|
+
}
|
|
117
151
|
}
|
|
118
152
|
finally {
|
|
119
|
-
if (
|
|
153
|
+
if (local.db) {
|
|
120
154
|
try {
|
|
121
|
-
yield
|
|
155
|
+
yield local.db.close();
|
|
122
156
|
}
|
|
123
157
|
catch (_b) { }
|
|
124
158
|
}
|
package/dist/commands/trace.js
CHANGED
|
@@ -44,8 +44,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.trace = void 0;
|
|
46
46
|
const commander_1 = require("commander");
|
|
47
|
+
const graph_handler_1 = require("../lib/daemon/graph-handler");
|
|
47
48
|
const callsites_1 = require("../lib/graph/callsites");
|
|
48
|
-
const graph_builder_1 = require("../lib/graph/graph-builder");
|
|
49
49
|
const formatter_1 = require("../lib/output/formatter");
|
|
50
50
|
const vector_db_1 = require("../lib/store/vector-db");
|
|
51
51
|
const agent_errors_1 = require("../lib/utils/agent-errors");
|
|
@@ -53,6 +53,7 @@ const exit_1 = require("../lib/utils/exit");
|
|
|
53
53
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
54
54
|
const project_root_1 = require("../lib/utils/project-root");
|
|
55
55
|
const stale_hint_1 = require("../lib/utils/stale-hint");
|
|
56
|
+
const store_access_1 = require("../lib/utils/store-access");
|
|
56
57
|
const useColors = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
57
58
|
const dim = (s) => (useColors ? `\x1b[2m${s}\x1b[22m` : s);
|
|
58
59
|
const bold = (s) => (useColors ? `\x1b[1m${s}\x1b[22m` : s);
|
|
@@ -231,21 +232,31 @@ exports.trace = new commander_1.Command("trace")
|
|
|
231
232
|
const root = (0, project_registry_1.resolveRootOrExit)(opts.root);
|
|
232
233
|
if (root === null)
|
|
233
234
|
return;
|
|
234
|
-
|
|
235
|
+
// Opened only if the daemon is unreachable; withStoreRead decides.
|
|
236
|
+
const local = { db: null };
|
|
235
237
|
try {
|
|
236
238
|
const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
|
|
237
239
|
(0, stale_hint_1.maybeWarnStaleChunker)(projectRoot, { agent: opts.agent });
|
|
238
240
|
(0, stale_hint_1.maybeWarnStaleEmbedding)(projectRoot, { agent: opts.agent });
|
|
239
|
-
const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
|
|
240
|
-
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
241
241
|
const { resolveScope } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/scope-filter")));
|
|
242
242
|
const scope = resolveScope({
|
|
243
243
|
projectRoot,
|
|
244
244
|
in: opts.in,
|
|
245
245
|
exclude: opts.exclude,
|
|
246
246
|
});
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
// The daemon returns the graph; call-site snippets below are read from
|
|
248
|
+
// the working tree by this process, which can already see it.
|
|
249
|
+
const graph = yield (0, graph_handler_1.callGraphVerb)("graph.trace", {
|
|
250
|
+
projectRoot,
|
|
251
|
+
scope,
|
|
252
|
+
payload: { target: symbol, hops: depth },
|
|
253
|
+
render: (resp) => resp.graph,
|
|
254
|
+
inProcess: () => {
|
|
255
|
+
var _a;
|
|
256
|
+
(_a = local.db) !== null && _a !== void 0 ? _a : (local.db = new vector_db_1.VectorDB((0, project_root_1.ensureProjectPaths)(projectRoot).lancedbDir));
|
|
257
|
+
return (0, graph_handler_1.runGraphTrace)(local.db, { symbol, hops: depth, scope });
|
|
258
|
+
},
|
|
259
|
+
});
|
|
249
260
|
if (opts.inbound) {
|
|
250
261
|
if (!graph.center) {
|
|
251
262
|
console.log((0, agent_errors_1.symbolNotFoundLines)(symbol, { agent: opts.agent }).join("\n"));
|
|
@@ -275,14 +286,18 @@ exports.trace = new commander_1.Command("trace")
|
|
|
275
286
|
}
|
|
276
287
|
}
|
|
277
288
|
catch (error) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
289
|
+
// A sandbox refusal is already one actionable line; a "Trace failed:"
|
|
290
|
+
// prefix would bury the settings key that fixes it.
|
|
291
|
+
if (!(0, store_access_1.reportStoreAccessRefusal)(error)) {
|
|
292
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
293
|
+
console.error("Trace failed:", message);
|
|
294
|
+
process.exitCode = 1;
|
|
295
|
+
}
|
|
281
296
|
}
|
|
282
297
|
finally {
|
|
283
|
-
if (
|
|
298
|
+
if (local.db) {
|
|
284
299
|
try {
|
|
285
|
-
yield
|
|
300
|
+
yield local.db.close();
|
|
286
301
|
}
|
|
287
302
|
catch (err) {
|
|
288
303
|
console.error("Failed to close VectorDB:", err);
|
|
@@ -76,7 +76,10 @@ const pool_1 = require("../workers/pool");
|
|
|
76
76
|
const ipc_handler_1 = require("./ipc-handler");
|
|
77
77
|
const mlx_server_manager_1 = require("./mlx-server-manager");
|
|
78
78
|
const process_manager_1 = require("./process-manager");
|
|
79
|
+
const read_verbs_1 = require("./read-verbs");
|
|
80
|
+
const rows_handler_1 = require("./rows-handler");
|
|
79
81
|
const search_handler_1 = require("./search-handler");
|
|
82
|
+
const vector_handler_1 = require("./vector-handler");
|
|
80
83
|
const watcher_manager_1 = require("./watcher-manager");
|
|
81
84
|
// 30 min was too aggressive — every shutdown is a chance for races, FSEvents
|
|
82
85
|
// drops, and orphan MLX cleanup. 4 hours keeps the daemon resident through a
|
|
@@ -220,6 +223,15 @@ class Daemon {
|
|
|
220
223
|
return __awaiter(this, void 0, void 0, function* () {
|
|
221
224
|
var _a;
|
|
222
225
|
process.title = "gmax-daemon";
|
|
226
|
+
// Read verbs register here rather than at read-verbs.ts module scope: the
|
|
227
|
+
// registry is asserted on exactly in tests/ipc-read-verbs.test.ts, and a
|
|
228
|
+
// module-scope registration would make it non-empty on import. Register
|
|
229
|
+
// before the socket server starts (step 2) so no client can race in and
|
|
230
|
+
// get "unknown command" for a verb this daemon does support. Idempotent:
|
|
231
|
+
// re-registering replaces by name.
|
|
232
|
+
(0, read_verbs_1.registerGraphVerbs)();
|
|
233
|
+
(0, rows_handler_1.registerRowsVerbs)();
|
|
234
|
+
(0, vector_handler_1.registerVectorVerbs)();
|
|
223
235
|
// 0. Singleton enforcement: find and kill ALL stale daemon/worker processes
|
|
224
236
|
yield this.processManager.killStaleProcesses();
|
|
225
237
|
this.assertStartupActive();
|
|
@@ -724,6 +736,20 @@ class Daemon {
|
|
|
724
736
|
}));
|
|
725
737
|
});
|
|
726
738
|
}
|
|
739
|
+
/**
|
|
740
|
+
* The slice of the daemon a read verb handler needs: the warm store and the
|
|
741
|
+
* activity touch that keeps the idle timer honest. One accessor for every
|
|
742
|
+
* read verb (graph, rows, vector) — extend this rather than adding a second;
|
|
743
|
+
* handlers get no other access to daemon internals.
|
|
744
|
+
*/
|
|
745
|
+
storeReadDeps() {
|
|
746
|
+
return {
|
|
747
|
+
vectorDb: this.vectorDb,
|
|
748
|
+
touchActivity: () => {
|
|
749
|
+
this.lastActivity = Date.now();
|
|
750
|
+
},
|
|
751
|
+
};
|
|
752
|
+
}
|
|
727
753
|
listProjects() {
|
|
728
754
|
return [...this.processors.keys()].map((root) => ({
|
|
729
755
|
root,
|