magector 2.16.5 → 2.16.7
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.16.
|
|
3
|
+
"version": "2.16.7",
|
|
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.7",
|
|
37
|
+
"@magector/cli-linux-x64": "2.16.7",
|
|
38
|
+
"@magector/cli-linux-arm64": "2.16.7",
|
|
39
|
+
"@magector/cli-win32-x64": "2.16.7"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
|
42
42
|
"magento",
|
package/src/mcp-server.js
CHANGED
|
@@ -4901,11 +4901,14 @@ const _callToolHandler = async (request) => {
|
|
|
4901
4901
|
let tm;
|
|
4902
4902
|
while ((tm = typeBlockRegex.exec(content)) !== null) {
|
|
4903
4903
|
const typeName = tm[1].replace(/\\\\/g, '\\');
|
|
4904
|
-
// FQCN: exact match. Short name: match
|
|
4905
|
-
|
|
4904
|
+
// FQCN: exact match. Short name: match last segment OR any namespace segment
|
|
4905
|
+
// (catches sub-namespace types like Payment\State\CaptureCommand when searching for "Payment")
|
|
4906
|
+
const typeSegments = typeName.split('\\').map(s => s.toLowerCase());
|
|
4907
|
+
const isExactMatch = isFqcn
|
|
4906
4908
|
? typeName === normalizedTarget
|
|
4907
|
-
:
|
|
4908
|
-
|
|
4909
|
+
: typeSegments[typeSegments.length - 1] === shortTarget;
|
|
4910
|
+
const isSubNamespace = !isFqcn && !isExactMatch && typeSegments.includes(shortTarget);
|
|
4911
|
+
if (!isExactMatch && !isSubNamespace) continue;
|
|
4909
4912
|
const block = tm[2];
|
|
4910
4913
|
const pluginRegex = /<plugin\s+([^/>]*)\/?>/g;
|
|
4911
4914
|
let pm;
|
|
@@ -4926,6 +4929,7 @@ const _callToolHandler = async (request) => {
|
|
|
4926
4929
|
pluginClass: attrs.type || '',
|
|
4927
4930
|
disabled: attrs.disabled === 'true',
|
|
4928
4931
|
sortOrder: attrs.sortOrder || null,
|
|
4932
|
+
isSubNamespace,
|
|
4929
4933
|
area,
|
|
4930
4934
|
file: relPath
|
|
4931
4935
|
});
|
|
@@ -4942,8 +4946,9 @@ const _callToolHandler = async (request) => {
|
|
|
4942
4946
|
if (pluginFile) {
|
|
4943
4947
|
reg.methods = extractPluginMethods(pluginFile);
|
|
4944
4948
|
reg.resolvedFile = pluginFile.replace(fpRoot2 + '/', '');
|
|
4945
|
-
// Read method bodies —
|
|
4946
|
-
|
|
4949
|
+
// Read method bodies — for exact matches, filter by targetMethod to reduce bloat
|
|
4950
|
+
// For sub-namespace matches, read ALL bodies (intercepted method name may differ)
|
|
4951
|
+
const methodsToRead = (args.targetMethod && !reg.isSubNamespace)
|
|
4947
4952
|
? reg.methods.filter(m => m.targetMethod === args.targetMethod)
|
|
4948
4953
|
: reg.methods;
|
|
4949
4954
|
for (const m of methodsToRead) {
|
|
@@ -4955,12 +4960,27 @@ const _callToolHandler = async (request) => {
|
|
|
4955
4960
|
}
|
|
4956
4961
|
|
|
4957
4962
|
let text = formatSearchResults(enrichedResults);
|
|
4963
|
+
const exactRegs = diRegistrations.filter(r => !r.isSubNamespace);
|
|
4964
|
+
const subNsRegs = diRegistrations.filter(r => r.isSubNamespace);
|
|
4958
4965
|
if (diRegistrations.length > 0) {
|
|
4959
|
-
|
|
4960
|
-
|
|
4966
|
+
if (exactRegs.length > 0) {
|
|
4967
|
+
text += `\n\n### DI Plugin Registrations for ${args.targetClass} (${exactRegs.length})\n`;
|
|
4968
|
+
}
|
|
4969
|
+
if (subNsRegs.length > 0) {
|
|
4970
|
+
if (exactRegs.length === 0) text += '\n';
|
|
4971
|
+
text += `\n### Plugins on ${args.targetClass} sub-classes (${subNsRegs.length})\n`;
|
|
4972
|
+
text += `> These intercept classes in the \\${args.targetClass}\\ namespace subtree — operations, state commands, etc.\n\n`;
|
|
4973
|
+
}
|
|
4974
|
+
const orderedRegs = [...exactRegs, ...subNsRegs];
|
|
4975
|
+
let inSubNs = false;
|
|
4976
|
+
for (const reg of orderedRegs) {
|
|
4977
|
+
if (!inSubNs && reg.isSubNamespace) {
|
|
4978
|
+
inSubNs = true;
|
|
4979
|
+
}
|
|
4961
4980
|
const disabledTag = reg.disabled ? ' **[DISABLED]**' : '';
|
|
4962
4981
|
const sortTag = reg.sortOrder ? ` (sortOrder: ${reg.sortOrder})` : '';
|
|
4963
|
-
|
|
4982
|
+
const targetTag = reg.isSubNamespace ? ` on \`${reg.target.split('\\').pop()}\`` : '';
|
|
4983
|
+
text += `- **${reg.pluginName}**${targetTag} → \`${reg.pluginClass}\` [${reg.area}]${sortTag}${disabledTag} (${reg.file})\n`;
|
|
4964
4984
|
if (reg.resolvedFile) {
|
|
4965
4985
|
text += ` PHP: \`${reg.resolvedFile}\`\n`;
|
|
4966
4986
|
}
|
|
@@ -6257,25 +6277,30 @@ const _callToolHandler = async (request) => {
|
|
|
6257
6277
|
while ((tm = typeBlockRegex.exec(diContent)) !== null) {
|
|
6258
6278
|
if (regCount >= 8) break;
|
|
6259
6279
|
const typeName = tm[1].replace(/\\\\/g, '\\');
|
|
6260
|
-
const
|
|
6261
|
-
|
|
6280
|
+
const batchSegs = typeName.split('\\').map(s => s.toLowerCase());
|
|
6281
|
+
const isExact = isFqcn ? typeName === normalizedTarget : batchSegs[batchSegs.length - 1] === shortTarget;
|
|
6282
|
+
const isSubNs = !isFqcn && !isExact && batchSegs.includes(shortTarget);
|
|
6283
|
+
if (!isExact && !isSubNs) continue;
|
|
6262
6284
|
const block = tm[2];
|
|
6263
|
-
const
|
|
6285
|
+
const pluginRegex2 = /<plugin\s+([^/>]*)\/?>/g;
|
|
6264
6286
|
let pm;
|
|
6265
|
-
while ((pm =
|
|
6266
|
-
if (regCount >=
|
|
6287
|
+
while ((pm = pluginRegex2.exec(block)) !== null) {
|
|
6288
|
+
if (regCount >= 12) break;
|
|
6267
6289
|
const attrs = {};
|
|
6268
6290
|
const localAttrRe = /(\w+)="([^"]*)"/g;
|
|
6269
6291
|
let am2;
|
|
6270
6292
|
while ((am2 = localAttrRe.exec(pm[1])) !== null) attrs[am2[1]] = am2[2];
|
|
6271
6293
|
const disabled = attrs.disabled === 'true' ? ' [DISABLED]' : '';
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6294
|
+
const subTag = isSubNs ? ` on \`${typeName.split('\\').pop()}\`` : '';
|
|
6295
|
+
text += `- **${attrs.name || '?'}**${subTag} → \`${attrs.type || '?'}\`${disabled} (${relPath})\n`;
|
|
6296
|
+
// Read method bodies: exact matches filter by targetMethod; sub-namespace reads ALL
|
|
6297
|
+
if (attrs.type) {
|
|
6275
6298
|
const pFile = findClassFile(config.magentoRoot, attrs.type);
|
|
6276
6299
|
if (pFile) {
|
|
6277
6300
|
const methods = extractPluginMethods(pFile);
|
|
6278
|
-
const relevant =
|
|
6301
|
+
const relevant = (a.targetMethod && !isSubNs)
|
|
6302
|
+
? methods.filter(m => m.targetMethod === a.targetMethod)
|
|
6303
|
+
: methods;
|
|
6279
6304
|
for (const m of relevant) {
|
|
6280
6305
|
const body = readFullMethodBody(pFile, m.name);
|
|
6281
6306
|
text += ` - \`${m.type}\` **${m.targetMethod}** → \`${m.name}()\`\n`;
|
|
@@ -38,6 +38,14 @@ This project is indexed with Magector. Use the MCP tools below to search the cod
|
|
|
38
38
|
- Include Magento terms: "plugin for save", "observer for order place"
|
|
39
39
|
- Be specific: "customer address validation before checkout" not just "validation"
|
|
40
40
|
|
|
41
|
+
## Analysis Patterns
|
|
42
|
+
|
|
43
|
+
### Negative match audit
|
|
44
|
+
When \`magento_grep\` finds a bug pattern in only SOME files of a known group (e.g. \`orderRepository->save()\` in 5 of 8 transition handlers), always read the files that DON'T match to understand why they differ. This narrows the fix scope — files with a different code path may not need fixing.
|
|
45
|
+
|
|
46
|
+
### Follow up DI listings with code reads
|
|
47
|
+
When \`magento_trace_dependency\` or \`magento_find_plugin\` returns a list of plugins/preferences, don't stop at the names. Use \`magento_read\` or \`Read\` to inspect the actual implementation of each — the root cause is often in a specific condition inside the plugin code, not in the DI wiring itself.
|
|
48
|
+
|
|
41
49
|
## Re-indexing
|
|
42
50
|
|
|
43
51
|
After significant code changes, re-index:
|
|
@@ -40,6 +40,11 @@ Before reading files manually, ALWAYS use Magector MCP tools to find relevant co
|
|
|
40
40
|
- Include Magento terms: "plugin for save", "observer for order place", "checkout totals collector"
|
|
41
41
|
- Be specific: "customer address validation before checkout" not just "validation"
|
|
42
42
|
|
|
43
|
+
## Analysis Patterns
|
|
44
|
+
|
|
45
|
+
- **Negative match audit:** When \`magento_grep\` finds a bug pattern in only SOME files of a group, always read the non-matching files to understand why they differ. This narrows the fix scope.
|
|
46
|
+
- **Follow up DI listings with code reads:** When \`magento_trace_dependency\` or \`magento_find_plugin\` returns plugin/preference names, always read the actual implementation. The root cause is often in a condition inside the code, not in the DI wiring.
|
|
47
|
+
|
|
43
48
|
## Magento Development Patterns
|
|
44
49
|
|
|
45
50
|
- Always check for existing plugins before modifying core behavior
|