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.
- package/package.json +4 -1
- package/scripts/setup-database.js +108 -0
- package/src/auth/shared-auth-storage.js +43 -6
- package/src/compliance/compliance-manager.js +249 -0
- package/src/compliance/compliance-prompt.js +183 -0
- package/src/database/migrations.js +289 -0
- package/src/database/user-database-client.js +266 -0
- package/src/database/user-schema.js +118 -0
- package/src/ide-integration/applescript-manager.cjs +199 -145
- package/src/ide-integration/applescript-manager.js +234 -96
- package/src/ide-integration/claude-code-cli-manager.cjs +120 -1
- package/src/ide-integration/provider-manager.cjs +67 -1
- package/src/index.cjs +2 -0
- package/src/index.js +6 -0
- package/src/llm/direct-llm-manager.cjs +110 -73
- package/src/quota-management/index.js +108 -0
- package/src/sync/aws-setup.js +445 -0
- package/src/sync/sync-engine.js +410 -0
- package/src/utils/download-with-progress.js +92 -0
- package/src/utils/electron-update-checker.js +7 -0
- package/src/utils/env-helpers.js +54 -0
- package/src/utils/requirement-helpers.js +865 -100
- package/src/utils/requirements-parser.js +324 -0
- package/src/utils/update-checker.js +7 -0
- package/test-quota-system.js +67 -0
- package/test-requirement-stats.js +66 -0
|
@@ -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
|
}
|
|
@@ -118,11 +182,43 @@ class AppleScriptManager {
|
|
|
118
182
|
set frontmost to true
|
|
119
183
|
delay 0.8
|
|
120
184
|
|
|
121
|
-
-- Try to find
|
|
185
|
+
-- Try to find model selection button with multiple possible texts
|
|
122
186
|
try
|
|
123
|
-
set
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
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
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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 -
|
|
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
|
|
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
|
|
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(
|
|
501
|
+
this.logger.log(`❌ AppleScript interaction failed for ${ideName}:`, error.message);
|
|
448
502
|
|
|
449
|
-
//
|
|
503
|
+
// Return failure - DO NOT fallback to simulation
|
|
450
504
|
return {
|
|
451
|
-
success:
|
|
452
|
-
|
|
453
|
-
message: `
|
|
454
|
-
note:
|
|
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
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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:')}`);
|