magector 2.16.2 → 2.16.4
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/package.json +5 -5
- package/src/mcp-server.js +56 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magector",
|
|
3
|
-
"version": "2.16.
|
|
3
|
+
"version": "2.16.4",
|
|
4
4
|
"description": "Semantic code search for Magento 2 — index, search, MCP server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/mcp-server.js",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"ruvector": "^0.1.96"
|
|
34
34
|
},
|
|
35
35
|
"optionalDependencies": {
|
|
36
|
-
"@magector/cli-darwin-arm64": "2.16.
|
|
37
|
-
"@magector/cli-linux-x64": "2.16.
|
|
38
|
-
"@magector/cli-linux-arm64": "2.16.
|
|
39
|
-
"@magector/cli-win32-x64": "2.16.
|
|
36
|
+
"@magector/cli-darwin-arm64": "2.16.4",
|
|
37
|
+
"@magector/cli-linux-x64": "2.16.4",
|
|
38
|
+
"@magector/cli-linux-arm64": "2.16.4",
|
|
39
|
+
"@magector/cli-win32-x64": "2.16.4"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
|
42
42
|
"magento",
|
package/src/mcp-server.js
CHANGED
|
@@ -817,6 +817,8 @@ function startServeProcess() {
|
|
|
817
817
|
// First line is ready signal
|
|
818
818
|
if (parsed.ready) {
|
|
819
819
|
serveReady = true;
|
|
820
|
+
// Clear stale cache entries — they may contain [] from when index was unavailable
|
|
821
|
+
searchCache.clear();
|
|
820
822
|
logToFile('INFO', `Serve process ready (PID ${proc.pid})`);
|
|
821
823
|
if (serveReadyResolve) { serveReadyResolve(true); serveReadyResolve = null; }
|
|
822
824
|
// Now that serve is up, persist primary lock state to data.db
|
|
@@ -952,6 +954,7 @@ function tryConnectSocket() {
|
|
|
952
954
|
|
|
953
955
|
isSocketClient = true;
|
|
954
956
|
serveReady = true;
|
|
957
|
+
searchCache.clear(); // clear stale [] entries from before socket was available
|
|
955
958
|
logToFile('INFO', 'Connected to existing serve process via socket proxy');
|
|
956
959
|
resolve(true);
|
|
957
960
|
});
|
|
@@ -997,6 +1000,15 @@ async function rustSearchAsync(query, limit = 10) {
|
|
|
997
1000
|
await Promise.race([serveReadyPromise, new Promise(r => setTimeout(() => r(false), 10000))]);
|
|
998
1001
|
}
|
|
999
1002
|
|
|
1003
|
+
// Secondary instance: retry socket if not connected (primary may have (re)started serve)
|
|
1004
|
+
if (!serveProcess && !globalServeQuery) {
|
|
1005
|
+
const reconnected = await tryConnectSocket();
|
|
1006
|
+
if (reconnected) {
|
|
1007
|
+
logToFile('INFO', 'rustSearchAsync: reconnected to serve socket');
|
|
1008
|
+
searchCache.clear(); // clear stale empty results before using new serve
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1000
1012
|
// Try socket proxy (secondary instance) or local serve process (primary)
|
|
1001
1013
|
const queryFn = globalServeQuery || ((serveProcess && serveReady) ? serveQuery : null);
|
|
1002
1014
|
if (queryFn) {
|
|
@@ -4492,41 +4504,54 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
4492
4504
|
* Returns null when not re-indexing.
|
|
4493
4505
|
*/
|
|
4494
4506
|
function getReindexWarning() {
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4507
|
+
// Primary instance: use in-memory state (accurate phase + ETA)
|
|
4508
|
+
if (reindexInProgress && reindexStartTime) {
|
|
4509
|
+
const elapsedSec = Math.round((Date.now() - reindexStartTime) / 1000);
|
|
4510
|
+
const elapsedStr = elapsedSec >= 60
|
|
4511
|
+
? `${Math.floor(elapsedSec / 60)}m ${elapsedSec % 60}s`
|
|
4512
|
+
: `${elapsedSec}s`;
|
|
4513
|
+
|
|
4514
|
+
let phaseStr, etaStr;
|
|
4515
|
+
if (reindexPhase <= 0) {
|
|
4516
|
+
phaseStr = 'initializing';
|
|
4517
|
+
etaStr = 'est. ~40–70 min total';
|
|
4518
|
+
} else if (reindexPhase === 1) {
|
|
4519
|
+
const filesStr = reindexTotalFiles > 0 ? ` (${reindexTotalFiles.toLocaleString('en')} files)` : '';
|
|
4520
|
+
phaseStr = `phase 1/3: AST parsing${filesStr}`;
|
|
4521
|
+
etaStr = 'est. ~1–3 min for this phase, then ~40–60 min for embeddings';
|
|
4522
|
+
} else if (reindexPhase === 2) {
|
|
4523
|
+
const itemsStr = reindexItemsToEmbed > 0 ? ` (${reindexItemsToEmbed.toLocaleString('en')} items)` : '';
|
|
4524
|
+
phaseStr = `phase 2/3: generating embeddings${itemsStr}`;
|
|
4525
|
+
if (reindexPhase2Start && reindexItemsToEmbed > 0) {
|
|
4526
|
+
// Empirical rate: ~87k items ≈ 45 min on 8-core ONNX. Scale linearly.
|
|
4527
|
+
const estimatedTotalSec = Math.round((reindexItemsToEmbed / 87000) * 45 * 60);
|
|
4528
|
+
const phase2Elapsed = (Date.now() - reindexPhase2Start) / 1000;
|
|
4529
|
+
const remainingSec = Math.max(estimatedTotalSec - phase2Elapsed, 0);
|
|
4530
|
+
etaStr = remainingSec > 60
|
|
4531
|
+
? `est. ~${Math.round(remainingSec / 60)} min remaining`
|
|
4532
|
+
: 'almost done with embeddings';
|
|
4533
|
+
} else {
|
|
4534
|
+
etaStr = 'est. 30–60 min for this phase';
|
|
4535
|
+
}
|
|
4520
4536
|
} else {
|
|
4521
|
-
|
|
4537
|
+
phaseStr = 'phase 3/3: building HNSW vector index';
|
|
4538
|
+
etaStr = 'est. ~5–10 min remaining';
|
|
4522
4539
|
}
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4540
|
+
|
|
4541
|
+
return `> ⏳ **Re-indexing in progress** — ${elapsedStr} elapsed, ${phaseStr}. ${etaStr}.\n` +
|
|
4542
|
+
`> Results below use the **previous index** — valid, but may miss recently added files.\n\n`;
|
|
4526
4543
|
}
|
|
4527
4544
|
|
|
4528
|
-
|
|
4529
|
-
|
|
4545
|
+
// Secondary instance: detect via PID file (no phase info available)
|
|
4546
|
+
try {
|
|
4547
|
+
const externalPid = getRunningReindexPid();
|
|
4548
|
+
if (externalPid) {
|
|
4549
|
+
return `> ⏳ **Re-indexing in progress** (PID ${externalPid}) — semantic search may return empty results until complete.\n` +
|
|
4550
|
+
`> Grep and filesystem-based tools work normally. Check \`.magector/magector.log\` for progress.\n\n`;
|
|
4551
|
+
}
|
|
4552
|
+
} catch { /* ignore */ }
|
|
4553
|
+
|
|
4554
|
+
return null;
|
|
4530
4555
|
}
|
|
4531
4556
|
|
|
4532
4557
|
const _callToolHandler = async (request) => {
|