grepmax 0.18.0 → 0.19.0
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/README.md +27 -2
- package/dist/commands/add.js +4 -2
- package/dist/commands/claude-code.js +1 -1
- package/dist/commands/codex.js +3 -1
- package/dist/commands/dead.js +2 -6
- package/dist/commands/doctor.js +26 -7
- package/dist/commands/extract.js +3 -5
- package/dist/commands/impact.js +6 -4
- package/dist/commands/index.js +7 -2
- package/dist/commands/log.js +4 -2
- package/dist/commands/mcp.js +587 -715
- package/dist/commands/peek.js +15 -9
- package/dist/commands/plugin.js +1 -1
- package/dist/commands/project.js +15 -5
- package/dist/commands/related.js +8 -9
- package/dist/commands/review.js +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/similar.js +4 -4
- package/dist/commands/status.js +5 -3
- package/dist/commands/summarize.js +6 -4
- package/dist/commands/test-find.js +2 -2
- package/dist/commands/trace.js +51 -9
- package/dist/commands/watch.js +9 -5
- package/dist/eval-graph-nav.js +4 -1
- package/dist/eval-graph-recovery-probe.js +56 -14
- package/dist/eval-graph-spotcheck.js +10 -2
- package/dist/eval-graph-totals.js +5 -2
- package/dist/eval-oss.js +212 -37
- package/dist/eval-seed.js +13 -4
- package/dist/index.js +9 -9
- package/dist/lib/daemon/daemon.js +22 -13
- package/dist/lib/daemon/ipc-handler.js +18 -5
- package/dist/lib/daemon/mlx-server-manager.js +11 -3
- package/dist/lib/daemon/process-manager.js +1 -2
- package/dist/lib/daemon/watcher-manager.js +4 -4
- package/dist/lib/graph/callsites.js +151 -25
- package/dist/lib/help/agent-cheatsheet.js +1 -1
- package/dist/lib/index/batch-processor.js +6 -5
- package/dist/lib/index/chunker.js +2 -0
- package/dist/lib/index/syncer.js +7 -6
- package/dist/lib/llm/diff.js +56 -11
- package/dist/lib/llm/investigate.js +12 -5
- package/dist/lib/llm/review.js +21 -8
- package/dist/lib/llm/server.js +16 -7
- package/dist/lib/output/agent-search-formatter.js +25 -3
- package/dist/lib/output/index-state-footer.js +1 -1
- package/dist/lib/review/risk.js +2 -4
- package/dist/lib/search/searcher.js +37 -11
- package/dist/lib/search/seed-weight.js +4 -1
- package/dist/lib/skeleton/symbol-extractor.js +2 -1
- package/dist/lib/utils/cross-project.js +5 -1
- package/dist/lib/utils/daemon-client.js +5 -1
- package/dist/lib/utils/git.js +10 -2
- package/dist/lib/utils/project-registry.js +3 -2
- package/dist/lib/utils/scope-filter.js +3 -1
- package/dist/lib/utils/watcher-launcher.js +4 -1
- package/dist/lib/utils/watcher-store.js +2 -1
- package/dist/lib/workers/embeddings/mlx-client.js +7 -2
- package/dist/lib/workers/pool.js +9 -6
- package/dist/lib/workers/process-child.js +1 -1
- package/package.json +22 -19
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
- package/plugins/grepmax/hooks/cwd-changed.js +4 -1
- package/plugins/grepmax/hooks/pre-grep.js +2 -1
- package/plugins/grepmax/hooks/start.js +45 -10
- package/plugins/grepmax/hooks/subagent-start.js +1 -4
package/dist/eval-oss.js
CHANGED
|
@@ -61,60 +61,232 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
61
61
|
// concurrency issues during the back-to-back search runs.
|
|
62
62
|
(_a = (_e = process.env).GMAX_WORKER_COUNT) !== null && _a !== void 0 ? _a : (_e.GMAX_WORKER_COUNT = "1");
|
|
63
63
|
const path = __importStar(require("node:path"));
|
|
64
|
+
const config_1 = require("./config");
|
|
64
65
|
const searcher_1 = require("./lib/search/searcher");
|
|
65
66
|
const vector_db_1 = require("./lib/store/vector-db");
|
|
66
67
|
const exit_1 = require("./lib/utils/exit");
|
|
67
|
-
const config_1 = require("./config");
|
|
68
68
|
// ─── express 4.21.1 P1 — sverklo-bench/tasks/express.gen.ts resolved against
|
|
69
69
|
// a fresh checkout. `merge` dropped: it's the utils-merge package, not
|
|
70
70
|
// an in-tree definition, so the sverklo resolver returns no location.
|
|
71
71
|
const EXPRESS_CASES = [
|
|
72
|
-
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
{
|
|
73
|
+
id: "ex-p1-01",
|
|
74
|
+
query: "createApplication",
|
|
75
|
+
expectedFile: "lib/express.js",
|
|
76
|
+
expectedLine: 37,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "ex-p1-02",
|
|
80
|
+
query: "Route",
|
|
81
|
+
expectedFile: "lib/router/route.js",
|
|
82
|
+
expectedLine: 43,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "ex-p1-03",
|
|
86
|
+
query: "Layer",
|
|
87
|
+
expectedFile: "lib/router/layer.js",
|
|
88
|
+
expectedLine: 33,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "ex-p1-04",
|
|
92
|
+
query: "View",
|
|
93
|
+
expectedFile: "lib/view.js",
|
|
94
|
+
expectedLine: 52,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: "ex-p1-05",
|
|
98
|
+
query: "query",
|
|
99
|
+
expectedFile: "lib/express.js",
|
|
100
|
+
expectedLine: 79,
|
|
101
|
+
note: "re-export site — middleware/query.js doesn't match the function-decl patterns",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: "ex-p1-06",
|
|
105
|
+
query: "init",
|
|
106
|
+
expectedFile: "lib/middleware/init.js",
|
|
107
|
+
expectedLine: 28,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "ex-p1-07",
|
|
111
|
+
query: "acceptParams",
|
|
112
|
+
expectedFile: "lib/utils.js",
|
|
113
|
+
expectedLine: 126,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: "ex-p1-08",
|
|
117
|
+
query: "stringify",
|
|
118
|
+
expectedFile: "lib/response.js",
|
|
119
|
+
expectedLine: 1155,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "ex-p1-09",
|
|
123
|
+
query: "compileETag",
|
|
124
|
+
expectedFile: "lib/utils.js",
|
|
125
|
+
expectedLine: 150,
|
|
126
|
+
},
|
|
81
127
|
];
|
|
82
128
|
// ─── lodash 4.17.21 P1 — hand-verified line numbers in lodash.js, copied
|
|
83
129
|
// verbatim from sverklo-bench/tasks/lodash.gen.ts. All 10 live in the
|
|
84
130
|
// same 17K-line UMD file, so line-window matching (NOT path-only match)
|
|
85
131
|
// is what makes this fixture set discriminating.
|
|
86
132
|
const LODASH_CASES = [
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
133
|
+
{
|
|
134
|
+
id: "ld-p1-01",
|
|
135
|
+
query: "map",
|
|
136
|
+
expectedFile: "lodash.js",
|
|
137
|
+
expectedLine: 9620,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "ld-p1-02",
|
|
141
|
+
query: "filter",
|
|
142
|
+
expectedFile: "lodash.js",
|
|
143
|
+
expectedLine: 9239,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: "ld-p1-03",
|
|
147
|
+
query: "reduce",
|
|
148
|
+
expectedFile: "lodash.js",
|
|
149
|
+
expectedLine: 9745,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: "ld-p1-04",
|
|
153
|
+
query: "debounce",
|
|
154
|
+
expectedFile: "lodash.js",
|
|
155
|
+
expectedLine: 10372,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: "ld-p1-05",
|
|
159
|
+
query: "throttle",
|
|
160
|
+
expectedFile: "lodash.js",
|
|
161
|
+
expectedLine: 10965,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: "ld-p1-06",
|
|
165
|
+
query: "merge",
|
|
166
|
+
expectedFile: "lodash.js",
|
|
167
|
+
expectedLine: 13505,
|
|
168
|
+
note: "var merge = createAssigner(...) binding site, not the re-export at 16689",
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: "ld-p1-07",
|
|
172
|
+
query: "cloneDeep",
|
|
173
|
+
expectedFile: "lodash.js",
|
|
174
|
+
expectedLine: 11155,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "ld-p1-08",
|
|
178
|
+
query: "get",
|
|
179
|
+
expectedFile: "lodash.js",
|
|
180
|
+
expectedLine: 13194,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: "ld-p1-09",
|
|
184
|
+
query: "set",
|
|
185
|
+
expectedFile: "lodash.js",
|
|
186
|
+
expectedLine: 13741,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: "ld-p1-10",
|
|
190
|
+
query: "chunk",
|
|
191
|
+
expectedFile: "lodash.js",
|
|
192
|
+
expectedLine: 6903,
|
|
193
|
+
},
|
|
97
194
|
];
|
|
98
195
|
// ─── platform monorepo (private) — 15 hand-curated P1 cases across packages
|
|
99
196
|
// to test the "modular monorepo" shape that neither express nor lodash
|
|
100
197
|
// covers. Symbols resolved against the live checkout. Bare-symbol
|
|
101
198
|
// queries match sverklo's P1 methodology so results are comparable.
|
|
102
199
|
const PLATFORM_CASES = [
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
{
|
|
116
|
-
|
|
117
|
-
|
|
200
|
+
{
|
|
201
|
+
id: "pf-p1-01",
|
|
202
|
+
query: "formatCents",
|
|
203
|
+
expectedFile: "packages/shared/src/format.ts",
|
|
204
|
+
expectedLine: 8,
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
id: "pf-p1-02",
|
|
208
|
+
query: "formatTimeAgo",
|
|
209
|
+
expectedFile: "packages/shared/src/format.ts",
|
|
210
|
+
expectedLine: 44,
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: "pf-p1-03",
|
|
214
|
+
query: "BeyondError",
|
|
215
|
+
expectedFile: "packages/shared/src/errors.ts",
|
|
216
|
+
expectedLine: 37,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: "pf-p1-04",
|
|
220
|
+
query: "ErrorCodes",
|
|
221
|
+
expectedFile: "packages/shared/src/errors.ts",
|
|
222
|
+
expectedLine: 5,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
id: "pf-p1-05",
|
|
226
|
+
query: "createDb",
|
|
227
|
+
expectedFile: "packages/db/src/index.ts",
|
|
228
|
+
expectedLine: 42,
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: "pf-p1-06",
|
|
232
|
+
query: "createDbAsync",
|
|
233
|
+
expectedFile: "packages/db/src/index.ts",
|
|
234
|
+
expectedLine: 50,
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
id: "pf-p1-07",
|
|
238
|
+
query: "authMiddleware",
|
|
239
|
+
expectedFile: "packages/api/src/middleware/auth.ts",
|
|
240
|
+
expectedLine: 39,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
id: "pf-p1-08",
|
|
244
|
+
query: "requireAuth",
|
|
245
|
+
expectedFile: "packages/api/src/middleware/auth.ts",
|
|
246
|
+
expectedLine: 45,
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
id: "pf-p1-09",
|
|
250
|
+
query: "resolveActor",
|
|
251
|
+
expectedFile: "packages/api/src/middleware/auth.ts",
|
|
252
|
+
expectedLine: 71,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: "pf-p1-10",
|
|
256
|
+
query: "getActor",
|
|
257
|
+
expectedFile: "packages/api/src/middleware/auth.ts",
|
|
258
|
+
expectedLine: 1136,
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: "pf-p1-11",
|
|
262
|
+
query: "rateLimit",
|
|
263
|
+
expectedFile: "packages/api/src/middleware/rate-limit.ts",
|
|
264
|
+
expectedLine: 94,
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: "pf-p1-12",
|
|
268
|
+
query: "checkRateLimitKey",
|
|
269
|
+
expectedFile: "packages/api/src/middleware/rate-limit.ts",
|
|
270
|
+
expectedLine: 158,
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
id: "pf-p1-13",
|
|
274
|
+
query: "errorHandler",
|
|
275
|
+
expectedFile: "packages/api/src/middleware/error.ts",
|
|
276
|
+
expectedLine: 128,
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
id: "pf-p1-14",
|
|
280
|
+
query: "activityTracker",
|
|
281
|
+
expectedFile: "packages/api/src/middleware/activity-tracker.ts",
|
|
282
|
+
expectedLine: 17,
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
id: "pf-p1-15",
|
|
286
|
+
query: "initializeApp",
|
|
287
|
+
expectedFile: "packages/api/src/app.ts",
|
|
288
|
+
expectedLine: 68,
|
|
289
|
+
},
|
|
118
290
|
];
|
|
119
291
|
const DATASETS = {
|
|
120
292
|
express: {
|
|
@@ -151,7 +323,8 @@ const DATASETS = {
|
|
|
151
323
|
function chunkMatches(chunk, expectedFile, expectedLine, expectedSymbol) {
|
|
152
324
|
var _a, _b, _c, _d, _e, _f;
|
|
153
325
|
const path = String(((_a = chunk.metadata) === null || _a === void 0 ? void 0 : _a.path) || "").toLowerCase();
|
|
154
|
-
if (!path.endsWith(`/${expectedFile.toLowerCase()}`) &&
|
|
326
|
+
if (!path.endsWith(`/${expectedFile.toLowerCase()}`) &&
|
|
327
|
+
!path.endsWith(expectedFile.toLowerCase())) {
|
|
155
328
|
return false;
|
|
156
329
|
}
|
|
157
330
|
// (b) defining-chunk match
|
|
@@ -190,7 +363,9 @@ function runDataset(ds, rerank, topK) {
|
|
|
190
363
|
return __awaiter(this, void 0, void 0, function* () {
|
|
191
364
|
const vectorDb = new vector_db_1.VectorDB(config_1.PATHS.lancedbDir);
|
|
192
365
|
const searcher = new searcher_1.Searcher(vectorDb);
|
|
193
|
-
const pathPrefix = ds.projectRoot.endsWith("/")
|
|
366
|
+
const pathPrefix = ds.projectRoot.endsWith("/")
|
|
367
|
+
? ds.projectRoot
|
|
368
|
+
: `${ds.projectRoot}/`;
|
|
194
369
|
const results = [];
|
|
195
370
|
for (const c of ds.cases) {
|
|
196
371
|
const t0 = performance.now();
|
package/dist/eval-seed.js
CHANGED
|
@@ -83,10 +83,10 @@ var _d;
|
|
|
83
83
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
84
84
|
(_a = (_d = process.env).GMAX_WORKER_COUNT) !== null && _a !== void 0 ? _a : (_d.GMAX_WORKER_COUNT = "1");
|
|
85
85
|
const path = __importStar(require("node:path"));
|
|
86
|
+
const config_1 = require("./config");
|
|
86
87
|
const searcher_1 = require("./lib/search/searcher");
|
|
87
88
|
const vector_db_1 = require("./lib/store/vector-db");
|
|
88
89
|
const exit_1 = require("./lib/utils/exit");
|
|
89
|
-
const config_1 = require("./config");
|
|
90
90
|
// Route/recover cases target the gmax repo itself — the corpus whose graph the
|
|
91
91
|
// author can verify by hand. The "idle timeout" concept lives in three
|
|
92
92
|
// subsystems (worker reap / LLM server / daemon); "health check" in three more.
|
|
@@ -250,9 +250,18 @@ function run() {
|
|
|
250
250
|
const summary = {
|
|
251
251
|
cases: results.length,
|
|
252
252
|
passes,
|
|
253
|
-
route: {
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
route: {
|
|
254
|
+
total: byKind("route").length,
|
|
255
|
+
pass: byKind("route").filter((r) => r.pass).length,
|
|
256
|
+
},
|
|
257
|
+
recover: {
|
|
258
|
+
total: byKind("recover").length,
|
|
259
|
+
pass: byKind("recover").filter((r) => r.pass).length,
|
|
260
|
+
},
|
|
261
|
+
guard: {
|
|
262
|
+
total: byKind("guard").length,
|
|
263
|
+
pass: byKind("guard").filter((r) => r.pass).length,
|
|
264
|
+
},
|
|
256
265
|
};
|
|
257
266
|
if (jsonMode) {
|
|
258
267
|
process.stdout.write(`${JSON.stringify({ rerank, summary, results }, null, 2)}\n`);
|
package/dist/index.js
CHANGED
|
@@ -40,38 +40,38 @@ const path = __importStar(require("node:path"));
|
|
|
40
40
|
const commander_1 = require("commander");
|
|
41
41
|
const add_1 = require("./commands/add");
|
|
42
42
|
const audit_1 = require("./commands/audit");
|
|
43
|
-
const context_1 = require("./commands/context");
|
|
44
|
-
const dead_1 = require("./commands/dead");
|
|
45
|
-
const diff_1 = require("./commands/diff");
|
|
46
43
|
const claude_code_1 = require("./commands/claude-code");
|
|
47
44
|
const codex_1 = require("./commands/codex");
|
|
48
45
|
const config_1 = require("./commands/config");
|
|
46
|
+
const context_1 = require("./commands/context");
|
|
47
|
+
const dead_1 = require("./commands/dead");
|
|
48
|
+
const diff_1 = require("./commands/diff");
|
|
49
49
|
const doctor_1 = require("./commands/doctor");
|
|
50
|
+
const droid_1 = require("./commands/droid");
|
|
50
51
|
const extract_1 = require("./commands/extract");
|
|
51
52
|
const help_agent_1 = require("./commands/help-agent");
|
|
52
53
|
const impact_1 = require("./commands/impact");
|
|
53
|
-
const droid_1 = require("./commands/droid");
|
|
54
54
|
const index_1 = require("./commands/index");
|
|
55
55
|
const investigate_1 = require("./commands/investigate");
|
|
56
56
|
const list_1 = require("./commands/list");
|
|
57
57
|
const llm_1 = require("./commands/llm");
|
|
58
58
|
const log_1 = require("./commands/log");
|
|
59
59
|
const mcp_1 = require("./commands/mcp");
|
|
60
|
+
const opencode_1 = require("./commands/opencode");
|
|
60
61
|
const peek_1 = require("./commands/peek");
|
|
62
|
+
const plugin_1 = require("./commands/plugin");
|
|
61
63
|
const project_1 = require("./commands/project");
|
|
62
64
|
const recent_1 = require("./commands/recent");
|
|
63
65
|
const related_1 = require("./commands/related");
|
|
64
|
-
const review_1 = require("./commands/review");
|
|
65
|
-
const opencode_1 = require("./commands/opencode");
|
|
66
|
-
const plugin_1 = require("./commands/plugin");
|
|
67
66
|
const remove_1 = require("./commands/remove");
|
|
67
|
+
const review_1 = require("./commands/review");
|
|
68
68
|
const search_1 = require("./commands/search");
|
|
69
|
-
const similar_1 = require("./commands/similar");
|
|
70
69
|
const serve_1 = require("./commands/serve");
|
|
71
70
|
const setup_1 = require("./commands/setup");
|
|
71
|
+
const similar_1 = require("./commands/similar");
|
|
72
72
|
const skeleton_1 = require("./commands/skeleton");
|
|
73
|
-
const summarize_1 = require("./commands/summarize");
|
|
74
73
|
const status_1 = require("./commands/status");
|
|
74
|
+
const summarize_1 = require("./commands/summarize");
|
|
75
75
|
const symbols_1 = require("./commands/symbols");
|
|
76
76
|
const test_find_1 = require("./commands/test-find");
|
|
77
77
|
const trace_1 = require("./commands/trace");
|
|
@@ -51,23 +51,23 @@ const net = __importStar(require("node:net"));
|
|
|
51
51
|
const path = __importStar(require("node:path"));
|
|
52
52
|
const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
|
|
53
53
|
const config_1 = require("../../config");
|
|
54
|
+
const index_config_1 = require("../index/index-config");
|
|
54
55
|
const syncer_1 = require("../index/syncer");
|
|
55
|
-
const
|
|
56
|
+
const server_1 = require("../llm/server");
|
|
56
57
|
const meta_cache_1 = require("../store/meta-cache");
|
|
57
58
|
const vector_db_1 = require("../store/vector-db");
|
|
59
|
+
const daemon_launcher_1 = require("../utils/daemon-launcher");
|
|
60
|
+
const log_rotate_1 = require("../utils/log-rotate");
|
|
61
|
+
const logger_1 = require("../utils/logger");
|
|
58
62
|
const process_1 = require("../utils/process");
|
|
59
63
|
const project_registry_1 = require("../utils/project-registry");
|
|
60
64
|
const watcher_store_1 = require("../utils/watcher-store");
|
|
61
|
-
const
|
|
65
|
+
const pool_1 = require("../workers/pool");
|
|
62
66
|
const ipc_handler_1 = require("./ipc-handler");
|
|
63
|
-
const process_manager_1 = require("./process-manager");
|
|
64
67
|
const mlx_server_manager_1 = require("./mlx-server-manager");
|
|
68
|
+
const process_manager_1 = require("./process-manager");
|
|
69
|
+
const search_handler_1 = require("./search-handler");
|
|
65
70
|
const watcher_manager_1 = require("./watcher-manager");
|
|
66
|
-
const logger_1 = require("../utils/logger");
|
|
67
|
-
const index_config_1 = require("../index/index-config");
|
|
68
|
-
const log_rotate_1 = require("../utils/log-rotate");
|
|
69
|
-
const pool_1 = require("../workers/pool");
|
|
70
|
-
const daemon_launcher_1 = require("../utils/daemon-launcher");
|
|
71
71
|
// 30 min was too aggressive — every shutdown is a chance for races, FSEvents
|
|
72
72
|
// drops, and orphan MLX cleanup. 4 hours keeps the daemon resident through a
|
|
73
73
|
// normal workday while still freeing resources overnight. Override with
|
|
@@ -128,8 +128,12 @@ class Daemon {
|
|
|
128
128
|
getVectorDb: () => this.vectorDb,
|
|
129
129
|
getMetaCache: () => this.metaCache,
|
|
130
130
|
getShuttingDown: () => this.shuttingDown,
|
|
131
|
-
touchActivity: () => {
|
|
132
|
-
|
|
131
|
+
touchActivity: () => {
|
|
132
|
+
this.lastActivity = Date.now();
|
|
133
|
+
},
|
|
134
|
+
evictSearcher: (root) => {
|
|
135
|
+
this.searchers.delete(root);
|
|
136
|
+
},
|
|
133
137
|
});
|
|
134
138
|
this.projectLocks = new Map();
|
|
135
139
|
// Full-index progress per root while initialSync runs (--reset / initial
|
|
@@ -285,7 +289,8 @@ class Daemon {
|
|
|
285
289
|
// Re-check shuttingDown each iteration: shutdown's pendingLocks drain is a
|
|
286
290
|
// snapshot, so a new project op kicked off after the snapshot would race
|
|
287
291
|
// with vectorDb.close() and fail with "VectorDB connection is closed".
|
|
288
|
-
const pending = allProjects.filter((p) => (p.status === "pending" || p.status === "error") &&
|
|
292
|
+
const pending = allProjects.filter((p) => (p.status === "pending" || p.status === "error") &&
|
|
293
|
+
fs.existsSync(p.root));
|
|
289
294
|
void (() => __awaiter(this, void 0, void 0, function* () {
|
|
290
295
|
for (const p of pending) {
|
|
291
296
|
if (this.shuttingDown)
|
|
@@ -403,7 +408,9 @@ class Daemon {
|
|
|
403
408
|
projectRoot: root,
|
|
404
409
|
vectorDb: this.vectorDb,
|
|
405
410
|
metaCache: this.metaCache,
|
|
406
|
-
onProgress: () => {
|
|
411
|
+
onProgress: () => {
|
|
412
|
+
this.resetActivity();
|
|
413
|
+
},
|
|
407
414
|
});
|
|
408
415
|
const proj = (0, project_registry_1.getProject)(root);
|
|
409
416
|
if (proj) {
|
|
@@ -506,7 +513,9 @@ class Daemon {
|
|
|
506
513
|
var _a;
|
|
507
514
|
const prev = (_a = this.projectLocks.get(root)) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
508
515
|
let release;
|
|
509
|
-
const next = new Promise((r) => {
|
|
516
|
+
const next = new Promise((r) => {
|
|
517
|
+
release = r;
|
|
518
|
+
});
|
|
510
519
|
this.projectLocks.set(root, next);
|
|
511
520
|
yield prev;
|
|
512
521
|
try {
|
|
@@ -107,7 +107,12 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
107
107
|
(0, logger_1.debug)("daemon", `ipc cmd=${cmd.cmd}${cmd.root ? ` root=${cmd.root}` : ""}`);
|
|
108
108
|
switch (cmd.cmd) {
|
|
109
109
|
case "ping":
|
|
110
|
-
return {
|
|
110
|
+
return {
|
|
111
|
+
ok: true,
|
|
112
|
+
pid: process.pid,
|
|
113
|
+
uptime: daemon.uptime(),
|
|
114
|
+
version: DAEMON_VERSION,
|
|
115
|
+
};
|
|
111
116
|
case "watch": {
|
|
112
117
|
const root = String(cmd.root || "");
|
|
113
118
|
if (!root)
|
|
@@ -135,7 +140,9 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
135
140
|
const fromPid = (_b = cmd.from_pid) !== null && _b !== void 0 ? _b : "?";
|
|
136
141
|
const fromPpid = (_c = cmd.from_ppid) !== null && _c !== void 0 ? _c : "?";
|
|
137
142
|
const fromVer = (_d = cmd.from_version) !== null && _d !== void 0 ? _d : "?";
|
|
138
|
-
const fromArgv = Array.isArray(cmd.from_argv)
|
|
143
|
+
const fromArgv = Array.isArray(cmd.from_argv)
|
|
144
|
+
? cmd.from_argv.join(" ")
|
|
145
|
+
: "?";
|
|
139
146
|
const fromParentCmd = (_e = cmd.from_parent_cmd) !== null && _e !== void 0 ? _e : "?";
|
|
140
147
|
console.log(`[daemon] shutdown command received via IPC: reason=${reason} from_pid=${fromPid} from_ppid=${fromPpid} from_version=${fromVer} from_argv=[${fromArgv}] from_parent_cmd=[${fromParentCmd}]`);
|
|
141
148
|
setImmediate(() => daemon.shutdown());
|
|
@@ -155,12 +162,16 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
155
162
|
conn.on("close", onClose);
|
|
156
163
|
try {
|
|
157
164
|
const limitRaw = typeof cmd.limit === "number" ? cmd.limit : 10;
|
|
158
|
-
const skeletonLimitRaw = typeof cmd.skeletonLimit === "number"
|
|
165
|
+
const skeletonLimitRaw = typeof cmd.skeletonLimit === "number"
|
|
166
|
+
? cmd.skeletonLimit
|
|
167
|
+
: undefined;
|
|
159
168
|
// Accept both the legacy single-string `exclude` and the new
|
|
160
169
|
// `excludePrefixes`/`inPrefixes` arrays (--in/--exclude on the CLI).
|
|
161
170
|
// Daemon may outlive a CLI restart, so keep both wire shapes for
|
|
162
171
|
// one release; drop the single-string form in v0.17.x.
|
|
163
|
-
const filters = cmd.filters &&
|
|
172
|
+
const filters = cmd.filters &&
|
|
173
|
+
typeof cmd.filters === "object" &&
|
|
174
|
+
!Array.isArray(cmd.filters)
|
|
164
175
|
? cmd.filters
|
|
165
176
|
: undefined;
|
|
166
177
|
const resp = yield daemon.search({
|
|
@@ -171,7 +182,9 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
171
182
|
pathPrefix: typeof cmd.pathPrefix === "string" ? cmd.pathPrefix : undefined,
|
|
172
183
|
rerank: cmd.rerank === true,
|
|
173
184
|
explain: cmd.explain === true,
|
|
174
|
-
seeds: cmd.seeds &&
|
|
185
|
+
seeds: cmd.seeds &&
|
|
186
|
+
typeof cmd.seeds === "object" &&
|
|
187
|
+
!Array.isArray(cmd.seeds)
|
|
175
188
|
? cmd.seeds
|
|
176
189
|
: undefined,
|
|
177
190
|
includeSkeletons: cmd.includeSkeletons === true,
|
|
@@ -69,15 +69,23 @@ class MlxServerManager {
|
|
|
69
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
70
|
const port = parseInt(process.env.MLX_EMBED_PORT || "8100", 10);
|
|
71
71
|
return new Promise((resolve) => {
|
|
72
|
-
const req = http.get({ hostname: "127.0.0.1", port, path: "/health", timeout: 2000 }, (res) => {
|
|
72
|
+
const req = http.get({ hostname: "127.0.0.1", port, path: "/health", timeout: 2000 }, (res) => {
|
|
73
|
+
res.resume();
|
|
74
|
+
resolve(res.statusCode === 200);
|
|
75
|
+
});
|
|
73
76
|
req.on("error", () => resolve(false));
|
|
74
|
-
req.on("timeout", () => {
|
|
77
|
+
req.on("timeout", () => {
|
|
78
|
+
req.destroy();
|
|
79
|
+
resolve(false);
|
|
80
|
+
});
|
|
75
81
|
});
|
|
76
82
|
});
|
|
77
83
|
}
|
|
78
84
|
getPortPid(port) {
|
|
79
85
|
try {
|
|
80
|
-
const out = (0, node_child_process_1.execSync)(`lsof -ti :${port}`, { timeout: 5000 })
|
|
86
|
+
const out = (0, node_child_process_1.execSync)(`lsof -ti :${port}`, { timeout: 5000 })
|
|
87
|
+
.toString()
|
|
88
|
+
.trim();
|
|
81
89
|
const pid = parseInt(out.split("\n")[0], 10);
|
|
82
90
|
return Number.isFinite(pid) ? pid : null;
|
|
83
91
|
}
|
|
@@ -83,8 +83,7 @@ class ProcessManager {
|
|
|
83
83
|
killStaleProcesses() {
|
|
84
84
|
return __awaiter(this, void 0, void 0, function* () {
|
|
85
85
|
// 1. Check for other daemon processes
|
|
86
|
-
const daemonPids = this.findProcessesByTitle("gmax-daemon")
|
|
87
|
-
.filter((pid) => pid !== process.pid);
|
|
86
|
+
const daemonPids = this.findProcessesByTitle("gmax-daemon").filter((pid) => pid !== process.pid);
|
|
88
87
|
const workerPids = this.findProcessesByTitle("gmax-worker");
|
|
89
88
|
if (daemonPids.length === 0 && workerPids.length === 0) {
|
|
90
89
|
(0, logger_1.log)("daemon", "No stale processes found");
|
|
@@ -50,9 +50,9 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
|
50
50
|
};
|
|
51
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
52
|
exports.WatcherManager = void 0;
|
|
53
|
-
const watcher = __importStar(require("@parcel/watcher"));
|
|
54
53
|
const fs = __importStar(require("node:fs"));
|
|
55
54
|
const path = __importStar(require("node:path"));
|
|
55
|
+
const watcher = __importStar(require("@parcel/watcher"));
|
|
56
56
|
const batch_processor_1 = require("../index/batch-processor");
|
|
57
57
|
const watcher_1 = require("../index/watcher");
|
|
58
58
|
const logger_1 = require("../utils/logger");
|
|
@@ -250,7 +250,7 @@ class WatcherManager {
|
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
252
252
|
// Backoff: wait before re-subscribing (3s, 6s, 12s)
|
|
253
|
-
const delayMs = 3000 * Math.pow(2, fails - 1);
|
|
253
|
+
const delayMs = 3000 * Math.pow(2, (fails - 1));
|
|
254
254
|
console.error(`[daemon:${name}] Recovering watcher (attempt ${fails}/${MAX_WATCHER_RETRIES}, backoff ${delayMs}ms)...`);
|
|
255
255
|
setTimeout(() => {
|
|
256
256
|
if (this.deps.getShuttingDown()) {
|
|
@@ -378,7 +378,7 @@ class WatcherManager {
|
|
|
378
378
|
if (!isFileCached(cached, stats)) {
|
|
379
379
|
// Fast path: if only mtime changed but size is identical and we have a hash,
|
|
380
380
|
// just verify the hash in-process instead of sending to a worker.
|
|
381
|
-
if (cached
|
|
381
|
+
if ((cached === null || cached === void 0 ? void 0 : cached.hash) && cached.size === stats.size) {
|
|
382
382
|
const { computeBufferHash } = yield Promise.resolve().then(() => __importStar(require("../utils/file-utils")));
|
|
383
383
|
const buf = yield fs.promises.readFile(absPath);
|
|
384
384
|
const hash = computeBufferHash(buf);
|
|
@@ -400,7 +400,7 @@ class WatcherManager {
|
|
|
400
400
|
// batch processor drain and compaction run between bursts.
|
|
401
401
|
if (queued % 500 === 0) {
|
|
402
402
|
(0, logger_1.debug)("catchup", `${path.basename(root)}: throttle pause at ${queued} queued`);
|
|
403
|
-
yield new Promise(r => setTimeout(r, 5000));
|
|
403
|
+
yield new Promise((r) => setTimeout(r, 5000));
|
|
404
404
|
}
|
|
405
405
|
}
|
|
406
406
|
else {
|