grepmax 0.18.1 → 0.20.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.
Files changed (78) hide show
  1. package/.claude-plugin/marketplace.json +23 -0
  2. package/README.md +28 -3
  3. package/dist/commands/add.js +4 -2
  4. package/dist/commands/claude-code.js +1 -1
  5. package/dist/commands/codex.js +3 -1
  6. package/dist/commands/context.js +1 -1
  7. package/dist/commands/dead.js +2 -6
  8. package/dist/commands/doctor.js +26 -7
  9. package/dist/commands/extract.js +3 -5
  10. package/dist/commands/impact.js +6 -4
  11. package/dist/commands/index.js +7 -2
  12. package/dist/commands/log.js +4 -2
  13. package/dist/commands/mcp.js +594 -722
  14. package/dist/commands/peek.js +15 -9
  15. package/dist/commands/plugin.js +36 -22
  16. package/dist/commands/project.js +16 -6
  17. package/dist/commands/related.js +8 -9
  18. package/dist/commands/remove.js +9 -2
  19. package/dist/commands/review.js +1 -1
  20. package/dist/commands/setup.js +4 -2
  21. package/dist/commands/similar.js +4 -4
  22. package/dist/commands/status.js +6 -4
  23. package/dist/commands/summarize.js +6 -4
  24. package/dist/commands/symbols.js +1 -1
  25. package/dist/commands/test-find.js +2 -2
  26. package/dist/commands/trace.js +12 -5
  27. package/dist/commands/watch.js +33 -9
  28. package/dist/eval-graph-nav.js +4 -1
  29. package/dist/eval-graph-recovery-probe.js +56 -14
  30. package/dist/eval-graph-spotcheck.js +10 -2
  31. package/dist/eval-graph-totals.js +5 -2
  32. package/dist/eval-oss.js +212 -37
  33. package/dist/eval-seed.js +13 -4
  34. package/dist/index.js +9 -9
  35. package/dist/lib/daemon/daemon.js +32 -13
  36. package/dist/lib/daemon/ipc-handler.js +24 -5
  37. package/dist/lib/daemon/mlx-server-manager.js +11 -3
  38. package/dist/lib/daemon/process-manager.js +1 -2
  39. package/dist/lib/daemon/watcher-manager.js +22 -6
  40. package/dist/lib/graph/callsites.js +151 -25
  41. package/dist/lib/graph/graph-builder.js +2 -2
  42. package/dist/lib/graph/impact.js +6 -6
  43. package/dist/lib/index/batch-processor.js +16 -6
  44. package/dist/lib/index/chunker.js +2 -0
  45. package/dist/lib/index/syncer.js +22 -10
  46. package/dist/lib/index/watcher-batch.js +10 -1
  47. package/dist/lib/llm/config.js +2 -1
  48. package/dist/lib/llm/diff.js +56 -11
  49. package/dist/lib/llm/investigate.js +52 -11
  50. package/dist/lib/llm/review.js +21 -8
  51. package/dist/lib/llm/server.js +25 -9
  52. package/dist/lib/llm/tools.js +1 -1
  53. package/dist/lib/output/agent-search-formatter.js +25 -3
  54. package/dist/lib/output/index-state-footer.js +1 -1
  55. package/dist/lib/review/risk.js +2 -4
  56. package/dist/lib/search/pagerank.js +1 -1
  57. package/dist/lib/search/searcher.js +43 -17
  58. package/dist/lib/search/seed-weight.js +4 -1
  59. package/dist/lib/skeleton/symbol-extractor.js +2 -1
  60. package/dist/lib/store/vector-db.js +21 -10
  61. package/dist/lib/utils/cross-project.js +5 -1
  62. package/dist/lib/utils/daemon-client.js +39 -1
  63. package/dist/lib/utils/filter-builder.js +22 -0
  64. package/dist/lib/utils/git.js +10 -2
  65. package/dist/lib/utils/project-registry.js +3 -2
  66. package/dist/lib/utils/scope-filter.js +6 -6
  67. package/dist/lib/utils/watcher-launcher.js +4 -1
  68. package/dist/lib/utils/watcher-store.js +2 -1
  69. package/dist/lib/workers/embeddings/granite.js +4 -1
  70. package/dist/lib/workers/embeddings/mlx-client.js +7 -2
  71. package/dist/lib/workers/pool.js +30 -7
  72. package/dist/lib/workers/process-child.js +1 -1
  73. package/package.json +23 -19
  74. package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
  75. package/plugins/grepmax/hooks/cwd-changed.js +4 -1
  76. package/plugins/grepmax/hooks/pre-grep.js +2 -1
  77. package/plugins/grepmax/hooks/start.js +45 -10
  78. package/plugins/grepmax/hooks/subagent-start.js +1 -4
@@ -60,8 +60,8 @@ const path = __importStar(require("node:path"));
60
60
  const config_1 = require("./config");
61
61
  const vector_db_1 = require("./lib/store/vector-db");
62
62
  const exit_1 = require("./lib/utils/exit");
63
- const pool_1 = require("./lib/workers/pool");
64
63
  const filter_builder_1 = require("./lib/utils/filter-builder");
64
+ const pool_1 = require("./lib/workers/pool");
65
65
  const PLATFORM_ROOT = path.join((_b = process.env.HOME) !== null && _b !== void 0 ? _b : "", "Development/beyond/platform");
66
66
  const PRE_K = 500;
67
67
  const STAGE1_K = 200;
@@ -89,7 +89,9 @@ function toStrArr(val) {
89
89
  if (typeof m.toArray === "function") {
90
90
  try {
91
91
  const a = m.toArray();
92
- return Array.isArray(a) ? a.filter((v) => typeof v === "string") : [];
92
+ return Array.isArray(a)
93
+ ? a.filter((v) => typeof v === "string")
94
+ : [];
93
95
  }
94
96
  catch (_a) {
95
97
  return [];
@@ -101,22 +103,50 @@ function probe(table, sym, expectedFile) {
101
103
  return __awaiter(this, void 0, void 0, function* () {
102
104
  const pool = (0, pool_1.getWorkerPool)();
103
105
  const { dense } = yield pool.encodeQuery(sym);
104
- const prefix = PLATFORM_ROOT.endsWith("/") ? PLATFORM_ROOT : `${PLATFORM_ROOT}/`;
106
+ const prefix = PLATFORM_ROOT.endsWith("/")
107
+ ? PLATFORM_ROOT
108
+ : `${PLATFORM_ROOT}/`;
105
109
  const where = `path LIKE '${(0, filter_builder_1.escapeSqlString)(prefix)}%'`;
106
- const columns = ["id", "path", "chunk_index", "defined_symbols", "referenced_symbols"];
107
- const vectorRows = (yield table.vectorSearch(dense).select([...columns, "_distance"]).where(where).limit(PRE_K).toArray());
110
+ const columns = [
111
+ "id",
112
+ "path",
113
+ "chunk_index",
114
+ "defined_symbols",
115
+ "referenced_symbols",
116
+ ];
117
+ const vectorRows = (yield table
118
+ .vectorSearch(dense)
119
+ .select([...columns, "_distance"])
120
+ .where(where)
121
+ .limit(PRE_K)
122
+ .toArray());
108
123
  let ftsRows = [];
109
124
  try {
110
- ftsRows = (yield table.search(sym).select([...columns, "_score"]).where(where).limit(PRE_K).toArray());
125
+ ftsRows = (yield table
126
+ .search(sym)
127
+ .select([...columns, "_score"])
128
+ .where(where)
129
+ .limit(PRE_K)
130
+ .toArray());
111
131
  }
112
132
  catch (_a) { }
113
133
  const scores = new Map();
114
134
  const docMap = new Map();
115
135
  const keyOf = (d) => d.id || `${d.path}:${d.chunk_index}`;
116
- vectorRows.forEach((d, r) => { const k = keyOf(d); docMap.set(k, d); scores.set(k, (scores.get(k) || 0) + 1 / (RRF_K + r + 1)); });
117
- ftsRows.forEach((d, r) => { const k = keyOf(d); if (!docMap.has(k))
118
- docMap.set(k, d); scores.set(k, (scores.get(k) || 0) + 1 / (RRF_K + r + 1)); });
119
- const fusedKeys = Array.from(scores.entries()).sort((a, b) => b[1] - a[1]).map(([k]) => k);
136
+ vectorRows.forEach((d, r) => {
137
+ const k = keyOf(d);
138
+ docMap.set(k, d);
139
+ scores.set(k, (scores.get(k) || 0) + 1 / (RRF_K + r + 1));
140
+ });
141
+ ftsRows.forEach((d, r) => {
142
+ const k = keyOf(d);
143
+ if (!docMap.has(k))
144
+ docMap.set(k, d);
145
+ scores.set(k, (scores.get(k) || 0) + 1 / (RRF_K + r + 1));
146
+ });
147
+ const fusedKeys = Array.from(scores.entries())
148
+ .sort((a, b) => b[1] - a[1])
149
+ .map(([k]) => k);
120
150
  const fused = fusedKeys.map((k) => docMap.get(k));
121
151
  // Locate the expected definition chunk among retrieved rows.
122
152
  const isExpected = (d) => String(d.path).toLowerCase().endsWith(`/${expectedFile.toLowerCase()}`) &&
@@ -134,7 +164,12 @@ function probe(table, sym, expectedFile) {
134
164
  // If not in the union, query directly to confirm it exists in the index.
135
165
  let defExistsInIndex = defInUnion;
136
166
  if (!defInUnion) {
137
- const direct = (yield table.query().select(columns).where(`${where} AND array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(sym)}')`).limit(50).toArray());
167
+ const direct = (yield table
168
+ .query()
169
+ .select(columns)
170
+ .where(`${where} AND array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(sym)}')`)
171
+ .limit(50)
172
+ .toArray());
138
173
  defExistsInIndex = direct.some((d) => String(d.path).toLowerCase().endsWith(`/${expectedFile.toLowerCase()}`));
139
174
  }
140
175
  // ref->def reachability: among top-SEED_K fusion seeds, how many reference `sym`?
@@ -149,8 +184,12 @@ function probe(table, sym, expectedFile) {
149
184
  }
150
185
  });
151
186
  const loc = defRetrievalRank > 0
152
- ? (defInPool ? `pool#${defRetrievalRank}` : `union#${defRetrievalRank}(>200)`)
153
- : (defExistsInIndex ? "OUTSIDE-500" : "NOT-IN-INDEX?");
187
+ ? defInPool
188
+ ? `pool#${defRetrievalRank}`
189
+ : `union#${defRetrievalRank}(>200)`
190
+ : defExistsInIndex
191
+ ? "OUTSIDE-500"
192
+ : "NOT-IN-INDEX?";
154
193
  return { sym, expectedFile, loc, seedsRefSym, firstRefSeedRank };
155
194
  });
156
195
  }
@@ -167,4 +206,7 @@ function main() {
167
206
  yield (0, exit_1.gracefulExit)(0);
168
207
  });
169
208
  }
170
- main().catch((e) => { console.error(e); process.exit(1); });
209
+ main().catch((e) => {
210
+ console.error(e);
211
+ process.exit(1);
212
+ });
@@ -37,7 +37,9 @@ function toStrArr(v) {
37
37
  if (typeof m.toArray === "function") {
38
38
  try {
39
39
  const a = m.toArray();
40
- return Array.isArray(a) ? a.filter((x) => typeof x === "string") : [];
40
+ return Array.isArray(a)
41
+ ? a.filter((x) => typeof x === "string")
42
+ : [];
41
43
  }
42
44
  catch (_a) {
43
45
  return [];
@@ -53,7 +55,13 @@ function main() {
53
55
  console.log(`\n── ${file}`);
54
56
  const rows = (yield table
55
57
  .query()
56
- .select(["start_line", "end_line", "chunk_type", "defined_symbols", "referenced_symbols"])
58
+ .select([
59
+ "start_line",
60
+ "end_line",
61
+ "chunk_type",
62
+ "defined_symbols",
63
+ "referenced_symbols",
64
+ ])
57
65
  .where(`path = '${(0, filter_builder_1.escapeSqlString)(file)}'`)
58
66
  .limit(20)
59
67
  .toArray());
@@ -69,7 +69,9 @@ function main() {
69
69
  return __awaiter(this, void 0, void 0, function* () {
70
70
  const db = new vector_db_1.VectorDB(config_1.PATHS.lancedbDir);
71
71
  const table = yield db.ensureTable();
72
- const pathPrefix = PLATFORM_ROOT.endsWith("/") ? PLATFORM_ROOT : `${PLATFORM_ROOT}/`;
72
+ const pathPrefix = PLATFORM_ROOT.endsWith("/")
73
+ ? PLATFORM_ROOT
74
+ : `${PLATFORM_ROOT}/`;
73
75
  const scope = `path LIKE '${(0, filter_builder_1.escapeSqlString)(pathPrefix)}%'`;
74
76
  console.log(`Platform graph density check — pathPrefix=${PLATFORM_ROOT}\n`);
75
77
  for (const sym of TARGETS) {
@@ -103,7 +105,8 @@ function main() {
103
105
  let arr = [];
104
106
  if (Array.isArray(raw))
105
107
  arr = raw.filter((v) => typeof v === "string");
106
- else if (raw && typeof raw.toArray === "function") {
108
+ else if (raw &&
109
+ typeof raw.toArray === "function") {
107
110
  try {
108
111
  const a = raw.toArray();
109
112
  if (Array.isArray(a))
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
- { id: "ex-p1-01", query: "createApplication", expectedFile: "lib/express.js", expectedLine: 37 },
73
- { id: "ex-p1-02", query: "Route", expectedFile: "lib/router/route.js", expectedLine: 43 },
74
- { id: "ex-p1-03", query: "Layer", expectedFile: "lib/router/layer.js", expectedLine: 33 },
75
- { id: "ex-p1-04", query: "View", expectedFile: "lib/view.js", expectedLine: 52 },
76
- { id: "ex-p1-05", query: "query", expectedFile: "lib/express.js", expectedLine: 79, note: "re-export site — middleware/query.js doesn't match the function-decl patterns" },
77
- { id: "ex-p1-06", query: "init", expectedFile: "lib/middleware/init.js", expectedLine: 28 },
78
- { id: "ex-p1-07", query: "acceptParams", expectedFile: "lib/utils.js", expectedLine: 126 },
79
- { id: "ex-p1-08", query: "stringify", expectedFile: "lib/response.js", expectedLine: 1155 },
80
- { id: "ex-p1-09", query: "compileETag", expectedFile: "lib/utils.js", expectedLine: 150 },
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
- { id: "ld-p1-01", query: "map", expectedFile: "lodash.js", expectedLine: 9620 },
88
- { id: "ld-p1-02", query: "filter", expectedFile: "lodash.js", expectedLine: 9239 },
89
- { id: "ld-p1-03", query: "reduce", expectedFile: "lodash.js", expectedLine: 9745 },
90
- { id: "ld-p1-04", query: "debounce", expectedFile: "lodash.js", expectedLine: 10372 },
91
- { id: "ld-p1-05", query: "throttle", expectedFile: "lodash.js", expectedLine: 10965 },
92
- { id: "ld-p1-06", query: "merge", expectedFile: "lodash.js", expectedLine: 13505, note: "var merge = createAssigner(...) binding site, not the re-export at 16689" },
93
- { id: "ld-p1-07", query: "cloneDeep", expectedFile: "lodash.js", expectedLine: 11155 },
94
- { id: "ld-p1-08", query: "get", expectedFile: "lodash.js", expectedLine: 13194 },
95
- { id: "ld-p1-09", query: "set", expectedFile: "lodash.js", expectedLine: 13741 },
96
- { id: "ld-p1-10", query: "chunk", expectedFile: "lodash.js", expectedLine: 6903 },
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
- { id: "pf-p1-01", query: "formatCents", expectedFile: "packages/shared/src/format.ts", expectedLine: 8 },
104
- { id: "pf-p1-02", query: "formatTimeAgo", expectedFile: "packages/shared/src/format.ts", expectedLine: 44 },
105
- { id: "pf-p1-03", query: "BeyondError", expectedFile: "packages/shared/src/errors.ts", expectedLine: 37 },
106
- { id: "pf-p1-04", query: "ErrorCodes", expectedFile: "packages/shared/src/errors.ts", expectedLine: 5 },
107
- { id: "pf-p1-05", query: "createDb", expectedFile: "packages/db/src/index.ts", expectedLine: 42 },
108
- { id: "pf-p1-06", query: "createDbAsync", expectedFile: "packages/db/src/index.ts", expectedLine: 50 },
109
- { id: "pf-p1-07", query: "authMiddleware", expectedFile: "packages/api/src/middleware/auth.ts", expectedLine: 39 },
110
- { id: "pf-p1-08", query: "requireAuth", expectedFile: "packages/api/src/middleware/auth.ts", expectedLine: 45 },
111
- { id: "pf-p1-09", query: "resolveActor", expectedFile: "packages/api/src/middleware/auth.ts", expectedLine: 71 },
112
- { id: "pf-p1-10", query: "getActor", expectedFile: "packages/api/src/middleware/auth.ts", expectedLine: 1136 },
113
- { id: "pf-p1-11", query: "rateLimit", expectedFile: "packages/api/src/middleware/rate-limit.ts", expectedLine: 94 },
114
- { id: "pf-p1-12", query: "checkRateLimitKey", expectedFile: "packages/api/src/middleware/rate-limit.ts", expectedLine: 158 },
115
- { id: "pf-p1-13", query: "errorHandler", expectedFile: "packages/api/src/middleware/error.ts", expectedLine: 128 },
116
- { id: "pf-p1-14", query: "activityTracker", expectedFile: "packages/api/src/middleware/activity-tracker.ts", expectedLine: 17 },
117
- { id: "pf-p1-15", query: "initializeApp", expectedFile: "packages/api/src/app.ts", expectedLine: 68 },
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()}`) && !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("/") ? ds.projectRoot : `${ds.projectRoot}/`;
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: { total: byKind("route").length, pass: byKind("route").filter((r) => r.pass).length },
254
- recover: { total: byKind("recover").length, pass: byKind("recover").filter((r) => r.pass).length },
255
- guard: { total: byKind("guard").length, pass: byKind("guard").filter((r) => r.pass).length },
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 search_handler_1 = require("./search-handler");
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 server_1 = require("../llm/server");
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
@@ -116,6 +116,10 @@ class Daemon {
116
116
  this.heartbeatTick = 0;
117
117
  this.shuttingDown = false;
118
118
  this.recycling = false;
119
+ // False until LanceDB + MetaCache are open. The socket starts listening early
120
+ // (so liveness probes succeed during slow init), so commands that need those
121
+ // resources must be gated on this to avoid hitting null stores mid-startup.
122
+ this.ready = false;
119
123
  this.processManager = new process_manager_1.ProcessManager({
120
124
  getShuttingDown: () => this.shuttingDown,
121
125
  });
@@ -128,8 +132,12 @@ class Daemon {
128
132
  getVectorDb: () => this.vectorDb,
129
133
  getMetaCache: () => this.metaCache,
130
134
  getShuttingDown: () => this.shuttingDown,
131
- touchActivity: () => { this.lastActivity = Date.now(); },
132
- evictSearcher: (root) => { this.searchers.delete(root); },
135
+ touchActivity: () => {
136
+ this.lastActivity = Date.now();
137
+ },
138
+ evictSearcher: (root) => {
139
+ this.searchers.delete(root);
140
+ },
133
141
  });
134
142
  this.projectLocks = new Map();
135
143
  // Full-index progress per root while initialSync runs (--reset / initial
@@ -249,6 +257,8 @@ class Daemon {
249
257
  this.vectorDb.startMaintenanceLoop();
250
258
  console.log("[daemon] Opening MetaCache:", config_1.PATHS.lmdbPath);
251
259
  this.metaCache = new meta_cache_1.MetaCache(config_1.PATHS.lmdbPath);
260
+ // Resources are open — only now may resource-dependent IPC commands run.
261
+ this.ready = true;
252
262
  }
253
263
  catch (err) {
254
264
  console.error("[daemon] Failed to open shared resources:", err);
@@ -285,7 +295,8 @@ class Daemon {
285
295
  // Re-check shuttingDown each iteration: shutdown's pendingLocks drain is a
286
296
  // snapshot, so a new project op kicked off after the snapshot would race
287
297
  // with vectorDb.close() and fail with "VectorDB connection is closed".
288
- const pending = allProjects.filter((p) => (p.status === "pending" || p.status === "error") && fs.existsSync(p.root));
298
+ const pending = allProjects.filter((p) => (p.status === "pending" || p.status === "error") &&
299
+ fs.existsSync(p.root));
289
300
  void (() => __awaiter(this, void 0, void 0, function* () {
290
301
  for (const p of pending) {
291
302
  if (this.shuttingDown)
@@ -403,7 +414,9 @@ class Daemon {
403
414
  projectRoot: root,
404
415
  vectorDb: this.vectorDb,
405
416
  metaCache: this.metaCache,
406
- onProgress: () => { this.resetActivity(); },
417
+ onProgress: () => {
418
+ this.resetActivity();
419
+ },
407
420
  });
408
421
  const proj = (0, project_registry_1.getProject)(root);
409
422
  if (proj) {
@@ -492,6 +505,10 @@ class Daemon {
492
505
  uptime() {
493
506
  return Math.floor((Date.now() - this.startTime) / 1000);
494
507
  }
508
+ /** True once shared resources (LanceDB + MetaCache) are open. */
509
+ isReady() {
510
+ return this.ready;
511
+ }
495
512
  getDiskPressure() {
496
513
  var _a, _b;
497
514
  return (_b = (_a = this.vectorDb) === null || _a === void 0 ? void 0 : _a.diskPressure) !== null && _b !== void 0 ? _b : "unknown";
@@ -506,7 +523,9 @@ class Daemon {
506
523
  var _a;
507
524
  const prev = (_a = this.projectLocks.get(root)) !== null && _a !== void 0 ? _a : Promise.resolve();
508
525
  let release;
509
- const next = new Promise((r) => { release = r; });
526
+ const next = new Promise((r) => {
527
+ release = r;
528
+ });
510
529
  this.projectLocks.set(root, next);
511
530
  yield prev;
512
531
  try {