magector 2.3.0 → 2.4.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.
- package/README.md +31 -6
- package/package.json +5 -5
- package/src/mcp-server.js +189 -13
- package/src/validation/test-data-generator.js +0 -672
- package/src/validation/test-queries.js +0 -326
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Technology-aware MCP server for Magento 2 and Adobe Commerce with intelligent indexing and search.**
|
|
4
4
|
|
|
5
|
-
Magector is a Model Context Protocol (MCP) server that deeply understands Magento 2 and Adobe Commerce. It builds a semantic vector index of your entire codebase — 18,000+ files across hundreds of modules — and exposes
|
|
5
|
+
Magector is a Model Context Protocol (MCP) server that deeply understands Magento 2 and Adobe Commerce. It builds a semantic vector index of your entire codebase — 18,000+ files across hundreds of modules — and exposes 34 tools that let AI assistants search, navigate, and understand the code with domain-specific intelligence. Instead of grepping for keywords, your AI asks *"how are checkout totals calculated?"* and gets ranked, relevant results in under 50ms, enriched with Magento pattern detection (plugins, observers, controllers, DI preferences, layout XML, and 20+ more).
|
|
6
6
|
|
|
7
7
|
[](https://www.rust-lang.org)
|
|
8
8
|
[](https://nodejs.org)
|
|
@@ -58,7 +58,7 @@ The result: your AI assistant calls one MCP tool and gets ranked, pattern-enrich
|
|
|
58
58
|
- **Complexity analysis** -- cyclomatic complexity, function count, and hotspot detection across modules
|
|
59
59
|
- **Fast** -- 10-45ms queries via persistent serve process, batched ONNX embedding with adaptive thread scaling
|
|
60
60
|
- **LLM description enrichment** -- generate natural-language descriptions of di.xml files using Claude, stored in SQLite, and prepend them to embedding text so descriptions influence vector search ranking (not just post-retrieval display)
|
|
61
|
-
- **MCP server** --
|
|
61
|
+
- **MCP server** -- 34 tools integrating with Claude Code, Cursor, and any MCP-compatible AI tool
|
|
62
62
|
- **Clean architecture** -- Rust core handles all indexing/search, Node.js MCP server delegates to it
|
|
63
63
|
|
|
64
64
|
---
|
|
@@ -70,7 +70,7 @@ flowchart LR
|
|
|
70
70
|
subgraph node ["Node.js Layer"]
|
|
71
71
|
direction TB
|
|
72
72
|
G["CLI<br/>init · index · search · describe"]
|
|
73
|
-
E["MCP Server<br/>
|
|
73
|
+
E["MCP Server<br/>34 tools · LRU cache"]
|
|
74
74
|
F["Persistent Serve Process"]
|
|
75
75
|
G --> F
|
|
76
76
|
E --> F
|
|
@@ -369,7 +369,7 @@ npx magector index --force
|
|
|
369
369
|
|
|
370
370
|
## MCP Server Tools
|
|
371
371
|
|
|
372
|
-
The MCP server exposes
|
|
372
|
+
The MCP server exposes 34 tools for AI-assisted Magento 2 and Adobe Commerce development. All search tools return **structured JSON** with file paths, class names, methods, role badges, and content snippets -- enabling AI clients to parse results programmatically and minimize file-read round-trips.
|
|
373
373
|
|
|
374
374
|
### Output Format
|
|
375
375
|
|
|
@@ -432,7 +432,10 @@ All search tools return structured JSON:
|
|
|
432
432
|
| `magento_trace_flow` | Trace execution flow from an entry point (route, API, GraphQL, event, cron) -- maps controller → plugins → observers → templates in one call |
|
|
433
433
|
| `magento_trace_dependency` | Trace DI graph for a class/interface -- preferences, plugins, virtualTypes, argument overrides (parses all di.xml, no index needed) |
|
|
434
434
|
| `magento_find_event_flow` | Trace complete event chain: dispatchers → observers → handler PHP classes (parses events.xml + vector search) |
|
|
435
|
+
| `magento_find_event_dispatchers` | Find all PHP locations where a specific event is dispatched -- exact grep matching with method context and surrounding code **(v2.3)** |
|
|
435
436
|
| `magento_find_layout` | Find layout XML files by handle or content -- lists blocks, containers, and referenceBlock declarations |
|
|
437
|
+
| `magento_trace_data_flow` | Trace how a data attribute flows: find all setters (magic setter, setData, addData) and getters (magic getter, getData) across PHP and XML **(v2.3)** |
|
|
438
|
+
| `magento_trace_call_chain` | Trace internal method call chain: follows `$this->method()`, `$this->dep->method()`, and `dispatch()` calls to build an execution tree **(v2.2)** |
|
|
436
439
|
|
|
437
440
|
Auto-detects entry type from pattern (`/V1/...` → API, `snake_case` → event, `camelCase` → GraphQL, `path/segments` → route), or override with `entryType`. Use `depth: "shallow"` (entry + config + plugins) or `depth: "deep"` (adds observers, layout, templates, DI preferences).
|
|
438
441
|
|
|
@@ -442,6 +445,9 @@ Auto-detects entry type from pattern (`/V1/...` → API, `snake_case` → event,
|
|
|
442
445
|
|------|-------------|
|
|
443
446
|
| `magento_impact_analysis` | Analyze impact of changing a class -- finds use statements, DI references, direct instantiations, and type hints across the codebase |
|
|
444
447
|
| `magento_find_test` | Find PHPUnit tests for a given class/method -- searches Test/ directories for coverage, mocks, and assertions |
|
|
448
|
+
| `magento_find_implementors` | Find all classes implementing a given PHP interface -- scans `implements` keywords and di.xml `<preference>` declarations **(v2.2)** |
|
|
449
|
+
| `magento_find_callers` | Find all call sites of a method across PHP and XML files -- `->method()` and `::method()` calls **(v2.2)** |
|
|
450
|
+
| `magento_find_di_wiring` | Complete DI picture for a class: preferences, plugins, constructor args, virtual types, and argument overrides from di.xml **(v2.2)** |
|
|
445
451
|
|
|
446
452
|
### Diagnostics
|
|
447
453
|
|
|
@@ -470,9 +476,22 @@ Auto-detects entry type from pattern (`/V1/...` → API, `snake_case` → event,
|
|
|
470
476
|
|
|
471
477
|
- **Hybrid BM25+vector search** -- combines text frequency scoring with semantic vector similarity for better exact class name matches
|
|
472
478
|
- **Query expansion** -- automatically expands queries with Magento domain synonyms (plugin → interceptor, checkout → cart/quote/totals, etc.)
|
|
473
|
-
- **Module filtering** -- `moduleFilter` parameter on `magento_search` to limit results by vendor/module pattern
|
|
479
|
+
- **Module filtering** -- `moduleFilter` parameter on `magento_search` to limit results by vendor/module pattern. Accepts a single string or array of strings. Supports wildcards, e.g., `"Vendor_*"` or `["Acme_PaymentGateway", "Acme_FreeShipping"]`
|
|
474
480
|
- **Non-blocking reindex** -- old index stays usable during background rebuild; new index is built to a temp path and swapped in atomically on completion
|
|
475
481
|
|
|
482
|
+
### Deep Code Analysis (v2.2)
|
|
483
|
+
|
|
484
|
+
- **`magento_find_implementors`** -- find all classes implementing a PHP interface (PHP `implements` + di.xml `<preference>`)
|
|
485
|
+
- **`magento_find_callers`** -- find all call sites of a method across PHP and XML files
|
|
486
|
+
- **`magento_find_di_wiring`** -- complete DI picture: preferences, plugins, constructor args, virtual types, argument overrides
|
|
487
|
+
- **`magento_trace_call_chain`** -- trace internal method execution chain: `$this->method()`, `$this->dep->method()`, and `dispatch()` calls with event→observer resolution
|
|
488
|
+
|
|
489
|
+
### Data Flow & Event Tracing (v2.3)
|
|
490
|
+
|
|
491
|
+
- **`magento_trace_data_flow`** -- trace all setters and getters for a data attribute (magic methods, setData/getData, addData, constants, XML references). Answers "who writes/reads `custom_discounted_price_incl_tax` on `Quote\Address`?"
|
|
492
|
+
- **`magento_find_event_dispatchers`** -- grep-based exact search for all PHP locations dispatching a specific event, with method context and surrounding code. Complements `magento_find_event_flow` with higher precision.
|
|
493
|
+
- **`magento_find_plugin` area context** -- enriched output shows DI area (frontend/adminhtml/global/graphql) and explicit di.xml plugin registrations when `targetClass` is provided
|
|
494
|
+
|
|
476
495
|
### Tool Cross-References
|
|
477
496
|
|
|
478
497
|
Each tool description includes "See also" hints to help AI clients chain tools effectively:
|
|
@@ -549,6 +568,12 @@ magento_trace_flow({ entryPoint: "checkout/cart/add", depth: "deep" })
|
|
|
549
568
|
magento_trace_flow({ entryPoint: "/V1/products" })
|
|
550
569
|
magento_trace_flow({ entryPoint: "placeOrder", entryType: "graphql" })
|
|
551
570
|
magento_trace_flow({ entryPoint: "sales_order_place_after" })
|
|
571
|
+
magento_trace_data_flow({ attributeKey: "custom_discounted_price_incl_tax", modelClass: "Quote\\Address" })
|
|
572
|
+
magento_find_event_dispatchers({ eventName: "custom_discount_rule_validation_before" })
|
|
573
|
+
magento_find_implementors({ interfaceName: "ProductRepositoryInterface" })
|
|
574
|
+
magento_find_callers({ methodName: "collectTotals", className: "TotalsCollector" })
|
|
575
|
+
magento_find_di_wiring({ className: "CartManagementInterface" })
|
|
576
|
+
magento_trace_call_chain({ className: "Magento\\Quote\\Model\\QuoteManagement", methodName: "submit" })
|
|
552
577
|
```
|
|
553
578
|
|
|
554
579
|
---
|
|
@@ -629,7 +654,7 @@ cd rust-core && cargo run --release -- validate -m ./magento2 --skip-index
|
|
|
629
654
|
magector/
|
|
630
655
|
├── src/ # Node.js source
|
|
631
656
|
│ ├── cli.js # CLI entry point (npx magector <command>)
|
|
632
|
-
│ ├── mcp-server.js # MCP server (
|
|
657
|
+
│ ├── mcp-server.js # MCP server (34 tools, structured JSON output)
|
|
633
658
|
│ ├── binary.js # Platform binary resolver
|
|
634
659
|
│ ├── model.js # ONNX model resolver/downloader
|
|
635
660
|
│ ├── init.js # Full init command (index + IDE config)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magector",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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.
|
|
37
|
-
"@magector/cli-linux-x64": "2.
|
|
38
|
-
"@magector/cli-linux-arm64": "2.
|
|
39
|
-
"@magector/cli-win32-x64": "2.
|
|
36
|
+
"@magector/cli-darwin-arm64": "2.4.0",
|
|
37
|
+
"@magector/cli-linux-x64": "2.4.0",
|
|
38
|
+
"@magector/cli-linux-arm64": "2.4.0",
|
|
39
|
+
"@magector/cli-win32-x64": "2.4.0"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
|
42
42
|
"magento",
|
package/src/mcp-server.js
CHANGED
|
@@ -32,6 +32,8 @@ import {
|
|
|
32
32
|
} from 'ruvector/dist/analysis/complexity.js';
|
|
33
33
|
import { resolveBinary } from './binary.js';
|
|
34
34
|
import { resolveModels } from './model.js';
|
|
35
|
+
import { createRequire } from 'module';
|
|
36
|
+
const __pkg = createRequire(import.meta.url)('../package.json');
|
|
35
37
|
|
|
36
38
|
const config = {
|
|
37
39
|
dbPath: process.env.MAGECTOR_DB || './.magector/index.db',
|
|
@@ -2816,7 +2818,7 @@ async function traceCallChain(startClass, startMethod, maxDepth = 3) {
|
|
|
2816
2818
|
const server = new Server(
|
|
2817
2819
|
{
|
|
2818
2820
|
name: 'magector',
|
|
2819
|
-
version:
|
|
2821
|
+
version: __pkg.version
|
|
2820
2822
|
},
|
|
2821
2823
|
{
|
|
2822
2824
|
capabilities: {
|
|
@@ -2848,7 +2850,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
2848
2850
|
{ type: 'string' },
|
|
2849
2851
|
{ type: 'array', items: { type: 'string' } }
|
|
2850
2852
|
],
|
|
2851
|
-
description: 'Filter results by vendor/module pattern(s). Accepts a single string or array of strings. Supports wildcards and vendor prefix matching. Uses "/" or "_" interchangeably as separator. Examples: "Vendor_*", ["
|
|
2853
|
+
description: 'Filter results by vendor/module pattern(s). Accepts a single string or array of strings. Supports wildcards and vendor prefix matching. Uses "/" or "_" interchangeably as separator. Examples: "Vendor_*", ["Acme_PaymentGateway", "Acme_FreeShipping"], "Magento_Catalog".'
|
|
2852
2854
|
},
|
|
2853
2855
|
expand: {
|
|
2854
2856
|
type: 'boolean',
|
|
@@ -3086,7 +3088,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
3086
3088
|
},
|
|
3087
3089
|
{
|
|
3088
3090
|
name: 'magento_find_db_schema',
|
|
3089
|
-
description: 'Find database table definitions, columns, indexes, and constraints declared in db_schema.xml (Magento declarative schema). See also:
|
|
3091
|
+
description: 'Find database table definitions, columns, indexes, and constraints declared in db_schema.xml (Magento declarative schema) AND legacy Setup scripts (InstallSchema, UpgradeSchema). Covers both modern declarative schema and legacy $setup->newTable() / addColumn() table definitions. See also: magento_find_trigger (DB triggers), magento_find_table_usage (cross-module table references).',
|
|
3090
3092
|
inputSchema: {
|
|
3091
3093
|
type: 'object',
|
|
3092
3094
|
properties: {
|
|
@@ -3098,6 +3100,37 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
3098
3100
|
required: ['tableName']
|
|
3099
3101
|
}
|
|
3100
3102
|
},
|
|
3103
|
+
{
|
|
3104
|
+
name: 'magento_find_trigger',
|
|
3105
|
+
description: 'Find MySQL database trigger definitions in Magento Setup scripts. Detects triggers created via TriggerFactory (setName, setTable, setEvent, setTime, addStatement, createTrigger). Returns trigger name, target table, event type (INSERT/UPDATE/DELETE), timing (BEFORE/AFTER), and SQL statements. Use when investigating DB-level automation, trigger chains, or performance issues caused by cascading triggers.',
|
|
3106
|
+
inputSchema: {
|
|
3107
|
+
type: 'object',
|
|
3108
|
+
properties: {
|
|
3109
|
+
triggerName: {
|
|
3110
|
+
type: 'string',
|
|
3111
|
+
description: 'Optional trigger name or pattern to search for. If omitted, finds all triggers in the codebase.'
|
|
3112
|
+
},
|
|
3113
|
+
tableName: {
|
|
3114
|
+
type: 'string',
|
|
3115
|
+
description: 'Optional table name to find triggers targeting this table.'
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
},
|
|
3120
|
+
{
|
|
3121
|
+
name: 'magento_find_table_usage',
|
|
3122
|
+
description: 'Find all code that references a database table — across db_schema.xml, Setup scripts (InstallSchema/UpgradeSchema), raw SQL (Zend_Db_Expr, $connection->query), getTable() calls, and resource model definitions. Builds a cross-module dependency map showing who reads/writes/creates a given table. Essential for impact analysis of schema changes.',
|
|
3123
|
+
inputSchema: {
|
|
3124
|
+
type: 'object',
|
|
3125
|
+
properties: {
|
|
3126
|
+
tableName: {
|
|
3127
|
+
type: 'string',
|
|
3128
|
+
description: 'Database table name to find all references for. Examples: "salesrule_ordered", "catalog_product_entity", "quote_item"'
|
|
3129
|
+
}
|
|
3130
|
+
},
|
|
3131
|
+
required: ['tableName']
|
|
3132
|
+
}
|
|
3133
|
+
},
|
|
3101
3134
|
{
|
|
3102
3135
|
name: 'magento_module_structure',
|
|
3103
3136
|
description: 'Get the complete structure of a Magento module — lists all controllers, models, blocks, plugins, observers, API classes, XML configs, and templates. Provides an overview of module architecture.',
|
|
@@ -3330,7 +3363,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
3330
3363
|
properties: {
|
|
3331
3364
|
methodName: {
|
|
3332
3365
|
type: 'string',
|
|
3333
|
-
description: 'Method name to find callers for. Examples: "execute", "save", "collectTotals", "
|
|
3366
|
+
description: 'Method name to find callers for. Examples: "execute", "save", "collectTotals", "copySalesRuleIdsFromParentToChildQuote"'
|
|
3334
3367
|
},
|
|
3335
3368
|
className: {
|
|
3336
3369
|
type: 'string',
|
|
@@ -3362,7 +3395,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
3362
3395
|
properties: {
|
|
3363
3396
|
className: {
|
|
3364
3397
|
type: 'string',
|
|
3365
|
-
description: 'Full PHP class name (FQCN) to start tracing from. Examples: "
|
|
3398
|
+
description: 'Full PHP class name (FQCN) to start tracing from. Examples: "Vendor\\OrderSplit\\Model\\CreateOrder\\CreateChildOrder", "Magento\\Quote\\Model\\QuoteManagement"'
|
|
3366
3399
|
},
|
|
3367
3400
|
methodName: {
|
|
3368
3401
|
type: 'string',
|
|
@@ -3379,13 +3412,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
3379
3412
|
},
|
|
3380
3413
|
{
|
|
3381
3414
|
name: 'magento_trace_data_flow',
|
|
3382
|
-
description: 'Trace how a data attribute flows through the Magento codebase: find all PHP files that set (via magic setter, setData, addData) and get (via magic getter, getData) a specific attribute key. Shows which classes write vs read the attribute, in which methods, and whether XML configs reference it. Use this to understand data dependencies — e.g., who sets
|
|
3415
|
+
description: 'Trace how a data attribute flows through the Magento codebase: find all PHP files that set (via magic setter, setData, addData) and get (via magic getter, getData) a specific attribute key. Shows which classes write vs read the attribute, in which methods, and whether XML configs reference it. Use this to understand data dependencies — e.g., who sets custom_discounted_price_incl_tax on Quote\\Address and who reads it.',
|
|
3383
3416
|
inputSchema: {
|
|
3384
3417
|
type: 'object',
|
|
3385
3418
|
properties: {
|
|
3386
3419
|
attributeKey: {
|
|
3387
3420
|
type: 'string',
|
|
3388
|
-
description: 'The snake_case data attribute key to trace. Examples: "
|
|
3421
|
+
description: 'The snake_case data attribute key to trace. Examples: "custom_discounted_price_incl_tax", "base_grand_total", "custom_free_shipping_price", "subtotal_with_discount"'
|
|
3389
3422
|
},
|
|
3390
3423
|
modelClass: {
|
|
3391
3424
|
type: 'string',
|
|
@@ -3403,7 +3436,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
3403
3436
|
properties: {
|
|
3404
3437
|
eventName: {
|
|
3405
3438
|
type: 'string',
|
|
3406
|
-
description: 'Magento event name to find dispatchers for. Examples: "sales_order_place_after", "
|
|
3439
|
+
description: 'Magento event name to find dispatchers for. Examples: "sales_order_place_after", "custom_discount_rule_validation_before", "checkout_cart_add_product_complete"'
|
|
3407
3440
|
}
|
|
3408
3441
|
},
|
|
3409
3442
|
required: ['eventName']
|
|
@@ -3807,17 +3840,160 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3807
3840
|
}
|
|
3808
3841
|
|
|
3809
3842
|
case 'magento_find_db_schema': {
|
|
3810
|
-
|
|
3811
|
-
const
|
|
3812
|
-
|
|
3843
|
+
// Search both declarative schema (db_schema.xml) and legacy Setup scripts
|
|
3844
|
+
const declQuery = `db_schema.xml table ${args.tableName} column declarative schema`;
|
|
3845
|
+
const legacyQuery = `create_table ${args.tableName} legacy_schema table_created ${args.tableName} setup install schema newTable addColumn`;
|
|
3846
|
+
const [declRaw, legacyRaw] = await Promise.all([
|
|
3847
|
+
rustSearchAsync(declQuery, 40),
|
|
3848
|
+
rustSearchAsync(legacyQuery, 30)
|
|
3849
|
+
]);
|
|
3850
|
+
|
|
3851
|
+
let declResults = declRaw.map(normalizeResult).filter(r =>
|
|
3813
3852
|
r.path?.includes('db_schema.xml')
|
|
3814
3853
|
);
|
|
3815
|
-
|
|
3854
|
+
declResults = rerank(declResults, { fileType: 'xml', pathContains: ['db_schema.xml'] });
|
|
3855
|
+
|
|
3856
|
+
let legacyResults = legacyRaw.map(normalizeResult).filter(r => {
|
|
3857
|
+
const p = r.path || '';
|
|
3858
|
+
return (p.includes('/Setup/') || p.includes('InstallSchema') ||
|
|
3859
|
+
p.includes('UpgradeSchema') || p.includes('/Patch/')) &&
|
|
3860
|
+
(r.snippet?.toLowerCase().includes(args.tableName.toLowerCase()) ||
|
|
3861
|
+
r.searchText?.toLowerCase().includes(args.tableName.toLowerCase()));
|
|
3862
|
+
});
|
|
3863
|
+
|
|
3864
|
+
// Deduplicate by path
|
|
3865
|
+
const seen = new Set(declResults.map(r => r.path));
|
|
3866
|
+
for (const r of legacyResults) {
|
|
3867
|
+
if (!seen.has(r.path)) {
|
|
3868
|
+
seen.add(r.path);
|
|
3869
|
+
declResults.push(r);
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3873
|
+
// Add section headers
|
|
3874
|
+
let output = '';
|
|
3875
|
+
const xmlResults = declResults.filter(r => r.path?.includes('db_schema.xml'));
|
|
3876
|
+
const setupResults = declResults.filter(r => !r.path?.includes('db_schema.xml'));
|
|
3877
|
+
|
|
3878
|
+
if (xmlResults.length > 0) {
|
|
3879
|
+
output += formatSearchResults(xmlResults.slice(0, 10));
|
|
3880
|
+
}
|
|
3881
|
+
if (setupResults.length > 0) {
|
|
3882
|
+
output += `\n\n### Legacy Setup Scripts (InstallSchema/UpgradeSchema)\n`;
|
|
3883
|
+
output += formatSearchResults(setupResults.slice(0, 10));
|
|
3884
|
+
}
|
|
3816
3885
|
|
|
3817
3886
|
return {
|
|
3818
3887
|
content: [{
|
|
3819
3888
|
type: 'text',
|
|
3820
|
-
text: formatSearchResults(
|
|
3889
|
+
text: output || formatSearchResults([])
|
|
3890
|
+
}]
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
|
|
3894
|
+
case 'magento_find_trigger': {
|
|
3895
|
+
// Search for DB trigger definitions in Setup scripts
|
|
3896
|
+
const triggerTerm = args.triggerName || args.tableName || '';
|
|
3897
|
+
const query = `db_trigger create_trigger sql_trigger TriggerFactory createTrigger setName setEvent ${triggerTerm} setup database_trigger trigger`;
|
|
3898
|
+
const raw = await rustSearchAsync(query, 50);
|
|
3899
|
+
let results = raw.map(normalizeResult).filter(r => {
|
|
3900
|
+
const p = r.path || '';
|
|
3901
|
+
const s = (r.searchText || '') + ' ' + (r.snippet || '');
|
|
3902
|
+
// Must be a Setup file that contains trigger-related terms
|
|
3903
|
+
return (p.includes('/Setup/') || p.includes('InstallSchema') ||
|
|
3904
|
+
p.includes('UpgradeSchema') || p.includes('/Patch/')) &&
|
|
3905
|
+
(s.toLowerCase().includes('trigger') || s.includes('db_trigger') || s.includes('create_trigger'));
|
|
3906
|
+
});
|
|
3907
|
+
|
|
3908
|
+
// If searching for specific trigger/table, filter further
|
|
3909
|
+
if (triggerTerm) {
|
|
3910
|
+
const term = triggerTerm.toLowerCase();
|
|
3911
|
+
const filtered = results.filter(r => {
|
|
3912
|
+
const s = ((r.searchText || '') + ' ' + (r.snippet || '')).toLowerCase();
|
|
3913
|
+
return s.includes(term);
|
|
3914
|
+
});
|
|
3915
|
+
if (filtered.length > 0) results = filtered;
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3918
|
+
results = rerank(results, { pathContains: ['/Setup/', 'UpgradeSchema', 'InstallSchema'] });
|
|
3919
|
+
|
|
3920
|
+
return {
|
|
3921
|
+
content: [{
|
|
3922
|
+
type: 'text',
|
|
3923
|
+
text: results.length > 0
|
|
3924
|
+
? `### DB Trigger Definitions\n\n` + formatSearchResults(results.slice(0, 15)) +
|
|
3925
|
+
`\n\n**Tip:** Read the matched Setup files to see trigger names, target tables, events (INSERT/UPDATE/DELETE), timing (BEFORE/AFTER), and SQL statements.`
|
|
3926
|
+
: `No database triggers found${triggerTerm ? ` matching "${triggerTerm}"` : ''}. Triggers are defined in Setup scripts using TriggerFactory.`
|
|
3927
|
+
}]
|
|
3928
|
+
};
|
|
3929
|
+
}
|
|
3930
|
+
|
|
3931
|
+
case 'magento_find_table_usage': {
|
|
3932
|
+
const table = args.tableName;
|
|
3933
|
+
// Multi-query strategy: search declarative schema, setup scripts, and inline SQL references
|
|
3934
|
+
const queries = [
|
|
3935
|
+
`table ${table} db_schema.xml declarative schema column`,
|
|
3936
|
+
`sql_table ${table} table_reference ${table} Zend_Db_Expr getTable`,
|
|
3937
|
+
`create_table ${table} legacy_schema setup trigger ${table}`,
|
|
3938
|
+
`${table.replace(/_/g, ' ')} resource model collection`,
|
|
3939
|
+
];
|
|
3940
|
+
|
|
3941
|
+
const rawResults = await Promise.all(queries.map(q => rustSearchAsync(q, 25)));
|
|
3942
|
+
const allResults = rawResults.flat().map(normalizeResult);
|
|
3943
|
+
|
|
3944
|
+
// Deduplicate by path
|
|
3945
|
+
const pathMap = new Map();
|
|
3946
|
+
for (const r of allResults) {
|
|
3947
|
+
if (!r.path) continue;
|
|
3948
|
+
const s = ((r.searchText || '') + ' ' + (r.snippet || '')).toLowerCase();
|
|
3949
|
+
if (s.includes(table.toLowerCase()) || r.path.includes('db_schema.xml')) {
|
|
3950
|
+
if (!pathMap.has(r.path) || (r.score || 0) > (pathMap.get(r.path).score || 0)) {
|
|
3951
|
+
pathMap.set(r.path, r);
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
const unique = Array.from(pathMap.values());
|
|
3956
|
+
|
|
3957
|
+
// Categorize results
|
|
3958
|
+
const categories = {
|
|
3959
|
+
'Declarative Schema (db_schema.xml)': unique.filter(r => r.path?.includes('db_schema.xml')),
|
|
3960
|
+
'Setup Scripts (InstallSchema/UpgradeSchema/Patch)': unique.filter(r => {
|
|
3961
|
+
const p = r.path || '';
|
|
3962
|
+
return !p.includes('db_schema.xml') &&
|
|
3963
|
+
(p.includes('/Setup/') || p.includes('InstallSchema') ||
|
|
3964
|
+
p.includes('UpgradeSchema') || p.includes('/Patch/'));
|
|
3965
|
+
}),
|
|
3966
|
+
'PHP Code (raw SQL, getTable, Zend_Db_Expr)': unique.filter(r => {
|
|
3967
|
+
const p = r.path || '';
|
|
3968
|
+
return p.endsWith('.php') && !p.includes('db_schema.xml') &&
|
|
3969
|
+
!p.includes('/Setup/') && !p.includes('InstallSchema') &&
|
|
3970
|
+
!p.includes('UpgradeSchema') && !p.includes('/Patch/');
|
|
3971
|
+
}),
|
|
3972
|
+
'XML Config': unique.filter(r => {
|
|
3973
|
+
const p = r.path || '';
|
|
3974
|
+
return p.endsWith('.xml') && !p.includes('db_schema.xml');
|
|
3975
|
+
}),
|
|
3976
|
+
};
|
|
3977
|
+
|
|
3978
|
+
let output = `### Table Usage: \`${table}\`\n\n`;
|
|
3979
|
+
output += `Found ${unique.length} file(s) referencing this table.\n\n`;
|
|
3980
|
+
|
|
3981
|
+
for (const [category, items] of Object.entries(categories)) {
|
|
3982
|
+
if (items.length > 0) {
|
|
3983
|
+
output += `#### ${category} (${items.length})\n`;
|
|
3984
|
+
output += formatSearchResults(items.slice(0, 8));
|
|
3985
|
+
output += '\n';
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
if (unique.length === 0) {
|
|
3990
|
+
output += `No references found for table "${table}". Try a broader search with magento_search.`;
|
|
3991
|
+
}
|
|
3992
|
+
|
|
3993
|
+
return {
|
|
3994
|
+
content: [{
|
|
3995
|
+
type: 'text',
|
|
3996
|
+
text: output
|
|
3821
3997
|
}]
|
|
3822
3998
|
};
|
|
3823
3999
|
}
|