magector 1.2.13 → 1.2.15

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 (3) hide show
  1. package/README.md +138 -148
  2. package/package.json +5 -5
  3. package/src/mcp-server.js +87 -36
package/README.md CHANGED
@@ -1,20 +1,21 @@
1
1
  # Magector
2
2
 
3
- **Semantic code search engine for Magento 2, powered by ONNX embeddings and HNSW vector search.**
3
+ **Semantic code search engine for Magento 2 and Adobe Commerce, powered by ONNX embeddings and HNSW vector search.**
4
4
 
5
- Magector indexes an entire Magento 2 codebase and lets you search it with natural language. Instead of grepping for keywords, ask questions like *"how are checkout totals calculated?"* or *"where is the product price determined?"* and get ranked, relevant results in under 50ms.
5
+ Magector indexes an entire Magento 2 or Adobe Commerce codebase and lets you search it with natural language. Instead of grepping for keywords, ask questions like *"how are checkout totals calculated?"* or *"where is the product price determined?"* and get ranked, relevant results in under 50ms.
6
6
 
7
7
  [![Rust](https://img.shields.io/badge/rust-1.75+-orange.svg)](https://www.rust-lang.org)
8
8
  [![Node.js](https://img.shields.io/badge/node-18+-green.svg)](https://nodejs.org)
9
9
  [![Magento](https://img.shields.io/badge/magento-2.4.x-blue.svg)](https://magento.com)
10
- [![Accuracy](https://img.shields.io/badge/accuracy-94.9%25-brightgreen.svg)](#validation)
10
+ [![Adobe Commerce](https://img.shields.io/badge/adobe%20commerce-supported-blue.svg)](https://business.adobe.com/products/magento/magento-commerce.html)
11
+ [![Accuracy](https://img.shields.io/badge/accuracy-99.2%25-brightgreen.svg)](#validation)
11
12
  [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)
12
13
 
13
14
  ---
14
15
 
15
16
  ## Why Magector
16
17
 
17
- Magento 2 has **18,000+ source files** across hundreds of modules. Finding the right code is slow:
18
+ Magento 2 and Adobe Commerce have **18,000+ source files** across hundreds of modules. Finding the right code is slow:
18
19
 
19
20
  | Approach | Finds semantic matches | Understands Magento patterns | Speed (18K files) |
20
21
  |----------|:---------------------:|:---------------------------:|:-----------------:|
@@ -29,7 +30,7 @@ Magector understands that a query about *"payment capture"* should return `Sales
29
30
 
30
31
  ## Magector vs Built-in AI Search
31
32
 
32
- Claude Code and Cursor both have built-in code search -- but they rely on keyword matching (`grep`/`ripgrep`) and file-tree heuristics. On a Magento 2 codebase with 18,000+ files, that approach breaks down fast.
33
+ Claude Code and Cursor both have built-in code search -- but they rely on keyword matching (`grep`/`ripgrep`) and file-tree heuristics. On a Magento 2 / Adobe Commerce codebase with 18,000+ files, that approach breaks down fast.
33
34
 
34
35
  | Capability | Claude Code / Cursor (built-in) | Magector |
35
36
  |---|---|---|
@@ -52,13 +53,14 @@ Without Magector, asking Claude Code or Cursor *"how are checkout totals calcula
52
53
  ## Features
53
54
 
54
55
  - **Semantic search** -- find code by meaning, not exact keywords
55
- - **94.9% accuracy** -- validated with 101 E2E test queries across 16 tool categories, plus 557 Rust-level test cases
56
+ - **99.2% accuracy** -- validated with 101 E2E test queries across 16 tool categories, plus 557 Rust-level test cases
56
57
  - **Hybrid search** -- combines semantic vector similarity with keyword re-ranking for best-of-both-worlds results
57
58
  - **Structured JSON output** -- results include file path, class name, methods list, role badges, and content snippets for minimal round-trips
58
59
  - **Persistent serve mode** -- keeps ONNX model and HNSW index resident in memory, eliminating cold-start latency
59
60
  - **ONNX embeddings** -- native 384-dim transformer embeddings via ONNX Runtime
60
- - **36K+ vectors** -- indexes the complete Magento 2 codebase including framework internals
61
+ - **36K+ vectors** -- indexes the complete Magento 2 / Adobe Commerce codebase including framework internals
61
62
  - **Magento-aware** -- understands controllers, plugins, observers, blocks, resolvers, repositories, and 20+ Magento patterns
63
+ - **Adobe Commerce compatible** -- works with both Magento Open Source and Adobe Commerce (B2B, Staging, and all Commerce-specific modules)
62
64
  - **AST-powered** -- tree-sitter parsing for PHP and JavaScript extracts classes, methods, namespaces, and inheritance
63
65
  - **Cross-tool discovery** -- tool descriptions include keywords and "See also" references so AI clients find the right tool on the first try
64
66
  - **Diff analysis** -- risk scoring and change classification for git commits and staged changes
@@ -72,19 +74,22 @@ Without Magector, asking Claude Code or Cursor *"how are checkout totals calcula
72
74
  ## Architecture
73
75
 
74
76
  ```mermaid
75
- block-beta
76
- columns 2
77
- block:rust["Rust Core"]:1
78
- A["Tree-sitter AST Parser\nPHP + JS"]
79
- B["Magento Pattern Detection\n20+ patterns"]
80
- C["ONNX Embedder\nMiniLM-L6-v2 · 384 dim"]
81
- D["HNSW Vector DB\n+ Hybrid Reranking"]
77
+ flowchart TD
78
+ subgraph rust ["Rust Core"]
79
+ A["AST Parser · PHP + JS"]
80
+ B["Pattern Detection · 20+"]
81
+ C["ONNX Embedder · 384d"]
82
+ D["HNSW + Reranking"]
83
+ A --> B --> C --> D
82
84
  end
83
- block:node["Node.js Layer"]:1
84
- E["MCP Server\n19 tools · JSON output"]
85
- F["Persistent Serve Process\nstdin/stdout JSON"]
86
- G["CLI Interface\ninit · index · search · serve"]
85
+ subgraph node ["Node.js Layer"]
86
+ E["MCP Server · 19 tools"]
87
+ F["Persistent Serve"]
88
+ G["CLI · init/index/search"]
89
+ E --> F
90
+ G --> F
87
91
  end
92
+ node -->|stdin/stdout JSON| rust
88
93
 
89
94
  style rust fill:#f4a460,color:#000
90
95
  style node fill:#68b684,color:#000
@@ -93,26 +98,25 @@ block-beta
93
98
  ### Indexing Pipeline
94
99
 
95
100
  ```mermaid
96
- flowchart LR
97
- A[Source File\n.php .xml .js .phtml .graphqls] --> B[Tree-sitter\nAST Parser]
98
- B --> C[Magento Pattern\nDetection]
99
- C --> D[Search Text\nEnrichment]
100
- D --> E[ONNX Runtime\nMiniLM-L6-v2]
101
- E --> F[384-dim\nEmbedding]
102
- A --> G[Metadata\npath · class · namespace\nmethods · patterns]
103
- F --> H[(HNSW Index\n35,795 vectors)]
104
- G --> H
101
+ flowchart TD
102
+ A[Source File] --> B[AST Parser]
103
+ B --> C[Pattern Detection]
104
+ C --> D[Text Enrichment]
105
+ D --> E[ONNX Embedding]
106
+ E --> F[(HNSW Index)]
107
+ A --> G[Metadata]
108
+ G --> F
105
109
  ```
106
110
 
107
111
  ### Search Pipeline
108
112
 
109
113
  ```mermaid
110
- flowchart LR
111
- Q[Query Text] --> E1[Pattern Synonym\nEnrichment]
112
- E1 --> E2[ONNX Embedding\n384-dim vector]
113
- E2 --> H[HNSW\nNearest Neighbor]
114
- H --> R[Hybrid\nReranking]
115
- R --> J[Structured JSON\npath · class · methods\nbadges · snippet]
114
+ flowchart TD
115
+ Q[Query] --> E1[Synonym Enrichment]
116
+ E1 --> E2[ONNX Embedding]
117
+ E2 --> H[HNSW Search]
118
+ H --> R[Hybrid Reranking]
119
+ R --> J[Structured JSON]
116
120
  ```
117
121
 
118
122
  ### Components
@@ -135,22 +139,22 @@ flowchart LR
135
139
 
136
140
  - [Node.js 18+](https://nodejs.org)
137
141
 
138
- ### 1. Initialize in Your Magento Project
142
+ ### 1. Initialize in Your Project
139
143
 
140
144
  ```bash
141
- cd /path/to/your/magento2
145
+ cd /path/to/your/magento2 # or Adobe Commerce project
142
146
  npx magector init
143
147
  ```
144
148
 
145
149
  This single command handles the entire setup:
146
150
 
147
151
  ```mermaid
148
- flowchart LR
149
- A["npx magector init"] --> B[Verify Magento\nProject]
150
- B --> C[Download ONNX Model\n~86MB · cached]
151
- C --> D[Index Codebase\n36K+ vectors]
152
- D --> E[Detect IDE\nCursor / Claude Code]
153
- E --> F[Write Config\nMCP + IDE rules]
152
+ flowchart TD
153
+ A["npx magector init"] --> B[Verify Project]
154
+ B --> C[Download Model]
155
+ C --> D[Index Codebase]
156
+ D --> E[Detect IDE]
157
+ E --> F[Write Config]
154
158
  F --> G[Update .gitignore]
155
159
  ```
156
160
 
@@ -265,7 +269,7 @@ npx magector help # Show help
265
269
 
266
270
  ## MCP Server Tools
267
271
 
268
- The MCP server exposes 19 tools for AI-assisted Magento 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.
272
+ The MCP server exposes 19 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.
269
273
 
270
274
  ### Output Format
271
275
 
@@ -341,35 +345,35 @@ All search tools return structured JSON:
341
345
  Each tool description includes "See also" hints to help AI clients chain tools effectively:
342
346
 
343
347
  ```mermaid
344
- graph LR
345
- class["find_class"] --> plugin["find_plugin"]
346
- class --> pref["find_preference"]
347
- class --> method["find_method"]
348
- config["find_config"] --> observer["find_observer"]
349
- config --> pref
350
- config --> api["find_api"]
351
- plugin --> class
352
- plugin --> method
353
- template["find_template"] --> block["find_block"]
354
- block --> template
355
- block --> config
356
- db["find_db_schema"] --> class
357
- graphql["find_graphql"] --> class
358
- graphql --> method
359
- controller["find_controller"] --> config
360
-
361
- style class fill:#4a90d9,color:#fff
362
- style method fill:#4a90d9,color:#fff
363
- style config fill:#e8a838,color:#000
364
- style plugin fill:#d94a4a,color:#fff
365
- style observer fill:#d94a4a,color:#fff
366
- style pref fill:#e8a838,color:#000
348
+ graph TD
349
+ cls["find_class"] --> plg["find_plugin"]
350
+ cls --> prf["find_preference"]
351
+ cls --> mtd["find_method"]
352
+ cfg["find_config"] --> obs["find_observer"]
353
+ cfg --> prf
354
+ cfg --> api["find_api"]
355
+ plg --> cls
356
+ plg --> mtd
357
+ tpl["find_template"] --> blk["find_block"]
358
+ blk --> tpl
359
+ blk --> cfg
360
+ dbs["find_db_schema"] --> cls
361
+ gql["find_graphql"] --> cls
362
+ gql --> mtd
363
+ ctl["find_controller"] --> cfg
364
+
365
+ style cls fill:#4a90d9,color:#fff
366
+ style mtd fill:#4a90d9,color:#fff
367
+ style cfg fill:#e8a838,color:#000
368
+ style plg fill:#d94a4a,color:#fff
369
+ style obs fill:#d94a4a,color:#fff
370
+ style prf fill:#e8a838,color:#000
367
371
  style api fill:#e8a838,color:#000
368
- style template fill:#68b684,color:#000
369
- style block fill:#68b684,color:#000
370
- style db fill:#9b59b6,color:#fff
371
- style graphql fill:#9b59b6,color:#fff
372
- style controller fill:#4a90d9,color:#fff
372
+ style tpl fill:#68b684,color:#000
373
+ style blk fill:#68b684,color:#000
374
+ style dbs fill:#9b59b6,color:#fff
375
+ style gql fill:#9b59b6,color:#fff
376
+ style ctl fill:#4a90d9,color:#fff
373
377
  ```
374
378
 
375
379
  ### Query Examples
@@ -425,24 +429,20 @@ Magector is validated at two levels:
425
429
  config:
426
430
  themeVariables:
427
431
  pie1: "#4caf50"
428
- pie2: "#ff9800"
429
- pie3: "#2196f3"
430
- pie4: "#9c27b0"
432
+ pie2: "#f44336"
431
433
  ---
432
- pie title Accuracy Breakdown (94.9/100)
433
- "Pass Rate (100%)" : 100
434
- "Precision (93.2%)" : 93.2
435
- "MRR (99.2%)" : 99.2
436
- "NDCG@10 (85.5%)" : 85.5
434
+ pie title Test Pass Rate (101 queries)
435
+ "Passed (101)" : 101
436
+ "Failed (0)" : 0
437
437
  ```
438
438
 
439
439
  | Metric | Value |
440
440
  |--------|-------|
441
- | **Grade** | **A (94.9/100)** |
441
+ | **Grade** | **A+ (99.2/100)** |
442
442
  | **Pass rate** | 101/101 (100%) |
443
- | **Precision** | 93.2% |
444
- | **MRR** | 99.2% |
445
- | **NDCG@10** | 85.5% |
443
+ | **Precision** | 98.7% |
444
+ | **MRR** | 99.3% |
445
+ | **NDCG@10** | 98.7% |
446
446
  | **Index size** | 35,795 vectors |
447
447
  | **Query time** | 10-45ms |
448
448
 
@@ -451,19 +451,20 @@ pie title Accuracy Breakdown (94.9/100)
451
451
  | Tool | Pass | Precision | MRR | NDCG |
452
452
  |------|------|-----------|-----|------|
453
453
  | find_class | 100% | 100% | 100% | 100% |
454
- | find_method | 100% | 89% | 100% | 87% |
455
- | find_controller | 100% | 100% | 100% | -- |
454
+ | find_method | 100% | 98% | 92% | 97% |
455
+ | find_controller | 100% | 100% | 100% | 100% |
456
456
  | find_observer | 100% | 100% | 100% | 100% |
457
- | find_plugin | 100% | 96% | 100% | 100% |
457
+ | find_plugin | 100% | 100% | 100% | 100% |
458
458
  | find_preference | 100% | 100% | 100% | 100% |
459
459
  | find_api | 100% | 100% | 100% | 100% |
460
460
  | find_cron | 100% | 100% | 100% | 100% |
461
461
  | find_db_schema | 100% | 100% | 100% | 100% |
462
462
  | find_graphql | 100% | 100% | 100% | 100% |
463
463
  | find_block | 100% | 100% | 100% | 100% |
464
- | find_config | 100% | 89% | 89% | 93% |
465
- | find_template | 100% | 84% | 100% | 100% |
466
- | search | 100% | 99% | 100% | 100% |
464
+ | find_config | 100% | 100% | 100% | 100% |
465
+ | find_template | 100% | 100% | 100% | 100% |
466
+ | search | 100% | 100% | 100% | 100% |
467
+ | module_structure | 100% | 100% | 100% | 100% |
467
468
 
468
469
  ### Integration Tests
469
470
 
@@ -548,7 +549,7 @@ magector/
548
549
 
549
550
  ### 1. Indexing
550
551
 
551
- Magector scans every `.php`, `.js`, `.xml`, `.phtml`, and `.graphqls` file in a Magento codebase:
552
+ Magector scans every `.php`, `.js`, `.xml`, `.phtml`, and `.graphqls` file in a Magento 2 or Adobe Commerce codebase:
552
553
 
553
554
  1. **AST parsing** -- Tree-sitter extracts class names, namespaces, methods, inheritance, and interface implementations from PHP and JavaScript files
554
555
  2. **Pattern detection** -- Identifies Magento-specific patterns: controllers, models, repositories, plugins, observers, blocks, GraphQL resolvers, admin grids, cron jobs, and more
@@ -569,23 +570,20 @@ Magector scans every `.php`, `.js`, `.xml`, `.phtml`, and `.graphqls` file in a
569
570
  The MCP server spawns a persistent Rust process (`magector-core serve`) that keeps the ONNX model and HNSW index loaded in memory. Queries are sent as JSON over stdin and responses returned via stdout -- eliminating the ~2.6s cold-start overhead of loading the model per query. Falls back to single-shot `execFileSync` if the serve process is unavailable.
570
571
 
571
572
  ```mermaid
572
- flowchart TB
573
+ flowchart TD
573
574
  subgraph startup ["Startup (once)"]
574
- S1[Load ONNX Model\n~500ms] --> S2[Load HNSW Index\n~1s]
575
- S2 --> S3["Send ready signal\n{ok:true, ready:true}"]
575
+ S1[Load Model] --> S2[Load Index]
576
+ S2 --> S3[Ready Signal]
576
577
  end
577
-
578
- subgraph query ["Per Query (~10-45ms)"]
579
- Q1["stdin: JSON query"] --> Q2[Embed query\n~2ms]
580
- Q2 --> Q3[HNSW search\n~5-15ms]
581
- Q3 --> Q4[Hybrid rerank\n~1ms]
582
- Q4 --> Q5["stdout: JSON response"]
578
+ subgraph query ["Per Query (10-45ms)"]
579
+ Q1[stdin JSON] --> Q2[Embed]
580
+ Q2 --> Q3[HNSW Search]
581
+ Q3 --> Q4[Rerank]
582
+ Q4 --> Q5[stdout JSON]
583
583
  end
584
-
585
584
  startup --> query
586
-
587
- subgraph fallback ["Fallback (if serve unavailable)"]
588
- F1["execFileSync\n~2.6s cold start"]
585
+ subgraph fallback ["Fallback"]
586
+ F1[execFileSync ~2.6s]
589
587
  end
590
588
 
591
589
  style startup fill:#e8f4e8,color:#000
@@ -599,20 +597,20 @@ The MCP server delegates all search/index operations to the Rust core binary. An
599
597
 
600
598
  ```mermaid
601
599
  sequenceDiagram
602
- participant Dev as Developer
603
- participant AI as AI Assistant
604
- participant MCP as MCP Server<br/>(Node.js)
605
- participant Rust as Persistent Rust<br/>Process
606
- participant HNSW as HNSW Index<br/>(35K vectors)
607
-
608
- Dev->>AI: "How does checkout totals calculation work?"
609
- AI->>MCP: magento_search("checkout totals collector")
610
- MCP->>Rust: {"command":"search","query":"...","limit":10}
611
- Rust->>HNSW: Embed query → nearest neighbor
612
- HNSW-->>Rust: Top candidates + scores
613
- Rust-->>MCP: {"ok":true,"data":[...]}
614
- MCP-->>AI: Structured JSON with paths,<br/>methods, badges, snippets
615
- AI-->>Dev: TotalsCollector.php,<br/>Address/Total/Collector.php, ...
600
+ participant Dev
601
+ participant AI
602
+ participant MCP
603
+ participant Rust
604
+ participant HNSW
605
+
606
+ Dev->>AI: "checkout totals?"
607
+ AI->>MCP: magento_search(...)
608
+ MCP->>Rust: JSON query
609
+ Rust->>HNSW: embed + search
610
+ HNSW-->>Rust: candidates
611
+ Rust-->>MCP: JSON results
612
+ MCP-->>AI: paths, methods, badges
613
+ AI-->>Dev: TotalsCollector.php
616
614
  ```
617
615
 
618
616
  ---
@@ -621,38 +619,29 @@ sequenceDiagram
621
619
 
622
620
  ```mermaid
623
621
  mindmap
624
- root((Magento 2\nPatterns))
625
- PHP Classes
622
+ root((Patterns))
623
+ PHP
626
624
  Controller
627
625
  Model
628
626
  Repository
629
627
  Block
630
628
  Helper
631
629
  ViewModel
632
- Console Command
633
- Data Provider
634
630
  Interception
635
631
  Plugin
636
632
  Observer
637
633
  Preference
638
- XML Config
634
+ XML
639
635
  di.xml
640
636
  events.xml
641
637
  webapi.xml
642
638
  routes.xml
643
- system.xml
644
- layout XML
645
- module.xml
646
639
  crontab.xml
647
640
  db_schema.xml
648
641
  Frontend
649
- PHTML Template
642
+ Template
650
643
  JavaScript
651
- GraphQL Schema
652
- GraphQL Resolver
653
- Database
654
- Setup Patch
655
- Declarative Schema
644
+ GraphQL
656
645
  ```
657
646
 
658
647
  Magector understands these Magento 2 architectural patterns:
@@ -856,23 +845,24 @@ struct IndexMetadata {
856
845
 
857
846
  ```mermaid
858
847
  gantt
859
- title Magector Development Roadmap
848
+ title Roadmap
860
849
  dateFormat YYYY-MM
861
- axisFormat %b %Y
862
- section Completed
863
- Hybrid search (semantic + keyword) :done, 2025-01, 2025-02
864
- Persistent serve mode :done, 2025-02, 2025-03
865
- Structured JSON output :done, 2025-03, 2025-03
866
- Cross-tool discovery hints :done, 2025-03, 2025-03
867
- E2E accuracy test suite (101 queries) :done, 2025-03, 2025-03
868
- section Planned
869
- Method-level chunking :active, 2025-04, 2025-05
870
- Query intent classification :2025-05, 2025-06
871
- Vector-level file type filtering :2025-06, 2025-07
872
- Incremental indexing :2025-07, 2025-08
873
- VSCode extension :2025-08, 2025-10
874
- Web UI for browsing results :2025-10, 2025-12
875
- Magento Commerce support :2026-01, 2026-03
850
+ axisFormat %b
851
+ section Done
852
+ Hybrid search :done, 2025-01, 30d
853
+ Serve mode :done, 2025-02, 30d
854
+ JSON output :done, 2025-03, 15d
855
+ Cross-tool hints :done, 2025-03, 15d
856
+ E2E tests :done, 2025-03, 15d
857
+ Adobe Commerce :done, 2025-03, 15d
858
+ section Next
859
+ Method chunking :active, 2025-04, 30d
860
+ Intent detection :2025-05, 30d
861
+ Type filtering :2025-06, 30d
862
+ Incremental index :2025-07, 30d
863
+ section Future
864
+ VSCode extension :2025-08, 60d
865
+ Web UI :2025-10, 60d
876
866
  ```
877
867
 
878
868
  - [x] Hybrid search (semantic + keyword re-ranking)
@@ -880,13 +870,13 @@ gantt
880
870
  - [x] Structured JSON output (methods, badges, snippets)
881
871
  - [x] Cross-tool discovery hints for AI clients
882
872
  - [x] E2E accuracy test suite (101 queries)
873
+ - [x] Adobe Commerce support (B2B, Staging, and all Commerce-specific modules)
883
874
  - [ ] Method-level chunking (per-method vectors for direct method search)
884
875
  - [ ] Query intent classification (auto-detect "give me XML" vs "give me PHP")
885
876
  - [ ] Filtered search by file type at the vector level
886
877
  - [ ] Incremental indexing (only re-index changed files)
887
878
  - [ ] VSCode extension
888
879
  - [ ] Web UI for browsing results
889
- - [ ] Support for Magento 2 Commerce (B2B, Staging modules)
890
880
 
891
881
  ---
892
882
 
@@ -908,4 +898,4 @@ Contributions are welcome. Please:
908
898
 
909
899
  ---
910
900
 
911
- Built with Rust and Node.js for the Magento community.
901
+ Built with Rust and Node.js for the Magento and Adobe Commerce community.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magector",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
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": "1.2.13",
37
- "@magector/cli-linux-x64": "1.2.13",
38
- "@magector/cli-linux-arm64": "1.2.13",
39
- "@magector/cli-win32-x64": "1.2.13"
36
+ "@magector/cli-darwin-arm64": "1.2.15",
37
+ "@magector/cli-linux-x64": "1.2.15",
38
+ "@magector/cli-linux-arm64": "1.2.15",
39
+ "@magector/cli-win32-x64": "1.2.15"
40
40
  },
41
41
  "keywords": [
42
42
  "magento",
package/src/mcp-server.js CHANGED
@@ -697,19 +697,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
697
697
 
698
698
  case 'magento_find_method': {
699
699
  const query = `method ${args.methodName} function ${args.className || ''}`.trim();
700
- const raw = await rustSearchAsync(query, 30);
700
+ const raw = await rustSearchAsync(query, 50);
701
701
  const methodLower = args.methodName.toLowerCase();
702
+ // Hard-filter: only results that actually define/contain this method
702
703
  let results = raw.map(normalizeResult).filter(r =>
703
704
  r.methodName?.toLowerCase() === methodLower ||
704
- r.methodName?.toLowerCase().includes(methodLower) ||
705
- r.methods?.some(m => m.toLowerCase() === methodLower || m.toLowerCase().includes(methodLower)) ||
706
- r.path?.toLowerCase().includes(methodLower)
705
+ r.methods?.some(m => m.toLowerCase() === methodLower || m.toLowerCase().includes(methodLower))
707
706
  );
707
+ // If not enough results from methods[], fall back to path-based matching
708
+ if (results.length < 3) {
709
+ const pathFallback = raw.map(normalizeResult).filter(r =>
710
+ r.path?.toLowerCase().includes(methodLower) &&
711
+ !results.some(existing => existing.path === r.path)
712
+ );
713
+ results = results.concat(pathFallback);
714
+ }
708
715
  // Boost exact method matches to top
709
716
  results = results.map(r => {
710
- const exact = r.methodName?.toLowerCase() === methodLower ||
711
- r.methods?.some(m => m.toLowerCase() === methodLower);
712
- return { ...r, score: (r.score || 0) + (exact ? 0.5 : 0) };
717
+ let bonus = 0;
718
+ if (r.methods?.some(m => m.toLowerCase() === methodLower)) bonus += 0.5;
719
+ if (r.methodName?.toLowerCase() === methodLower) bonus += 0.3;
720
+ return { ...r, score: (r.score || 0) + bonus };
713
721
  }).sort((a, b) => b.score - a.score);
714
722
  return {
715
723
  content: [{
@@ -722,18 +730,24 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
722
730
  case 'magento_find_config': {
723
731
  let query = args.query;
724
732
  if (args.configType && args.configType !== 'other') {
725
- query = `${args.configType}.xml ${args.query}`;
733
+ query = `${args.configType}.xml xml config ${args.query}`;
726
734
  }
727
- const raw = await rustSearchAsync(query, 30);
728
- const pathBoost = args.configType ? [`${args.configType}.xml`] : ['.xml'];
735
+ const raw = await rustSearchAsync(query, 100);
729
736
  let normalized = raw.map(normalizeResult);
730
- // Prefer XML results when configType is specified, but don't hard-exclude
731
- if (args.configType) {
732
- const xmlOnly = normalized.filter(r =>
733
- r.type === 'xml' || r.path?.endsWith('.xml') || r.path?.includes('.xml')
737
+ // Hard-filter to XML results
738
+ const xmlOnly = normalized.filter(r =>
739
+ r.type === 'xml' || r.path?.endsWith('.xml') || r.path?.includes('.xml')
740
+ );
741
+ if (xmlOnly.length > 0) normalized = xmlOnly;
742
+ // Hard-filter to specific config type when specified
743
+ if (args.configType && args.configType !== 'other') {
744
+ const configTypeFile = `${args.configType}.xml`;
745
+ const typeSpecific = normalized.filter(r =>
746
+ r.path?.includes(configTypeFile)
734
747
  );
735
- if (xmlOnly.length > 0) normalized = xmlOnly;
748
+ if (typeSpecific.length >= 3) normalized = typeSpecific;
736
749
  }
750
+ const pathBoost = args.configType ? [`${args.configType}.xml`] : ['.xml'];
737
751
  const results = rerank(normalized, { fileType: 'xml', pathContains: pathBoost });
738
752
  return {
739
753
  content: [{
@@ -747,8 +761,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
747
761
  let query = args.query;
748
762
  if (args.area) query = `${args.area} ${query}`;
749
763
  query += ' template phtml';
750
- const raw = await rustSearchAsync(query, 15);
751
- const results = rerank(raw.map(normalizeResult), { pathContains: ['.phtml'] });
764
+ const raw = await rustSearchAsync(query, 50);
765
+ // Hard-filter to .phtml template files only
766
+ let results = raw.map(normalizeResult).filter(r =>
767
+ r.path?.includes('.phtml') || r.type === 'template'
768
+ );
769
+ results = rerank(results, { pathContains: ['.phtml'] });
752
770
  return {
753
771
  content: [{
754
772
  type: 'text',
@@ -850,10 +868,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
850
868
  const namespaceParts = parts.map(p => p.charAt(0).toUpperCase() + p.slice(1));
851
869
  const query = `${namespaceParts.join(' ')} controller execute action`;
852
870
 
853
- const raw = await rustSearchAsync(query, 30);
871
+ const raw = await rustSearchAsync(query, 50);
872
+ // Prefer path-based controller detection, fall back to isController flag
854
873
  let results = raw.map(normalizeResult).filter(r =>
855
- r.isController || r.path?.includes('/Controller/')
874
+ r.path?.includes('/Controller/')
856
875
  );
876
+ if (results.length < 5) {
877
+ // Add isController-flagged results not already included
878
+ const extra = raw.map(normalizeResult).filter(r =>
879
+ r.isController && !results.some(e => e.path === r.path)
880
+ );
881
+ results = results.concat(extra);
882
+ }
857
883
 
858
884
  // Boost results whose path matches the route segments
859
885
  if (parts.length >= 2) {
@@ -947,11 +973,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
947
973
  }
948
974
 
949
975
  case 'magento_module_structure': {
950
- const raw = await rustSearchAsync(args.moduleName, 100);
951
- const moduleName = args.moduleName.replace('_', '/');
952
- const results = raw.map(normalizeResult).filter(r =>
953
- r.path?.includes(moduleName) || r.module?.includes(args.moduleName)
954
- );
976
+ const raw = await rustSearchAsync(args.moduleName, 200);
977
+ // Support both app/code (Magento/Catalog/) and vendor (module-catalog/) paths
978
+ const modulePath = args.moduleName.replace('_', '/') + '/';
979
+ const parts = args.moduleName.split('_');
980
+ const vendorPath = parts.length === 2
981
+ ? `module-${parts[1].toLowerCase()}/`
982
+ : '';
983
+ const results = raw.map(normalizeResult).filter(r => {
984
+ const path = r.path || '';
985
+ const mod = r.module || '';
986
+ // Exact module match or directory-level path match (trailing slash prevents Catalog matching CatalogRule)
987
+ return mod === args.moduleName ||
988
+ path.includes(modulePath) ||
989
+ (vendorPath && path.toLowerCase().includes(vendorPath));
990
+ });
955
991
 
956
992
  const structure = {
957
993
  controllers: results.filter(r => r.isController || r.path?.includes('/Controller/')),
@@ -970,24 +1006,39 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
970
1006
  )
971
1007
  };
972
1008
 
973
- let text = `## Module Structure: ${args.moduleName}\n\n`;
974
-
1009
+ // Build structured JSON output for module structure
1010
+ const structureOutput = {
1011
+ module: args.moduleName,
1012
+ totalFiles: results.length,
1013
+ categories: {}
1014
+ };
975
1015
  for (const [category, items] of Object.entries(structure)) {
976
1016
  if (items.length > 0) {
977
- text += `### ${category.charAt(0).toUpperCase() + category.slice(1)} (${items.length})\n`;
978
- items.slice(0, 10).forEach(item => {
979
- text += `- ${item.className || item.path} (${item.path})\n`;
980
- });
981
- if (items.length > 10) text += ` ... and ${items.length - 10} more\n`;
982
- text += '\n';
1017
+ structureOutput.categories[category] = {
1018
+ count: items.length,
1019
+ files: items.slice(0, 10).map(item => ({
1020
+ path: item.path,
1021
+ className: item.className || null,
1022
+ methods: item.methods?.length > 0 ? item.methods : undefined
1023
+ }))
1024
+ };
983
1025
  }
984
1026
  }
985
1027
 
986
- if (results.length === 0) {
987
- text += 'No code found for this module. Try re-indexing or check the module name.';
988
- }
1028
+ // Return both JSON and formatted summary
1029
+ const jsonOutput = JSON.stringify({
1030
+ results: results.slice(0, 50).map((r, i) => ({
1031
+ rank: i + 1,
1032
+ path: r.path,
1033
+ className: r.className || undefined,
1034
+ magentoType: r.magentoType || undefined,
1035
+ module: r.module || undefined
1036
+ })),
1037
+ count: results.length,
1038
+ structure: structureOutput.categories
1039
+ });
989
1040
 
990
- return { content: [{ type: 'text', text }] };
1041
+ return { content: [{ type: 'text', text: jsonOutput }] };
991
1042
  }
992
1043
 
993
1044
  case 'magento_analyze_diff': {