vibecodingmachine-core 2026.1.3-2209 → 2026.1.23-1010

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 (32) hide show
  1. package/__tests__/provider-manager-fallback.test.js +43 -0
  2. package/__tests__/provider-manager-rate-limit.test.js +61 -0
  3. package/package.json +1 -1
  4. package/src/compliance/compliance-manager.js +5 -2
  5. package/src/database/migrations.js +135 -12
  6. package/src/database/user-database-client.js +63 -8
  7. package/src/database/user-schema.js +7 -0
  8. package/src/health-tracking/__tests__/ide-health-tracker.test.js +420 -0
  9. package/src/health-tracking/__tests__/interaction-recorder.test.js +392 -0
  10. package/src/health-tracking/errors.js +50 -0
  11. package/src/health-tracking/health-reporter.js +331 -0
  12. package/src/health-tracking/ide-health-tracker.js +446 -0
  13. package/src/health-tracking/interaction-recorder.js +161 -0
  14. package/src/health-tracking/json-storage.js +276 -0
  15. package/src/health-tracking/storage-interface.js +63 -0
  16. package/src/health-tracking/validators.js +277 -0
  17. package/src/ide-integration/applescript-manager.cjs +1062 -4
  18. package/src/ide-integration/applescript-manager.js +560 -11
  19. package/src/ide-integration/provider-manager.cjs +158 -28
  20. package/src/ide-integration/quota-detector.cjs +339 -16
  21. package/src/ide-integration/quota-detector.js +6 -1
  22. package/src/index.cjs +32 -1
  23. package/src/index.js +16 -0
  24. package/src/localization/translations/en.js +13 -1
  25. package/src/localization/translations/es.js +12 -0
  26. package/src/utils/admin-utils.js +33 -0
  27. package/src/utils/error-reporter.js +12 -4
  28. package/src/utils/requirement-helpers.js +34 -4
  29. package/src/utils/requirements-parser.js +3 -3
  30. package/tests/health-tracking/health-reporter.test.js +329 -0
  31. package/tests/health-tracking/ide-health-tracker.test.js +368 -0
  32. package/tests/health-tracking/interaction-recorder.test.js +309 -0
@@ -370,19 +370,43 @@ class AppleScriptManager {
370
370
 
371
371
  // Handle macOS platform
372
372
  try {
373
- this.logger.log('Opening VS Code...');
373
+ this.logger.log('Opening VS Code with remote debugging enabled...');
374
374
 
375
- let command = 'open -a "Visual Studio Code"';
375
+ // First, check if VS Code is already running
376
+ try {
377
+ const isRunning = execSync('pgrep -x "Code"', { encoding: 'utf8', stdio: 'pipe' }).trim();
378
+ if (isRunning) {
379
+ this.logger.log('VS Code is already running - closing it to enable remote debugging...');
380
+ execSync('pkill -x "Code"', { stdio: 'pipe' });
381
+ await new Promise(resolve => setTimeout(resolve, 1000));
382
+ }
383
+ } catch (err) {
384
+ // VS Code not running, that's fine
385
+ }
386
+
387
+ // Launch VS Code with remote debugging enabled for quota detection
388
+ let command = 'open -a "Visual Studio Code" --args --remote-debugging-port=9222';
376
389
  if (repoPath) {
377
- command += ` "${repoPath}"`;
390
+ command = `open -a "Visual Studio Code" "${repoPath}" --args --remote-debugging-port=9222`;
378
391
  this.logger.log(`Opening VS Code with repository: ${repoPath}`);
379
392
  }
380
393
 
381
394
  execSync(command, { stdio: 'pipe' });
382
395
 
383
- await new Promise(resolve => setTimeout(resolve, 2000));
396
+ await new Promise(resolve => setTimeout(resolve, 3000));
397
+
398
+ // Verify remote debugging port is accessible
399
+ try {
400
+ const CDP = require('chrome-remote-interface');
401
+ await CDP.List({ port: 9222 });
402
+ this.logger.log('✅ VS Code remote debugging port 9222 is accessible');
403
+ } catch (cdpError) {
404
+ this.logger.log(`⚠️ Warning: VS Code remote debugging port not accessible: ${cdpError.message}`);
405
+ this.logger.log(' Waiting additional 2 seconds for VS Code to fully start...');
406
+ await new Promise(resolve => setTimeout(resolve, 2000));
407
+ }
384
408
 
385
- this.logger.log('VS Code opened successfully');
409
+ this.logger.log('VS Code opened successfully with remote debugging');
386
410
  return { success: true, message: `VS Code opened with repository: ${repoPath}`, method: 'applescript' };
387
411
  } catch (error) {
388
412
  this.logger.log('Error opening VS Code:', error.message);
@@ -390,6 +414,125 @@ class AppleScriptManager {
390
414
  }
391
415
  }
392
416
 
417
+ /**
418
+ * Open VS Code with a specific extension installed
419
+ * @param {string} extension - Extension key (e.g., 'github-copilot', 'amazon-q')
420
+ * @param {string} repoPath - Optional repository path to open
421
+ * @returns {Promise<Object>} Result object with success status and details
422
+ */
423
+ async openVSCodeWithExtension(extension, repoPath = null) {
424
+ try {
425
+ this.logger.log(`Opening VS Code with ${extension} extension...`);
426
+
427
+ // Extension IDs mapping
428
+ const extensionIds = {
429
+ 'github-copilot': 'GitHub.copilot',
430
+ 'amazon-q': 'amazonwebservices.amazon-q-vscode',
431
+ 'continue': 'Continue.continue'
432
+ };
433
+
434
+ const extensionId = extensionIds[extension];
435
+ if (!extensionId) {
436
+ return { success: false, error: `Unknown extension: ${extension}`, method: 'applescript' };
437
+ }
438
+
439
+ // First, check if the extension is installed
440
+ try {
441
+ const checkCmd = `code --list-extensions | grep -i "${extensionId}"`;
442
+ execSync(checkCmd, { stdio: 'pipe' });
443
+ this.logger.log(`Extension ${extension} is already installed`);
444
+ } catch (checkError) {
445
+ // Extension not found, try to install it
446
+ this.logger.log(`Extension ${extension} not found, installing...`);
447
+ try {
448
+ execSync(`code --install-extension ${extensionId} --force`, { stdio: 'pipe', timeout: 60000 });
449
+ this.logger.log(`Extension ${extension} installed successfully`);
450
+ } catch (installError) {
451
+ this.logger.log(`Failed to install extension ${extension}:`, installError.message);
452
+ return { success: false, error: `Failed to install extension: ${installError.message}`, method: 'applescript' };
453
+ }
454
+ }
455
+
456
+ // First, check if VS Code is already running
457
+ try {
458
+ const isRunning = execSync('pgrep -x "Code"', { encoding: 'utf8', stdio: 'pipe' }).trim();
459
+ if (isRunning) {
460
+ this.logger.log('VS Code is already running - closing it to enable remote debugging...');
461
+ execSync('pkill -x "Code"', { stdio: 'pipe' });
462
+ await new Promise(resolve => setTimeout(resolve, 1000));
463
+ }
464
+ } catch (err) {
465
+ // VS Code not running, that's fine
466
+ }
467
+
468
+ // Open VS Code with the repository and remote debugging enabled
469
+ let command = 'open -a "Visual Studio Code" --args --remote-debugging-port=9222';
470
+ if (repoPath) {
471
+ command = `open -a "Visual Studio Code" "${repoPath}" --args --remote-debugging-port=9222`;
472
+ this.logger.log(`Opening VS Code with repository: ${repoPath}`);
473
+ }
474
+
475
+ execSync(command, { stdio: 'pipe' });
476
+ await new Promise(resolve => setTimeout(resolve, 3000));
477
+
478
+ // Verify remote debugging port is accessible
479
+ try {
480
+ const CDP = require('chrome-remote-interface');
481
+ await CDP.List({ port: 9222 });
482
+ this.logger.log('✅ VS Code remote debugging port 9222 is accessible');
483
+ } catch (cdpError) {
484
+ this.logger.log(`⚠️ Warning: VS Code remote debugging port not accessible: ${cdpError.message}`);
485
+ this.logger.log(' Waiting additional 2 seconds for VS Code to fully start...');
486
+ await new Promise(resolve => setTimeout(resolve, 2000));
487
+ }
488
+
489
+ this.logger.log(`VS Code opened successfully with ${extension} extension and remote debugging`);
490
+ return { success: true, message: `VS Code opened with ${extension} extension`, method: 'applescript' };
491
+ } catch (error) {
492
+ this.logger.log(`Error opening VS Code with ${extension}:`, error.message);
493
+ return { success: false, error: error.message, method: 'applescript' };
494
+ }
495
+ }
496
+
497
+ /**
498
+ * Open Replit Agent with optional repository path
499
+ * @param {string} repoPath - Optional repository path to open
500
+ * @returns {Promise<Object>} Result object with success status and details
501
+ */
502
+ async openReplit(repoPath = null) {
503
+ try {
504
+ this.logger.log('Opening Replit...');
505
+ this.logger.log(`Platform detected: ${this.platform}`);
506
+
507
+ // Replit typically uses web browser, so we'll open the Replit website
508
+ // If Replit has a desktop app or CLI, this can be updated
509
+ const replitUrl = repoPath
510
+ ? `https://replit.com/@replit/agent?path=${encodeURIComponent(repoPath)}`
511
+ : 'https://replit.com/@replit/agent';
512
+
513
+ let command;
514
+ if (this.platform === 'darwin') {
515
+ command = `open "${replitUrl}"`;
516
+ this.logger.log(`Using macOS command: ${command}`);
517
+ } else if (this.platform === 'win32') {
518
+ command = `start "" "${replitUrl}"`;
519
+ this.logger.log(`Using Windows command: ${command}`);
520
+ } else {
521
+ command = `xdg-open "${replitUrl}"`;
522
+ this.logger.log(`Using Linux command: ${command}`);
523
+ }
524
+
525
+ execSync(command, { stdio: 'pipe' });
526
+ await new Promise(resolve => setTimeout(resolve, 1000));
527
+
528
+ this.logger.log('Replit opened successfully');
529
+ return { success: true, message: 'Replit opened in browser', method: 'applescript' };
530
+ } catch (error) {
531
+ this.logger.log('Error opening Replit:', error.message);
532
+ return { success: false, error: error.message, method: 'applescript' };
533
+ }
534
+ }
535
+
393
536
 
394
537
  /**
395
538
  * Open Windsurf IDE with optional repository path
@@ -562,6 +705,85 @@ class AppleScriptManager {
562
705
  }
563
706
  }
564
707
 
708
+ /**
709
+ * Check Antigravity UI for Gemini quota limit popup text.
710
+ * This is best-effort: Antigravity may render the popup in a WebView that AppleScript can't read.
711
+ * @returns {Promise<{isRateLimited: boolean, message?: string, resumeAt?: string, note?: string}>}
712
+ */
713
+ async checkAntigravityQuotaLimit() {
714
+ try {
715
+ const script = `
716
+ tell application "System Events"
717
+ if not (exists process "Antigravity") then
718
+ return "NOT_RUNNING"
719
+ end if
720
+ tell process "Antigravity"
721
+ set frontmost to true
722
+ delay 0.4
723
+
724
+ set allText to ""
725
+ try
726
+ set allText to allText & (value of static text of window 1 as string) & "\\n"
727
+ end try
728
+
729
+ try
730
+ set groupsList to groups of window 1
731
+ repeat with g in groupsList
732
+ try
733
+ set allText to allText & (value of static text of g as string) & "\\n"
734
+ end try
735
+ end repeat
736
+ end try
737
+
738
+ return allText
739
+ end tell
740
+ end tell
741
+ `;
742
+
743
+ const raw = execSync(`osascript -e '${script.replace(/'/g, "'\\\\''")}'`, {
744
+ encoding: 'utf8',
745
+ timeout: 8000
746
+ }).trim();
747
+
748
+ if (!raw || raw === 'NOT_RUNNING') {
749
+ return {
750
+ isRateLimited: false,
751
+ note: raw === 'NOT_RUNNING' ? 'Antigravity not running' : 'No readable UI text'
752
+ };
753
+ }
754
+
755
+ const text = raw.replace(/\\s+/g, ' ').trim();
756
+ const lower = text.toLowerCase();
757
+
758
+ const hasGeminiQuota = lower.includes('model quota limit exceeded') ||
759
+ (lower.includes('quota limit') && lower.includes('you can resume')) ||
760
+ lower.includes('you have reached the quota limit') ||
761
+ lower.includes('spending cap reached') ||
762
+ lower.includes('usage cap reached') ||
763
+ lower.includes('rate limit reached');
764
+
765
+ if (!hasGeminiQuota) {
766
+ return { isRateLimited: false };
767
+ }
768
+
769
+ const resumeAtMatch = text.match(/resume\s+(?:using\s+this\s+model\s+)?at\s+(\d{1,2}\/\d{1,2}\/\d{4})\s*,?\s*(\d{1,2}:\d{2}(?::\d{2})?)\s*(AM|PM)/i);
770
+ const resumeAt = resumeAtMatch
771
+ ? `${resumeAtMatch[1]}, ${resumeAtMatch[2]} ${resumeAtMatch[3].toUpperCase()}`
772
+ : undefined;
773
+
774
+ return {
775
+ isRateLimited: true,
776
+ message: text,
777
+ resumeAt
778
+ };
779
+ } catch (error) {
780
+ return {
781
+ isRateLimited: false,
782
+ note: `Failed to check Antigravity quota: ${error.message}`
783
+ };
784
+ }
785
+ }
786
+
565
787
  /**
566
788
  * Handle Antigravity quota limit by automatically switching models
567
789
  * @returns {Promise<{success: boolean, model?: string, error?: string}>}
@@ -617,7 +839,7 @@ class AppleScriptManager {
617
839
 
618
840
  -- Look for model dropdown/menu items
619
841
  -- Try alternative models in order of preference
620
- set modelNames to {"Gemini 3 Pro (Low)", "Claude Sonnet 4.5", "Claude Sonnet 4.5 (Thinking)", "GPT-OSS 120B (Medium)"}
842
+ set modelNames to {"Gemini 3 Flash", "Gemini 3 Pro (High)", "Gemini 3 Pro (Low)", "Claude Sonnet 4.5", "Claude Sonnet 4.5 (Thinking)", "Claude Opus 4.5 (Thinking)", "GPT-OSS 120B (Medium)"}
621
843
 
622
844
  repeat with modelName in modelNames
623
845
  try
@@ -626,7 +848,7 @@ class AppleScriptManager {
626
848
 
627
849
  -- Try menu items
628
850
  try
629
- set modelItems to menu items of menu 1 of window 1 whose name is modelName
851
+ set modelItems to menu items of menu 1 of window 1 whose name contains modelName
630
852
  end try
631
853
 
632
854
  -- Try buttons if no menu items found
@@ -636,6 +858,22 @@ class AppleScriptManager {
636
858
  end try
637
859
  end if
638
860
 
861
+ -- Search in groups
862
+ if (count of modelItems) = 0 then
863
+ try
864
+ set allGroups to groups of window 1
865
+ repeat with grp in allGroups
866
+ try
867
+ set matchingItems to (every UI element of grp whose name contains modelName)
868
+ if (count of matchingItems) > 0 then
869
+ set modelItems to matchingItems
870
+ exit repeat
871
+ end if
872
+ end try
873
+ end repeat
874
+ end try
875
+ end if
876
+
639
877
  if (count of modelItems) > 0 then
640
878
  click item 1 of modelItems
641
879
  delay 0.8
@@ -711,6 +949,14 @@ class AppleScriptManager {
711
949
  return await this.openAntigravity(repoPath);
712
950
  case 'vscode':
713
951
  return await this.openVSCode(repoPath);
952
+ case 'github-copilot':
953
+ // Open VS Code with GitHub Copilot extension
954
+ return await this.openVSCodeWithExtension('github-copilot', repoPath);
955
+ case 'amazon-q':
956
+ // Open VS Code with Amazon Q extension
957
+ return await this.openVSCodeWithExtension('amazon-q', repoPath);
958
+ case 'replit':
959
+ return await this.openReplit(repoPath);
714
960
  case 'kiro':
715
961
  return await this.openKiro(repoPath);
716
962
  case 'claude':
@@ -721,7 +967,7 @@ class AppleScriptManager {
721
967
  default:
722
968
  return {
723
969
  success: false,
724
- error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity, vscode, claude, claude-code, gemini`
970
+ error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity, vscode, github-copilot, amazon-q, replit, kiro, claude, claude-code, gemini`
725
971
  };
726
972
  }
727
973
  }
@@ -833,7 +1079,23 @@ class AppleScriptManager {
833
1079
 
834
1080
  -- Press Enter (increased delay for chat window to fully open)
835
1081
  key code 36
836
- delay 2.5
1082
+ delay 3.0
1083
+
1084
+ -- Additional step for Amazon Q: ensure it's properly focused
1085
+ ${extension === 'amazon-q' ? `
1086
+ -- Wait for Amazon Q to fully load and then ensure focus
1087
+ delay 1.0
1088
+ -- Try to set focus to the Amazon Q chat input
1089
+ try
1090
+ -- Look for the Amazon Q chat input field and focus it
1091
+ keystroke tab
1092
+ delay 0.5
1093
+ keystroke tab
1094
+ delay 0.5
1095
+ on error
1096
+ -- If tab navigation fails, continue
1097
+ end try
1098
+ ` : ''}
837
1099
 
838
1100
 
839
1101
  -- Type the message (increased delay for input field to be ready)
@@ -1231,8 +1493,9 @@ class AppleScriptManager {
1231
1493
  } else if (ide === 'cursor') {
1232
1494
  // Cursor already has new chat logic in generateAIPanelFocusScript (Cmd+T)
1233
1495
  appleScript = this.appleScriptUtils.generateAIPanelFocusScript(text, 'Cursor');
1234
- } else if (ide === 'vscode') {
1496
+ } else if (ide === 'vscode' || ide === 'github-copilot' || ide === 'amazon-q') {
1235
1497
  // Delegate to the dedicated VS Code method
1498
+ // github-copilot and amazon-q are VS Code extensions
1236
1499
  return await this.sendTextToVSCode(text);
1237
1500
  } else if (ide === 'antigravity') {
1238
1501
  // AppleScript for Google Antigravity - Cmd+Shift+L opens Agent chat (non-toggle)
@@ -1311,7 +1574,7 @@ class AppleScriptManager {
1311
1574
  return {
1312
1575
  success: false,
1313
1576
  error: `Unsupported IDE for AppleScript: ${ide}`,
1314
- note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, VS Code, and AWS Kiro'
1577
+ note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, VS Code, GitHub Copilot, Amazon Q, AWS Kiro, and Claude'
1315
1578
  };
1316
1579
  }
1317
1580
 
@@ -1353,6 +1616,28 @@ class AppleScriptManager {
1353
1616
  } catch (error) {
1354
1617
  this.logger.log('AppleScript interaction failed:', error.message);
1355
1618
 
1619
+ // Check for Accessibility permission error
1620
+ if (error.message.includes('not allowed to send keystrokes') ||
1621
+ error.message.includes('assistive devices') ||
1622
+ (error.message.includes('System Events') && error.message.includes('not allowed'))) {
1623
+
1624
+ this.logger.log('⚠️ Accessibility permissions missing. Opening System Settings...');
1625
+ try {
1626
+ // Open System Settings -> Privacy & Security -> Accessibility
1627
+ execSync('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"');
1628
+ } catch (settingsErr) {
1629
+ this.logger.log('Failed to open System Settings:', settingsErr.message);
1630
+ }
1631
+
1632
+ return {
1633
+ success: false,
1634
+ error: 'Missing Accessibility Permissions',
1635
+ message: 'Please grant Accessibility permissions to Terminal/Node in System Settings',
1636
+ permissionError: true,
1637
+ note: 'macOS blocked keystroke automation. Opened settings for user.'
1638
+ };
1639
+ }
1640
+
1356
1641
  // For Claude, don't fall back to simulated response - return actual failure
1357
1642
  if (ide === 'claude' || ide === 'claude-code') {
1358
1643
  return {
@@ -1363,6 +1648,16 @@ class AppleScriptManager {
1363
1648
  };
1364
1649
  }
1365
1650
 
1651
+ // For Antigravity, also return failure to trigger user notification in auto.js
1652
+ if (ide === 'antigravity' || ide === 'kiro') {
1653
+ return {
1654
+ success: false,
1655
+ method: 'applescript',
1656
+ error: `Failed to send text to ${ideName}: ${error.message}`,
1657
+ note: `${ideName} automation failed.`
1658
+ };
1659
+ }
1660
+
1366
1661
  // For other IDEs, fall back to simulated response
1367
1662
  return {
1368
1663
  success: true,
@@ -2937,6 +3232,260 @@ end tell
2937
3232
  };
2938
3233
  }
2939
3234
  }
3235
+
3236
+ /**
3237
+ * Check if an IDE is running and accessible
3238
+ * @param {string} ide - The IDE name
3239
+ * @returns {Promise<Object>} Result object with success status and details
3240
+ */
3241
+ async getIDEStatus(ide) {
3242
+ if (!ide || typeof ide !== 'string') {
3243
+ return {
3244
+ success: false,
3245
+ error: 'Invalid IDE name provided',
3246
+ running: false
3247
+ };
3248
+ }
3249
+
3250
+ try {
3251
+ this.logger.log(`🔍 Checking status of ${ide}...`);
3252
+
3253
+ switch (ide.toLowerCase()) {
3254
+ case 'cursor':
3255
+ return await this._checkCursorStatus();
3256
+ case 'vscode':
3257
+ return await this._checkVSCodeStatus();
3258
+ case 'windsurf':
3259
+ return await this._checkWindsurfStatus();
3260
+ case 'antigravity':
3261
+ return await this._checkAntigravityStatus();
3262
+ case 'cline':
3263
+ return await this._checkClineStatus();
3264
+ default:
3265
+ return {
3266
+ success: false,
3267
+ error: `Unsupported IDE: ${ide}`,
3268
+ running: false
3269
+ };
3270
+ }
3271
+ } catch (error) {
3272
+ return {
3273
+ success: false,
3274
+ error: `Failed to check IDE status: ${error.message}`,
3275
+ running: false
3276
+ };
3277
+ }
3278
+ }
3279
+
3280
+ /**
3281
+ * Check Cursor status
3282
+ * @private
3283
+ */
3284
+ async _checkCursorStatus() {
3285
+ try {
3286
+ const script = `
3287
+ tell application "System Events"
3288
+ set isRunning to (exists process "Cursor")
3289
+ if isRunning then
3290
+ try
3291
+ tell application "Cursor" to activate
3292
+ delay 0.5
3293
+ return "running"
3294
+ on error
3295
+ return "error"
3296
+ end try
3297
+ else
3298
+ return "not_running"
3299
+ end if
3300
+ end tell
3301
+ `;
3302
+
3303
+ const result = this.appleScriptUtils.executeAppleScript(script);
3304
+ const running = result.includes('running');
3305
+
3306
+ return {
3307
+ success: true,
3308
+ running,
3309
+ status: running ? 'running' : 'not_running',
3310
+ message: running ? 'Cursor is running and accessible' : 'Cursor is not running'
3311
+ };
3312
+ } catch (error) {
3313
+ return {
3314
+ success: false,
3315
+ error: `Failed to check Cursor status: ${error.message}`,
3316
+ running: false
3317
+ };
3318
+ }
3319
+ }
3320
+
3321
+ /**
3322
+ * Check VS Code status
3323
+ * @private
3324
+ */
3325
+ async _checkVSCodeStatus() {
3326
+ try {
3327
+ const script = `
3328
+ tell application "System Events"
3329
+ set isRunning to (exists process "Code")
3330
+ if isRunning then
3331
+ try
3332
+ tell application "Visual Studio Code" to activate
3333
+ delay 0.5
3334
+ return "running"
3335
+ on error
3336
+ return "error"
3337
+ end try
3338
+ else
3339
+ return "not_running"
3340
+ end if
3341
+ end tell
3342
+ `;
3343
+
3344
+ const result = this.appleScriptUtils.executeAppleScript(script);
3345
+ const running = result.includes('running');
3346
+
3347
+ return {
3348
+ success: true,
3349
+ running,
3350
+ status: running ? 'running' : 'not_running',
3351
+ message: running ? 'VS Code is running and accessible' : 'VS Code is not running'
3352
+ };
3353
+ } catch (error) {
3354
+ return {
3355
+ success: false,
3356
+ error: `Failed to check VS Code status: ${error.message}`,
3357
+ running: false
3358
+ };
3359
+ }
3360
+ }
3361
+
3362
+ /**
3363
+ * Check Windsurf status
3364
+ * @private
3365
+ */
3366
+ async _checkWindsurfStatus() {
3367
+ try {
3368
+ const script = `
3369
+ tell application "System Events"
3370
+ set isRunning to (exists process "Windsurf")
3371
+ if isRunning then
3372
+ try
3373
+ tell application "Windsurf" to activate
3374
+ delay 0.5
3375
+ return "running"
3376
+ on error
3377
+ return "error"
3378
+ end try
3379
+ else
3380
+ return "not_running"
3381
+ end if
3382
+ end tell
3383
+ `;
3384
+
3385
+ const result = this.appleScriptUtils.executeAppleScript(script);
3386
+ const running = result.includes('running');
3387
+
3388
+ return {
3389
+ success: true,
3390
+ running,
3391
+ status: running ? 'running' : 'not_running',
3392
+ message: running ? 'Windsurf is running and accessible' : 'Windsurf is not running'
3393
+ };
3394
+ } catch (error) {
3395
+ return {
3396
+ success: false,
3397
+ error: `Failed to check Windsurf status: ${error.message}`,
3398
+ running: false
3399
+ };
3400
+ }
3401
+ }
3402
+
3403
+ /**
3404
+ * Check Antigravity status
3405
+ * @private
3406
+ */
3407
+ async _checkAntigravityStatus() {
3408
+ try {
3409
+ // Antigravity runs in browser, check if Chrome/Edge is running with Antigravity tab
3410
+ const script = `
3411
+ tell application "System Events"
3412
+ set isChromeRunning to (exists process "Google Chrome")
3413
+ set isEdgeRunning to (exists process "Microsoft Edge")
3414
+
3415
+ if isChromeRunning then
3416
+ try
3417
+ tell application "Google Chrome" to activate
3418
+ delay 0.5
3419
+ return "running"
3420
+ on error
3421
+ return "error"
3422
+ end try
3423
+ else if isEdgeRunning then
3424
+ try
3425
+ tell application "Microsoft Edge" to activate
3426
+ delay 0.5
3427
+ return "running"
3428
+ on error
3429
+ return "error"
3430
+ end try
3431
+ else
3432
+ return "not_running"
3433
+ end if
3434
+ end tell
3435
+ `;
3436
+
3437
+ const result = this.appleScriptUtils.executeAppleScript(script);
3438
+ const running = result.includes('running');
3439
+
3440
+ return {
3441
+ success: true,
3442
+ running,
3443
+ status: running ? 'running' : 'not_running',
3444
+ message: running ? 'Browser is running (Antigravity accessible)' : 'Browser is not running'
3445
+ };
3446
+ } catch (error) {
3447
+ return {
3448
+ success: false,
3449
+ error: `Failed to check Antigravity status: ${error.message}`,
3450
+ running: false
3451
+ };
3452
+ }
3453
+ }
3454
+
3455
+ /**
3456
+ * Check Cline status
3457
+ * @private
3458
+ */
3459
+ async _checkClineStatus() {
3460
+ try {
3461
+ // Cline runs in VS Code as an extension
3462
+ const vscodeStatus = await this._checkVSCodeStatus();
3463
+
3464
+ if (!vscodeStatus.running) {
3465
+ return {
3466
+ success: true,
3467
+ running: false,
3468
+ status: 'not_running',
3469
+ message: 'Cline requires VS Code to be running'
3470
+ };
3471
+ }
3472
+
3473
+ // For now, assume Cline is available if VS Code is running
3474
+ // In a more sophisticated implementation, we could check if the extension is installed
3475
+ return {
3476
+ success: true,
3477
+ running: true,
3478
+ status: 'running',
3479
+ message: 'Cline is available (VS Code running)'
3480
+ };
3481
+ } catch (error) {
3482
+ return {
3483
+ success: false,
3484
+ error: `Failed to check Cline status: ${error.message}`,
3485
+ running: false
3486
+ };
3487
+ }
3488
+ }
2940
3489
  }
2941
3490
 
2942
3491
  module.exports = AppleScriptManager;