vibecodingmachine-core 1.0.2 β†’ 2025.11.2-7.1302

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 (49) hide show
  1. package/.babelrc +13 -13
  2. package/README.md +28 -28
  3. package/__tests__/applescript-manager-claude-fix.test.js +286 -286
  4. package/__tests__/requirement-2-auto-start-looping.test.js +69 -69
  5. package/__tests__/requirement-3-auto-start-looping.test.js +69 -69
  6. package/__tests__/requirement-4-auto-start-looping.test.js +69 -69
  7. package/__tests__/requirement-6-auto-start-looping.test.js +73 -73
  8. package/__tests__/requirement-7-status-tracking.test.js +332 -332
  9. package/jest.config.js +18 -18
  10. package/jest.setup.js +12 -12
  11. package/package.json +48 -48
  12. package/src/auth/access-denied.html +119 -119
  13. package/src/auth/shared-auth-storage.js +230 -230
  14. package/src/autonomous-mode/feature-implementer.cjs +70 -70
  15. package/src/autonomous-mode/feature-implementer.js +425 -425
  16. package/src/chat-management/chat-manager.cjs +71 -71
  17. package/src/chat-management/chat-manager.js +342 -342
  18. package/src/ide-integration/__tests__/applescript-manager-thread-closure.test.js +227 -227
  19. package/src/ide-integration/aider-cli-manager.cjs +850 -850
  20. package/src/ide-integration/applescript-manager.cjs +1088 -1088
  21. package/src/ide-integration/applescript-manager.js +2802 -2802
  22. package/src/ide-integration/applescript-utils.js +306 -306
  23. package/src/ide-integration/cdp-manager.cjs +221 -221
  24. package/src/ide-integration/cdp-manager.js +321 -321
  25. package/src/ide-integration/claude-code-cli-manager.cjs +301 -301
  26. package/src/ide-integration/cline-cli-manager.cjs +2252 -2252
  27. package/src/ide-integration/continue-cli-manager.js +431 -431
  28. package/src/ide-integration/provider-manager.cjs +354 -354
  29. package/src/ide-integration/quota-detector.cjs +34 -34
  30. package/src/ide-integration/quota-detector.js +349 -349
  31. package/src/ide-integration/windows-automation-manager.js +262 -262
  32. package/src/index.cjs +47 -43
  33. package/src/index.js +17 -17
  34. package/src/llm/direct-llm-manager.cjs +609 -609
  35. package/src/ui/ButtonComponents.js +247 -247
  36. package/src/ui/ChatInterface.js +499 -499
  37. package/src/ui/StateManager.js +259 -259
  38. package/src/utils/audit-logger.cjs +116 -116
  39. package/src/utils/config-helpers.cjs +94 -94
  40. package/src/utils/config-helpers.js +94 -94
  41. package/src/utils/electron-update-checker.js +113 -85
  42. package/src/utils/gcloud-auth.cjs +394 -394
  43. package/src/utils/logger.cjs +193 -193
  44. package/src/utils/logger.js +191 -191
  45. package/src/utils/repo-helpers.cjs +120 -120
  46. package/src/utils/repo-helpers.js +120 -120
  47. package/src/utils/requirement-helpers.js +432 -432
  48. package/src/utils/update-checker.js +227 -167
  49. package/src/utils/version-checker.js +169 -0
@@ -1,425 +1,425 @@
1
- // @vibecodingmachine/core - Feature Implementer
2
- // Handles autonomous mode feature implementation and development workflow
3
-
4
- import { QuotaDetector } from '../ide-integration/quota-detector.js';
5
- import { ChatManager } from '../chat-management/chat-manager.js';
6
-
7
- /**
8
- * Feature Implementer for autonomous development
9
- * Manages autonomous mode workflow, quota checking, and feature implementation
10
- */
11
- export class FeatureImplementer {
12
- constructor(options = {}) {
13
- this.logger = options.logger || console;
14
- this.electronAPI = options.electronAPI || null;
15
- this.onStatusUpdate = options.onStatusUpdate || (() => {});
16
- this.onProgressUpdate = options.onProgressUpdate || (() => {});
17
- this.onMessageUpdate = options.onMessageUpdate || (() => {});
18
- this.onErrorUpdate = options.onErrorUpdate || (() => {});
19
- this.onCompleteUpdate = options.onCompleteUpdate || (() => {});
20
-
21
- // Managers
22
- this.quotaDetector = new QuotaDetector();
23
- this.chatManager = new ChatManager({
24
- logger: this.logger,
25
- electronAPI: this.electronAPI,
26
- onMessageUpdate: this.onMessageUpdate,
27
- onStatusUpdate: this.onStatusUpdate,
28
- onProgressUpdate: this.onProgressUpdate
29
- });
30
-
31
- // State
32
- this.isAutonomousMode = false;
33
- this.isPaused = false;
34
- this.isStopped = false;
35
- this.currentProgress = 0;
36
- this.taskCount = 0;
37
- this.maxTasks = 10;
38
- this.completedFeatures = [];
39
- this.errorLog = [];
40
- }
41
-
42
- /**
43
- * Start autonomous mode with recovery capabilities
44
- * @param {string} ide - The IDE to use for autonomous mode
45
- * @param {string} tabId - The tab ID for tracking
46
- * @returns {Promise<Object>} Result of autonomous mode execution
47
- */
48
- async startAutonomousMode(ide, tabId) {
49
- this.logger.log('πŸ€– ===== AUTONOMOUS MODE START =====');
50
- this.logger.log('πŸ€– startAutonomousMode called for:', ide);
51
-
52
- this.isAutonomousMode = true;
53
- this.isStopped = false;
54
- this.currentProgress = 0;
55
- this.taskCount = 0;
56
- this.completedFeatures = [];
57
- this.errorLog = [];
58
-
59
- this.onStatusUpdate(tabId, 'πŸ€– Starting enhanced autonomous mode with backend integration...');
60
-
61
- try {
62
- // Check if this is a Windsurf tab for enhanced functionality
63
- const isWindsurfTab = ide === 'windsurf';
64
- this.logger.log('πŸ€– Is Windsurf tab:', isWindsurfTab);
65
-
66
- if (isWindsurfTab) {
67
- this.onStatusUpdate(tabId, 'πŸš€ Starting Windsurf-specific autonomous development...');
68
- this.logger.log('πŸ€– Windsurf tab detected - using enhanced autonomous mode');
69
- } else {
70
- this.onStatusUpdate(tabId, 'πŸ€– Starting standard autonomous mode...');
71
- this.logger.log('πŸ€– Standard IDE tab detected - using standard autonomous mode');
72
- }
73
-
74
- // Enhanced autonomous mode for Windsurf
75
- if (isWindsurfTab) {
76
- this.logger.log('πŸ€– Using enhanced Windsurf autonomous mode...');
77
- this.onStatusUpdate(tabId, 'πŸ€– Starting enhanced Windsurf autonomous mode...');
78
-
79
- // Check for quota warning in Windsurf first
80
- this.logger.log('πŸ€– Checking Windsurf quota before starting autonomous mode...');
81
- this.onStatusUpdate(tabId, 'πŸ€– Checking Windsurf quota...');
82
-
83
- const quotaCheck = await this.checkQuotaAndSwitch('windsurf');
84
-
85
- if (quotaCheck.switched) {
86
- this.logger.log('πŸ€– βœ… Switched from Windsurf to another IDE due to quota warning');
87
- this.onStatusUpdate(tabId, `πŸ€– Switched to ${quotaCheck.newIde} due to Windsurf quota warning`);
88
-
89
- // Continue with autonomous mode using the new IDE
90
- this.logger.log('πŸ€– Continuing autonomous mode with new IDE...');
91
- this.onStatusUpdate(tabId, `πŸ€– Continuing autonomous mode with ${quotaCheck.newIde}...`);
92
-
93
- // Reset states for the new IDE
94
- this.isStopped = false;
95
- this.currentProgress = 0;
96
-
97
- // Use the new IDE for autonomous mode
98
- const newIde = quotaCheck.newIde;
99
- this.logger.log(`πŸ€– Using ${newIde} for autonomous mode instead of Windsurf`);
100
-
101
- return await this.runAutonomousLoop(newIde, tabId);
102
- } else if (quotaCheck.error) {
103
- this.logger.log('πŸ€– ⚠️ Quota check failed:', quotaCheck.error);
104
- // Continue with Windsurf even if quota check failed
105
- } else {
106
- this.logger.log('πŸ€– βœ… No quota warning in Windsurf, proceeding with Windsurf autonomous mode');
107
- this.onStatusUpdate(tabId, 'πŸ€– Windsurf quota OK, starting autonomous mode...');
108
- }
109
- }
110
-
111
- // Run autonomous loop with the specified IDE
112
- return await this.runAutonomousLoop(ide, tabId);
113
-
114
- } catch (error) {
115
- this.logger.error('❌ Error starting autonomous mode:', error);
116
- this.onErrorUpdate(tabId, `Error starting autonomous mode: ${error.message}`);
117
- this.stopAutonomousMode();
118
-
119
- return {
120
- success: false,
121
- error: error.message
122
- };
123
- }
124
- }
125
-
126
- /**
127
- * Run the autonomous development loop
128
- * @param {string} ide - The IDE to use
129
- * @param {string} tabId - The tab ID for tracking
130
- * @returns {Promise<Object>} Result of autonomous loop execution
131
- */
132
- async runAutonomousLoop(ide, tabId) {
133
- this.logger.log(`πŸ€– Starting ${ide} autonomous loop...`);
134
-
135
- // Send initial command to start autonomous development
136
- const initialCommand = 'Follow the instructions in the INSTRUCTIONS.md file in the root of the repo. Please implement the features and report progress percentage after each task.';
137
-
138
- let currentProgress = 0;
139
- let taskCount = 0;
140
-
141
- this.logger.log('πŸ€– Initial conditions:', { currentProgress, taskCount, maxTasks: this.maxTasks, isStopped: this.isStopped, isAutonomousMode: this.isAutonomousMode });
142
-
143
- // Main autonomous loop
144
- while (currentProgress < 100 && taskCount < this.maxTasks && !this.isStopped && this.isAutonomousMode) {
145
- // Check if paused
146
- while (this.isPaused && this.isAutonomousMode && !this.isStopped) {
147
- this.logger.log('⏸️ Autonomous mode paused, waiting...');
148
- await new Promise(resolve => setTimeout(resolve, 1000));
149
- }
150
-
151
- // Check if stopped
152
- if (this.isStopped || !this.isAutonomousMode) {
153
- this.logger.log('πŸ›‘ Autonomous mode stopped, exiting...');
154
- break;
155
- }
156
-
157
- taskCount++;
158
- this.taskCount = taskCount;
159
- this.onStatusUpdate(tabId, `πŸ€– Task ${taskCount}: Implementing features (${currentProgress}% complete)...`);
160
-
161
- // Send command and wait for response
162
- const commandResult = await this.sendAutonomousCommand(initialCommand, ide, tabId);
163
-
164
- if (commandResult.success) {
165
- if (commandResult.progress !== undefined) {
166
- currentProgress = commandResult.progress;
167
- this.currentProgress = currentProgress;
168
- this.onProgressUpdate(currentProgress);
169
- }
170
-
171
- if (commandResult.completed) {
172
- this.onStatusUpdate(tabId, 'πŸŽ‰ All features implemented! Autonomous development complete!');
173
- this.onCompleteUpdate(tabId, true);
174
- this.stopAutonomousMode();
175
-
176
- return {
177
- success: true,
178
- progress: 100,
179
- completed: true,
180
- taskCount: taskCount
181
- };
182
- }
183
-
184
- // Wait before next task
185
- await new Promise(resolve => setTimeout(resolve, 2000));
186
- } else {
187
- this.logger.log('❌ Command failed:', commandResult.error);
188
- this.onErrorUpdate(tabId, `Task ${taskCount} failed: ${commandResult.error}`);
189
-
190
- // Add to error log
191
- this.errorLog.push({
192
- task: taskCount,
193
- error: commandResult.error,
194
- timestamp: Date.now()
195
- });
196
-
197
- // Continue with next task
198
- await new Promise(resolve => setTimeout(resolve, 3000));
199
- }
200
- }
201
-
202
- // Check why we exited the loop
203
- if (taskCount >= this.maxTasks) {
204
- this.onStatusUpdate(tabId, '⚠️ Maximum tasks reached, autonomous mode stopping...');
205
- } else if (this.isStopped) {
206
- this.onStatusUpdate(tabId, 'πŸ›‘ Autonomous mode stopped by user');
207
- } else if (currentProgress >= 100) {
208
- this.onStatusUpdate(tabId, 'πŸŽ‰ 100% completion reached!');
209
- this.onCompleteUpdate(tabId, true);
210
- }
211
-
212
- this.stopAutonomousMode();
213
-
214
- return {
215
- success: true,
216
- progress: currentProgress,
217
- completed: currentProgress >= 100,
218
- taskCount: taskCount,
219
- errorLog: this.errorLog
220
- };
221
- }
222
-
223
- /**
224
- * Send an autonomous command to an IDE
225
- * @param {string} command - The command to send
226
- * @param {string} ide - The IDE to send to
227
- * @param {string} tabId - The tab ID for tracking
228
- * @returns {Promise<Object>} Result of the command execution
229
- */
230
- async sendAutonomousCommand(command, ide, tabId) {
231
- this.logger.log(`πŸ€– Sending autonomous command: ${command.substring(0, 100)}...`);
232
-
233
- try {
234
- // Check for quota warnings before sending command
235
- const quotaCheck = await this.checkQuotaAndSwitch(ide);
236
-
237
- if (quotaCheck.switched) {
238
- this.logger.log('πŸ€– Switched from', ide, 'to', quotaCheck.newIde);
239
- this.onStatusUpdate(tabId, `πŸ€– Switched to ${quotaCheck.newIde} due to quota warning`);
240
-
241
- // Send the command to the new IDE instead
242
- return await this.sendAutonomousCommand(command, quotaCheck.newIde, tabId);
243
- } else if (quotaCheck.error) {
244
- this.logger.log('πŸ€– ⚠️ Quota check failed:', quotaCheck.error);
245
- // Continue with sending command even if quota check failed
246
- } else {
247
- this.logger.log('πŸ€– βœ… No quota warnings detected, proceeding with command');
248
- }
249
-
250
- // Add auto-sent message to chat display
251
- this.onMessageUpdate(tabId, {
252
- role: 'auto',
253
- text: command,
254
- timestamp: Date.now()
255
- });
256
-
257
- // Send the command using chat manager
258
- const sendResult = await this.chatManager.sendMessage(command, ide, tabId);
259
-
260
- if (sendResult && sendResult.success) {
261
- this.logger.log('βœ… Command sent successfully');
262
-
263
- // Wait for response completion
264
- const responseResult = await this.chatManager.detectResponseCompletion(ide, '');
265
-
266
- if (responseResult.completed) {
267
- this.logger.log('βœ… Response completed successfully');
268
-
269
- // If we're at 100%, don't send another command
270
- if (responseResult.progress === 100) {
271
- this.logger.log('πŸŽ‰ 100% completion reached - stopping autonomous mode');
272
- return { success: true, progress: 100, completed: true };
273
- }
274
-
275
- return { success: true, progress: responseResult.progress || 0 };
276
- } else {
277
- this.logger.log('⚠️ Response detection failed or incomplete');
278
- return { success: false, reason: 'response_incomplete' };
279
- }
280
- } else {
281
- this.logger.log('❌ Failed to send command:', sendResult?.error);
282
- return { success: false, error: sendResult?.error };
283
- }
284
- } catch (error) {
285
- this.logger.log('❌ Error in autonomous command:', error.message);
286
- return { success: false, error: error.message };
287
- }
288
- }
289
-
290
- /**
291
- * Check quota and switch to available IDE if needed
292
- * @param {string} ide - The IDE to check
293
- * @returns {Promise<Object>} Quota check result
294
- */
295
- async checkQuotaAndSwitch(ide) {
296
- try {
297
- this.logger.log(`πŸ” Checking quota for ${ide}...`);
298
-
299
- const quotaResult = await this.quotaDetector.detectQuotaWarning(ide);
300
-
301
- if (quotaResult.hasQuotaWarning) {
302
- this.logger.log(`❌ Quota warning detected in ${ide}:`, quotaResult.note);
303
-
304
- // Get available IDEs without quota warnings
305
- const availableIdes = await this.quotaDetector.getAvailableIdes(['vscode', 'cursor', 'windsurf']);
306
-
307
- // Remove the current IDE from available options
308
- const otherIdes = availableIdes.filter(availableIde => availableIde !== ide);
309
-
310
- if (otherIdes.length > 0) {
311
- const newIde = otherIdes[0]; // Use the first available IDE
312
- this.logger.log(`πŸ”„ Switching from ${ide} to ${newIde} due to quota warning`);
313
-
314
- return {
315
- switched: true,
316
- newIde: newIde,
317
- reason: 'quota_warning',
318
- originalIde: ide
319
- };
320
- } else {
321
- this.logger.log('❌ No available IDEs found, cannot switch');
322
- return {
323
- switched: false,
324
- error: 'No available IDEs without quota warnings'
325
- };
326
- }
327
- } else {
328
- this.logger.log(`βœ… No quota warnings detected in ${ide}`);
329
- return {
330
- switched: false,
331
- ide: ide
332
- };
333
- }
334
- } catch (error) {
335
- this.logger.log(`❌ Error checking quota for ${ide}:`, error.message);
336
- return {
337
- switched: false,
338
- error: error.message
339
- };
340
- }
341
- }
342
-
343
- /**
344
- * Stop autonomous mode
345
- */
346
- stopAutonomousMode() {
347
- this.isAutonomousMode = false;
348
- this.isStopped = true;
349
- this.chatManager.stop();
350
- this.logger.log('πŸ›‘ Autonomous mode stopped');
351
- }
352
-
353
- /**
354
- * Pause autonomous mode
355
- */
356
- pauseAutonomousMode() {
357
- this.isPaused = true;
358
- this.chatManager.pause();
359
- this.logger.log('⏸️ Autonomous mode paused');
360
- }
361
-
362
- /**
363
- * Resume autonomous mode
364
- */
365
- resumeAutonomousMode() {
366
- this.isPaused = false;
367
- this.chatManager.resume();
368
- this.logger.log('▢️ Autonomous mode resumed');
369
- }
370
-
371
- /**
372
- * Get current autonomous mode state
373
- * @returns {Object} Current state
374
- */
375
- getState() {
376
- return {
377
- isAutonomousMode: this.isAutonomousMode,
378
- isPaused: this.isPaused,
379
- isStopped: this.isStopped,
380
- currentProgress: this.currentProgress,
381
- taskCount: this.taskCount,
382
- maxTasks: this.maxTasks,
383
- completedFeatures: this.completedFeatures,
384
- errorLog: this.errorLog
385
- };
386
- }
387
-
388
- /**
389
- * Set electron API for Electron environment
390
- * @param {Object} electronAPI - The electron API object
391
- */
392
- setElectronAPI(electronAPI) {
393
- this.electronAPI = electronAPI;
394
- this.chatManager.setElectronAPI(electronAPI);
395
- }
396
-
397
- /**
398
- * Set callback functions
399
- * @param {Object} callbacks - Object containing callback functions
400
- */
401
- setCallbacks(callbacks) {
402
- if (callbacks.onStatusUpdate) {
403
- this.onStatusUpdate = callbacks.onStatusUpdate;
404
- }
405
- if (callbacks.onProgressUpdate) {
406
- this.onProgressUpdate = callbacks.onProgressUpdate;
407
- }
408
- if (callbacks.onMessageUpdate) {
409
- this.onMessageUpdate = callbacks.onMessageUpdate;
410
- }
411
- if (callbacks.onErrorUpdate) {
412
- this.onErrorUpdate = callbacks.onErrorUpdate;
413
- }
414
- if (callbacks.onCompleteUpdate) {
415
- this.onCompleteUpdate = callbacks.onCompleteUpdate;
416
- }
417
-
418
- // Update chat manager callbacks
419
- this.chatManager.setCallbacks({
420
- onMessageUpdate: this.onMessageUpdate,
421
- onStatusUpdate: this.onStatusUpdate,
422
- onProgressUpdate: this.onProgressUpdate
423
- });
424
- }
425
- }
1
+ // @vibecodingmachine/core - Feature Implementer
2
+ // Handles autonomous mode feature implementation and development workflow
3
+
4
+ import { QuotaDetector } from '../ide-integration/quota-detector.js';
5
+ import { ChatManager } from '../chat-management/chat-manager.js';
6
+
7
+ /**
8
+ * Feature Implementer for autonomous development
9
+ * Manages autonomous mode workflow, quota checking, and feature implementation
10
+ */
11
+ export class FeatureImplementer {
12
+ constructor(options = {}) {
13
+ this.logger = options.logger || console;
14
+ this.electronAPI = options.electronAPI || null;
15
+ this.onStatusUpdate = options.onStatusUpdate || (() => {});
16
+ this.onProgressUpdate = options.onProgressUpdate || (() => {});
17
+ this.onMessageUpdate = options.onMessageUpdate || (() => {});
18
+ this.onErrorUpdate = options.onErrorUpdate || (() => {});
19
+ this.onCompleteUpdate = options.onCompleteUpdate || (() => {});
20
+
21
+ // Managers
22
+ this.quotaDetector = new QuotaDetector();
23
+ this.chatManager = new ChatManager({
24
+ logger: this.logger,
25
+ electronAPI: this.electronAPI,
26
+ onMessageUpdate: this.onMessageUpdate,
27
+ onStatusUpdate: this.onStatusUpdate,
28
+ onProgressUpdate: this.onProgressUpdate
29
+ });
30
+
31
+ // State
32
+ this.isAutonomousMode = false;
33
+ this.isPaused = false;
34
+ this.isStopped = false;
35
+ this.currentProgress = 0;
36
+ this.taskCount = 0;
37
+ this.maxTasks = 10;
38
+ this.completedFeatures = [];
39
+ this.errorLog = [];
40
+ }
41
+
42
+ /**
43
+ * Start autonomous mode with recovery capabilities
44
+ * @param {string} ide - The IDE to use for autonomous mode
45
+ * @param {string} tabId - The tab ID for tracking
46
+ * @returns {Promise<Object>} Result of autonomous mode execution
47
+ */
48
+ async startAutonomousMode(ide, tabId) {
49
+ this.logger.log('πŸ€– ===== AUTONOMOUS MODE START =====');
50
+ this.logger.log('πŸ€– startAutonomousMode called for:', ide);
51
+
52
+ this.isAutonomousMode = true;
53
+ this.isStopped = false;
54
+ this.currentProgress = 0;
55
+ this.taskCount = 0;
56
+ this.completedFeatures = [];
57
+ this.errorLog = [];
58
+
59
+ this.onStatusUpdate(tabId, 'πŸ€– Starting enhanced autonomous mode with backend integration...');
60
+
61
+ try {
62
+ // Check if this is a Windsurf tab for enhanced functionality
63
+ const isWindsurfTab = ide === 'windsurf';
64
+ this.logger.log('πŸ€– Is Windsurf tab:', isWindsurfTab);
65
+
66
+ if (isWindsurfTab) {
67
+ this.onStatusUpdate(tabId, 'πŸš€ Starting Windsurf-specific autonomous development...');
68
+ this.logger.log('πŸ€– Windsurf tab detected - using enhanced autonomous mode');
69
+ } else {
70
+ this.onStatusUpdate(tabId, 'πŸ€– Starting standard autonomous mode...');
71
+ this.logger.log('πŸ€– Standard IDE tab detected - using standard autonomous mode');
72
+ }
73
+
74
+ // Enhanced autonomous mode for Windsurf
75
+ if (isWindsurfTab) {
76
+ this.logger.log('πŸ€– Using enhanced Windsurf autonomous mode...');
77
+ this.onStatusUpdate(tabId, 'πŸ€– Starting enhanced Windsurf autonomous mode...');
78
+
79
+ // Check for quota warning in Windsurf first
80
+ this.logger.log('πŸ€– Checking Windsurf quota before starting autonomous mode...');
81
+ this.onStatusUpdate(tabId, 'πŸ€– Checking Windsurf quota...');
82
+
83
+ const quotaCheck = await this.checkQuotaAndSwitch('windsurf');
84
+
85
+ if (quotaCheck.switched) {
86
+ this.logger.log('πŸ€– βœ… Switched from Windsurf to another IDE due to quota warning');
87
+ this.onStatusUpdate(tabId, `πŸ€– Switched to ${quotaCheck.newIde} due to Windsurf quota warning`);
88
+
89
+ // Continue with autonomous mode using the new IDE
90
+ this.logger.log('πŸ€– Continuing autonomous mode with new IDE...');
91
+ this.onStatusUpdate(tabId, `πŸ€– Continuing autonomous mode with ${quotaCheck.newIde}...`);
92
+
93
+ // Reset states for the new IDE
94
+ this.isStopped = false;
95
+ this.currentProgress = 0;
96
+
97
+ // Use the new IDE for autonomous mode
98
+ const newIde = quotaCheck.newIde;
99
+ this.logger.log(`πŸ€– Using ${newIde} for autonomous mode instead of Windsurf`);
100
+
101
+ return await this.runAutonomousLoop(newIde, tabId);
102
+ } else if (quotaCheck.error) {
103
+ this.logger.log('πŸ€– ⚠️ Quota check failed:', quotaCheck.error);
104
+ // Continue with Windsurf even if quota check failed
105
+ } else {
106
+ this.logger.log('πŸ€– βœ… No quota warning in Windsurf, proceeding with Windsurf autonomous mode');
107
+ this.onStatusUpdate(tabId, 'πŸ€– Windsurf quota OK, starting autonomous mode...');
108
+ }
109
+ }
110
+
111
+ // Run autonomous loop with the specified IDE
112
+ return await this.runAutonomousLoop(ide, tabId);
113
+
114
+ } catch (error) {
115
+ this.logger.error('❌ Error starting autonomous mode:', error);
116
+ this.onErrorUpdate(tabId, `Error starting autonomous mode: ${error.message}`);
117
+ this.stopAutonomousMode();
118
+
119
+ return {
120
+ success: false,
121
+ error: error.message
122
+ };
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Run the autonomous development loop
128
+ * @param {string} ide - The IDE to use
129
+ * @param {string} tabId - The tab ID for tracking
130
+ * @returns {Promise<Object>} Result of autonomous loop execution
131
+ */
132
+ async runAutonomousLoop(ide, tabId) {
133
+ this.logger.log(`πŸ€– Starting ${ide} autonomous loop...`);
134
+
135
+ // Send initial command to start autonomous development
136
+ const initialCommand = 'Follow the instructions in the INSTRUCTIONS.md file in the root of the repo. Please implement the features and report progress percentage after each task.';
137
+
138
+ let currentProgress = 0;
139
+ let taskCount = 0;
140
+
141
+ this.logger.log('πŸ€– Initial conditions:', { currentProgress, taskCount, maxTasks: this.maxTasks, isStopped: this.isStopped, isAutonomousMode: this.isAutonomousMode });
142
+
143
+ // Main autonomous loop
144
+ while (currentProgress < 100 && taskCount < this.maxTasks && !this.isStopped && this.isAutonomousMode) {
145
+ // Check if paused
146
+ while (this.isPaused && this.isAutonomousMode && !this.isStopped) {
147
+ this.logger.log('⏸️ Autonomous mode paused, waiting...');
148
+ await new Promise(resolve => setTimeout(resolve, 1000));
149
+ }
150
+
151
+ // Check if stopped
152
+ if (this.isStopped || !this.isAutonomousMode) {
153
+ this.logger.log('πŸ›‘ Autonomous mode stopped, exiting...');
154
+ break;
155
+ }
156
+
157
+ taskCount++;
158
+ this.taskCount = taskCount;
159
+ this.onStatusUpdate(tabId, `πŸ€– Task ${taskCount}: Implementing features (${currentProgress}% complete)...`);
160
+
161
+ // Send command and wait for response
162
+ const commandResult = await this.sendAutonomousCommand(initialCommand, ide, tabId);
163
+
164
+ if (commandResult.success) {
165
+ if (commandResult.progress !== undefined) {
166
+ currentProgress = commandResult.progress;
167
+ this.currentProgress = currentProgress;
168
+ this.onProgressUpdate(currentProgress);
169
+ }
170
+
171
+ if (commandResult.completed) {
172
+ this.onStatusUpdate(tabId, 'πŸŽ‰ All features implemented! Autonomous development complete!');
173
+ this.onCompleteUpdate(tabId, true);
174
+ this.stopAutonomousMode();
175
+
176
+ return {
177
+ success: true,
178
+ progress: 100,
179
+ completed: true,
180
+ taskCount: taskCount
181
+ };
182
+ }
183
+
184
+ // Wait before next task
185
+ await new Promise(resolve => setTimeout(resolve, 2000));
186
+ } else {
187
+ this.logger.log('❌ Command failed:', commandResult.error);
188
+ this.onErrorUpdate(tabId, `Task ${taskCount} failed: ${commandResult.error}`);
189
+
190
+ // Add to error log
191
+ this.errorLog.push({
192
+ task: taskCount,
193
+ error: commandResult.error,
194
+ timestamp: Date.now()
195
+ });
196
+
197
+ // Continue with next task
198
+ await new Promise(resolve => setTimeout(resolve, 3000));
199
+ }
200
+ }
201
+
202
+ // Check why we exited the loop
203
+ if (taskCount >= this.maxTasks) {
204
+ this.onStatusUpdate(tabId, '⚠️ Maximum tasks reached, autonomous mode stopping...');
205
+ } else if (this.isStopped) {
206
+ this.onStatusUpdate(tabId, 'πŸ›‘ Autonomous mode stopped by user');
207
+ } else if (currentProgress >= 100) {
208
+ this.onStatusUpdate(tabId, 'πŸŽ‰ 100% completion reached!');
209
+ this.onCompleteUpdate(tabId, true);
210
+ }
211
+
212
+ this.stopAutonomousMode();
213
+
214
+ return {
215
+ success: true,
216
+ progress: currentProgress,
217
+ completed: currentProgress >= 100,
218
+ taskCount: taskCount,
219
+ errorLog: this.errorLog
220
+ };
221
+ }
222
+
223
+ /**
224
+ * Send an autonomous command to an IDE
225
+ * @param {string} command - The command to send
226
+ * @param {string} ide - The IDE to send to
227
+ * @param {string} tabId - The tab ID for tracking
228
+ * @returns {Promise<Object>} Result of the command execution
229
+ */
230
+ async sendAutonomousCommand(command, ide, tabId) {
231
+ this.logger.log(`πŸ€– Sending autonomous command: ${command.substring(0, 100)}...`);
232
+
233
+ try {
234
+ // Check for quota warnings before sending command
235
+ const quotaCheck = await this.checkQuotaAndSwitch(ide);
236
+
237
+ if (quotaCheck.switched) {
238
+ this.logger.log('πŸ€– Switched from', ide, 'to', quotaCheck.newIde);
239
+ this.onStatusUpdate(tabId, `πŸ€– Switched to ${quotaCheck.newIde} due to quota warning`);
240
+
241
+ // Send the command to the new IDE instead
242
+ return await this.sendAutonomousCommand(command, quotaCheck.newIde, tabId);
243
+ } else if (quotaCheck.error) {
244
+ this.logger.log('πŸ€– ⚠️ Quota check failed:', quotaCheck.error);
245
+ // Continue with sending command even if quota check failed
246
+ } else {
247
+ this.logger.log('πŸ€– βœ… No quota warnings detected, proceeding with command');
248
+ }
249
+
250
+ // Add auto-sent message to chat display
251
+ this.onMessageUpdate(tabId, {
252
+ role: 'auto',
253
+ text: command,
254
+ timestamp: Date.now()
255
+ });
256
+
257
+ // Send the command using chat manager
258
+ const sendResult = await this.chatManager.sendMessage(command, ide, tabId);
259
+
260
+ if (sendResult && sendResult.success) {
261
+ this.logger.log('βœ… Command sent successfully');
262
+
263
+ // Wait for response completion
264
+ const responseResult = await this.chatManager.detectResponseCompletion(ide, '');
265
+
266
+ if (responseResult.completed) {
267
+ this.logger.log('βœ… Response completed successfully');
268
+
269
+ // If we're at 100%, don't send another command
270
+ if (responseResult.progress === 100) {
271
+ this.logger.log('πŸŽ‰ 100% completion reached - stopping autonomous mode');
272
+ return { success: true, progress: 100, completed: true };
273
+ }
274
+
275
+ return { success: true, progress: responseResult.progress || 0 };
276
+ } else {
277
+ this.logger.log('⚠️ Response detection failed or incomplete');
278
+ return { success: false, reason: 'response_incomplete' };
279
+ }
280
+ } else {
281
+ this.logger.log('❌ Failed to send command:', sendResult?.error);
282
+ return { success: false, error: sendResult?.error };
283
+ }
284
+ } catch (error) {
285
+ this.logger.log('❌ Error in autonomous command:', error.message);
286
+ return { success: false, error: error.message };
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Check quota and switch to available IDE if needed
292
+ * @param {string} ide - The IDE to check
293
+ * @returns {Promise<Object>} Quota check result
294
+ */
295
+ async checkQuotaAndSwitch(ide) {
296
+ try {
297
+ this.logger.log(`πŸ” Checking quota for ${ide}...`);
298
+
299
+ const quotaResult = await this.quotaDetector.detectQuotaWarning(ide);
300
+
301
+ if (quotaResult.hasQuotaWarning) {
302
+ this.logger.log(`❌ Quota warning detected in ${ide}:`, quotaResult.note);
303
+
304
+ // Get available IDEs without quota warnings
305
+ const availableIdes = await this.quotaDetector.getAvailableIdes(['vscode', 'cursor', 'windsurf']);
306
+
307
+ // Remove the current IDE from available options
308
+ const otherIdes = availableIdes.filter(availableIde => availableIde !== ide);
309
+
310
+ if (otherIdes.length > 0) {
311
+ const newIde = otherIdes[0]; // Use the first available IDE
312
+ this.logger.log(`πŸ”„ Switching from ${ide} to ${newIde} due to quota warning`);
313
+
314
+ return {
315
+ switched: true,
316
+ newIde: newIde,
317
+ reason: 'quota_warning',
318
+ originalIde: ide
319
+ };
320
+ } else {
321
+ this.logger.log('❌ No available IDEs found, cannot switch');
322
+ return {
323
+ switched: false,
324
+ error: 'No available IDEs without quota warnings'
325
+ };
326
+ }
327
+ } else {
328
+ this.logger.log(`βœ… No quota warnings detected in ${ide}`);
329
+ return {
330
+ switched: false,
331
+ ide: ide
332
+ };
333
+ }
334
+ } catch (error) {
335
+ this.logger.log(`❌ Error checking quota for ${ide}:`, error.message);
336
+ return {
337
+ switched: false,
338
+ error: error.message
339
+ };
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Stop autonomous mode
345
+ */
346
+ stopAutonomousMode() {
347
+ this.isAutonomousMode = false;
348
+ this.isStopped = true;
349
+ this.chatManager.stop();
350
+ this.logger.log('πŸ›‘ Autonomous mode stopped');
351
+ }
352
+
353
+ /**
354
+ * Pause autonomous mode
355
+ */
356
+ pauseAutonomousMode() {
357
+ this.isPaused = true;
358
+ this.chatManager.pause();
359
+ this.logger.log('⏸️ Autonomous mode paused');
360
+ }
361
+
362
+ /**
363
+ * Resume autonomous mode
364
+ */
365
+ resumeAutonomousMode() {
366
+ this.isPaused = false;
367
+ this.chatManager.resume();
368
+ this.logger.log('▢️ Autonomous mode resumed');
369
+ }
370
+
371
+ /**
372
+ * Get current autonomous mode state
373
+ * @returns {Object} Current state
374
+ */
375
+ getState() {
376
+ return {
377
+ isAutonomousMode: this.isAutonomousMode,
378
+ isPaused: this.isPaused,
379
+ isStopped: this.isStopped,
380
+ currentProgress: this.currentProgress,
381
+ taskCount: this.taskCount,
382
+ maxTasks: this.maxTasks,
383
+ completedFeatures: this.completedFeatures,
384
+ errorLog: this.errorLog
385
+ };
386
+ }
387
+
388
+ /**
389
+ * Set electron API for Electron environment
390
+ * @param {Object} electronAPI - The electron API object
391
+ */
392
+ setElectronAPI(electronAPI) {
393
+ this.electronAPI = electronAPI;
394
+ this.chatManager.setElectronAPI(electronAPI);
395
+ }
396
+
397
+ /**
398
+ * Set callback functions
399
+ * @param {Object} callbacks - Object containing callback functions
400
+ */
401
+ setCallbacks(callbacks) {
402
+ if (callbacks.onStatusUpdate) {
403
+ this.onStatusUpdate = callbacks.onStatusUpdate;
404
+ }
405
+ if (callbacks.onProgressUpdate) {
406
+ this.onProgressUpdate = callbacks.onProgressUpdate;
407
+ }
408
+ if (callbacks.onMessageUpdate) {
409
+ this.onMessageUpdate = callbacks.onMessageUpdate;
410
+ }
411
+ if (callbacks.onErrorUpdate) {
412
+ this.onErrorUpdate = callbacks.onErrorUpdate;
413
+ }
414
+ if (callbacks.onCompleteUpdate) {
415
+ this.onCompleteUpdate = callbacks.onCompleteUpdate;
416
+ }
417
+
418
+ // Update chat manager callbacks
419
+ this.chatManager.setCallbacks({
420
+ onMessageUpdate: this.onMessageUpdate,
421
+ onStatusUpdate: this.onStatusUpdate,
422
+ onProgressUpdate: this.onProgressUpdate
423
+ });
424
+ }
425
+ }