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 +4 -1
- package/src/auth/shared-auth-storage.js +43 -6
- package/src/ide-integration/applescript-manager.cjs +126 -18
- package/src/ide-integration/applescript-manager.js +172 -84
- package/src/index.cjs +2 -0
- package/src/index.js +2 -0
- package/src/sync/aws-setup.js +445 -0
- package/src/sync/sync-engine.js +388 -0
- package/src/utils/requirement-helpers.js +139 -70
- package/src/utils/requirements-parser.js +310 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibecodingmachine-core",
|
|
3
|
-
"version": "2025.12.
|
|
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
|
-
|
|
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
|
-
*
|
|
66
|
+
* Get stored refresh token
|
|
65
67
|
*/
|
|
66
|
-
async
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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 ? `
|
|
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:
|
|
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
|
|
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
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
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
|
-
|
|
1049
|
+
note: 'Text validation failed'
|
|
1002
1050
|
};
|
|
1003
1051
|
}
|
|
1004
1052
|
|
|
1005
|
-
const
|
|
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
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
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
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
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
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
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
|
|
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
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
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
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
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';
|