magector 2.7.2 → 2.8.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magector",
3
- "version": "2.7.2",
3
+ "version": "2.8.1",
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.7.2",
37
- "@magector/cli-linux-x64": "2.7.2",
38
- "@magector/cli-linux-arm64": "2.7.2",
39
- "@magector/cli-win32-x64": "2.7.2"
36
+ "@magector/cli-darwin-arm64": "2.8.1",
37
+ "@magector/cli-linux-x64": "2.8.1",
38
+ "@magector/cli-linux-arm64": "2.8.1",
39
+ "@magector/cli-win32-x64": "2.8.1"
40
40
  },
41
41
  "keywords": [
42
42
  "magento",
package/src/cli.js CHANGED
File without changes
package/src/mcp-server.js CHANGED
@@ -4043,11 +4043,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
4043
4043
  const reqStart = Date.now();
4044
4044
  logToFile('REQ', `${name}(${JSON.stringify(args || {})})`);
4045
4045
 
4046
- // ── Warmup guard: index compatibility check or serve process still loading ──
4046
+ // ── Warmup guard: only block if no DB exists at all (nothing to search) ──
4047
+ // Tools with filesystem fallback work without the serve process, so we
4048
+ // don't block them during warmup. Only block if the DB doesn't exist.
4047
4049
  const indexFreeTools = ['magento_stats', 'magento_analyze_diff', 'magento_complexity',
4048
4050
  'magento_trace_dependency', 'magento_error_parser', 'magento_find_layout',
4049
4051
  'magento_impact_analysis', 'magento_find_event_flow', 'magento_find_test',
4050
- 'magento_trace_data_flow', 'magento_find_event_dispatchers'];
4052
+ 'magento_trace_data_flow', 'magento_find_event_dispatchers',
4053
+ // These tools have filesystem/di.xml fallbacks — work without serve process
4054
+ 'magento_find_class', 'magento_find_method', 'magento_find_plugin',
4055
+ 'magento_find_observer', 'magento_find_di_wiring', 'magento_module_structure',
4056
+ 'magento_batch', 'magento_find_config', 'magento_find_callers'];
4051
4057
  if (warmupInProgress && !indexFreeTools.includes(name)) {
4052
4058
  logToFile('REQ', `${name} → blocked (warmup: loading index)`);
4053
4059
  return {
@@ -5960,8 +5966,9 @@ async function main() {
5960
5966
  logToFile('WARN', `Serve process version mismatch: ${staleVersion} vs ${__pkg.version} — killing stale process`);
5961
5967
  console.error(`Killing stale serve process (version ${staleVersion}, current ${__pkg.version})`);
5962
5968
  killStaleServeProcess();
5963
- // Remove stale socket so we don't connect to it
5969
+ // Remove stale socket and lock so we don't connect to dead process
5964
5970
  try { if (existsSync(SOCK_PATH)) unlinkSync(SOCK_PATH); } catch {}
5971
+ releasePrimaryLock();
5965
5972
  }
5966
5973
 
5967
5974
  const connected = await tryConnectSocket();
@@ -5972,47 +5979,53 @@ async function main() {
5972
5979
  role = 'primary';
5973
5980
  logToFile('INFO', 'Acquired primary lock — this instance owns the serve process');
5974
5981
 
5975
- // Check DB format (uses cache instant if already validated)
5976
- if (existsSync(config.dbPath)) {
5977
- if (!(await checkDbFormat())) {
5978
- logToFile('WARN', 'Database format incompatible — scheduling background re-index');
5979
- startBackgroundReindex();
5980
- } else {
5981
- logToFile('INFO', 'Existing database is compatible — reusing index');
5982
- }
5983
- } else if (config.magentoRoot && existsSync(config.magentoRoot)) {
5984
- logToFile('INFO', 'No index database found — scheduling background index');
5985
- startBackgroundReindex();
5986
- }
5987
-
5988
- const canStartServe = !reindexInProgress || (existsSync(config.dbPath) && (() => { try { return statSync(config.dbPath).size > 100; } catch { return false; } })());
5989
- if (canStartServe) {
5982
+ // Start serve process in background don't block tool availability
5983
+ // Tools with filesystem fallbacks work immediately via execFileSync.
5984
+ // Serve process provides faster search once ready.
5985
+ (async () => {
5990
5986
  try {
5991
- startServeProcess();
5992
- if (serveReadyPromise) {
5993
- const ready = await Promise.race([
5994
- serveReadyPromise,
5995
- new Promise(r => setTimeout(() => r(false), 60000))
5996
- ]);
5997
- if (ready) {
5998
- logToFile('INFO', 'Serve process ready (primary)');
5999
- console.error('Serve process ready (primary)');
6000
- startSocketProxy();
5987
+ // Check DB format (uses cache → instant if already validated)
5988
+ if (existsSync(config.dbPath)) {
5989
+ if (!(await checkDbFormat())) {
5990
+ logToFile('WARN', 'Database format incompatible — scheduling background re-index');
5991
+ startBackgroundReindex();
6001
5992
  } else {
6002
- logToFile('WARN', 'Serve process not ready in time, will use fallback');
6003
- console.error('Serve process not ready in time, will use fallback');
5993
+ logToFile('INFO', 'Existing database is compatible reusing index');
5994
+ }
5995
+ } else if (config.magentoRoot && existsSync(config.magentoRoot)) {
5996
+ logToFile('INFO', 'No index database found — scheduling background index');
5997
+ startBackgroundReindex();
5998
+ }
5999
+
6000
+ const canStartServe = !reindexInProgress || (existsSync(config.dbPath) && (() => { try { return statSync(config.dbPath).size > 100; } catch { return false; } })());
6001
+ if (canStartServe) {
6002
+ startServeProcess();
6003
+ if (serveReadyPromise) {
6004
+ const ready = await Promise.race([
6005
+ serveReadyPromise,
6006
+ new Promise(r => setTimeout(() => r(false), 60000))
6007
+ ]);
6008
+ if (ready) {
6009
+ logToFile('INFO', 'Serve process ready (primary)');
6010
+ console.error('Serve process ready (primary)');
6011
+ startSocketProxy();
6012
+ } else {
6013
+ logToFile('WARN', 'Serve process not ready in time, will use fallback');
6014
+ console.error('Serve process not ready in time, will use fallback');
6015
+ }
6004
6016
  }
6005
6017
  }
6006
6018
  } catch {
6007
6019
  // Non-fatal: falls back to execFileSync per query
6008
6020
  }
6009
- }
6021
+ })();
6010
6022
  } else {
6011
- // Another instance is starting up — wait for its socket to appear
6012
- logToFile('INFO', 'Another instance is primary — waiting for socket...');
6013
- console.error('Waiting for primary instance to start serve process...');
6014
- for (let i = 0; i < 12; i++) { // wait up to 60s
6015
- await new Promise(r => setTimeout(r, 5000));
6023
+ // Another instance is starting up — try socket briefly, then fall through
6024
+ logToFile('INFO', 'Another instance is primary — trying socket...');
6025
+ console.error('Trying to join existing serve process...');
6026
+ // Quick check: 3 attempts at 2s intervals (6s max), then give up and use fallback
6027
+ for (let i = 0; i < 3; i++) {
6028
+ await new Promise(r => setTimeout(r, 2000));
6016
6029
  if (await tryConnectSocket()) {
6017
6030
  logToFile('INFO', 'Connected to socket after waiting (secondary)');
6018
6031
  console.error('Joined existing serve process (secondary)');
@@ -6020,15 +6033,21 @@ async function main() {
6020
6033
  }
6021
6034
  }
6022
6035
  if (!globalServeQuery) {
6023
- logToFile('WARN', 'Socket not available after waiting using cold-start fallback');
6036
+ logToFile('INFO', 'Socket not available tools will use cold-start fallback');
6024
6037
  }
6025
6038
  }
6026
6039
 
6027
- await loadDescriptions();
6028
- } finally {
6040
+ // Mark tools as available ASAP — filesystem fallbacks work without serve process
6029
6041
  warmupInProgress = false;
6030
- logToFile('INFO', 'Warmup complete all tools available');
6042
+ logToFile('INFO', 'Tools available (serve process loading in background)');
6031
6043
  console.error('Warmup complete — all tools available');
6044
+
6045
+ // Load descriptions in background (non-blocking)
6046
+ loadDescriptions().catch(() => {});
6047
+ } catch (err) {
6048
+ warmupInProgress = false;
6049
+ logToFile('WARN', `Startup error (tools still available via fallback): ${err.message}`);
6050
+ console.error('Warmup complete — all tools available (with fallbacks)');
6032
6051
  }
6033
6052
  }
6034
6053