vibecodingmachine-core 2025.12.1-534 → 2025.12.22-2230

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.
@@ -38,10 +38,10 @@ class AppleScriptManager {
38
38
  }
39
39
  }
40
40
 
41
- /**
42
- * Open Windsurf IDE
43
- * @returns {Promise<Object>} Result object with success status and details
44
- */
41
+ /**
42
+ * Open Windsurf IDE
43
+ * @returns {Promise<Object>} Result object with success status and details
44
+ */
45
45
  async openWindsurf() {
46
46
  try {
47
47
  // Use multiple separate AppleScript calls for better reliability
@@ -84,22 +84,86 @@ class AppleScriptManager {
84
84
  try {
85
85
  this.logger.log('Opening Google Antigravity...');
86
86
 
87
+ // Google Antigravity app path
88
+ const antigravityPath = '/Applications/Antigravity.app';
89
+
90
+ // Check if Antigravity is installed
91
+ try {
92
+ const fs = require('fs');
93
+ fs.accessSync(antigravityPath);
94
+ } catch {
95
+ throw new Error('Google Antigravity is not installed at /Applications/Antigravity.app');
96
+ }
97
+
87
98
  let command = `open -a "Antigravity"`;
88
99
  if (repoPath) {
89
100
  command += ` "${repoPath}"`;
90
101
  }
91
102
 
92
- execSync(command, { encoding: 'utf8', timeout: 5000 });
103
+ this.logger.log(`Executing command: ${command}`);
104
+ execSync(command, { stdio: 'pipe' });
105
+
106
+ // Wait a moment for Antigravity to start
93
107
  await new Promise(resolve => setTimeout(resolve, 2000));
94
108
 
109
+ this.logger.log('Google Antigravity opened successfully');
110
+ return {
111
+ success: true,
112
+ message: repoPath ? `Google Antigravity opened with repository: ${repoPath}` : 'Google Antigravity opened successfully',
113
+ method: 'applescript'
114
+ };
115
+ } catch (error) {
116
+ this.logger.log('Error opening Google Antigravity:', error.message);
117
+ return {
118
+ success: false,
119
+ error: error.message,
120
+ method: 'applescript'
121
+ };
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Open AWS Kiro IDE with optional repository path
127
+ * @param {string} repoPath - Optional repository path to open
128
+ * @returns {Promise<Object>} Result object with success status and details
129
+ */
130
+ async openKiro(repoPath = null) {
131
+ try {
132
+ this.logger.log('Opening AWS Kiro...');
133
+
134
+ let command = 'open -a "AWS Kiro"';
135
+ if (repoPath) {
136
+ command += ` "${repoPath}"`;
137
+ }
138
+
139
+ try {
140
+ this.logger.log(`Executing command: ${command}`);
141
+ execSync(command, { stdio: 'pipe' });
142
+ } catch (e) {
143
+ // Fallback to just "Kiro"
144
+ this.logger.log('Failed to open "AWS Kiro", trying "Kiro"...');
145
+ command = 'open -a "Kiro"';
146
+ if (repoPath) {
147
+ command += ` "${repoPath}"`;
148
+ }
149
+ execSync(command, { stdio: 'pipe' });
150
+ }
151
+
152
+ // Wait a moment for Kiro to start
153
+ await new Promise(resolve => setTimeout(resolve, 3000));
154
+
155
+ this.logger.log('AWS Kiro opened successfully');
95
156
  return {
96
157
  success: true,
97
- message: repoPath ? `Google Antigravity opened with repository: ${repoPath}` : 'Google Antigravity opened successfully'
158
+ message: repoPath ? `AWS Kiro opened with repository: ${repoPath}` : 'AWS Kiro opened successfully',
159
+ method: 'applescript'
98
160
  };
99
161
  } catch (error) {
162
+ this.logger.log('Error opening AWS Kiro:', error.message);
100
163
  return {
101
164
  success: false,
102
- error: `Failed to open Google Antigravity: ${error.message}`
165
+ error: error.message,
166
+ method: 'applescript'
103
167
  };
104
168
  }
105
169
  }
@@ -118,11 +182,43 @@ class AppleScriptManager {
118
182
  set frontmost to true
119
183
  delay 0.8
120
184
 
121
- -- Try to find and click "Select another model" button
185
+ -- Try to find model selection button with multiple possible texts
122
186
  try
123
- set modelButtons to buttons of window 1 whose name contains "Select another model"
124
- if (count of modelButtons) > 0 then
125
- click item 1 of modelButtons
187
+ set buttonTexts to {"Select another model", "Switch model", "Change model", "Select model", "Try another model", "Choose model"}
188
+ set foundButton to missing value
189
+
190
+ -- Search for button in window 1
191
+ repeat with buttonText in buttonTexts
192
+ try
193
+ set matchingButtons to buttons of window 1 whose name contains buttonText
194
+ if (count of matchingButtons) > 0 then
195
+ set foundButton to item 1 of matchingButtons
196
+ exit repeat
197
+ end if
198
+ end try
199
+ end repeat
200
+
201
+ -- Also search in groups within window 1
202
+ if foundButton is missing value then
203
+ repeat with buttonText in buttonTexts
204
+ try
205
+ set allGroups to groups of window 1
206
+ repeat with grp in allGroups
207
+ try
208
+ set matchingButtons to buttons of grp whose name contains buttonText
209
+ if (count of matchingButtons) > 0 then
210
+ set foundButton to item 1 of matchingButtons
211
+ exit repeat
212
+ end if
213
+ end try
214
+ end repeat
215
+ if foundButton is not missing value then exit repeat
216
+ end try
217
+ end repeat
218
+ end if
219
+
220
+ if foundButton is not missing value then
221
+ click foundButton
126
222
  delay 1.5
127
223
 
128
224
  -- Look for model dropdown/menu items
@@ -131,20 +227,38 @@ class AppleScriptManager {
131
227
 
132
228
  repeat with modelName in modelNames
133
229
  try
134
- -- Try to find and click this model option
135
- set modelItems to menu items of menu 1 of window 1 whose name is modelName
230
+ -- Try to find and click this model option in various locations
231
+ set modelItems to {}
232
+
233
+ -- Try menu items
234
+ try
235
+ set modelItems to menu items of menu 1 of window 1 whose name is modelName
236
+ end try
237
+
238
+ -- Try buttons if no menu items found
239
+ if (count of modelItems) = 0 then
240
+ try
241
+ set modelItems to buttons of window 1 whose name contains modelName
242
+ end try
243
+ end if
244
+
136
245
  if (count of modelItems) > 0 then
137
246
  click item 1 of modelItems
138
247
  delay 0.8
139
248
 
140
249
  -- Click "Accept all" or similar confirmation button
141
250
  try
142
- set acceptButtons to buttons of window 1 whose name contains "Accept"
143
- if (count of acceptButtons) > 0 then
144
- click item 1 of acceptButtons
145
- delay 0.5
146
- return "success:" & modelName
147
- end if
251
+ set acceptTexts to {"Accept", "OK", "Confirm", "Continue"}
252
+ repeat with acceptText in acceptTexts
253
+ try
254
+ set acceptButtons to buttons of window 1 whose name contains acceptText
255
+ if (count of acceptButtons) > 0 then
256
+ click item 1 of acceptButtons
257
+ delay 0.5
258
+ return "success:" & modelName
259
+ end if
260
+ end try
261
+ end repeat
148
262
  end try
149
263
 
150
264
  return "success:" & modelName
@@ -195,10 +309,12 @@ class AppleScriptManager {
195
309
  return await this.openWindsurf(repoPath);
196
310
  case 'antigravity':
197
311
  return await this.openAntigravity(repoPath);
312
+ case 'kiro':
313
+ return await this.openKiro(repoPath);
198
314
  default:
199
315
  return {
200
316
  success: false,
201
- error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity`
317
+ error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity, kiro`
202
318
  };
203
319
  }
204
320
  }
@@ -218,7 +334,7 @@ class AppleScriptManager {
218
334
  };
219
335
  }
220
336
 
221
- const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : 'Unknown IDE';
337
+ const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : ide === 'kiro' ? 'AWS Kiro' : 'Unknown IDE';
222
338
 
223
339
  this.logger.log(`${ideName} detected - using AppleScript for reliable text sending`);
224
340
 
@@ -274,118 +390,14 @@ class AppleScriptManager {
274
390
  end tell
275
391
  `;
276
392
  } else if (ide === 'cursor') {
277
- // AppleScript for Cursor - proven to work (from commit 3403c17)
393
+ // AppleScript for Cursor - Using working shortcuts
278
394
  appleScript = `
279
395
  tell application "System Events"
280
396
  tell process "Cursor"
281
397
  set frontmost to true
282
- delay 1
283
-
284
- -- DYNAMIC SCREENSHOT-BASED CHAT INPUT TARGETING
285
- -- Method 1: Take screenshot of the monitor where Cursor is running
286
- try
287
- -- Get the bounds of the Cursor window to determine which monitor it's on
288
- set cursorBounds to bounds of window 1
289
- set cursorX to item 1 of cursorBounds
290
- set cursorY to item 2 of cursorBounds
291
-
292
- -- Take a screenshot of the specific monitor where Cursor is located
293
- set screenshotPath to (path to desktop as string) & "cursor_screenshot.png"
294
-
295
- -- Use screencapture with display selection based on Cursor window position
296
- -- If Cursor is on the right side (aux monitor), use display 2
297
- if cursorX > 1000 then
298
- do shell script "screencapture -D 2 -x " & quoted form of POSIX path of screenshotPath
299
- else
300
- do shell script "screencapture -D 1 -x " & quoted form of POSIX path of screenshotPath
301
- end if
302
- delay 0.5
303
-
304
- -- Use Python with PIL to analyze the screenshot and find text input area
305
- set pythonScript to "
306
- import sys
307
- import os
308
- from PIL import Image, ImageDraw
309
- import subprocess
310
-
311
- try:
312
- # Read the screenshot
313
- img = Image.open('" & POSIX path of screenshotPath & "')
314
- width, height = img.size
315
-
316
- # Convert to grayscale for analysis
317
- gray = img.convert('L')
318
-
319
- # Get screen dimensions to calculate relative positions
320
- screen_width = width
321
- screen_height = height
322
-
323
- # Determine if this is the auxiliary monitor based on Cursor window position
324
- cursor_x = " & cursorX & "
325
- is_aux_monitor = cursor_x > 1000
326
-
327
- if is_aux_monitor:
328
- # For auxiliary monitor, adjust coordinates
329
- # Chat input is typically in the right side of the aux monitor
330
- candidates = [
331
- (int(screen_width * 0.8), int(screen_height * 0.85)), # Bottom-right
332
- (int(screen_width * 0.75), int(screen_height * 0.8)), # Slightly up
333
- (int(screen_width * 0.85), int(screen_height * 0.8)), # More right
334
- (int(screen_width * 0.7), int(screen_height * 0.9)), # Bottom-left of right area
335
- ]
336
- else:
337
- # For main monitor, use standard coordinates
338
- candidates = [
339
- (int(screen_width * 0.8), int(screen_height * 0.85)), # Bottom-right
340
- (int(screen_width * 0.75), int(screen_height * 0.8)), # Slightly up
341
- (int(screen_width * 0.85), int(screen_height * 0.8)), # More right
342
- (int(screen_width * 0.7), int(screen_height * 0.9)), # Bottom-left of right area
343
- ]
344
-
345
- # Use the first candidate (bottom-right area)
346
- x, y = candidates[0]
347
- print(f'{x},{y}')
348
-
349
- except Exception as e:
350
- # Fallback to estimated coordinates based on monitor
351
- if " & cursorX & " > 1000:
352
- print('1000,600') # Aux monitor fallback
353
- else:
354
- print('800,500') # Main monitor fallback
355
- "
356
-
357
- -- Execute Python script to find coordinates
358
- set coordinates to do shell script "python3 -c " & quoted form of pythonScript
359
- delay 0.3
360
-
361
- -- Click at the detected coordinates
362
- do shell script "/usr/local/bin/cliclick c:" & coordinates
363
- delay 0.5
364
-
365
- -- Clean up screenshot
366
- do shell script "rm " & quoted form of POSIX path of screenshotPath
367
-
368
- on error
369
- -- Fallback: Use estimated coordinates if screenshot analysis fails
370
- try
371
- -- Click in the main editor area to escape terminal
372
- do shell script "/usr/local/bin/cliclick c:600,400"
373
- delay 0.3
374
-
375
- -- Click in the chat panel area to focus it
376
- do shell script "/usr/local/bin/cliclick c:1200,500"
377
- delay 0.3
378
-
379
- -- Click in the chat input area specifically
380
- do shell script "/usr/local/bin/cliclick c:1100,700"
381
- delay 0.3
382
-
383
- on error
384
- delay 0.3
385
- end try
386
- end try
398
+ delay 1.0
387
399
 
388
- -- Open new chat session with Cmd+T to prevent crashes
400
+ -- Open new chat session with Cmd+T (proven to work)
389
401
  key code 17 using {command down} -- Cmd+T
390
402
  delay 1.0
391
403
 
@@ -396,8 +408,8 @@ except Exception as e:
396
408
  delay 0.5
397
409
 
398
410
  -- Press Cmd+Enter to send (more reliable than just Enter)
399
- key code 36 using {command down}
400
- delay 1
411
+ key code 36 using {command down} -- Cmd+Enter
412
+ delay 1.0
401
413
 
402
414
  return "Message sent via AppleScript"
403
415
  end tell
@@ -425,11 +437,53 @@ except Exception as e:
425
437
  end tell
426
438
  end tell
427
439
  `;
440
+ } else if (ide === 'kiro') {
441
+ // AWS Kiro support
442
+ this.logger.log('🚀 [AWS Kiro] Sending text via AppleScript accessibility (with fallback check)...');
443
+
444
+ appleScript = `
445
+ tell application "System Events"
446
+ set processName to "AWS Kiro"
447
+ try
448
+ if not (exists process "AWS Kiro") then
449
+ set processName to "Kiro"
450
+ end if
451
+ on error
452
+ set processName to "Kiro"
453
+ end try
454
+
455
+ tell process processName
456
+ set frontmost to true
457
+ delay 1.0
458
+
459
+ -- Attempt to focus chat via standard AI IDE shortcuts
460
+ -- Try Cmd+L (Cursor/Windsurf standard)
461
+ try
462
+ key code 37 using {command down}
463
+ delay 0.5
464
+ on error
465
+ -- Ignore if fails
466
+ end try
467
+
468
+ -- Use clipboard for more reliable text entry than keystrokes
469
+ set the clipboard to "${text.replace(/"/g, '\\"')}"
470
+ delay 0.3
471
+
472
+ -- Paste
473
+ key code 9 using {command down}
474
+ delay 0.5
475
+
476
+ -- Send Enter
477
+ key code 36
478
+ delay 0.5
479
+ end tell
480
+ end tell
481
+ `;
428
482
  } else {
429
483
  return {
430
484
  success: false,
431
485
  error: `Unsupported IDE for AppleScript: ${ide}`,
432
- note: 'AppleScript is only supported for Cursor, Windsurf, and Antigravity'
486
+ note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, VS Code, and AWS Kiro'
433
487
  };
434
488
  }
435
489
 
@@ -444,14 +498,14 @@ except Exception as e:
444
498
  };
445
499
 
446
500
  } catch (error) {
447
- this.logger.log('AppleScript interaction failed, falling back to simulated response:', error.message);
501
+ this.logger.log(`❌ AppleScript interaction failed for ${ideName}:`, error.message);
448
502
 
449
- // Fallback to simulated response if AppleScript fails
503
+ // Return failure - DO NOT fallback to simulation
450
504
  return {
451
- success: true,
452
- method: 'simulated',
453
- message: `Simulated ${ideName} response: ${text}`,
454
- note: `${ideName} AppleScript automation failed. Using simulated response for testing.`
505
+ success: false,
506
+ error: error.message,
507
+ message: `Failed to send message to ${ideName}`,
508
+ note: `AppleScript automation failed. Error: ${error.message}`
455
509
  };
456
510
  }
457
511
  }
@@ -669,14 +723,14 @@ except Exception as e:
669
723
 
670
724
  // Check if the result is just diagnostic information
671
725
  const isDiagnosticResult = result.includes('DEBUG:') ||
672
- result.includes('diagnostic') ||
673
- result.includes('No chat content found') ||
674
- result.includes('Text areas found: 0') ||
675
- result.includes('Static text found:') ||
676
- result.includes('Window count:') ||
677
- result.includes('Sample text:') ||
678
- result.includes('Could not read') ||
679
- result.includes('No readable text content detected');
726
+ result.includes('diagnostic') ||
727
+ result.includes('No chat content found') ||
728
+ result.includes('Text areas found: 0') ||
729
+ result.includes('Static text found:') ||
730
+ result.includes('Window count:') ||
731
+ result.includes('Sample text:') ||
732
+ result.includes('Could not read') ||
733
+ result.includes('No readable text content detected');
680
734
 
681
735
  this.logger.log(`🔍 Diagnostic detection check: isDiagnosticResult = ${isDiagnosticResult}`);
682
736
  this.logger.log(`🔍 Result contains 'DEBUG:': ${result.includes('DEBUG:')}`);