magector 1.3.2 → 1.3.4
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 +5 -5
- package/src/init.js +7 -5
- package/src/mcp-server.js +24 -4
- package/src/templates/cursor-rules-mdc.js +52 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magector",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
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.3.
|
|
37
|
-
"@magector/cli-linux-x64": "1.3.
|
|
38
|
-
"@magector/cli-linux-arm64": "1.3.
|
|
39
|
-
"@magector/cli-win32-x64": "1.3.
|
|
36
|
+
"@magector/cli-darwin-arm64": "1.3.4",
|
|
37
|
+
"@magector/cli-linux-x64": "1.3.4",
|
|
38
|
+
"@magector/cli-linux-arm64": "1.3.4",
|
|
39
|
+
"@magector/cli-win32-x64": "1.3.4"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
|
42
42
|
"magento",
|
package/src/init.js
CHANGED
|
@@ -6,7 +6,7 @@ import { execFileSync } from 'child_process';
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { resolveBinary } from './binary.js';
|
|
8
8
|
import { ensureModels } from './model.js';
|
|
9
|
-
import {
|
|
9
|
+
import { CURSOR_RULES_MDC } from './templates/cursor-rules-mdc.js';
|
|
10
10
|
import { CLAUDE_MD } from './templates/claude-md.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -39,7 +39,7 @@ function isMagentoProject(projectPath) {
|
|
|
39
39
|
function detectIDEs(projectPath) {
|
|
40
40
|
const cursor =
|
|
41
41
|
existsSync(path.join(projectPath, '.cursor')) ||
|
|
42
|
-
existsSync(path.join(projectPath, '.
|
|
42
|
+
existsSync(path.join(projectPath, '.cursor', 'rules'));
|
|
43
43
|
const claude =
|
|
44
44
|
existsSync(path.join(projectPath, '.claude')) ||
|
|
45
45
|
existsSync(path.join(projectPath, 'CLAUDE.md')) ||
|
|
@@ -131,9 +131,11 @@ function writeRules(projectPath, ides) {
|
|
|
131
131
|
const writeClaude = ides.claude || (!ides.cursor && !ides.claude);
|
|
132
132
|
|
|
133
133
|
if (writeCursor) {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
const rulesDir = path.join(projectPath, '.cursor', 'rules');
|
|
135
|
+
mkdirSync(rulesDir, { recursive: true });
|
|
136
|
+
const mdcPath = path.join(rulesDir, 'magector.mdc');
|
|
137
|
+
writeFileSync(mdcPath, CURSOR_RULES_MDC);
|
|
138
|
+
written.push('.cursor/rules/magector.mdc (created)');
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
if (writeClaude) {
|
package/src/mcp-server.js
CHANGED
|
@@ -72,8 +72,11 @@ let serveReady = false;
|
|
|
72
72
|
let servePending = new Map();
|
|
73
73
|
let serveNextId = 1;
|
|
74
74
|
let serveReadline = null;
|
|
75
|
+
let serveReadyPromise = null;
|
|
76
|
+
let serveReadyResolve = null;
|
|
75
77
|
|
|
76
78
|
function startServeProcess() {
|
|
79
|
+
serveReadyPromise = new Promise((resolve) => { serveReadyResolve = resolve; });
|
|
77
80
|
try {
|
|
78
81
|
const args = [
|
|
79
82
|
'serve',
|
|
@@ -87,8 +90,8 @@ function startServeProcess() {
|
|
|
87
90
|
const proc = spawn(config.rustBinary, args,
|
|
88
91
|
{ stdio: ['pipe', 'pipe', 'pipe'], env: rustEnv });
|
|
89
92
|
|
|
90
|
-
proc.on('error', () => { serveProcess = null; serveReady = false; });
|
|
91
|
-
proc.on('exit', () => { serveProcess = null; serveReady = false; });
|
|
93
|
+
proc.on('error', () => { serveProcess = null; serveReady = false; if (serveReadyResolve) { serveReadyResolve(false); serveReadyResolve = null; } });
|
|
94
|
+
proc.on('exit', () => { serveProcess = null; serveReady = false; if (serveReadyResolve) { serveReadyResolve(false); serveReadyResolve = null; } });
|
|
92
95
|
proc.stderr.on('data', () => {}); // drain stderr
|
|
93
96
|
|
|
94
97
|
serveReadline = createInterface({ input: proc.stdout });
|
|
@@ -99,6 +102,7 @@ function startServeProcess() {
|
|
|
99
102
|
// First line is ready signal
|
|
100
103
|
if (parsed.ready) {
|
|
101
104
|
serveReady = true;
|
|
105
|
+
if (serveReadyResolve) { serveReadyResolve(true); serveReadyResolve = null; }
|
|
102
106
|
return;
|
|
103
107
|
}
|
|
104
108
|
|
|
@@ -114,6 +118,7 @@ function startServeProcess() {
|
|
|
114
118
|
} catch {
|
|
115
119
|
serveProcess = null;
|
|
116
120
|
serveReady = false;
|
|
121
|
+
if (serveReadyResolve) { serveReadyResolve(false); serveReadyResolve = null; }
|
|
117
122
|
}
|
|
118
123
|
}
|
|
119
124
|
|
|
@@ -138,6 +143,11 @@ async function rustSearchAsync(query, limit = 10) {
|
|
|
138
143
|
return searchCache.get(cacheKey);
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
// Wait for serve process if it's starting up but not yet ready
|
|
147
|
+
if (serveProcess && !serveReady && serveReadyPromise) {
|
|
148
|
+
await Promise.race([serveReadyPromise, new Promise(r => setTimeout(() => r(false), 10000))]);
|
|
149
|
+
}
|
|
150
|
+
|
|
141
151
|
// Try persistent serve process first
|
|
142
152
|
if (serveProcess && serveReady) {
|
|
143
153
|
try {
|
|
@@ -1176,8 +1186,18 @@ async function main() {
|
|
|
1176
1186
|
// Try to start persistent Rust serve process for fast queries
|
|
1177
1187
|
try {
|
|
1178
1188
|
startServeProcess();
|
|
1179
|
-
//
|
|
1180
|
-
|
|
1189
|
+
// Wait for the serve process to load ONNX model + HNSW index (up to 15s)
|
|
1190
|
+
if (serveReadyPromise) {
|
|
1191
|
+
const ready = await Promise.race([
|
|
1192
|
+
serveReadyPromise,
|
|
1193
|
+
new Promise(r => setTimeout(() => r(false), 15000))
|
|
1194
|
+
]);
|
|
1195
|
+
if (ready) {
|
|
1196
|
+
console.error('Serve process ready (persistent mode)');
|
|
1197
|
+
} else {
|
|
1198
|
+
console.error('Serve process not ready in time, will use fallback');
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1181
1201
|
} catch {
|
|
1182
1202
|
// Non-fatal: falls back to execFileSync per query
|
|
1183
1203
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .cursor/rules/magector.mdc content for Magento projects using Magector.
|
|
3
|
+
* This is the new Cursor rules format (MDC) that replaces .cursorrules.
|
|
4
|
+
*/
|
|
5
|
+
export const CURSOR_RULES_MDC = `---
|
|
6
|
+
description: Magento 2 semantic code search with Magector MCP tools
|
|
7
|
+
globs:
|
|
8
|
+
alwaysApply: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Magento 2 Development Rules (Magector)
|
|
12
|
+
|
|
13
|
+
## Semantic Search First
|
|
14
|
+
|
|
15
|
+
Before reading files manually, ALWAYS use Magector MCP tools to find relevant code:
|
|
16
|
+
|
|
17
|
+
1. \`magento_search\` — Natural language search across the entire codebase
|
|
18
|
+
2. \`magento_find_class\` — Find a PHP class, interface, or trait
|
|
19
|
+
3. \`magento_find_method\` — Find method implementations
|
|
20
|
+
4. \`magento_find_config\` — Find XML configuration (di.xml, events.xml, etc.)
|
|
21
|
+
5. \`magento_find_template\` — Find PHTML templates
|
|
22
|
+
6. \`magento_find_plugin\` — Find interceptor plugins
|
|
23
|
+
7. \`magento_find_observer\` — Find event observers
|
|
24
|
+
8. \`magento_find_preference\` — Find DI preference overrides
|
|
25
|
+
9. \`magento_find_api\` — Find REST/SOAP API endpoints
|
|
26
|
+
10. \`magento_find_controller\` — Find controllers by route
|
|
27
|
+
11. \`magento_find_block\` — Find Block classes
|
|
28
|
+
12. \`magento_find_cron\` — Find cron job definitions
|
|
29
|
+
13. \`magento_find_graphql\` — Find GraphQL resolvers and schema
|
|
30
|
+
14. \`magento_find_db_schema\` — Find database table definitions
|
|
31
|
+
15. \`magento_module_structure\` — Get full module structure
|
|
32
|
+
16. \`magento_index\` — Re-index the codebase
|
|
33
|
+
17. \`magento_stats\` — View index statistics
|
|
34
|
+
18. \`magento_analyze_diff\` — Analyze git diffs for risk
|
|
35
|
+
19. \`magento_complexity\` — Analyze code complexity
|
|
36
|
+
|
|
37
|
+
## Writing Effective Queries
|
|
38
|
+
|
|
39
|
+
- Describe what the code DOES, not what it IS: "calculate product price" not "price file"
|
|
40
|
+
- Include Magento terms: "plugin for save", "observer for order place", "checkout totals collector"
|
|
41
|
+
- Be specific: "customer address validation before checkout" not just "validation"
|
|
42
|
+
|
|
43
|
+
## Magento Development Patterns
|
|
44
|
+
|
|
45
|
+
- Always check for existing plugins before modifying core behavior
|
|
46
|
+
- Use dependency injection — never instantiate classes with \`new\`
|
|
47
|
+
- Prefer interfaces over concrete classes
|
|
48
|
+
- Check events.xml for observer hooks before adding plugins
|
|
49
|
+
- Use repositories for entity CRUD, not direct model save
|
|
50
|
+
- Follow PSR-4 autoloading: Vendor\\\\Module\\\\Path\\\\ClassName
|
|
51
|
+
- Use db_schema.xml for database changes, not setup scripts
|
|
52
|
+
`;
|