vibecodingmachine-core 2025.12.1-534 → 2025.12.6-1702

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": "vibecodingmachine-core",
3
- "version": "2025.12.01-0534",
3
+ "version": "2025.12.06-1702",
4
4
  "description": "Shared core logic for Vibe Coding Machine IDE integration",
5
5
  "main": "src/index.cjs",
6
6
  "module": "src/index.js",
@@ -13,6 +13,9 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@aws-sdk/client-bedrock-runtime": "^3.932.0",
16
+ "@aws-sdk/client-dynamodb": "^3.600.0",
17
+ "@aws-sdk/lib-dynamodb": "^3.600.0",
18
+ "@aws-sdk/client-cognito-identity-provider": "^3.600.0",
16
19
  "chrome-remote-interface": "^0.33.0",
17
20
  "fs-extra": "^11.1.1",
18
21
  "jsonwebtoken": "^9.0.2",
@@ -46,13 +46,15 @@ class SharedAuthStorage {
46
46
  }
47
47
 
48
48
  /**
49
- * Get stored token
49
+ * Get stored token (returns id_token for backward compatibility)
50
50
  */
51
51
  async getToken() {
52
52
  try {
53
53
  if (await fs.pathExists(TOKEN_FILE)) {
54
54
  const data = await fs.readJson(TOKEN_FILE);
55
- return data.token;
55
+ // If data.token exists (old format), return it
56
+ // If data.id_token exists (new format), return it
57
+ return data.id_token || data.token;
56
58
  }
57
59
  } catch (error) {
58
60
  console.error('Failed to read token:', error);
@@ -61,15 +63,50 @@ class SharedAuthStorage {
61
63
  }
62
64
 
63
65
  /**
64
- * Save token
66
+ * Get stored refresh token
65
67
  */
66
- async saveToken(token) {
68
+ async getRefreshToken() {
69
+ try {
70
+ if (await fs.pathExists(TOKEN_FILE)) {
71
+ const data = await fs.readJson(TOKEN_FILE);
72
+ return data.refresh_token;
73
+ }
74
+ } catch (error) {
75
+ console.error('Failed to read refresh token:', error);
76
+ }
77
+ return null;
78
+ }
79
+
80
+ /**
81
+ * Save token (supports both string token and object with tokens)
82
+ */
83
+ async saveToken(tokenOrTokens) {
67
84
  await fs.ensureDir(CONFIG_DIR);
68
- await fs.writeJson(TOKEN_FILE, { token }, { spaces: 2 });
85
+
86
+ let tokenData = {};
87
+ let idToken = '';
88
+
89
+ if (typeof tokenOrTokens === 'string') {
90
+ // Legacy format: just the ID token
91
+ tokenData = { token: tokenOrTokens, id_token: tokenOrTokens };
92
+ idToken = tokenOrTokens;
93
+ } else {
94
+ // New format: object with id_token, access_token, refresh_token
95
+ tokenData = {
96
+ id_token: tokenOrTokens.id_token,
97
+ access_token: tokenOrTokens.access_token,
98
+ refresh_token: tokenOrTokens.refresh_token,
99
+ // Keep legacy field for backward compatibility
100
+ token: tokenOrTokens.id_token
101
+ };
102
+ idToken = tokenOrTokens.id_token;
103
+ }
104
+
105
+ await fs.writeJson(TOKEN_FILE, tokenData, { spaces: 2 });
69
106
 
70
107
  // Also save user profile from token
71
108
  try {
72
- const payload = this.decodeJWT(token);
109
+ const payload = this.decodeJWT(idToken);
73
110
  const email = payload.email;
74
111
 
75
112
  // Note: Beta access control is handled server-side by Cognito Pre-Auth Lambda
@@ -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
  }
@@ -195,10 +259,12 @@ class AppleScriptManager {
195
259
  return await this.openWindsurf(repoPath);
196
260
  case 'antigravity':
197
261
  return await this.openAntigravity(repoPath);
262
+ case 'kiro':
263
+ return await this.openKiro(repoPath);
198
264
  default:
199
265
  return {
200
266
  success: false,
201
- error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity`
267
+ error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity, kiro`
202
268
  };
203
269
  }
204
270
  }
@@ -218,7 +284,7 @@ class AppleScriptManager {
218
284
  };
219
285
  }
220
286
 
221
- const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : 'Unknown IDE';
287
+ const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : ide === 'kiro' ? 'AWS Kiro' : 'Unknown IDE';
222
288
 
223
289
  this.logger.log(`${ideName} detected - using AppleScript for reliable text sending`);
224
290
 
@@ -425,11 +491,53 @@ except Exception as e:
425
491
  end tell
426
492
  end tell
427
493
  `;
494
+ } else if (ide === 'kiro') {
495
+ // AWS Kiro support
496
+ this.logger.log('🚀 [AWS Kiro] Sending text via AppleScript accessibility (with fallback check)...');
497
+
498
+ appleScript = `
499
+ tell application "System Events"
500
+ set processName to "AWS Kiro"
501
+ try
502
+ if not (exists process "AWS Kiro") then
503
+ set processName to "Kiro"
504
+ end if
505
+ on error
506
+ set processName to "Kiro"
507
+ end try
508
+
509
+ tell process processName
510
+ set frontmost to true
511
+ delay 1.0
512
+
513
+ -- Attempt to focus chat via standard AI IDE shortcuts
514
+ -- Try Cmd+L (Cursor/Windsurf standard)
515
+ try
516
+ key code 37 using {command down}
517
+ delay 0.5
518
+ on error
519
+ -- Ignore if fails
520
+ end try
521
+
522
+ -- Use clipboard for more reliable text entry than keystrokes
523
+ set the clipboard to "${text.replace(/"/g, '\\"')}"
524
+ delay 0.3
525
+
526
+ -- Paste
527
+ key code 9 using {command down}
528
+ delay 0.5
529
+
530
+ -- Send Enter
531
+ key code 36
532
+ delay 0.5
533
+ end tell
534
+ end tell
535
+ `;
428
536
  } else {
429
537
  return {
430
538
  success: false,
431
539
  error: `Unsupported IDE for AppleScript: ${ide}`,
432
- note: 'AppleScript is only supported for Cursor, Windsurf, and Antigravity'
540
+ note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, VS Code, and AWS Kiro'
433
541
  };
434
542
  }
435
543
 
@@ -669,14 +777,14 @@ except Exception as e:
669
777
 
670
778
  // Check if the result is just diagnostic information
671
779
  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');
780
+ result.includes('diagnostic') ||
781
+ result.includes('No chat content found') ||
782
+ result.includes('Text areas found: 0') ||
783
+ result.includes('Static text found:') ||
784
+ result.includes('Window count:') ||
785
+ result.includes('Sample text:') ||
786
+ result.includes('Could not read') ||
787
+ result.includes('No readable text content detected');
680
788
 
681
789
  this.logger.log(`🔍 Diagnostic detection check: isDiagnosticResult = ${isDiagnosticResult}`);
682
790
  this.logger.log(`🔍 Result contains 'DEBUG:': ${result.includes('DEBUG:')}`);
@@ -72,7 +72,7 @@ class AppleScriptManager {
72
72
  } catch (rerr) {
73
73
  this.logger.log('⚠️ Deterministic: failed to read history before send:', rerr.message || rerr);
74
74
  historyOut = '';
75
- } finally { try { unlinkSync(tmpRead); } catch (e) {} }
75
+ } finally { try { unlinkSync(tmpRead); } catch (e) { } }
76
76
 
77
77
  this.logger.log('🔎 Deterministic: recent history snippet length:', historyOut.length);
78
78
 
@@ -128,7 +128,7 @@ class AppleScriptManager {
128
128
  const tempFile = join(tmpdir(), `claude_direct_${Date.now()}.scpt`);
129
129
  writeFileSync(tempFile, directSendScript, 'utf8');
130
130
  const out = execSync(`osascript "${tempFile}"`, { encoding: 'utf8', timeout: 30000, stdio: 'pipe' }).trim();
131
- try { unlinkSync(tempFile); } catch (e) {}
131
+ try { unlinkSync(tempFile); } catch (e) { }
132
132
 
133
133
  this.logger.log('🔁 Deterministic direct send output:', out);
134
134
  const verified = out.indexOf('|HIST:') !== -1 && out.split('|HIST:')[1].includes(text);
@@ -439,24 +439,24 @@ class AppleScriptManager {
439
439
  }
440
440
  }
441
441
 
442
- this.logger.log(`Executing command: ${command}`);
443
-
444
- // For Windsurf, we don't wait for the command to complete since it runs in background
445
- if (windsurfPath.includes('windsurf')) {
446
- // Use spawn to run in background
447
- const { spawn } = require('child_process');
448
- const windsurfProcess = spawn(windsurfPath, ['--reuse-window', repoPath], {
449
- stdio: 'pipe',
450
- detached: true
451
- });
452
-
453
- // Don't wait for completion, just give it a moment to start
454
- await new Promise(resolve => setTimeout(resolve, 1000));
455
- } else {
456
- execSync(command, { stdio: 'pipe' });
457
- // Wait a moment for Windsurf to start
458
- await new Promise(resolve => setTimeout(resolve, 2000));
459
- }
442
+ this.logger.log(`Executing command: ${command}`);
443
+
444
+ // For Windsurf, we don't wait for the command to complete since it runs in background
445
+ if (windsurfPath.includes('windsurf')) {
446
+ // Use spawn to run in background
447
+ const { spawn } = require('child_process');
448
+ const windsurfProcess = spawn(windsurfPath, ['--reuse-window', repoPath], {
449
+ stdio: 'pipe',
450
+ detached: true
451
+ });
452
+
453
+ // Don't wait for completion, just give it a moment to start
454
+ await new Promise(resolve => setTimeout(resolve, 1000));
455
+ } else {
456
+ execSync(command, { stdio: 'pipe' });
457
+ // Wait a moment for Windsurf to start
458
+ await new Promise(resolve => setTimeout(resolve, 2000));
459
+ }
460
460
 
461
461
  this.logger.log('Windsurf opened successfully');
462
462
  return {
@@ -516,6 +516,52 @@ class AppleScriptManager {
516
516
  }
517
517
  }
518
518
 
519
+ /**
520
+ * Open AWS Kiro IDE with optional repository path
521
+ * @param {string} repoPath - Optional repository path to open
522
+ * @returns {Promise<Object>} Result object with success status and details
523
+ */
524
+ async openKiro(repoPath = null) {
525
+ try {
526
+ this.logger.log('Opening AWS Kiro...');
527
+
528
+ let command = 'open -a "AWS Kiro"';
529
+ if (repoPath) {
530
+ command += ` "${repoPath}"`;
531
+ }
532
+
533
+ try {
534
+ this.logger.log(`Executing command: ${command}`);
535
+ execSync(command, { stdio: 'pipe' });
536
+ } catch (e) {
537
+ // Fallback to just "Kiro"
538
+ this.logger.log('Failed to open "AWS Kiro", trying "Kiro"...');
539
+ command = 'open -a "Kiro"';
540
+ if (repoPath) {
541
+ command += ` "${repoPath}"`;
542
+ }
543
+ execSync(command, { stdio: 'pipe' });
544
+ }
545
+
546
+ // Wait a moment for Kiro to start
547
+ await new Promise(resolve => setTimeout(resolve, 3000));
548
+
549
+ this.logger.log('AWS Kiro opened successfully');
550
+ return {
551
+ success: true,
552
+ message: repoPath ? `AWS Kiro opened with repository: ${repoPath}` : 'AWS Kiro opened successfully',
553
+ method: 'applescript'
554
+ };
555
+ } catch (error) {
556
+ this.logger.log('Error opening AWS Kiro:', error.message);
557
+ return {
558
+ success: false,
559
+ error: error.message,
560
+ method: 'applescript'
561
+ };
562
+ }
563
+ }
564
+
519
565
  /**
520
566
  * Handle Antigravity quota limit by automatically switching models
521
567
  * @returns {Promise<{success: boolean, model?: string, error?: string}>}
@@ -615,6 +661,8 @@ class AppleScriptManager {
615
661
  return await this.openAntigravity(repoPath);
616
662
  case 'vscode':
617
663
  return await this.openVSCode(repoPath);
664
+ case 'kiro':
665
+ return await this.openKiro(repoPath);
618
666
  case 'claude':
619
667
  return await this.openClaude(repoPath);
620
668
  case 'gemini':
@@ -781,7 +829,7 @@ class AppleScriptManager {
781
829
  };
782
830
  }
783
831
 
784
- const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : ide === 'claude' ? 'Claude' : ide === 'vscode' ? 'VS Code' : 'Unknown IDE';
832
+ const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : ide === 'claude' ? 'Claude' : ide === 'vscode' ? 'VS Code' : ide === 'kiro' ? 'AWS Kiro' : 'Unknown IDE';
785
833
 
786
834
  this.logger.log(`🚀 [${ideName}] Starting text send on ${this.platform} platform`);
787
835
  this.logger.log(`🚀 [${ideName}] Text to send: "${text}"`);
@@ -998,15 +1046,13 @@ class AppleScriptManager {
998
1046
  success: false,
999
1047
  method: 'applescript',
1000
1048
  error: `Invalid text parameter for Claude: received ${typeof text} instead of string`,
1001
- debug: { textType: typeof text, textValue: text }
1049
+ note: 'Text validation failed'
1002
1050
  };
1003
1051
  }
1004
1052
 
1005
- const escapedRepoPath = targetRepoPath.replace(/'/g, "'\\''");
1006
- const findAndSendScript = `
1053
+ const findAndSendToClaudeScript = `
1007
1054
  tell application "Terminal"
1008
1055
  activate
1009
-
1010
1056
  set claudeWindow to null
1011
1057
  set claudeTab to null
1012
1058
  set windowCount to count of windows
@@ -1070,58 +1116,58 @@ class AppleScriptManager {
1070
1116
  const tempFile = join(tmpdir(), `claude_script_${Date.now()}.scpt`);
1071
1117
  writeFileSync(tempFile, findAndSendScript, 'utf8');
1072
1118
 
1073
- let result;
1074
- try {
1075
- result = execSync(`osascript "${tempFile}"`, {
1076
- encoding: 'utf8',
1077
- timeout: 30000, // 30 seconds to allow for window searching and delays
1078
- stdio: 'pipe'
1079
- }).toString().trim();
1080
- } finally {
1081
- // Clean up temp file
1082
- try { unlinkSync(tempFile); } catch (cleanupError) { this.logger.log(`⚠️ [Claude] Failed to cleanup temp file: ${cleanupError.message}`); }
1083
- }
1119
+ let result;
1120
+ try {
1121
+ result = execSync(`osascript "${tempFile}"`, {
1122
+ encoding: 'utf8',
1123
+ timeout: 30000, // 30 seconds to allow for window searching and delays
1124
+ stdio: 'pipe'
1125
+ }).toString().trim();
1126
+ } finally {
1127
+ // Clean up temp file
1128
+ try { unlinkSync(tempFile); } catch (cleanupError) { this.logger.log(`⚠️ [Claude] Failed to cleanup temp file: ${cleanupError.message}`); }
1129
+ }
1130
+
1131
+ this.logger.log(`✅ [Claude] AppleScript execution output:`, result);
1084
1132
 
1085
- this.logger.log(`✅ [Claude] AppleScript execution output:`, result);
1086
-
1087
- // Verify that the sent text appears in the returned history snippet
1088
- try {
1089
- const sentVerified = result && result.indexOf('|HIST:') !== -1 && result.split('|HIST:')[1].includes(`${text}`);
1090
- if (sentVerified) {
1091
- this.logger.log('✅ [Claude] Verified sent text present in terminal history snippet');
1092
- return {
1093
- success: true,
1094
- method: 'applescript',
1095
- message: `Text sent and verified in Claude terminal: ${text}`,
1096
- note: result
1097
- };
1098
- }
1099
- this.logger.log('⚠️ [Claude] Sent text NOT found in terminal history snippet; will attempt deterministic retry');
1100
- } catch (verifyErr) {
1101
- this.logger.log('⚠️ [Claude] Verification parse error:', verifyErr.message || verifyErr);
1133
+ // Verify that the sent text appears in the returned history snippet
1134
+ try {
1135
+ const sentVerified = result && result.indexOf('|HIST:') !== -1 && result.split('|HIST:')[1].includes(`${text}`);
1136
+ if (sentVerified) {
1137
+ this.logger.log('✅ [Claude] Verified sent text present in terminal history snippet');
1138
+ return {
1139
+ success: true,
1140
+ method: 'applescript',
1141
+ message: `Text sent and verified in Claude terminal: ${text}`,
1142
+ note: result
1143
+ };
1102
1144
  }
1145
+ this.logger.log('⚠️ [Claude] Sent text NOT found in terminal history snippet; will attempt deterministic retry');
1146
+ } catch (verifyErr) {
1147
+ this.logger.log('⚠️ [Claude] Verification parse error:', verifyErr.message || verifyErr);
1148
+ }
1103
1149
 
1104
- // If verification failed, attempt a deterministic direct send to window 1 tab 1
1105
- try {
1106
- const det = await this.sendDeterministicToTerminalWindow1(text);
1107
- if (det && det.success) {
1108
- this.logger.log('✅ [Claude] Deterministic retry verified and succeeded');
1109
- return { success: true, method: 'applescript', message: `Text sent to newly opened Claude terminal: ${text}`, note: det.note };
1110
- }
1111
- this.logger.log('⚠️ [Claude] Deterministic retry did not verify:', det && det.note ? det.note : det && det.error ? det.error : det);
1112
- } catch (detErr) {
1113
- this.logger.log('❌ [Claude] Deterministic retry failed:', detErr.message || detErr);
1150
+ // If verification failed, attempt a deterministic direct send to window 1 tab 1
1151
+ try {
1152
+ const det = await this.sendDeterministicToTerminalWindow1(text);
1153
+ if (det && det.success) {
1154
+ this.logger.log('✅ [Claude] Deterministic retry verified and succeeded');
1155
+ return { success: true, method: 'applescript', message: `Text sent to newly opened Claude terminal: ${text}`, note: det.note };
1114
1156
  }
1157
+ this.logger.log('⚠️ [Claude] Deterministic retry did not verify:', det && det.note ? det.note : det && det.error ? det.error : det);
1158
+ } catch (detErr) {
1159
+ this.logger.log('❌ [Claude] Deterministic retry failed:', detErr.message || detErr);
1160
+ }
1115
1161
 
1116
- // CRITICAL FIX: If we reach here, text was sent but not verified
1117
- // Return success anyway since the AppleScript execution succeeded
1118
- this.logger.log('⚠️ [Claude] Text sent but verification inconclusive, returning success');
1119
- return {
1120
- success: true,
1121
- method: 'applescript',
1122
- message: `Text sent to Claude terminal (verification inconclusive): ${text}`,
1123
- note: 'Text sent successfully but verification did not confirm'
1124
- };
1162
+ // CRITICAL FIX: If we reach here, text was sent but not verified
1163
+ // Return success anyway since the AppleScript execution succeeded
1164
+ this.logger.log('⚠️ [Claude] Text sent but verification inconclusive, returning success');
1165
+ return {
1166
+ success: true,
1167
+ method: 'applescript',
1168
+ message: `Text sent to Claude terminal (verification inconclusive): ${text}`,
1169
+ note: 'Text sent successfully but verification did not confirm'
1170
+ };
1125
1171
  } catch (error) {
1126
1172
  this.logger.log('❌ [Claude] AppleScript failed:', error.message);
1127
1173
  return {
@@ -1168,11 +1214,53 @@ class AppleScriptManager {
1168
1214
  end tell
1169
1215
  end tell
1170
1216
  `;
1217
+ } else if (ide === 'kiro') {
1218
+ // AWS Kiro support
1219
+ this.logger.log('🚀 [AWS Kiro] Sending text via AppleScript accessibility (with fallback check)...');
1220
+
1221
+ appleScript = `
1222
+ tell application "System Events"
1223
+ set processName to "AWS Kiro"
1224
+ try
1225
+ if not (exists process "AWS Kiro") then
1226
+ set processName to "Kiro"
1227
+ end if
1228
+ on error
1229
+ set processName to "Kiro"
1230
+ end try
1231
+
1232
+ tell process processName
1233
+ set frontmost to true
1234
+ delay 1.0
1235
+
1236
+ -- Attempt to focus chat via standard AI IDE shortcuts
1237
+ -- Try Cmd+L (Cursor/Windsurf standard)
1238
+ try
1239
+ key code 37 using {command down}
1240
+ delay 0.5
1241
+ on error
1242
+ -- Ignore if fails
1243
+ end try
1244
+
1245
+ -- Use clipboard for more reliable text entry than keystrokes
1246
+ set the clipboard to "${text.replace(/"/g, '\\"')}"
1247
+ delay 0.3
1248
+
1249
+ -- Paste
1250
+ key code 9 using {command down}
1251
+ delay 0.5
1252
+
1253
+ -- Send Enter
1254
+ key code 36
1255
+ delay 0.5
1256
+ end tell
1257
+ end tell
1258
+ `;
1171
1259
  } else {
1172
1260
  return {
1173
1261
  success: false,
1174
1262
  error: `Unsupported IDE for AppleScript: ${ide}`,
1175
- note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, and VS Code'
1263
+ note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, VS Code, and AWS Kiro'
1176
1264
  };
1177
1265
  }
1178
1266
 
@@ -1820,14 +1908,14 @@ class AppleScriptManager {
1820
1908
 
1821
1909
  // Check if the result is just diagnostic information
1822
1910
  const isDiagnosticResult = result.includes('DEBUG:') ||
1823
- result.includes('diagnostic') ||
1824
- result.includes('No chat content found') ||
1825
- result.includes('Text areas found: 0') ||
1826
- result.includes('Static text found:') ||
1827
- result.includes('Window count:') ||
1828
- result.includes('Sample text:') ||
1829
- result.includes('Could not read') ||
1830
- result.includes('No readable text content detected');
1911
+ result.includes('diagnostic') ||
1912
+ result.includes('No chat content found') ||
1913
+ result.includes('Text areas found: 0') ||
1914
+ result.includes('Static text found:') ||
1915
+ result.includes('Window count:') ||
1916
+ result.includes('Sample text:') ||
1917
+ result.includes('Could not read') ||
1918
+ result.includes('No readable text content detected');
1831
1919
 
1832
1920
  this.logger.log(`🔍 Diagnostic detection check: isDiagnosticResult = ${isDiagnosticResult}`);
1833
1921
  this.logger.log(`🔍 Result contains 'DEBUG:': ${result.includes('DEBUG:')}`);
@@ -2701,9 +2789,9 @@ end tell
2701
2789
  try {
2702
2790
  // Check for VS Code extension environment variables
2703
2791
  return !!(process.env.VSCODE_PID ||
2704
- process.env.VSCODE_INJECTION ||
2705
- process.env.VSCODE_IPC_HOOK_CLI ||
2706
- (typeof require !== 'undefined' && require.main && require.main.filename.includes('vscode')));
2792
+ process.env.VSCODE_INJECTION ||
2793
+ process.env.VSCODE_IPC_HOOK_CLI ||
2794
+ (typeof require !== 'undefined' && require.main && require.main.filename.includes('vscode')));
2707
2795
  } catch (error) {
2708
2796
  this.logger.log('⚠️ Could not determine VS Code extension context:', error.message);
2709
2797
  return false;
package/src/index.cjs CHANGED
@@ -19,6 +19,7 @@ const configHelpers = require('./utils/config-helpers.cjs');
19
19
  const auditLogger = require('./utils/audit-logger.cjs');
20
20
  const { GCloudAuth } = require('./utils/gcloud-auth.cjs');
21
21
  const requirementHelpers = require('./utils/requirement-helpers.js');
22
+ const requirementsParser = require('./utils/requirements-parser.js');
22
23
  const updateChecker = require('./utils/update-checker.js');
23
24
  const electronUpdateChecker = require('./utils/electron-update-checker.js');
24
25
 
@@ -42,6 +43,7 @@ module.exports = {
42
43
  ...configHelpers,
43
44
  ...auditLogger,
44
45
  ...requirementHelpers,
46
+ ...requirementsParser,
45
47
  ...updateChecker,
46
48
  ...electronUpdateChecker
47
49
  };
package/src/index.js CHANGED
@@ -10,6 +10,8 @@ export { FeatureImplementer } from './autonomous-mode/feature-implementer.js';
10
10
  export { logger } from './utils/logger.js';
11
11
  export * from './utils/repo-helpers.js';
12
12
  export * from './utils/config-helpers.js';
13
+ export * from './utils/requirement-helpers.js';
14
+ export * from './utils/requirements-parser.js';
13
15
 
14
16
  // UI Components
15
17
  export * from './ui/ButtonComponents.js';