@mrxkun/mcfast-mcp 4.0.12 → 4.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrxkun/mcfast-mcp",
3
- "version": "4.0.12",
3
+ "version": "4.0.15",
4
4
  "description": "Ultra-fast code editing with WASM acceleration, fuzzy patching, multi-layer caching, and 8 unified tools. Optimized for AI code assistants with 80-98% latency reduction. Phase 4: ML Intelligence Layer.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -54,16 +54,69 @@ const VERBOSE = process.env.MCFAST_VERBOSE !== 'false'; // Default: true
54
54
 
55
55
  // Memory Engine (initialized lazily)
56
56
  let memoryEngine = null;
57
+ let memoryEngineInitPromise = null;
58
+ let memoryEngineReady = false;
57
59
 
60
+ /**
61
+ * Start background initialization of memory engine
62
+ * Call this on server startup to pre-initialize
63
+ */
64
+ async function backgroundInitializeMemoryEngine() {
65
+ if (memoryEngineInitPromise) return memoryEngineInitPromise;
66
+
67
+ memoryEngineInitPromise = (async () => {
68
+ try {
69
+ memoryEngine = new MemoryEngine({
70
+ apiKey: TOKEN,
71
+ enableSync: true
72
+ });
73
+ // Use a shorter timeout for initialization
74
+ const initTimeout = new Promise((_, reject) => {
75
+ setTimeout(() => reject(new Error('Memory engine init timeout')), 25000);
76
+ });
77
+
78
+ await Promise.race([
79
+ memoryEngine.initialize(process.cwd()),
80
+ initTimeout
81
+ ]);
82
+
83
+ memoryEngineReady = true;
84
+ console.error(`${colors.cyan}[Memory]${colors.reset} Engine initialized successfully`);
85
+ } catch (error) {
86
+ console.error(`${colors.yellow}[Memory]${colors.reset} Engine initialization failed: ${error.message}`);
87
+ // Don't throw - allow partial initialization
88
+ memoryEngineReady = false;
89
+ }
90
+ })();
91
+
92
+ return memoryEngineInitPromise;
93
+ }
94
+
95
+ /**
96
+ * Get memory engine - waits for initialization with timeout
97
+ */
58
98
  async function getMemoryEngine() {
99
+ if (memoryEngine && memoryEngineReady) {
100
+ return memoryEngine;
101
+ }
102
+
103
+ // Wait for initialization with timeout
104
+ if (memoryEngineInitPromise) {
105
+ try {
106
+ await Promise.race([
107
+ memoryEngineInitPromise,
108
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
109
+ ]);
110
+ } catch (error) {
111
+ console.error(`${colors.yellow}[Memory]${colors.reset} Waiting for engine: ${error.message}`);
112
+ }
113
+ }
114
+
115
+ // If still not ready, try to initialize now
59
116
  if (!memoryEngine) {
60
- memoryEngine = new MemoryEngine({
61
- apiKey: TOKEN,
62
- enableSync: true
63
- });
64
- await memoryEngine.initialize(process.cwd());
65
- console.error(`${colors.cyan}[Memory]${colors.reset} Engine initialized`);
117
+ await backgroundInitializeMemoryEngine();
66
118
  }
119
+
67
120
  return memoryEngine;
68
121
  }
69
122
 
@@ -1256,6 +1309,22 @@ async function handleReapply({ instruction, files, errorContext = "", attempt =
1256
1309
  */
1257
1310
  async function handleEdit({ instruction, files, code_edit, dryRun = false }) {
1258
1311
  const editStartTime = Date.now();
1312
+
1313
+ // Validate required parameters
1314
+ if (!instruction) {
1315
+ return {
1316
+ content: [{ type: "text", text: "❌ Error: 'instruction' parameter is required" }],
1317
+ isError: true
1318
+ };
1319
+ }
1320
+
1321
+ if (!files || Object.keys(files).length === 0) {
1322
+ return {
1323
+ content: [{ type: "text", text: "❌ Error: 'files' parameter is required and must contain at least one file" }],
1324
+ isError: true
1325
+ };
1326
+ }
1327
+
1259
1328
  const firstFile = Object.keys(files)[0];
1260
1329
 
1261
1330
  // 1. Retrieve memory context for enhanced understanding
@@ -1266,7 +1335,7 @@ async function handleEdit({ instruction, files, code_edit, dryRun = false }) {
1266
1335
  console.error(`${colors.cyan}[MEMORY]${colors.reset} Retrieved context for edit`);
1267
1336
  }
1268
1337
  } catch (error) {
1269
- console.error(`${colors.yellow}[MEMORY]${colors.reset} Context retrieval failed: ${error.message}`);
1338
+ console.error(`${colors.yellow}[Memory]${colors.reset} Context retrieval failed: ${error.message}`);
1270
1339
  }
1271
1340
 
1272
1341
  // 2. Analyze impact for rename operations
@@ -2512,7 +2581,7 @@ async function handleApplyFast({ instruction, files, dryRun, toolName }) {
2512
2581
  if (!TOKEN) {
2513
2582
  return {
2514
2583
  content: [{ type: "text", text: "❌ Error: MCFAST_TOKEN is missing. Please set it in your MCP config." }],
2515
- isError: true
2584
+ isError: true,
2516
2585
  };
2517
2586
  }
2518
2587
  try {
@@ -2881,6 +2950,18 @@ async function handleMemorySearch({ query, type = 'all', maxResults = 6, minScor
2881
2950
  */
2882
2951
  async function handleMemoryGet({ type }) {
2883
2952
  const start = Date.now();
2953
+
2954
+ // Early return if memory engine not ready
2955
+ if (!memoryEngineReady) {
2956
+ return {
2957
+ content: [{
2958
+ type: "text",
2959
+ text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
2960
+ }],
2961
+ isError: true
2962
+ };
2963
+ }
2964
+
2884
2965
  try {
2885
2966
  const engine = await getMemoryEngine();
2886
2967
  let output = '';
@@ -2946,6 +3027,18 @@ async function handleMemoryGet({ type }) {
2946
3027
  */
2947
3028
  async function handleDetectPatterns() {
2948
3029
  const start = Date.now();
3030
+
3031
+ // Early return if memory engine not ready
3032
+ if (!memoryEngineReady) {
3033
+ return {
3034
+ content: [{
3035
+ type: "text",
3036
+ text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
3037
+ }],
3038
+ isError: true
3039
+ };
3040
+ }
3041
+
2949
3042
  try {
2950
3043
  const engine = await getMemoryEngine();
2951
3044
  const patterns = await engine.detectPatterns();
@@ -2993,6 +3086,18 @@ async function handleDetectPatterns() {
2993
3086
  */
2994
3087
  async function handleGetSuggestions({ currentFile, currentLine }) {
2995
3088
  const start = Date.now();
3089
+
3090
+ // Early return if memory engine not ready
3091
+ if (!memoryEngineReady) {
3092
+ return {
3093
+ content: [{
3094
+ type: "text",
3095
+ text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
3096
+ }],
3097
+ isError: true
3098
+ };
3099
+ }
3100
+
2996
3101
  try {
2997
3102
  const engine = await getMemoryEngine();
2998
3103
  const suggestions = await engine.getSuggestions({
@@ -3046,6 +3151,18 @@ async function handleGetSuggestions({ currentFile, currentLine }) {
3046
3151
  */
3047
3152
  async function handleSelectStrategy({ instruction, files = [] }) {
3048
3153
  const start = Date.now();
3154
+
3155
+ // Early return if memory engine not ready
3156
+ if (!memoryEngineReady) {
3157
+ return {
3158
+ content: [{
3159
+ type: "text",
3160
+ text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
3161
+ }],
3162
+ isError: true
3163
+ };
3164
+ }
3165
+
3049
3166
  try {
3050
3167
  const engine = await getMemoryEngine();
3051
3168
  const result = await engine.selectStrategy(instruction, { files });
@@ -3090,5 +3207,11 @@ async function handleSelectStrategy({ instruction, files = [] }) {
3090
3207
  * Start Server
3091
3208
  */
3092
3209
  const transport = new StdioServerTransport();
3210
+
3211
+ // Pre-initialize memory engine in background
3212
+ backgroundInitializeMemoryEngine().catch(err => {
3213
+ console.error(`${colors.yellow}[Memory]${colors.reset} Background init error: ${err.message}`);
3214
+ });
3215
+
3093
3216
  await server.connect(transport);
3094
3217
  console.error("mcfast MCP v1.0.0 running on stdio");
@@ -118,12 +118,33 @@ export class MemoryEngine {
118
118
  }
119
119
  }
120
120
 
121
- // Load intelligence models
121
+ // Load intelligence models - run in background to not block initialization
122
122
  if (this.intelligenceEnabled) {
123
- await this.patternDetector.loadModel?.();
124
- await this.suggestionEngine.loadModel?.();
125
- await this.strategySelector.loadModel?.();
126
- console.log('[MemoryEngine] Intelligence models loaded');
123
+ // Start model loading in background without awaiting
124
+ (async () => {
125
+ try {
126
+ const loadPromises = [
127
+ this.patternDetector.loadModel?.(),
128
+ this.suggestionEngine.loadModel?.(),
129
+ this.strategySelector.loadModel?.()
130
+ ].filter(Boolean);
131
+
132
+ // Add timeout to prevent hanging
133
+ const timeoutPromise = new Promise((_, reject) =>
134
+ setTimeout(() => reject(new Error('Model loading timeout')), 5000)
135
+ );
136
+
137
+ await Promise.race([
138
+ Promise.all(loadPromises),
139
+ timeoutPromise
140
+ ]);
141
+
142
+ console.log('[MemoryEngine] ✅ Intelligence models loaded');
143
+ } catch (error) {
144
+ console.warn('[MemoryEngine] Model loading failed or timed out:', error.message);
145
+ // Don't disable intelligence - models are optional
146
+ }
147
+ })();
127
148
  }
128
149
  }
129
150
 
@@ -98,7 +98,7 @@ export class ParallelSearch {
98
98
  );
99
99
 
100
100
  results = [...results, ...slowResults];
101
- return this.mergeResults(results, maxResults);
101
+ return this.mergeResults(results, limit);
102
102
  }
103
103
 
104
104
  return merged;