vibecodingmachine-core 2025.12.25-25 → 2026.1.22-1441

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 (40) hide show
  1. package/ERROR_REPORTING_API.md +212 -0
  2. package/ERROR_REPORTING_USAGE.md +380 -0
  3. package/__tests__/provider-manager-fallback.test.js +43 -0
  4. package/__tests__/provider-manager-rate-limit.test.js +61 -0
  5. package/__tests__/utils/git-branch-manager.test.js +61 -0
  6. package/package.json +1 -1
  7. package/src/beta-request.js +160 -0
  8. package/src/compliance/compliance-manager.js +5 -2
  9. package/src/database/migrations.js +135 -12
  10. package/src/database/user-database-client.js +127 -8
  11. package/src/database/user-schema.js +28 -0
  12. package/src/health-tracking/__tests__/ide-health-tracker.test.js +420 -0
  13. package/src/health-tracking/__tests__/interaction-recorder.test.js +392 -0
  14. package/src/health-tracking/errors.js +50 -0
  15. package/src/health-tracking/health-reporter.js +331 -0
  16. package/src/health-tracking/ide-health-tracker.js +446 -0
  17. package/src/health-tracking/interaction-recorder.js +161 -0
  18. package/src/health-tracking/json-storage.js +276 -0
  19. package/src/health-tracking/storage-interface.js +63 -0
  20. package/src/health-tracking/validators.js +277 -0
  21. package/src/ide-integration/applescript-manager.cjs +1087 -9
  22. package/src/ide-integration/applescript-manager.js +565 -15
  23. package/src/ide-integration/applescript-utils.js +26 -18
  24. package/src/ide-integration/provider-manager.cjs +158 -28
  25. package/src/ide-integration/quota-detector.cjs +339 -16
  26. package/src/ide-integration/quota-detector.js +6 -1
  27. package/src/index.cjs +36 -1
  28. package/src/index.js +20 -0
  29. package/src/localization/translations/en.js +15 -1
  30. package/src/localization/translations/es.js +14 -0
  31. package/src/requirement-numbering.js +164 -0
  32. package/src/sync/aws-setup.js +4 -4
  33. package/src/utils/admin-utils.js +33 -0
  34. package/src/utils/error-reporter.js +117 -0
  35. package/src/utils/git-branch-manager.js +278 -0
  36. package/src/utils/requirement-helpers.js +44 -5
  37. package/src/utils/requirements-parser.js +28 -3
  38. package/tests/health-tracking/health-reporter.test.js +329 -0
  39. package/tests/health-tracking/ide-health-tracker.test.js +368 -0
  40. package/tests/health-tracking/interaction-recorder.test.js +309 -0
@@ -1,33 +1,356 @@
1
- // @vibecodingmachine/core - Quota Detector (CommonJS) - Stub
1
+ // @vibecodingmachine/core - Quota Detector (CommonJS)
2
2
  // Handles quota detection for different IDEs using CDP and AppleScript
3
3
 
4
+ const CDP = require('chrome-remote-interface');
5
+ const { AppleScriptManager } = require('./applescript-manager.cjs');
6
+
7
+ /**
8
+ * Quota Detector for IDE interactions
9
+ * Detects quota warnings in different IDEs using CDP and AppleScript
10
+ */
4
11
  class QuotaDetector {
5
12
  constructor() {
6
13
  this.logger = console;
14
+ this.appleScriptManager = new AppleScriptManager();
15
+ }
16
+
17
+ /**
18
+ * Timeout utility function
19
+ * @param {number} ms - Timeout in milliseconds
20
+ * @param {Promise} promise - Promise to timeout
21
+ * @returns {Promise} Promise with timeout
22
+ */
23
+ timeout(ms, promise) {
24
+ return Promise.race([
25
+ promise,
26
+ new Promise((_, reject) =>
27
+ setTimeout(() => reject(new Error(`Operation timed out after ${ms}ms`)), ms)
28
+ )
29
+ ]);
7
30
  }
8
31
 
32
+ /**
33
+ * Detect quota warnings in an IDE
34
+ * @param {string} ide - The IDE name ('vscode', 'cursor', 'windsurf')
35
+ * @returns {Promise<Object>} Quota detection result
36
+ */
9
37
  async detectQuotaWarning(ide = 'vscode') {
10
- this.logger.log(`🔍 Quota detection stub for ${ide}`);
11
- return {
12
- hasQuotaWarning: false,
13
- method: 'stub',
14
- note: 'Quota detection not implemented in stub'
15
- };
38
+ this.logger.log(`🔍 Starting quota detection for ${ide}...`);
39
+
40
+ // Determine the port based on the IDE
41
+ const port = ide === 'windsurf' ? 9224 : ide === 'cursor' ? 9225 : 9222;
42
+ const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : 'VS Code';
43
+
44
+ this.logger.log(`🔌 Checking ${ideName} on port ${port}...`);
45
+
46
+ // For Windsurf, use AppleScript detection since CDP is not supported
47
+ if (ide === 'windsurf') {
48
+ this.logger.log('🔍 Windsurf detected - using AppleScript quota detection');
49
+ return await this.appleScriptManager.detectQuotaWarning(ide);
50
+ }
51
+
52
+ // For VS Code and Cursor, use CDP detection
53
+ try {
54
+ this.logger.log(`🔍 Attempting CDP connection to ${ideName} on port ${port}...`);
55
+
56
+ // Try to connect to CDP
57
+ const targets = await this.timeout(5000, CDP.List({ port }));
58
+
59
+ if (!targets || targets.length === 0) {
60
+ this.logger.log(`❌ No CDP targets found on port ${port}`);
61
+
62
+ // For Windsurf, fall back to AppleScript
63
+ if (ide === 'windsurf') {
64
+ this.logger.log('🔍 Falling back to enhanced AppleScript quota detection...');
65
+ return await this.appleScriptManager.detectQuotaWarning(ide);
66
+ }
67
+
68
+ return {
69
+ hasQuotaWarning: false,
70
+ error: `Could not find ${ideName}. Make sure ${ideName} is running with --remote-debugging-port=${port}`,
71
+ note: 'CDP connection failed'
72
+ };
73
+ }
74
+
75
+ this.logger.log(`✅ Found ${targets.length} CDP targets`);
76
+
77
+ // For Cursor, prefer the workspace target over settings
78
+ let workbench;
79
+ if (ide === 'cursor') {
80
+ workbench = targets.find(t => t.title !== 'Cursor Settings' && t.type === 'page') ||
81
+ targets.find(t => t.url && t.url.includes('workbench')) ||
82
+ targets[0];
83
+ } else {
84
+ workbench = targets.find(t => t.url && t.url.includes('workbench')) || targets[0];
85
+ }
86
+
87
+ if (!workbench) {
88
+ this.logger.log(`❌ No suitable workbench target found`);
89
+ return {
90
+ hasQuotaWarning: false,
91
+ error: `No ${ideName} workbench target found.`,
92
+ note: 'No workbench target available'
93
+ };
94
+ }
95
+
96
+ this.logger.log(`✅ Selected workbench: ${workbench.title}`);
97
+
98
+ // Connect to CDP
99
+ const client = await this.timeout(10000, CDP({ port, target: workbench }));
100
+ const { Runtime, Page } = client;
101
+
102
+ await this.timeout(5000, Runtime.enable());
103
+ if (Page && Page.bringToFront) {
104
+ try {
105
+ await this.timeout(3000, Page.bringToFront());
106
+ } catch (error) {
107
+ this.logger.log(`⚠️ Bring to front failed: ${error.message}`);
108
+ }
109
+ }
110
+
111
+ // Execute JavaScript to detect quota warnings
112
+ const detectionScript = `
113
+ (() => {
114
+ console.log('🔍 Starting quota detection in ${ideName}...');
115
+
116
+ // Common quota warning patterns
117
+ const quotaPatterns = [
118
+ 'not enough credits',
119
+ 'upgrade to a paid plan',
120
+ 'switch to swe-1-lite',
121
+ 'quota exceeded',
122
+ 'credits exhausted',
123
+ 'payment required',
124
+ 'out of credits',
125
+ 'insufficient credits',
126
+ 'billing required',
127
+ 'subscription needed',
128
+ 'monthly chat messages quota',
129
+ 'upgrade to copilot pro',
130
+ 'allowance to renew',
131
+ 'reached your monthly',
132
+ 'wait for your allowance'
133
+ ];
134
+
135
+ // Function to check if text contains quota warnings
136
+ function containsQuotaWarning(text) {
137
+ if (!text) return false;
138
+ const lowerText = text.toLowerCase();
139
+ return quotaPatterns.some(pattern => lowerText.includes(pattern));
140
+ }
141
+
142
+ // Method 1: Check all text content in the document
143
+ const allText = document.body.innerText || document.body.textContent || '';
144
+ if (containsQuotaWarning(allText)) {
145
+ console.log('❌ Quota warning detected in document text');
146
+ return {
147
+ hasQuotaWarning: true,
148
+ method: 'document-text',
149
+ matchedText: allText.substring(0, 200) + '...'
150
+ };
151
+ }
152
+
153
+ // Method 2: Check specific elements that might contain quota warnings
154
+ const quotaElements = [
155
+ // VS Code specific selectors
156
+ '.monaco-workbench .part.auxiliarybar',
157
+ '.monaco-workbench .part.sidebar.right',
158
+ '.monaco-workbench .chat-view',
159
+ '.monaco-workbench .chat-input',
160
+
161
+ // Cursor specific selectors
162
+ '.aislash-editor-input',
163
+ '.aislash-chat-container',
164
+ '.aislash-panel',
165
+
166
+ // Generic selectors
167
+ '[data-testid*="chat"]',
168
+ '[aria-label*="chat"]',
169
+ '[class*="chat"]',
170
+ '[class*="quota"]',
171
+ '[class*="credits"]',
172
+ '[class*="billing"]'
173
+ ];
174
+
175
+ for (const selector of quotaElements) {
176
+ const elements = document.querySelectorAll(selector);
177
+ for (const element of elements) {
178
+ const elementText = element.innerText || element.textContent || '';
179
+ if (containsQuotaWarning(elementText)) {
180
+ console.log('❌ Quota warning detected in element:', selector);
181
+ return {
182
+ hasQuotaWarning: true,
183
+ method: 'element-specific',
184
+ selector: selector,
185
+ matchedText: elementText.substring(0, 200) + '...'
186
+ };
187
+ }
188
+ }
189
+ }
190
+
191
+ // Method 3: Check for disabled input fields (common when quota is exceeded)
192
+ const disabledInputs = document.querySelectorAll('input[disabled], textarea[disabled], [contenteditable="true"][aria-disabled="true"]');
193
+ if (disabledInputs.length > 0) {
194
+ console.log('⚠️ Found disabled input fields, checking for quota context...');
195
+
196
+ // Check if there are quota-related messages near disabled inputs
197
+ for (const input of disabledInputs) {
198
+ const parentText = input.parentElement?.innerText || '';
199
+ if (containsQuotaWarning(parentText)) {
200
+ console.log('❌ Quota warning detected near disabled input');
201
+ return {
202
+ hasQuotaWarning: true,
203
+ method: 'disabled-input-context',
204
+ matchedText: parentText.substring(0, 200) + '...'
205
+ };
206
+ }
207
+ }
208
+ }
209
+
210
+ // Method 4: Check for specific UI elements that indicate quota issues
211
+ const quotaButtons = document.querySelectorAll('button, a, [role="button"]');
212
+ for (const button of quotaButtons) {
213
+ const buttonText = button.innerText || button.textContent || '';
214
+ if (containsQuotaWarning(buttonText)) {
215
+ console.log('❌ Quota warning detected in button:', buttonText);
216
+ return {
217
+ hasQuotaWarning: true,
218
+ method: 'button-text',
219
+ matchedText: buttonText
220
+ };
221
+ }
222
+ }
223
+
224
+ // Method 5: Check for error messages or notifications
225
+ const errorElements = document.querySelectorAll('[class*="error"], [class*="warning"], [class*="notification"], [role="alert"]');
226
+ for (const error of errorElements) {
227
+ const errorText = error.innerText || error.textContent || '';
228
+ if (containsQuotaWarning(errorText)) {
229
+ console.log('❌ Quota warning detected in error element');
230
+ return {
231
+ hasQuotaWarning: true,
232
+ method: 'error-element',
233
+ matchedText: errorText.substring(0, 200) + '...'
234
+ };
235
+ }
236
+ }
237
+
238
+ console.log('✅ No quota warnings detected');
239
+ return {
240
+ hasQuotaWarning: false,
241
+ method: 'cdp-comprehensive',
242
+ note: 'No quota warnings found in ${ideName}'
243
+ };
244
+ })()
245
+ `;
246
+
247
+ const { result } = await this.timeout(10000, Runtime.evaluate({
248
+ expression: detectionScript,
249
+ returnByValue: true
250
+ }));
251
+
252
+ const detectionResult = result.value || result.unserializableValue;
253
+
254
+ this.logger.log('🔍 CDP quota detection result:', detectionResult);
255
+
256
+ if (detectionResult && detectionResult.hasQuotaWarning) {
257
+ this.logger.log('❌ Quota warning detected via CDP');
258
+ return {
259
+ hasQuotaWarning: true,
260
+ method: detectionResult.method,
261
+ matchedText: detectionResult.matchedText || 'Quota warning detected via CDP',
262
+ note: detectionResult.matchedText || 'Quota warning detected via CDP',
263
+ debug: detectionResult
264
+ };
265
+ }
266
+
267
+ this.logger.log('✅ No quota warnings detected via CDP');
268
+ return {
269
+ hasQuotaWarning: false,
270
+ method: 'cdp-comprehensive',
271
+ note: 'No quota warnings found in ' + ideName,
272
+ debug: detectionResult
273
+ };
274
+
275
+ } catch (error) {
276
+ this.logger.log(`❌ CDP quota detection failed: ${error.message}`);
277
+
278
+ // For Windsurf, fall back to AppleScript
279
+ if (ide === 'windsurf') {
280
+ this.logger.log('🔍 Falling back to AppleScript quota detection...');
281
+ return await this.appleScriptManager.detectQuotaWarning(ide);
282
+ }
283
+
284
+ return {
285
+ hasQuotaWarning: false,
286
+ error: error.message,
287
+ note: `CDP quota detection failed for ${ideName}`
288
+ };
289
+ }
16
290
  }
17
291
 
292
+ /**
293
+ * Get available IDEs without quota warnings
294
+ * @param {Array<string>} ides - Array of IDE names to check
295
+ * @returns {Promise<Array<string>>} Array of available IDE names
296
+ */
18
297
  async getAvailableIdes(ides = ['vscode', 'cursor', 'windsurf']) {
19
- this.logger.log('🔍 Available IDEs stub');
20
- return ides;
298
+ this.logger.log('🔍 Checking available IDEs without quota warnings...');
299
+
300
+ const availableIdes = [];
301
+
302
+ for (const ide of ides) {
303
+ try {
304
+ const quotaResult = await this.detectQuotaWarning(ide);
305
+
306
+ if (!quotaResult.hasQuotaWarning) {
307
+ availableIdes.push(ide);
308
+ this.logger.log(`✅ ${ide} is available (no quota warnings)`);
309
+ } else {
310
+ this.logger.log(`❌ ${ide} has quota warnings: ${quotaResult.note || 'Unknown quota issue'}`);
311
+ }
312
+ } catch (error) {
313
+ this.logger.log(`⚠️ Error checking ${ide}: ${error.message}`);
314
+ // If we can't check quota, assume the IDE is available
315
+ availableIdes.push(ide);
316
+ }
317
+ }
318
+
319
+ this.logger.log(`📋 Available IDEs: ${availableIdes.join(', ')}`);
320
+ return availableIdes;
21
321
  }
22
322
 
323
+ /**
324
+ * Test quota detection with a test message
325
+ * @param {string} ide - The IDE name to test
326
+ * @returns {Promise<Object>} Test result
327
+ */
23
328
  async testQuotaDetection(ide) {
24
- this.logger.log(`🧪 Quota detection test stub for ${ide}`);
25
- return {
26
- ide,
27
- success: true,
28
- hasQuotaWarning: false,
29
- method: 'stub'
30
- };
329
+ this.logger.log(`🧪 Testing quota detection for ${ide}...`);
330
+
331
+ try {
332
+ const quotaResult = await this.detectQuotaWarning(ide);
333
+
334
+ this.logger.log(`🧪 Quota detection test result for ${ide}:`, quotaResult);
335
+
336
+ return {
337
+ ide,
338
+ success: true,
339
+ hasQuotaWarning: quotaResult.hasQuotaWarning,
340
+ method: quotaResult.method,
341
+ note: quotaResult.note,
342
+ debug: quotaResult
343
+ };
344
+ } catch (error) {
345
+ this.logger.log(`❌ Quota detection test failed for ${ide}: ${error.message}`);
346
+
347
+ return {
348
+ ide,
349
+ success: false,
350
+ error: error.message,
351
+ note: `Quota detection test failed for ${ide}`
352
+ };
353
+ }
31
354
  }
32
355
  }
33
356
 
@@ -124,7 +124,12 @@ export class QuotaDetector {
124
124
  'out of credits',
125
125
  'insufficient credits',
126
126
  'billing required',
127
- 'subscription needed'
127
+ 'subscription needed',
128
+ 'monthly chat messages quota',
129
+ 'upgrade to copilot pro',
130
+ 'allowance to renew',
131
+ 'reached your monthly',
132
+ 'wait for your allowance'
128
133
  ];
129
134
 
130
135
  // Function to check if text contains quota warnings
package/src/index.cjs CHANGED
@@ -20,10 +20,26 @@ 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
22
  const requirementsParser = require('./utils/requirements-parser.js');
23
+ const requirementNumbering = require('./requirement-numbering.js');
24
+ const gitBranchManager = require('./utils/git-branch-manager.js');
23
25
  const updateChecker = require('./utils/update-checker.js');
24
26
  const electronUpdateChecker = require('./utils/electron-update-checker.js');
27
+ const { errorReporter, ErrorReporter } = require('./utils/error-reporter.js');
25
28
  const localization = require('./localization/index.js');
26
29
 
30
+ // Health Tracking (Foundational)
31
+ const { ValidationError, FileSystemError } = require('./health-tracking/errors.js');
32
+ const { JSONStorage, DEFAULT_STORAGE_FILE, DEFAULT_HEALTH_DATA } = require('./health-tracking/json-storage.js');
33
+ const { StorageInterface } = require('./health-tracking/storage-interface.js');
34
+ const validators = require('./health-tracking/validators.js');
35
+
36
+ // Health Tracking (User Story 1)
37
+ const { InteractionRecorder, MAX_INTERACTIONS, DEFAULT_IDE_RECORD } = require('./health-tracking/interaction-recorder.js');
38
+ const { IDEHealthTracker, MAX_RESPONSE_TIMES, CONSECUTIVE_FAILURE_THRESHOLD } = require('./health-tracking/ide-health-tracker.js');
39
+
40
+ // Health Tracking (User Story 2)
41
+ const { HealthReporter } = require('./health-tracking/health-reporter.js');
42
+
27
43
  module.exports = {
28
44
  CDPManager,
29
45
  AppleScriptManager,
@@ -45,7 +61,26 @@ module.exports = {
45
61
  ...auditLogger,
46
62
  ...requirementHelpers,
47
63
  ...requirementsParser,
64
+ ...requirementNumbering,
65
+ ...gitBranchManager,
48
66
  ...updateChecker,
49
67
  ...electronUpdateChecker,
50
- ...localization
68
+ errorReporter,
69
+ ErrorReporter,
70
+ ...localization,
71
+ // Health Tracking
72
+ ValidationError,
73
+ FileSystemError,
74
+ JSONStorage,
75
+ DEFAULT_STORAGE_FILE,
76
+ DEFAULT_HEALTH_DATA,
77
+ StorageInterface,
78
+ ...validators,
79
+ InteractionRecorder,
80
+ MAX_INTERACTIONS,
81
+ DEFAULT_IDE_RECORD,
82
+ IDEHealthTracker,
83
+ MAX_RESPONSE_TIMES,
84
+ CONSECUTIVE_FAILURE_THRESHOLD,
85
+ HealthReporter
51
86
  };
package/src/index.js CHANGED
@@ -12,6 +12,7 @@ export * from './utils/repo-helpers.js';
12
12
  export * from './utils/config-helpers.js';
13
13
  export * from './utils/requirement-helpers.js';
14
14
  export * from './utils/requirements-parser.js';
15
+ export * from './requirement-numbering.js';
15
16
 
16
17
  // Compliance
17
18
  const CompliancePrompt = require('./compliance/compliance-prompt.js');
@@ -24,3 +25,22 @@ export { ChatInterface } from './ui/ChatInterface.js';
24
25
 
25
26
  // Localization
26
27
  export * from './localization/index.js';
28
+
29
+ // Error Reporting
30
+ export * from './utils/error-reporter.js';
31
+
32
+ // Admin Utilities
33
+ export * from './utils/admin-utils.js';
34
+
35
+ // Health Tracking (Foundational)
36
+ export { ValidationError, FileSystemError } from './health-tracking/errors.js';
37
+ export { JSONStorage, DEFAULT_STORAGE_FILE, DEFAULT_HEALTH_DATA } from './health-tracking/json-storage.js';
38
+ export { StorageInterface } from './health-tracking/storage-interface.js';
39
+ export * from './health-tracking/validators.js';
40
+
41
+ // Health Tracking (User Story 1)
42
+ export { InteractionRecorder, MAX_INTERACTIONS, DEFAULT_IDE_RECORD } from './health-tracking/interaction-recorder.js';
43
+ export { IDEHealthTracker, MAX_RESPONSE_TIMES, CONSECUTIVE_FAILURE_THRESHOLD } from './health-tracking/ide-health-tracker.js';
44
+
45
+ // Health Tracking (User Story 2)
46
+ export { HealthReporter } from './health-tracking/health-reporter.js';
@@ -303,6 +303,18 @@ module.exports = {
303
303
  'interactive.sync.now': 'Sync Now',
304
304
  'interactive.logout': 'Logout',
305
305
  'interactive.exit': 'Exit',
306
+ 'interactive.feedback': 'Feedback',
307
+ 'interactive.feedback.title': 'Vibe Coding Machine Feedback',
308
+ 'interactive.feedback.instructions': 'Your feedback helps us make Vibe Coding Machine better! Please let us know what you think.',
309
+ 'interactive.feedback.email': 'Email (optional):',
310
+ 'interactive.feedback.comment': 'Comment:',
311
+ 'interactive.feedback.comment.instructions': 'Enter your comments below (press Enter twice on an empty line to finish):',
312
+ 'interactive.feedback.comment.required': 'Comment is required',
313
+ 'interactive.feedback.submitting': 'Submitting feedback',
314
+ 'interactive.feedback.success': 'Feedback submitted successfully!',
315
+ 'interactive.feedback.error': 'Failed to submit feedback',
316
+ 'interactive.feedback.error.network': 'Network error - please check your internet connection or try again later.',
317
+ 'interactive.feedback.cancelled': 'Feedback cancelled',
306
318
  'interactive.initialize': 'Initialize repository (.vibecodingmachine)',
307
319
  'interactive.goodbye': 'Goodbye! Be dreaming about what requirements to add!',
308
320
  'interactive.confirm.exit': 'Are you sure you want to exit? (x/y/N)',
@@ -323,7 +335,7 @@ module.exports = {
323
335
  'provider.available': 'Available',
324
336
  'provider.resets.in': 'Resets in',
325
337
  'provider.rate.limit.resets': 'Rate limit resets in',
326
- 'provider.instructions': '↑/↓ move selection j/k reorder e enable d disable Space toggle Enter save/select Esc cancel',
338
+ 'provider.instructions': '↑/↓ move selection j/k reorder e enable d disable i install Space toggle Enter save/select Esc cancel',
327
339
  'provider.status.available': 'Available',
328
340
  'provider.status.quota.infinite': 'Quota: Infinite',
329
341
  'provider.status.available.resets': 'available • resets in',
@@ -344,6 +356,8 @@ module.exports = {
344
356
 
345
357
  // System Information
346
358
  'system.repo': 'Repo:',
359
+ 'system.git.branch': 'Branch:',
360
+ 'system.git.status.dirty': '(modified)',
347
361
  'system.computer.name': 'Computer Name:',
348
362
 
349
363
  // Configuration Dialogs
@@ -303,6 +303,18 @@ module.exports = {
303
303
  'interactive.sync.now': 'Sincronizar Ahora',
304
304
  'interactive.logout': 'Cerrar Sesión',
305
305
  'interactive.exit': 'Salir',
306
+ 'interactive.feedback': 'Comentarios',
307
+ 'interactive.feedback.title': 'Comentarios de Vibe Coding Machine',
308
+ 'interactive.feedback.instructions': '¡Tus comentarios nos ayudan a mejorar Vibe Coding Machine! Por favor, dinos qué piensas.',
309
+ 'interactive.feedback.email': 'Correo electrónico (opcional):',
310
+ 'interactive.feedback.comment': 'Comentario:',
311
+ 'interactive.feedback.comment.instructions': 'Ingresa tus comentarios a continuación (presiona Enter dos veces en una línea vacía para terminar):',
312
+ 'interactive.feedback.comment.required': 'El comentario es obligatorio',
313
+ 'interactive.feedback.submitting': 'Enviando comentarios',
314
+ 'interactive.feedback.success': '¡Comentarios enviados con éxito!',
315
+ 'interactive.feedback.error': 'No se pudieron enviar los comentarios',
316
+ 'interactive.feedback.error.network': 'Error de red: por favor, verifica tu conexión a internet o inténtalo de nuevo más tarde.',
317
+ 'interactive.feedback.cancelled': 'Comentarios cancelados',
306
318
  'interactive.initialize': 'Inicializar repositorio (.vibecodingmachine)',
307
319
  'interactive.goodbye': '¡Adiós! ¡Sigue soñando sobre qué requisitos agregar!',
308
320
  'interactive.confirm.exit': '¿Estás seguro de que quieres salir? (x/y/N)',
@@ -344,6 +356,8 @@ module.exports = {
344
356
 
345
357
  // System Information
346
358
  'system.repo': 'Repositorio:',
359
+ 'system.git.branch': 'Rama:',
360
+ 'system.git.status.dirty': '(modificado)',
347
361
  'system.computer.name': 'Nombre de Computadora:',
348
362
 
349
363
  // Configuration Dialogs