magector 2.16.10 → 2.16.12

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 (2) hide show
  1. package/package.json +5 -5
  2. package/src/mcp-server.js +76 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magector",
3
- "version": "2.16.10",
3
+ "version": "2.16.12",
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.10",
37
- "@magector/cli-linux-x64": "2.16.10",
38
- "@magector/cli-linux-arm64": "2.16.10",
39
- "@magector/cli-win32-x64": "2.16.10"
36
+ "@magector/cli-darwin-arm64": "2.16.12",
37
+ "@magector/cli-linux-x64": "2.16.12",
38
+ "@magector/cli-linux-arm64": "2.16.12",
39
+ "@magector/cli-win32-x64": "2.16.12"
40
40
  },
41
41
  "keywords": [
42
42
  "magento",
package/src/mcp-server.js CHANGED
@@ -1978,6 +1978,7 @@ async function traceDependency(className, direction = 'both') {
1978
1978
  plugins: [],
1979
1979
  virtualTypes: [],
1980
1980
  argumentOverrides: [],
1981
+ argumentInjections: [],
1981
1982
  totalDiFiles: diFiles.length
1982
1983
  };
1983
1984
 
@@ -2045,6 +2046,54 @@ async function traceDependency(className, direction = 'both') {
2045
2046
  }
2046
2047
  }
2047
2048
  }
2049
+
2050
+ // Find argument injections: className used as an argument VALUE in any <type> or <virtualType> block.
2051
+ // Catches cases where an interface is injected via constructor argument, e.g.:
2052
+ // <virtualType name="SomeVT" type="SomeClass">
2053
+ // <argument name="validator" xsi:type="object">My\Interface</argument>
2054
+ // </virtualType>
2055
+ const allBlockRegex = /<(?:type|virtualType)\s+name="([^"]+)"[^>]*(?:type="([^"]+)")?[^>]*>([\s\S]*?)<\/(?:type|virtualType)>/g;
2056
+ let blockMatch;
2057
+ while ((blockMatch = allBlockRegex.exec(content)) !== null) {
2058
+ const blockName = blockMatch[1];
2059
+ const blockType = blockMatch[2] || null;
2060
+ const blockBody = blockMatch[3];
2061
+ // Skip if this block IS the target (already covered above)
2062
+ if (blockName.toLowerCase().includes(classLower)) continue;
2063
+
2064
+ // Search argument values for the className
2065
+ const objArgRegex = /<argument\s+name="([^"]+)"[^>]*xsi:type="object"[^>]*>([^<]*)<\/argument>/g;
2066
+ let oMatch;
2067
+ while ((oMatch = objArgRegex.exec(blockBody)) !== null) {
2068
+ const argValue = oMatch[2].trim();
2069
+ if (argValue.toLowerCase().includes(classLower) || argValue.toLowerCase().includes(classShort)) {
2070
+ result.argumentInjections.push({
2071
+ injectedAs: argValue,
2072
+ intoBlock: blockName,
2073
+ blockType: blockType,
2074
+ argumentName: oMatch[1],
2075
+ file: relativePath
2076
+ });
2077
+ }
2078
+ }
2079
+
2080
+ // Also check <item> values inside array arguments
2081
+ const itemRegex = /<item\s+name="([^"]+)"[^>]*xsi:type="object"[^>]*>([^<]*)<\/item>/g;
2082
+ let iMatch;
2083
+ while ((iMatch = itemRegex.exec(blockBody)) !== null) {
2084
+ const itemValue = iMatch[2].trim();
2085
+ if (itemValue.toLowerCase().includes(classLower) || itemValue.toLowerCase().includes(classShort)) {
2086
+ result.argumentInjections.push({
2087
+ injectedAs: itemValue,
2088
+ intoBlock: blockName,
2089
+ blockType: blockType,
2090
+ argumentName: iMatch[1],
2091
+ isArrayItem: true,
2092
+ file: relativePath
2093
+ });
2094
+ }
2095
+ }
2096
+ }
2048
2097
  }
2049
2098
  }
2050
2099
 
@@ -4968,10 +5017,12 @@ const _callToolHandler = async (request) => {
4968
5017
  }
4969
5018
  // SONA: record search with results for follow-up tracking
4970
5019
  sessionTracker.recordToolCall(name, args || {}, arr);
5020
+ const reindexWarn = getReindexWarning();
5021
+ const searchOutput = formatSearchResults(results.slice(0, args.limit || 5));
4971
5022
  return {
4972
5023
  content: [{
4973
5024
  type: 'text',
4974
- text: formatSearchResults(results.slice(0, args.limit || 5))
5025
+ text: reindexWarn ? `${reindexWarn}\n\n${searchOutput}` : searchOutput
4975
5026
  }]
4976
5027
  };
4977
5028
  }
@@ -6024,6 +6075,15 @@ const _callToolHandler = async (request) => {
6024
6075
  const result = await traceFlow(entryPoint, entryType, depth);
6025
6076
  result.summary = buildTraceSummary(result);
6026
6077
 
6078
+ const reindexWarn = getReindexWarning();
6079
+ if (reindexWarn) result.warning = reindexWarn;
6080
+
6081
+ // Detect empty trace — likely caused by search unavailability
6082
+ const traceKeys = Object.keys(result.trace || {});
6083
+ if (traceKeys.length === 0 && reindexInProgress) {
6084
+ result.warning = '⚠️ Re-indexing in progress — trace returned empty results. Search-dependent tracing will produce accurate results once re-indexing completes.';
6085
+ }
6086
+
6027
6087
  return {
6028
6088
  content: [{
6029
6089
  type: 'text',
@@ -6070,8 +6130,21 @@ const _callToolHandler = async (request) => {
6070
6130
  text += '\n';
6071
6131
  }
6072
6132
 
6073
- if (diResult.preferences.length === 0 && diResult.plugins.length === 0 &&
6074
- diResult.virtualTypes.length === 0 && diResult.argumentOverrides.length === 0) {
6133
+ if (diResult.argumentInjections && diResult.argumentInjections.length > 0) {
6134
+ text += `### Argument Injections (${diResult.argumentInjections.length})\n`;
6135
+ text += `_This class is injected as a constructor argument value in the following blocks:_\n`;
6136
+ for (const a of diResult.argumentInjections) {
6137
+ const blockLabel = a.blockType ? `\`${a.intoBlock}\` (type: \`${a.blockType}\`)` : `\`${a.intoBlock}\``;
6138
+ const itemTag = a.isArrayItem ? ' [array item]' : '';
6139
+ text += `- ${blockLabel} → argument \`${a.argumentName}\`${itemTag} = \`${a.injectedAs}\` (${a.file})\n`;
6140
+ }
6141
+ text += '\n';
6142
+ }
6143
+
6144
+ const totalFound = diResult.preferences.length + diResult.plugins.length +
6145
+ diResult.virtualTypes.length + diResult.argumentOverrides.length +
6146
+ (diResult.argumentInjections?.length || 0);
6147
+ if (totalFound === 0) {
6075
6148
  text += '_No DI configuration found for this class. It may use default Magento auto-resolution or be configured under a different name._\n';
6076
6149
  }
6077
6150