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,342 +1,342 @@
1
- // @vibecodingmachine/core - Chat Manager
2
- // Handles chat message management, polling, and response detection
3
-
4
- /**
5
- * Chat Manager for handling chat interactions
6
- * Manages message sending, response polling, and state management
7
- */
8
- export class ChatManager {
9
- constructor(options = {}) {
10
- this.logger = options.logger || console;
11
- this.electronAPI = options.electronAPI || null;
12
- this.onMessageUpdate = options.onMessageUpdate || (() => {});
13
- this.onStatusUpdate = options.onStatusUpdate || (() => {});
14
- this.onProgressUpdate = options.onProgressUpdate || (() => {});
15
-
16
- // State
17
- this.isPolling = false;
18
- this.isPaused = false;
19
- this.isStopped = false;
20
- this.responseWaiting = false;
21
- this.currentProgress = 0;
22
- this.pollingTimer = null;
23
- this.lastChangeAt = 0;
24
- }
25
-
26
- /**
27
- * Send a chat message to an IDE
28
- * @param {string} message - The message to send
29
- * @param {string} ide - The IDE to send to
30
- * @param {string} tabId - The tab ID for tracking
31
- * @returns {Promise<Object>} Result of the send operation
32
- */
33
- async sendMessage(message, ide, tabId) {
34
- this.logger.log('sendMessage called with:', { message: message.substring(0, 50) + '...', ide, tabId });
35
-
36
- if (!message || !message.trim() || this.isPaused || this.isStopped) {
37
- this.logger.log('sendMessage early return - message:', !!message, 'isPaused:', this.isPaused, 'isStopped:', this.isStopped);
38
- return {
39
- success: false,
40
- error: 'Cannot send message - invalid state or empty message'
41
- };
42
- }
43
-
44
- try {
45
- this.onStatusUpdate(tabId, 'Sending message...');
46
-
47
- let result;
48
- if (this.electronAPI && this.electronAPI.sendChat) {
49
- result = await this.electronAPI.sendChat(message, ide);
50
- } else {
51
- // Fallback for non-Electron environments
52
- result = { success: true, method: 'simulated', message: 'Simulated message sent' };
53
- }
54
-
55
- if (result && result.success) {
56
- this.logger.log(`Message sent successfully via ${result.method || 'chat'}`);
57
- this.onStatusUpdate(tabId, `✅ Message sent successfully via ${result.method || 'chat'}`);
58
-
59
- if (result.method !== 'terminal') {
60
- this.startPolling(ide, tabId);
61
- }
62
-
63
- return {
64
- success: true,
65
- method: result.method,
66
- message: result.message
67
- };
68
- } else {
69
- this.logger.log('Failed to send message:', result);
70
- this.onStatusUpdate(tabId, `❌ Failed to send message: ${result?.error || 'Unknown error'}`);
71
-
72
- return {
73
- success: false,
74
- error: result?.error || 'Unknown error'
75
- };
76
- }
77
- } catch (error) {
78
- this.logger.error('Error sending message:', error);
79
- this.onStatusUpdate(tabId, `❌ Error sending message: ${error.message}`);
80
-
81
- return {
82
- success: false,
83
- error: error.message
84
- };
85
- }
86
- }
87
-
88
- /**
89
- * Start polling for responses from an IDE
90
- * @param {string} ide - The IDE to poll
91
- * @param {string} tabId - The tab ID for tracking
92
- */
93
- startPolling(ide, tabId) {
94
- if (this.isPolling) {
95
- this.logger.log('Polling already in progress');
96
- return;
97
- }
98
-
99
- this.isPolling = true;
100
- this.lastChangeAt = Date.now();
101
-
102
- this.logger.log(`Starting polling for ${ide} (tab: ${tabId})`);
103
- this.onStatusUpdate(tabId, 'Polling for response...');
104
-
105
- this.pollingTimer = setInterval(async () => {
106
- if (this.isStopped || this.isPaused) {
107
- this.stopPolling();
108
- return;
109
- }
110
-
111
- try {
112
- const response = await this.readResponse(ide);
113
-
114
- if (response && response.length > 0) {
115
- this.lastChangeAt = Date.now();
116
-
117
- // Check if response is complete
118
- const completionResult = await this.detectResponseCompletion(ide, response);
119
-
120
- if (completionResult.completed) {
121
- this.logger.log('Response completed, stopping polling');
122
- this.onStatusUpdate(tabId, '✅ Response received');
123
- this.stopPolling();
124
-
125
- // Update messages with the complete response
126
- this.onMessageUpdate(tabId, {
127
- role: 'assistant',
128
- text: completionResult.response,
129
- timestamp: Date.now(),
130
- progress: completionResult.progress || 100
131
- });
132
- }
133
- }
134
-
135
- // Stop polling if no change for 30 seconds
136
- if (Date.now() - this.lastChangeAt > 30000) {
137
- this.logger.log('No response change for 30 seconds, stopping polling');
138
- this.onStatusUpdate(tabId, '⏰ Response timeout');
139
- this.stopPolling();
140
- }
141
- } catch (error) {
142
- this.logger.error('Error during polling:', error);
143
- this.onStatusUpdate(tabId, `❌ Polling error: ${error.message}`);
144
- this.stopPolling();
145
- }
146
- }, 2000); // Poll every 2 seconds
147
- }
148
-
149
- /**
150
- * Stop polling for responses
151
- */
152
- stopPolling() {
153
- if (this.pollingTimer) {
154
- clearInterval(this.pollingTimer);
155
- this.pollingTimer = null;
156
- }
157
- this.isPolling = false;
158
- this.responseWaiting = false;
159
- this.logger.log('Polling stopped');
160
- }
161
-
162
- /**
163
- * Read response from an IDE
164
- * @param {string} ide - The IDE to read from
165
- * @returns {Promise<string>} The response text
166
- */
167
- async readResponse(ide) {
168
- try {
169
- if (this.electronAPI && this.electronAPI.readChat) {
170
- return await this.electronAPI.readChat(ide);
171
- } else {
172
- // Fallback for non-Electron environments
173
- return 'Simulated response from ' + ide;
174
- }
175
- } catch (error) {
176
- this.logger.error('Error reading response:', error);
177
- return '';
178
- }
179
- }
180
-
181
- /**
182
- * Detect if a response is complete
183
- * @param {string} ide - The IDE name
184
- * @param {string} response - The current response text
185
- * @returns {Promise<Object>} Completion detection result
186
- */
187
- async detectResponseCompletion(ide, response) {
188
- if (ide !== 'windsurf') {
189
- // For non-Windsurf IDEs, assume response is complete after a delay
190
- return { completed: true, response };
191
- }
192
-
193
- this.logger.log('🔍 Detecting Windsurf response completion...');
194
- this.responseWaiting = true;
195
-
196
- try {
197
- const responseText = response.toLowerCase();
198
-
199
- // Check for ongoing status indicators - if these are present, response is NOT complete
200
- const hasOngoingStatus = responseText.includes('surfing') ||
201
- responseText.includes('navigating') ||
202
- responseText.includes('swimming') ||
203
- responseText.includes('floating') ||
204
- responseText.includes('proposing code') ||
205
- responseText.includes('reading file') ||
206
- responseText.includes('searching') ||
207
- responseText.includes('updating todo list');
208
-
209
- if (hasOngoingStatus) {
210
- this.logger.log('⏳ Response still in progress - waiting for completion...');
211
- return { completed: false, response };
212
- }
213
-
214
- // Check for completion indicators
215
- const hasCompletionIndicators = responseText.includes('thumbs up') ||
216
- responseText.includes('thumbs down') ||
217
- responseText.includes('👍') ||
218
- responseText.includes('👎') ||
219
- responseText.includes('copy icon') ||
220
- responseText.includes('bookmark icon') ||
221
- responseText.includes('bar chart icon') ||
222
- responseText.includes('view response summary') ||
223
- responseText.includes('ask anything (⌘l)') ||
224
- responseText.includes('microphone icon') ||
225
- responseText.includes('send button') ||
226
- responseText.includes('+ chat') ||
227
- responseText.includes('+ chat swe-1') ||
228
- responseText.includes('paper plane') ||
229
- responseText.includes('send icon') ||
230
- responseText.includes('chat swe-1') ||
231
- responseText.includes('ask anything') ||
232
- responseText.includes('⌘l') ||
233
- responseText.includes('command+l');
234
-
235
- if (hasCompletionIndicators) {
236
- this.logger.log('🎯 Completion indicators found!');
237
- this.responseWaiting = false;
238
- return { completed: true, response };
239
- }
240
-
241
- // Check for percentage in response
242
- const percentageMatch = response.match(/(\d+)%/);
243
- if (percentageMatch) {
244
- const percentage = parseInt(percentageMatch[1]);
245
- this.currentProgress = percentage;
246
- this.onProgressUpdate(percentage);
247
- this.logger.log(`📊 Progress detected: ${percentage}%`);
248
-
249
- if (percentage === 100) {
250
- this.logger.log('🎉 100% completion detected!');
251
- this.responseWaiting = false;
252
- return { completed: true, response, progress: 100 };
253
- }
254
- }
255
-
256
- // Response is not complete
257
- return { completed: false, response };
258
-
259
- } catch (error) {
260
- this.logger.error('Error detecting response completion:', error);
261
- this.responseWaiting = false;
262
- return { completed: false, response, error: error.message };
263
- }
264
- }
265
-
266
- /**
267
- * Pause chat operations
268
- */
269
- pause() {
270
- this.isPaused = true;
271
- this.logger.log('Chat operations paused');
272
- }
273
-
274
- /**
275
- * Resume chat operations
276
- */
277
- resume() {
278
- this.isPaused = false;
279
- this.logger.log('Chat operations resumed');
280
- }
281
-
282
- /**
283
- * Stop chat operations
284
- */
285
- stop() {
286
- this.isStopped = true;
287
- this.stopPolling();
288
- this.logger.log('Chat operations stopped');
289
- }
290
-
291
- /**
292
- * Reset chat state
293
- */
294
- reset() {
295
- this.isStopped = false;
296
- this.isPaused = false;
297
- this.isPolling = false;
298
- this.responseWaiting = false;
299
- this.currentProgress = 0;
300
- this.stopPolling();
301
- this.logger.log('Chat state reset');
302
- }
303
-
304
- /**
305
- * Get current chat state
306
- * @returns {Object} Current chat state
307
- */
308
- getState() {
309
- return {
310
- isPolling: this.isPolling,
311
- isPaused: this.isPaused,
312
- isStopped: this.isStopped,
313
- responseWaiting: this.responseWaiting,
314
- currentProgress: this.currentProgress,
315
- lastChangeAt: this.lastChangeAt
316
- };
317
- }
318
-
319
- /**
320
- * Set electron API for Electron environment
321
- * @param {Object} electronAPI - The electron API object
322
- */
323
- setElectronAPI(electronAPI) {
324
- this.electronAPI = electronAPI;
325
- }
326
-
327
- /**
328
- * Set callback functions
329
- * @param {Object} callbacks - Object containing callback functions
330
- */
331
- setCallbacks(callbacks) {
332
- if (callbacks.onMessageUpdate) {
333
- this.onMessageUpdate = callbacks.onMessageUpdate;
334
- }
335
- if (callbacks.onStatusUpdate) {
336
- this.onStatusUpdate = callbacks.onStatusUpdate;
337
- }
338
- if (callbacks.onProgressUpdate) {
339
- this.onProgressUpdate = callbacks.onProgressUpdate;
340
- }
341
- }
342
- }
1
+ // @vibecodingmachine/core - Chat Manager
2
+ // Handles chat message management, polling, and response detection
3
+
4
+ /**
5
+ * Chat Manager for handling chat interactions
6
+ * Manages message sending, response polling, and state management
7
+ */
8
+ export class ChatManager {
9
+ constructor(options = {}) {
10
+ this.logger = options.logger || console;
11
+ this.electronAPI = options.electronAPI || null;
12
+ this.onMessageUpdate = options.onMessageUpdate || (() => {});
13
+ this.onStatusUpdate = options.onStatusUpdate || (() => {});
14
+ this.onProgressUpdate = options.onProgressUpdate || (() => {});
15
+
16
+ // State
17
+ this.isPolling = false;
18
+ this.isPaused = false;
19
+ this.isStopped = false;
20
+ this.responseWaiting = false;
21
+ this.currentProgress = 0;
22
+ this.pollingTimer = null;
23
+ this.lastChangeAt = 0;
24
+ }
25
+
26
+ /**
27
+ * Send a chat message to an IDE
28
+ * @param {string} message - The message to send
29
+ * @param {string} ide - The IDE to send to
30
+ * @param {string} tabId - The tab ID for tracking
31
+ * @returns {Promise<Object>} Result of the send operation
32
+ */
33
+ async sendMessage(message, ide, tabId) {
34
+ this.logger.log('sendMessage called with:', { message: message.substring(0, 50) + '...', ide, tabId });
35
+
36
+ if (!message || !message.trim() || this.isPaused || this.isStopped) {
37
+ this.logger.log('sendMessage early return - message:', !!message, 'isPaused:', this.isPaused, 'isStopped:', this.isStopped);
38
+ return {
39
+ success: false,
40
+ error: 'Cannot send message - invalid state or empty message'
41
+ };
42
+ }
43
+
44
+ try {
45
+ this.onStatusUpdate(tabId, 'Sending message...');
46
+
47
+ let result;
48
+ if (this.electronAPI && this.electronAPI.sendChat) {
49
+ result = await this.electronAPI.sendChat(message, ide);
50
+ } else {
51
+ // Fallback for non-Electron environments
52
+ result = { success: true, method: 'simulated', message: 'Simulated message sent' };
53
+ }
54
+
55
+ if (result && result.success) {
56
+ this.logger.log(`Message sent successfully via ${result.method || 'chat'}`);
57
+ this.onStatusUpdate(tabId, `✅ Message sent successfully via ${result.method || 'chat'}`);
58
+
59
+ if (result.method !== 'terminal') {
60
+ this.startPolling(ide, tabId);
61
+ }
62
+
63
+ return {
64
+ success: true,
65
+ method: result.method,
66
+ message: result.message
67
+ };
68
+ } else {
69
+ this.logger.log('Failed to send message:', result);
70
+ this.onStatusUpdate(tabId, `❌ Failed to send message: ${result?.error || 'Unknown error'}`);
71
+
72
+ return {
73
+ success: false,
74
+ error: result?.error || 'Unknown error'
75
+ };
76
+ }
77
+ } catch (error) {
78
+ this.logger.error('Error sending message:', error);
79
+ this.onStatusUpdate(tabId, `❌ Error sending message: ${error.message}`);
80
+
81
+ return {
82
+ success: false,
83
+ error: error.message
84
+ };
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Start polling for responses from an IDE
90
+ * @param {string} ide - The IDE to poll
91
+ * @param {string} tabId - The tab ID for tracking
92
+ */
93
+ startPolling(ide, tabId) {
94
+ if (this.isPolling) {
95
+ this.logger.log('Polling already in progress');
96
+ return;
97
+ }
98
+
99
+ this.isPolling = true;
100
+ this.lastChangeAt = Date.now();
101
+
102
+ this.logger.log(`Starting polling for ${ide} (tab: ${tabId})`);
103
+ this.onStatusUpdate(tabId, 'Polling for response...');
104
+
105
+ this.pollingTimer = setInterval(async () => {
106
+ if (this.isStopped || this.isPaused) {
107
+ this.stopPolling();
108
+ return;
109
+ }
110
+
111
+ try {
112
+ const response = await this.readResponse(ide);
113
+
114
+ if (response && response.length > 0) {
115
+ this.lastChangeAt = Date.now();
116
+
117
+ // Check if response is complete
118
+ const completionResult = await this.detectResponseCompletion(ide, response);
119
+
120
+ if (completionResult.completed) {
121
+ this.logger.log('Response completed, stopping polling');
122
+ this.onStatusUpdate(tabId, '✅ Response received');
123
+ this.stopPolling();
124
+
125
+ // Update messages with the complete response
126
+ this.onMessageUpdate(tabId, {
127
+ role: 'assistant',
128
+ text: completionResult.response,
129
+ timestamp: Date.now(),
130
+ progress: completionResult.progress || 100
131
+ });
132
+ }
133
+ }
134
+
135
+ // Stop polling if no change for 30 seconds
136
+ if (Date.now() - this.lastChangeAt > 30000) {
137
+ this.logger.log('No response change for 30 seconds, stopping polling');
138
+ this.onStatusUpdate(tabId, '⏰ Response timeout');
139
+ this.stopPolling();
140
+ }
141
+ } catch (error) {
142
+ this.logger.error('Error during polling:', error);
143
+ this.onStatusUpdate(tabId, `❌ Polling error: ${error.message}`);
144
+ this.stopPolling();
145
+ }
146
+ }, 2000); // Poll every 2 seconds
147
+ }
148
+
149
+ /**
150
+ * Stop polling for responses
151
+ */
152
+ stopPolling() {
153
+ if (this.pollingTimer) {
154
+ clearInterval(this.pollingTimer);
155
+ this.pollingTimer = null;
156
+ }
157
+ this.isPolling = false;
158
+ this.responseWaiting = false;
159
+ this.logger.log('Polling stopped');
160
+ }
161
+
162
+ /**
163
+ * Read response from an IDE
164
+ * @param {string} ide - The IDE to read from
165
+ * @returns {Promise<string>} The response text
166
+ */
167
+ async readResponse(ide) {
168
+ try {
169
+ if (this.electronAPI && this.electronAPI.readChat) {
170
+ return await this.electronAPI.readChat(ide);
171
+ } else {
172
+ // Fallback for non-Electron environments
173
+ return 'Simulated response from ' + ide;
174
+ }
175
+ } catch (error) {
176
+ this.logger.error('Error reading response:', error);
177
+ return '';
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Detect if a response is complete
183
+ * @param {string} ide - The IDE name
184
+ * @param {string} response - The current response text
185
+ * @returns {Promise<Object>} Completion detection result
186
+ */
187
+ async detectResponseCompletion(ide, response) {
188
+ if (ide !== 'windsurf') {
189
+ // For non-Windsurf IDEs, assume response is complete after a delay
190
+ return { completed: true, response };
191
+ }
192
+
193
+ this.logger.log('🔍 Detecting Windsurf response completion...');
194
+ this.responseWaiting = true;
195
+
196
+ try {
197
+ const responseText = response.toLowerCase();
198
+
199
+ // Check for ongoing status indicators - if these are present, response is NOT complete
200
+ const hasOngoingStatus = responseText.includes('surfing') ||
201
+ responseText.includes('navigating') ||
202
+ responseText.includes('swimming') ||
203
+ responseText.includes('floating') ||
204
+ responseText.includes('proposing code') ||
205
+ responseText.includes('reading file') ||
206
+ responseText.includes('searching') ||
207
+ responseText.includes('updating todo list');
208
+
209
+ if (hasOngoingStatus) {
210
+ this.logger.log('⏳ Response still in progress - waiting for completion...');
211
+ return { completed: false, response };
212
+ }
213
+
214
+ // Check for completion indicators
215
+ const hasCompletionIndicators = responseText.includes('thumbs up') ||
216
+ responseText.includes('thumbs down') ||
217
+ responseText.includes('👍') ||
218
+ responseText.includes('👎') ||
219
+ responseText.includes('copy icon') ||
220
+ responseText.includes('bookmark icon') ||
221
+ responseText.includes('bar chart icon') ||
222
+ responseText.includes('view response summary') ||
223
+ responseText.includes('ask anything (⌘l)') ||
224
+ responseText.includes('microphone icon') ||
225
+ responseText.includes('send button') ||
226
+ responseText.includes('+ chat') ||
227
+ responseText.includes('+ chat swe-1') ||
228
+ responseText.includes('paper plane') ||
229
+ responseText.includes('send icon') ||
230
+ responseText.includes('chat swe-1') ||
231
+ responseText.includes('ask anything') ||
232
+ responseText.includes('⌘l') ||
233
+ responseText.includes('command+l');
234
+
235
+ if (hasCompletionIndicators) {
236
+ this.logger.log('🎯 Completion indicators found!');
237
+ this.responseWaiting = false;
238
+ return { completed: true, response };
239
+ }
240
+
241
+ // Check for percentage in response
242
+ const percentageMatch = response.match(/(\d+)%/);
243
+ if (percentageMatch) {
244
+ const percentage = parseInt(percentageMatch[1]);
245
+ this.currentProgress = percentage;
246
+ this.onProgressUpdate(percentage);
247
+ this.logger.log(`📊 Progress detected: ${percentage}%`);
248
+
249
+ if (percentage === 100) {
250
+ this.logger.log('🎉 100% completion detected!');
251
+ this.responseWaiting = false;
252
+ return { completed: true, response, progress: 100 };
253
+ }
254
+ }
255
+
256
+ // Response is not complete
257
+ return { completed: false, response };
258
+
259
+ } catch (error) {
260
+ this.logger.error('Error detecting response completion:', error);
261
+ this.responseWaiting = false;
262
+ return { completed: false, response, error: error.message };
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Pause chat operations
268
+ */
269
+ pause() {
270
+ this.isPaused = true;
271
+ this.logger.log('Chat operations paused');
272
+ }
273
+
274
+ /**
275
+ * Resume chat operations
276
+ */
277
+ resume() {
278
+ this.isPaused = false;
279
+ this.logger.log('Chat operations resumed');
280
+ }
281
+
282
+ /**
283
+ * Stop chat operations
284
+ */
285
+ stop() {
286
+ this.isStopped = true;
287
+ this.stopPolling();
288
+ this.logger.log('Chat operations stopped');
289
+ }
290
+
291
+ /**
292
+ * Reset chat state
293
+ */
294
+ reset() {
295
+ this.isStopped = false;
296
+ this.isPaused = false;
297
+ this.isPolling = false;
298
+ this.responseWaiting = false;
299
+ this.currentProgress = 0;
300
+ this.stopPolling();
301
+ this.logger.log('Chat state reset');
302
+ }
303
+
304
+ /**
305
+ * Get current chat state
306
+ * @returns {Object} Current chat state
307
+ */
308
+ getState() {
309
+ return {
310
+ isPolling: this.isPolling,
311
+ isPaused: this.isPaused,
312
+ isStopped: this.isStopped,
313
+ responseWaiting: this.responseWaiting,
314
+ currentProgress: this.currentProgress,
315
+ lastChangeAt: this.lastChangeAt
316
+ };
317
+ }
318
+
319
+ /**
320
+ * Set electron API for Electron environment
321
+ * @param {Object} electronAPI - The electron API object
322
+ */
323
+ setElectronAPI(electronAPI) {
324
+ this.electronAPI = electronAPI;
325
+ }
326
+
327
+ /**
328
+ * Set callback functions
329
+ * @param {Object} callbacks - Object containing callback functions
330
+ */
331
+ setCallbacks(callbacks) {
332
+ if (callbacks.onMessageUpdate) {
333
+ this.onMessageUpdate = callbacks.onMessageUpdate;
334
+ }
335
+ if (callbacks.onStatusUpdate) {
336
+ this.onStatusUpdate = callbacks.onStatusUpdate;
337
+ }
338
+ if (callbacks.onProgressUpdate) {
339
+ this.onProgressUpdate = callbacks.onProgressUpdate;
340
+ }
341
+ }
342
+ }