grepmax 0.26.32 → 0.26.34
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/dist/bin.js +109 -0
- package/dist/commands/context.js +12 -8
- package/dist/commands/doctor.js +7 -9
- package/dist/commands/droid.js +2 -1
- package/dist/commands/extract.js +8 -11
- package/dist/commands/impact.js +5 -8
- package/dist/commands/mcp.js +38 -41
- package/dist/commands/peek.js +6 -9
- package/dist/commands/search-output.js +10 -11
- package/dist/commands/search-run.js +5 -4
- package/dist/commands/search-skeletons.js +2 -1
- package/dist/commands/search.js +5 -4
- package/dist/commands/serve.js +2 -1
- package/dist/commands/similar.js +7 -6
- package/dist/commands/skeleton.js +17 -22
- package/dist/commands/test-find.js +5 -8
- package/dist/commands/watch.js +9 -0
- package/dist/config.js +19 -9
- package/dist/eval-oss.js +4 -3
- package/dist/eval-tokens.js +4 -4
- package/dist/eval.js +2 -5
- package/dist/index.js +4 -3
- package/dist/lib/daemon/daemon.js +36 -29
- package/dist/lib/daemon/graph-handler.js +2 -1
- package/dist/lib/daemon/mlx-server-manager.js +10 -9
- package/dist/lib/daemon/rows-handler.js +11 -13
- package/dist/lib/daemon/search-handler.js +6 -5
- package/dist/lib/daemon/vector-handler.js +2 -1
- package/dist/lib/daemon/watcher-manager.js +4 -2
- package/dist/lib/graph/graph-builder.js +4 -10
- package/dist/lib/graph/graph-traversal.js +0 -0
- package/dist/lib/index/batch-processor.js +13 -12
- package/dist/lib/index/chunker.js +22 -23
- package/dist/lib/index/syncer.js +2 -2
- package/dist/lib/llm/investigate.js +5 -4
- package/dist/lib/llm/review.js +2 -1
- package/dist/lib/llm/tools.js +6 -5
- package/dist/lib/output/agent-search-formatter.js +3 -2
- package/dist/lib/output/compact-results.js +16 -12
- package/dist/lib/search/searcher.js +11 -13
- package/dist/lib/setup/model-loader.js +1 -1
- package/dist/lib/skeleton/body-fields.js +2 -1
- package/dist/lib/skeleton/skeletonizer.js +8 -7
- package/dist/lib/store/vector-db.js +6 -5
- package/dist/lib/utils/autostart.js +6 -0
- package/dist/lib/utils/formatter.js +5 -4
- package/dist/lib/utils/stale-hint.js +4 -3
- package/dist/lib/utils/store-access.js +2 -1
- package/dist/lib/utils/stores.js +124 -0
- package/dist/lib/workers/embeddings/granite.js +2 -1
- package/dist/lib/workers/pool.js +14 -10
- package/package.json +5 -6
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
|
@@ -374,7 +374,8 @@ class Skeletonizer {
|
|
|
374
374
|
const refs = [];
|
|
375
375
|
const seen = new Set();
|
|
376
376
|
const extract = (n) => {
|
|
377
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j
|
|
377
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
378
|
+
var _k, _l, _m, _o;
|
|
378
379
|
if (n.type === "call_expression" ||
|
|
379
380
|
n.type === "call" ||
|
|
380
381
|
n.type === "function_call") {
|
|
@@ -401,13 +402,13 @@ class Skeletonizer {
|
|
|
401
402
|
else {
|
|
402
403
|
// Swift/Kotlin: call_expression has no "function" field;
|
|
403
404
|
// the callable is a positional child
|
|
404
|
-
const firstChild = ((
|
|
405
|
+
const firstChild = ((_k = n.namedChildren) !== null && _k !== void 0 ? _k : [])[0];
|
|
405
406
|
if (firstChild) {
|
|
406
407
|
let funcName = firstChild.text;
|
|
407
408
|
if (firstChild.type === "navigation_expression") {
|
|
408
|
-
const suffix = ((
|
|
409
|
+
const suffix = ((_l = firstChild.namedChildren) !== null && _l !== void 0 ? _l : []).find((c) => c.type === "navigation_suffix");
|
|
409
410
|
const methodId = suffix
|
|
410
|
-
? ((
|
|
411
|
+
? ((_m = suffix.namedChildren) !== null && _m !== void 0 ? _m : []).find((c) => c.type === "simple_identifier")
|
|
411
412
|
: null;
|
|
412
413
|
if (methodId)
|
|
413
414
|
funcName = methodId.text;
|
|
@@ -423,7 +424,7 @@ class Skeletonizer {
|
|
|
423
424
|
n.type === "invocation_expression" // C#
|
|
424
425
|
) {
|
|
425
426
|
// Java/C# method calls
|
|
426
|
-
const nameNode = ((
|
|
427
|
+
const nameNode = ((_d = n.childForFieldName) === null || _d === void 0 ? void 0 : _d.call(n, "name")) || ((_e = n.childForFieldName) === null || _e === void 0 ? void 0 : _e.call(n, "function"));
|
|
427
428
|
if (nameNode) {
|
|
428
429
|
refs.push(nameNode.text);
|
|
429
430
|
seen.add(nameNode.text);
|
|
@@ -433,7 +434,7 @@ class Skeletonizer {
|
|
|
433
434
|
n.type === "command" || // Ruby
|
|
434
435
|
n.type === "command_call" // Ruby
|
|
435
436
|
) {
|
|
436
|
-
const nameNode = ((
|
|
437
|
+
const nameNode = ((_f = n.childForFieldName) === null || _f === void 0 ? void 0 : _f.call(n, "method")) || ((_g = n.childForFieldName) === null || _g === void 0 ? void 0 : _g.call(n, "name"));
|
|
437
438
|
if (nameNode) {
|
|
438
439
|
refs.push(nameNode.text);
|
|
439
440
|
seen.add(nameNode.text);
|
|
@@ -447,7 +448,7 @@ class Skeletonizer {
|
|
|
447
448
|
c.type === "nested_identifier");
|
|
448
449
|
if (nameChild) {
|
|
449
450
|
const name = nameChild.type === "member_expression"
|
|
450
|
-
? ((_o = (
|
|
451
|
+
? ((_o = (_j = (_h = nameChild.childForFieldName) === null || _h === void 0 ? void 0 : _h.call(nameChild, "property")) === null || _j === void 0 ? void 0 : _j.text) !== null && _o !== void 0 ? _o : nameChild.text)
|
|
451
452
|
: nameChild.text;
|
|
452
453
|
if (name && /^[A-Z]/.test(name) && !seen.has(name)) {
|
|
453
454
|
seen.add(name);
|
|
@@ -315,7 +315,8 @@ class VectorDB {
|
|
|
315
315
|
* defer idle shutdown so we don't tear down LanceDB mid-optimize. */
|
|
316
316
|
/** Bytes held by LanceDB's index + metadata caches (0 before first connect). */
|
|
317
317
|
cacheSizeBytes() {
|
|
318
|
-
var _a
|
|
318
|
+
var _a;
|
|
319
|
+
var _b;
|
|
319
320
|
try {
|
|
320
321
|
return Number((_b = (_a = this.session) === null || _a === void 0 ? void 0 : _a.sizeBytes()) !== null && _b !== void 0 ? _b : 0);
|
|
321
322
|
}
|
|
@@ -574,7 +575,7 @@ class VectorDB {
|
|
|
574
575
|
return result;
|
|
575
576
|
}
|
|
576
577
|
finally {
|
|
577
|
-
yield
|
|
578
|
+
yield temporaryExclusiveLease === null || temporaryExclusiveLease === void 0 ? void 0 : temporaryExclusiveLease.release();
|
|
578
579
|
}
|
|
579
580
|
}));
|
|
580
581
|
}
|
|
@@ -850,8 +851,7 @@ class VectorDB {
|
|
|
850
851
|
rec.defined_symbols = (_g = rec.defined_symbols) !== null && _g !== void 0 ? _g : [];
|
|
851
852
|
rec.referenced_symbols = (_h = rec.referenced_symbols) !== null && _h !== void 0 ? _h : [];
|
|
852
853
|
rec.type_referenced_symbols = (_j = rec.type_referenced_symbols) !== null && _j !== void 0 ? _j : [];
|
|
853
|
-
rec.member_referenced_symbols =
|
|
854
|
-
(_k = rec.member_referenced_symbols) !== null && _k !== void 0 ? _k : [];
|
|
854
|
+
rec.member_referenced_symbols = (_k = rec.member_referenced_symbols) !== null && _k !== void 0 ? _k : [];
|
|
855
855
|
rec.imports = (_l = rec.imports) !== null && _l !== void 0 ? _l : [];
|
|
856
856
|
rec.exports = (_m = rec.exports) !== null && _m !== void 0 ? _m : [];
|
|
857
857
|
rec.role = (_o = rec.role) !== null && _o !== void 0 ? _o : "";
|
|
@@ -936,7 +936,8 @@ class VectorDB {
|
|
|
936
936
|
}
|
|
937
937
|
createVectorIndexUnsafe(rebuild, retries, checkOnly) {
|
|
938
938
|
return __awaiter(this, void 0, void 0, function* () {
|
|
939
|
-
var _a
|
|
939
|
+
var _a;
|
|
940
|
+
var _b;
|
|
940
941
|
const table = yield this.ensureTableUnsafe();
|
|
941
942
|
const rowCount = yield table.countRows();
|
|
942
943
|
if (rowCount < (0, ann_config_1.annMinRows)())
|
|
@@ -81,6 +81,12 @@ function autostartDisabledUndo() {
|
|
|
81
81
|
: `rm ${config_1.PATHS.autostartDisabledFile}`;
|
|
82
82
|
}
|
|
83
83
|
function autostartDisabledNotice() {
|
|
84
|
+
// A secondary store (src/bin.ts) runs in-process by design, not because the
|
|
85
|
+
// kill switch is on, so say that instead of naming an undo step. Callers use
|
|
86
|
+
// a non-null notice as the gate, so this must stay non-null.
|
|
87
|
+
if (process.env.GMAX_SECONDARY_STORE === "1") {
|
|
88
|
+
return `This project's index lives in ${config_1.PATHS.globalRoot} on an external drive — running in-process, not watched. Run \`gmax index\` after changing it.`;
|
|
89
|
+
}
|
|
84
90
|
const undo = autostartDisabledUndo();
|
|
85
91
|
if (!undo)
|
|
86
92
|
return null;
|
|
@@ -87,7 +87,8 @@ function cleanSnippetLines(snippet) {
|
|
|
87
87
|
* Supports compact (paths only), score display, and content truncation options.
|
|
88
88
|
*/
|
|
89
89
|
function formatTextResults(results, query, root, options) {
|
|
90
|
-
var _a, _b
|
|
90
|
+
var _a, _b;
|
|
91
|
+
var _c;
|
|
91
92
|
if (results.length === 0)
|
|
92
93
|
return `gmax: No results found for "${query}".`;
|
|
93
94
|
// --- MODE: COMPACT (File paths only) ---
|
|
@@ -149,7 +150,7 @@ function formatTextResults(results, query, root, options) {
|
|
|
149
150
|
// 1. Sort by score descending (best matches first)
|
|
150
151
|
chunks.sort((a, b) => b.score - a.score);
|
|
151
152
|
// 2. Apply per-file limit
|
|
152
|
-
const limit = (
|
|
153
|
+
const limit = (_c = options.perFile) !== null && _c !== void 0 ? _c : 1000;
|
|
153
154
|
const limitedChunks = chunks.slice(0, limit);
|
|
154
155
|
// 3. Re-sort by line number for display
|
|
155
156
|
limitedChunks.sort((a, b) => a.start_line - b.start_line);
|
|
@@ -162,7 +163,7 @@ function formatTextResults(results, query, root, options) {
|
|
|
162
163
|
if (next.start_line <= current.end_line + 10) {
|
|
163
164
|
current.content += `\n // ...\n${next.content}`;
|
|
164
165
|
current.end_line = next.end_line;
|
|
165
|
-
if ((
|
|
166
|
+
if ((_a = next.chunk_type) === null || _a === void 0 ? void 0 : _a.match(/function|class/))
|
|
166
167
|
current.chunk_type = next.chunk_type;
|
|
167
168
|
}
|
|
168
169
|
else {
|
|
@@ -181,7 +182,7 @@ function formatTextResults(results, query, root, options) {
|
|
|
181
182
|
const relPath = path.relative(root, filePath);
|
|
182
183
|
for (const item of merged) {
|
|
183
184
|
const tags = [];
|
|
184
|
-
if ((
|
|
185
|
+
if ((_b = item.chunk_type) === null || _b === void 0 ? void 0 : _b.match(/function|class/))
|
|
185
186
|
tags.push("Definition");
|
|
186
187
|
const tagStr = tags.length > 0 ? ` ${style.blue(`[${tags.join(", ")}]`)}` : "";
|
|
187
188
|
const line = Math.max(1, item.start_line + 1);
|
|
@@ -122,7 +122,8 @@ function maybeWarnStaleEmbedding(projectRoot, opts) {
|
|
|
122
122
|
* silently returning invalid cross-project rankings.
|
|
123
123
|
*/
|
|
124
124
|
function maybeWarnCrossProjectDim(roots, opts) {
|
|
125
|
-
var _a, _b
|
|
125
|
+
var _a, _b;
|
|
126
|
+
var _c, _d, _e, _f, _g;
|
|
126
127
|
if (crossDimEmitted)
|
|
127
128
|
return;
|
|
128
129
|
if (process.env.GMAX_NO_STALE_HINT === "1")
|
|
@@ -130,7 +131,7 @@ function maybeWarnCrossProjectDim(roots, opts) {
|
|
|
130
131
|
if (!roots || roots.length === 0)
|
|
131
132
|
return;
|
|
132
133
|
const current = (0, index_config_1.readGlobalConfig)();
|
|
133
|
-
const currentDim = (
|
|
134
|
+
const currentDim = (_e = (_c = current.vectorDim) !== null && _c !== void 0 ? _c : (_a = config_1.MODEL_TIERS[(_d = current.modelTier) !== null && _d !== void 0 ? _d : config_1.DEFAULT_MODEL_TIER]) === null || _a === void 0 ? void 0 : _a.vectorDim) !== null && _e !== void 0 ? _e : config_1.CONFIG.VECTOR_DIM;
|
|
134
135
|
const byRoot = new Map((0, project_registry_1.listProjects)().map((p) => [p.root, p]));
|
|
135
136
|
const dims = new Set([currentDim]);
|
|
136
137
|
const mismatched = [];
|
|
@@ -138,7 +139,7 @@ function maybeWarnCrossProjectDim(roots, opts) {
|
|
|
138
139
|
const p = byRoot.get(r.root);
|
|
139
140
|
if (!p)
|
|
140
141
|
continue;
|
|
141
|
-
const dim = (_g = (
|
|
142
|
+
const dim = (_g = (_f = p.vectorDim) !== null && _f !== void 0 ? _f : (_b = config_1.MODEL_TIERS[p.modelTier]) === null || _b === void 0 ? void 0 : _b.vectorDim) !== null && _g !== void 0 ? _g : currentDim;
|
|
142
143
|
dims.add(dim);
|
|
143
144
|
if (dim !== currentDim)
|
|
144
145
|
mismatched.push({ name: p.name || r.name, dim });
|
|
@@ -272,7 +272,8 @@ function isDaemonBypassed() {
|
|
|
272
272
|
*/
|
|
273
273
|
function withStoreRead(name, opts) {
|
|
274
274
|
return __awaiter(this, void 0, void 0, function* () {
|
|
275
|
-
var _a
|
|
275
|
+
var _a;
|
|
276
|
+
var _b;
|
|
276
277
|
const runInProcess = () => __awaiter(this, void 0, void 0, function* () {
|
|
277
278
|
try {
|
|
278
279
|
return yield opts.inProcess();
|
|
@@ -0,0 +1,124 @@
|
|
|
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.storesFilePath = storesFilePath;
|
|
37
|
+
exports.readStores = readStores;
|
|
38
|
+
exports.volumeOf = volumeOf;
|
|
39
|
+
exports.matchStore = matchStore;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const os = __importStar(require("node:os"));
|
|
42
|
+
const path = __importStar(require("node:path"));
|
|
43
|
+
function storesFilePath(home = os.homedir()) {
|
|
44
|
+
return path.join(home, ".gmax", "stores.json");
|
|
45
|
+
}
|
|
46
|
+
function readStores(file = storesFilePath()) {
|
|
47
|
+
let raw;
|
|
48
|
+
try {
|
|
49
|
+
raw = fs.readFileSync(file, "utf-8");
|
|
50
|
+
}
|
|
51
|
+
catch (_a) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
if (!Array.isArray(parsed.stores))
|
|
57
|
+
return [];
|
|
58
|
+
return parsed.stores.filter((s) => !!s &&
|
|
59
|
+
typeof s.prefix === "string" &&
|
|
60
|
+
typeof s.home === "string");
|
|
61
|
+
}
|
|
62
|
+
catch (_b) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// The volume a path lives on, for paths under /Volumes; null for the boot disk.
|
|
67
|
+
function volumeOf(p) {
|
|
68
|
+
const parts = path.resolve(p).split(path.sep);
|
|
69
|
+
return parts[1] === "Volumes" && parts[2]
|
|
70
|
+
? path.join("/Volumes", parts[2])
|
|
71
|
+
: null;
|
|
72
|
+
}
|
|
73
|
+
function realOrResolved(p) {
|
|
74
|
+
try {
|
|
75
|
+
return fs.realpathSync(p);
|
|
76
|
+
}
|
|
77
|
+
catch (_a) {
|
|
78
|
+
return path.resolve(p);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function within(child, parent) {
|
|
82
|
+
const rel = path.relative(parent, child);
|
|
83
|
+
return (rel === "" || (!!rel && !rel.startsWith("..") && !path.isAbsolute(rel)));
|
|
84
|
+
}
|
|
85
|
+
// A path behind a symlink (~/Development/packages -> /Volumes/External/...)
|
|
86
|
+
// matches through its realpath. When the drive is ejected the symlink dangles
|
|
87
|
+
// and realpath fails, so the link target is read directly to still name it.
|
|
88
|
+
function candidates(target) {
|
|
89
|
+
const out = new Set([path.resolve(target), realOrResolved(target)]);
|
|
90
|
+
let cur = path.resolve(target);
|
|
91
|
+
const tail = [];
|
|
92
|
+
while (cur !== path.dirname(cur)) {
|
|
93
|
+
try {
|
|
94
|
+
if (fs.lstatSync(cur).isSymbolicLink()) {
|
|
95
|
+
const link = path.resolve(path.dirname(cur), fs.readlinkSync(cur));
|
|
96
|
+
out.add(path.join(link, ...tail.slice().reverse()));
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (_a) {
|
|
101
|
+
// not there; keep walking up
|
|
102
|
+
}
|
|
103
|
+
tail.push(path.basename(cur));
|
|
104
|
+
cur = path.dirname(cur);
|
|
105
|
+
}
|
|
106
|
+
return [...out];
|
|
107
|
+
}
|
|
108
|
+
function matchStore(target, stores = readStores()) {
|
|
109
|
+
var _a;
|
|
110
|
+
if (!stores.length)
|
|
111
|
+
return { kind: "primary" };
|
|
112
|
+
for (const cand of candidates(target)) {
|
|
113
|
+
for (const store of stores) {
|
|
114
|
+
if (!within(cand, path.resolve(store.prefix)))
|
|
115
|
+
continue;
|
|
116
|
+
const volume = (_a = volumeOf(store.home)) !== null && _a !== void 0 ? _a : volumeOf(store.prefix);
|
|
117
|
+
if (volume && !fs.existsSync(volume)) {
|
|
118
|
+
return { kind: "offline", store, volume };
|
|
119
|
+
}
|
|
120
|
+
return { kind: "store", store };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { kind: "primary" };
|
|
124
|
+
}
|
|
@@ -147,7 +147,8 @@ class GraniteModel {
|
|
|
147
147
|
}
|
|
148
148
|
runBatch(texts) {
|
|
149
149
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
var _a
|
|
150
|
+
var _a;
|
|
151
|
+
var _b, _c;
|
|
151
152
|
// Lazy-load: in the normal path MLX/GPU handles dense embedding and this
|
|
152
153
|
// ONNX model is never used, so we avoid paying its resident cost in every
|
|
153
154
|
// worker. load() is idempotent and only runs on the first fallback batch.
|
package/dist/lib/workers/pool.js
CHANGED
|
@@ -327,7 +327,8 @@ class WorkerPool {
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
handleWorkerExit(worker, code, signal, reason = "exit", err) {
|
|
330
|
-
var _a, _b
|
|
330
|
+
var _a, _b;
|
|
331
|
+
var _c, _d;
|
|
331
332
|
// Crash paths can fire both 'error' and 'exit'. Either is sufficient
|
|
332
333
|
// to clean up; running this twice would double-respawn.
|
|
333
334
|
if (worker.cleanedUp)
|
|
@@ -337,7 +338,7 @@ class WorkerPool {
|
|
|
337
338
|
const failedTasks = Array.from(this.tasks.values()).filter((t) => t.worker === worker);
|
|
338
339
|
for (const task of failedTasks) {
|
|
339
340
|
this.clearTaskTimeout(task);
|
|
340
|
-
const filePath = (_d = (
|
|
341
|
+
const filePath = (_d = (_c = (_a = task.payload) === null || _a === void 0 ? void 0 : _a.path) !== null && _c !== void 0 ? _c : (_b = task.payload) === null || _b === void 0 ? void 0 : _b.absolutePath) !== null && _d !== void 0 ? _d : "unknown";
|
|
341
342
|
(0, logger_1.debug)("pool", `${reason} killed task=${task.id} method=${task.method} file=${filePath}`);
|
|
342
343
|
const exitDetail = err
|
|
343
344
|
? `: ${err.message}`
|
|
@@ -360,7 +361,8 @@ class WorkerPool {
|
|
|
360
361
|
const worker = new ProcessWorker(this.modulePath, this.execArgv, this.embeddingEnvironment, config_1.MAX_WORKER_MEMORY_MB);
|
|
361
362
|
(0, logger_1.log)("pool", `spawn PID:${worker.child.pid} (${this.workers.length + 1}/${Math.max(1, config_1.CONFIG.WORKER_THREADS)})`);
|
|
362
363
|
const onMessage = (msg) => {
|
|
363
|
-
var _a, _b, _c, _d
|
|
364
|
+
var _a, _b, _c, _d;
|
|
365
|
+
var _e, _f, _g, _h;
|
|
364
366
|
if (typeof msg.rss === "number")
|
|
365
367
|
worker.lastRssBytes = msg.rss;
|
|
366
368
|
const task = this.tasks.get(msg.id);
|
|
@@ -380,7 +382,7 @@ class WorkerPool {
|
|
|
380
382
|
return;
|
|
381
383
|
}
|
|
382
384
|
if ("error" in msg) {
|
|
383
|
-
const filePath = (
|
|
385
|
+
const filePath = (_f = (_e = (_a = task.payload) === null || _a === void 0 ? void 0 : _a.path) !== null && _e !== void 0 ? _e : (_b = task.payload) === null || _b === void 0 ? void 0 : _b.absolutePath) !== null && _f !== void 0 ? _f : "unknown";
|
|
384
386
|
(0, logger_1.debug)("pool", `error task=${task.id} method=${task.method} file=${filePath}: ${msg.error}`);
|
|
385
387
|
task.reject(new Error(msg.error));
|
|
386
388
|
}
|
|
@@ -388,7 +390,7 @@ class WorkerPool {
|
|
|
388
390
|
const elapsed = task.startTime
|
|
389
391
|
? `${Date.now() - task.startTime}ms`
|
|
390
392
|
: "?ms";
|
|
391
|
-
const filePath = (_h = (
|
|
393
|
+
const filePath = (_h = (_g = (_c = task.payload) === null || _c === void 0 ? void 0 : _c.path) !== null && _g !== void 0 ? _g : (_d = task.payload) === null || _d === void 0 ? void 0 : _d.absolutePath) !== null && _h !== void 0 ? _h : "";
|
|
392
394
|
(0, logger_1.debug)("pool", `complete task=${task.id} method=${task.method} ${elapsed}${filePath ? ` file=${filePath}` : ""}`);
|
|
393
395
|
task.resolve(msg.result);
|
|
394
396
|
}
|
|
@@ -471,12 +473,13 @@ class WorkerPool {
|
|
|
471
473
|
});
|
|
472
474
|
}
|
|
473
475
|
handleTaskTimeout(task, worker, reason = "no progress") {
|
|
474
|
-
var _a, _b
|
|
476
|
+
var _a, _b;
|
|
477
|
+
var _c, _d;
|
|
475
478
|
if (this.destroyed || !this.tasks.has(task.id))
|
|
476
479
|
return;
|
|
477
480
|
this.clearTaskTimeout(task);
|
|
478
481
|
const limitMs = reason === "hard deadline" ? HARD_DEADLINE_MS : TASK_TIMEOUT_MS;
|
|
479
|
-
const filePath = (_d = (
|
|
482
|
+
const filePath = (_d = (_c = (_a = task.payload) === null || _a === void 0 ? void 0 : _a.path) !== null && _c !== void 0 ? _c : (_b = task.payload) === null || _b === void 0 ? void 0 : _b.absolutePath) !== null && _d !== void 0 ? _d : "unknown";
|
|
480
483
|
(0, logger_1.log)("pool", `timeout task=${task.id} method=${task.method} file=${filePath} (${reason}, ${limitMs}ms) — killing worker PID:${worker.child.pid}`);
|
|
481
484
|
this.completeTask(task, null);
|
|
482
485
|
task.reject(new Error(`Worker task ${task.method} exceeded ${reason} limit (${limitMs}ms) on ${filePath}`));
|
|
@@ -495,7 +498,8 @@ class WorkerPool {
|
|
|
495
498
|
this.dispatch();
|
|
496
499
|
}
|
|
497
500
|
dispatch() {
|
|
498
|
-
var _a, _b
|
|
501
|
+
var _a, _b;
|
|
502
|
+
var _c, _d, _e;
|
|
499
503
|
if (this.destroyed)
|
|
500
504
|
return;
|
|
501
505
|
let idle = this.workers.find((w) => !w.busy);
|
|
@@ -505,7 +509,7 @@ class WorkerPool {
|
|
|
505
509
|
const t = this.tasks.get(id);
|
|
506
510
|
return t && !t.worker;
|
|
507
511
|
});
|
|
508
|
-
const nextTaskId = (
|
|
512
|
+
const nextTaskId = (_c = findUnassigned(this.priorityQueue)) !== null && _c !== void 0 ? _c : findUnassigned(this.taskQueue);
|
|
509
513
|
if (nextTaskId === undefined) {
|
|
510
514
|
this.clearScaleUpTimer();
|
|
511
515
|
return;
|
|
@@ -544,7 +548,7 @@ class WorkerPool {
|
|
|
544
548
|
// Absolute deadline: never cleared/re-armed by heartbeats, so a task that
|
|
545
549
|
// keeps emitting progress but never completes is still bounded.
|
|
546
550
|
task.hardTimeout = setTimeout(() => this.handleTaskTimeout(task, idle, "hard deadline"), HARD_DEADLINE_MS);
|
|
547
|
-
const filePath = (_e = (
|
|
551
|
+
const filePath = (_e = (_d = (_a = task.payload) === null || _a === void 0 ? void 0 : _a.path) !== null && _d !== void 0 ? _d : (_b = task.payload) === null || _b === void 0 ? void 0 : _b.absolutePath) !== null && _e !== void 0 ? _e : "";
|
|
548
552
|
const busyCount = this.workers.filter((w) => w.busy).length;
|
|
549
553
|
(0, logger_1.debug)("pool", `dispatch task=${task.id} method=${task.method}${filePath ? ` file=${filePath}` : ""} → PID:${idle.child.pid} (busy=${busyCount}/${this.workers.length} queue=${this.taskQueue.length}+${this.priorityQueue.length}p)`);
|
|
550
554
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grepmax",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.34",
|
|
4
4
|
"author": "Robert Owens <78518764+reowens@users.noreply.github.com>",
|
|
5
5
|
"homepage": "https://github.com/reowens/grepmax",
|
|
6
6
|
"bugs": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"main": "dist/index.js",
|
|
14
14
|
"bin": {
|
|
15
|
-
"gmax": "dist/
|
|
15
|
+
"gmax": "dist/bin.js"
|
|
16
16
|
},
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">=22.12.0"
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"postinstall": "node scripts/postinstall.js",
|
|
22
22
|
"prebuild": "rm -rf dist tsconfig.tsbuildinfo && mkdir -p dist",
|
|
23
23
|
"build": "tsc",
|
|
24
|
-
"postbuild": "chmod +x dist/index.js",
|
|
25
|
-
"dev": "npx tsc && node dist/
|
|
24
|
+
"postbuild": "chmod +x dist/bin.js dist/index.js",
|
|
25
|
+
"dev": "npx tsc && node dist/bin.js",
|
|
26
26
|
"test": "vitest run",
|
|
27
27
|
"test:watch": "vitest",
|
|
28
28
|
"bench:recall": "npx tsx src/eval.ts",
|
|
@@ -103,9 +103,8 @@
|
|
|
103
103
|
"@types/node": "^26.6.1",
|
|
104
104
|
"@types/proper-lockfile": "^4.1.4",
|
|
105
105
|
"node-gyp": "^13.0.2",
|
|
106
|
-
"ts-node": "^10.9.2",
|
|
107
106
|
"tsx": "^4.23.13",
|
|
108
|
-
"typescript": "^
|
|
107
|
+
"typescript": "^7.0.2",
|
|
109
108
|
"vite": "^8.3.0",
|
|
110
109
|
"vitest": "^5.0.1"
|
|
111
110
|
}
|