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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magector",
3
- "version": "1.3.2",
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.2",
37
- "@magector/cli-linux-x64": "1.3.2",
38
- "@magector/cli-linux-arm64": "1.3.2",
39
- "@magector/cli-win32-x64": "1.3.2"
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 { CURSORRULES } from './templates/cursorrules.js';
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, '.cursorrules'));
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 rulesPath = path.join(projectPath, '.cursorrules');
135
- const result = upsertMagectorSection(rulesPath, CURSORRULES, MARKER_START, MARKER_END);
136
- written.push(`.cursorrules (${result})`);
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
- // Give it a moment to load model+index
1180
- await new Promise(r => setTimeout(r, 100));
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
+ `;