vibecodingmachine-cli 2025.12.22-2230 → 2025.12.24-2348

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.
@@ -5,7 +5,11 @@
5
5
  */
6
6
 
7
7
  const chalk = require('chalk');
8
- const { DirectLLMManager, AppleScriptManager } = require('vibecodingmachine-core');
8
+ const { DirectLLMManager, AppleScriptManager, t, detectLocale, setLocale } = require('vibecodingmachine-core');
9
+
10
+ // Initialize locale detection for auto mode
11
+ const detectedLocale = detectLocale();
12
+ setLocale(detectedLocale);
9
13
  const { getRepoPath, getAutoConfig, setAutoConfig, getStages, DEFAULT_STAGES } = require('../utils/config');
10
14
  const { getRequirementsPath, readRequirements } = require('vibecodingmachine-core');
11
15
  const fs = require('fs-extra');
@@ -41,6 +45,25 @@ function getTimestamp() {
41
45
  }) + ' MST';
42
46
  }
43
47
 
48
+ /**
49
+ * Translate workflow stage names
50
+ */
51
+ function translateStage(stage) {
52
+ const stageMap = {
53
+ 'PREPARE': 'workflow.stage.prepare',
54
+ 'REPRODUCE': 'workflow.stage.reproduce',
55
+ 'CREATE UNIT TEST': 'workflow.stage.create.unit.test',
56
+ 'ACT': 'workflow.stage.act',
57
+ 'CLEAN UP': 'workflow.stage.clean.up',
58
+ 'VERIFY': 'workflow.stage.verify',
59
+ 'RUN UNIT TESTS': 'workflow.stage.run.unit.tests',
60
+ 'DONE': 'workflow.stage.done'
61
+ };
62
+
63
+ const key = stageMap[stage];
64
+ return key ? t(key) : stage;
65
+ }
66
+
44
67
  /**
45
68
  * Strip ANSI escape codes from a string
46
69
  */
@@ -151,7 +174,7 @@ async function updateRequirementsStatus(repoPath, status) {
151
174
  await fs.writeFile(reqPath, lines.join('\n'));
152
175
  } catch (error) {
153
176
  // Silently fail - don't break execution if status update fails
154
- console.error(chalk.gray(` Warning: Could not update status in requirements file: ${error.message}`));
177
+ console.error(chalk.gray(` ${t('auto.direct.status.update.warning')} ${error.message}`));
155
178
  }
156
179
  }
157
180
 
@@ -176,15 +199,16 @@ function printStatusCard(currentTitle, currentStatus) {
176
199
 
177
200
  // Build workflow line with visual prominence for current stage
178
201
  const stageParts = stages.map((stage, idx) => {
202
+ const translatedStage = translateStage(stage);
179
203
  if (idx < currentIndex) {
180
204
  // Completed stages - grey with checkmark
181
- return chalk.grey(`✅ ${stage}`);
205
+ return chalk.grey(`✅ ${translatedStage}`);
182
206
  } else if (idx === currentIndex) {
183
207
  // CURRENT stage - BRIGHT WHITE with hammer
184
- return chalk.bold.white(`🔨 ${stage}`);
208
+ return chalk.bold.white(`🔨 ${translatedStage}`);
185
209
  } else {
186
210
  // Future stages - grey with hourglass
187
- return chalk.grey(`⏳ ${stage}`);
211
+ return chalk.grey(`⏳ ${translatedStage}`);
188
212
  }
189
213
  });
190
214
 
@@ -195,9 +219,10 @@ function printStatusCard(currentTitle, currentStatus) {
195
219
  const boxWidth = Math.max(terminalWidth - 4, 80); // Leave 4 chars margin, minimum 80
196
220
 
197
221
  // Truncate title if needed to fit in box
198
- const maxTitleWidth = boxWidth - 20; // Leave room for "🎯 Working on: "
222
+ const workingOnLabel = `🎯 ${t('auto.direct.requirement.working.on')} `;
223
+ const maxTitleWidth = boxWidth - stringWidth(workingOnLabel) - 2; // Leave room for label
199
224
  const titleShort = currentTitle?.substring(0, maxTitleWidth) + (currentTitle?.length > maxTitleWidth ? '...' : '');
200
- const titleLine = chalk.cyan(`🎯 Working on: `) + chalk.white(titleShort);
225
+ const titleLine = chalk.cyan(workingOnLabel) + chalk.white(titleShort);
201
226
 
202
227
  // Build the status box content
203
228
  const statusBoxContent =
@@ -289,7 +314,7 @@ async function getCurrentRequirement(repoPath) {
289
314
 
290
315
  return null;
291
316
  } catch (err) {
292
- console.error('Error reading requirement:', err.message);
317
+ console.error(t('auto.direct.requirement.read.error'), err.message);
293
318
  return null;
294
319
  }
295
320
  }
@@ -336,7 +361,7 @@ async function countTodoRequirements(repoPath) {
336
361
 
337
362
  return count;
338
363
  } catch (err) {
339
- console.error('Error counting requirements:', err.message);
364
+ console.error(t('auto.direct.requirement.count.error'), err.message);
340
365
  return 0;
341
366
  }
342
367
  }
@@ -415,7 +440,7 @@ async function moveRequirementToVerify(repoPath, requirementText) {
415
440
  }
416
441
 
417
442
  if (requirementStartIndex === -1) {
418
- console.log(chalk.yellow(`⚠️ Could not find requirement "${requirementText.substring(0, 60)}..." in TODO section`));
443
+ console.log(chalk.yellow(`⚠️ ${t('auto.direct.requirement.not.found.todo', { requirement: requirementText.substring(0, 60) + '...' })}`));
419
444
  return false;
420
445
  }
421
446
 
@@ -451,7 +476,7 @@ async function moveRequirementToVerify(repoPath, requirementText) {
451
476
 
452
477
  // If no more TODO requirements, log message
453
478
  if (!hasMoreTodoRequirements) {
454
- console.log(chalk.green('🎉 No more requirements in TODO section'));
479
+ console.log(chalk.green(`🎉 ${t('auto.direct.requirement.no.more.todo')}`));
455
480
  }
456
481
 
457
482
 
@@ -536,7 +561,7 @@ async function moveRequirementToVerify(repoPath, requirementText) {
536
561
 
537
562
  // Safety check: verifyIndex should be valid
538
563
  if (verifyIndex === -1) {
539
- console.error('Failed to create TO VERIFY BY HUMAN section');
564
+ console.error(t('auto.direct.verify.section.create.failed'));
540
565
  return false;
541
566
  }
542
567
  }
@@ -619,7 +644,7 @@ async function moveRequirementToVerify(repoPath, requirementText) {
619
644
  console.log(chalk.green(`✅ Moved requirement to TO VERIFY BY HUMAN: ${requirementText.substring(0, 80)}...`));
620
645
  return true;
621
646
  } catch (err) {
622
- console.error('Error moving requirement to TO VERIFY:', err.message);
647
+ console.error(t('auto.direct.requirement.move.verify.error'), err.message);
623
648
  console.error('⚠️ Requirement may have been lost. Please check the requirements file.');
624
649
  return false;
625
650
  }
@@ -650,7 +675,7 @@ async function moveRequirementToRecycle(repoPath, requirementText) {
650
675
  }
651
676
 
652
677
  if (requirementIndex === -1) {
653
- console.log(chalk.yellow('⚠️ Could not find requirement'));
678
+ console.log(chalk.yellow(`⚠️ ${t('auto.direct.requirement.not.found')}`));
654
679
  return false;
655
680
  }
656
681
 
@@ -680,7 +705,7 @@ async function moveRequirementToRecycle(repoPath, requirementText) {
680
705
  await fs.writeFile(reqPath, lines.join('\n'));
681
706
  return true;
682
707
  } catch (err) {
683
- console.error('Error moving requirement:', err.message);
708
+ console.error(t('auto.direct.requirement.move.error'), err.message);
684
709
  return false;
685
710
  }
686
711
  }
@@ -862,19 +887,19 @@ async function acquireProviderConfig(excludeProvider = null) {
862
887
  }
863
888
 
864
889
  if (selection.status === 'no_providers') {
865
- console.log(chalk.red('\n✗ No providers available. Configure API keys or IDE agents first.\n'));
890
+ console.log(chalk.red(`\n✗ ${t('auto.direct.provider.none.available')}\n`));
866
891
  return null;
867
892
  }
868
893
 
869
894
  if (selection.status === 'no_enabled') {
870
- console.log(chalk.red('\n✗ All providers are disabled. Enable at least one provider in the Agent menu.\n'));
895
+ console.log(chalk.red(`\n✗ ${t('auto.direct.provider.all.disabled')}\n`));
871
896
  return null;
872
897
  }
873
898
 
874
899
  if (selection.status === 'all_rate_limited') {
875
- console.log(chalk.yellow('\n⚠️ All enabled providers are currently rate limited.'));
900
+ console.log(chalk.yellow(`\n⚠️ ${t('auto.direct.provider.all.rate.limited')}`));
876
901
  if (selection.disabledProviders && selection.disabledProviders.length > 0) {
877
- console.log(chalk.gray(' Tip: Enable additional providers in the Agent menu for more fallbacks.'));
902
+ console.log(chalk.gray(` ${t('auto.direct.provider.enable.tip')}`));
878
903
  }
879
904
  const waitMs = selection.nextResetMs || 60000;
880
905
  const waitMinutes = Math.max(1, Math.ceil(waitMs / 60000));
@@ -990,7 +1015,7 @@ async function applyFileChange(change, repoPath) {
990
1015
  let content = await fs.readFile(fullPath, 'utf8');
991
1016
 
992
1017
  // Try exact match first
993
- console.log(chalk.gray(` 🔍 Trying exact match...`));
1018
+ console.log(chalk.gray(` 🔍 ${t('auto.direct.files.trying.exact')}`));
994
1019
  if (content.includes(change.search)) {
995
1020
  const newContent = content.replace(change.search, change.replace);
996
1021
  await fs.writeFile(fullPath, newContent, 'utf8');
@@ -1000,7 +1025,7 @@ async function applyFileChange(change, repoPath) {
1000
1025
  console.log(chalk.gray(` ✗ Exact match failed`));
1001
1026
 
1002
1027
  // Try with normalized whitespace (fuzzy match)
1003
- console.log(chalk.gray(` 🔍 Trying fuzzy match (normalized whitespace)...`));
1028
+ console.log(chalk.gray(` 🔍 ${t('auto.direct.files.trying.fuzzy')}`));
1004
1029
  const normalizedSearch = normalizeWhitespace(change.search);
1005
1030
  const lines = content.split('\n');
1006
1031
  const searchLines = change.search.split('\n');
@@ -1128,7 +1153,7 @@ async function findRelevantFiles(requirement, repoPath) {
1128
1153
  relevantFiles.push('packages/cli/src/utils/interactive.js');
1129
1154
  }
1130
1155
  } catch (error) {
1131
- console.log(chalk.yellow(`⚠️ Error finding files: ${error.message}`));
1156
+ console.log(chalk.yellow(`⚠️ ${t('auto.direct.files.error')} ${error.message}`));
1132
1157
  }
1133
1158
 
1134
1159
  return relevantFiles;
@@ -1301,7 +1326,7 @@ async function readFileSnippets(files, repoPath, requirement) {
1301
1326
 
1302
1327
  async function runIdeProviderIteration(providerConfig, repoPath) {
1303
1328
  return new Promise((resolve) => {
1304
- console.log(chalk.cyan(`⚙️ Launching ${providerConfig.displayName} fallback (auto:start)...\n`));
1329
+ console.log(chalk.cyan(`⚙️ ${t('auto.direct.provider.launching', { provider: providerConfig.displayName })}\n`));
1305
1330
 
1306
1331
  const args = [CLI_ENTRY_POINT, 'auto:start', '--ide', providerConfig.ide || providerConfig.provider, '--max-chats', String(providerConfig.maxChats || 1)];
1307
1332
  const child = spawn(process.execPath, args, {
@@ -1368,9 +1393,9 @@ async function waitForIdeCompletion(repoPath, requirementText, ideType = '', tim
1368
1393
  let quotaHandled = false;
1369
1394
  const checkIntervalMs = 2000; // Check every 2 seconds
1370
1395
 
1371
- console.log(chalk.gray('\n⏳ Waiting for IDE agent to complete...'));
1372
- console.log(chalk.gray(` Monitoring: ${path.basename(reqPath)}`));
1373
- console.log(chalk.gray(` Timeout: ${Math.floor(timeoutMs / 60000)} minutes\n`));
1396
+ console.log(chalk.gray(`\n⏳ ${t('auto.direct.ide.waiting')}`));
1397
+ console.log(chalk.gray(` ${t('auto.direct.ide.monitoring', { filename: path.basename(reqPath) })}`));
1398
+ console.log(chalk.gray(` ${t('auto.direct.ide.timeout', { minutes: Math.floor(timeoutMs / 60000) })}\n`));
1374
1399
 
1375
1400
  const watcher = chokidar.watch(reqPath, {
1376
1401
  persistent: true,
@@ -1464,7 +1489,7 @@ async function waitForIdeCompletion(repoPath, requirementText, ideType = '', tim
1464
1489
  if (Date.now() - lastCheckTime >= 30000) {
1465
1490
  const elapsedMin = Math.floor(elapsed / 60000);
1466
1491
  const remainingMin = Math.floor((timeoutMs - elapsed) / 60000);
1467
- console.log(chalk.gray(` Still waiting... (${elapsedMin}m elapsed, ${remainingMin}m remaining)`));
1492
+ console.log(chalk.gray(` ${t('auto.direct.ide.still.waiting', { elapsed: elapsedMin, remaining: remainingMin })}`));
1468
1493
  lastCheckTime = Date.now();
1469
1494
  }
1470
1495
  } catch (error) {
@@ -1498,7 +1523,7 @@ async function runIdeFallbackIteration(requirement, providerConfig, repoPath, pr
1498
1523
  // Update console and requirements file with PREPARE status
1499
1524
  printStatusCard(requirement.text, 'PREPARE');
1500
1525
  await updateRequirementsStatus(repoPath, 'PREPARE');
1501
- console.log(chalk.gray('Skipping direct file context - delegating to IDE agent.\n'));
1526
+ console.log(chalk.gray(`${t('auto.direct.ide.skipping.context')}\n`));
1502
1527
 
1503
1528
  // Update console and requirements file with ACT status
1504
1529
  printStatusCard(requirement.text, 'ACT');
@@ -1515,14 +1540,14 @@ async function runIdeFallbackIteration(requirement, providerConfig, repoPath, pr
1515
1540
  return { success: false, error: ideResult.error || 'IDE provider failed' };
1516
1541
  }
1517
1542
 
1518
- console.log(chalk.green('✓ Prompt sent to IDE agent successfully'));
1543
+ console.log(chalk.green(`✓ ${t('auto.direct.ide.prompt.sent')}`));
1519
1544
 
1520
1545
  // Wait for IDE agent to complete the work (IDE will update status to DONE itself)
1521
1546
  const completionResult = await waitForIdeCompletion(repoPath, requirement.text, providerConfig.ide || providerConfig.provider);
1522
1547
 
1523
1548
  if (!completionResult.success) {
1524
1549
  if (completionResult.antigravityRateLimited) {
1525
- console.log(chalk.yellow('⚠️ Antigravity quota exhausted, switching to next IDE\n'));
1550
+ console.log(chalk.yellow(`⚠️ ${t('auto.direct.provider.quota.exhausted', { provider: 'Antigravity' })}\n`));
1526
1551
  providerManager.markRateLimited(providerConfig.provider, providerConfig.model, 'Quota limit reached');
1527
1552
  return { success: false, error: 'Antigravity quota limit', shouldRetry: true };
1528
1553
  }
@@ -1535,7 +1560,7 @@ async function runIdeFallbackIteration(requirement, providerConfig, repoPath, pr
1535
1560
  }
1536
1561
 
1537
1562
  printStatusCard(requirement.text, 'VERIFY');
1538
- console.log(chalk.green('✅ IDE provider completed iteration\n'));
1563
+ console.log(chalk.green(`✅ ${t('auto.direct.provider.completed')}\n`));
1539
1564
 
1540
1565
  printStatusCard(requirement.text, 'DONE');
1541
1566
  const duration = Date.now() - startTime;
@@ -1543,7 +1568,7 @@ async function runIdeFallbackIteration(requirement, providerConfig, repoPath, pr
1543
1568
 
1544
1569
  const moved = await moveRequirementToVerify(repoPath, requirement.text);
1545
1570
  if (moved) {
1546
- console.log(chalk.green('✓ Requirement moved to TO VERIFY BY HUMAN section'));
1571
+ console.log(chalk.green(`✓ ${t('auto.direct.status.verification.pending')}`));
1547
1572
  } else {
1548
1573
  console.log(chalk.yellow('⚠️ Requirement still pending verification in REQUIREMENTS file'));
1549
1574
  }
@@ -1574,15 +1599,15 @@ async function runIteration(requirement, providerConfig, repoPath) {
1574
1599
 
1575
1600
  console.log(chalk.bold.white('📋 REQUIREMENT:'));
1576
1601
  console.log(chalk.cyan(` ${requirement.text}\n`));
1577
- console.log(chalk.gray('Provider:'), chalk.white(providerConfig.displayName));
1578
- console.log(chalk.gray('Repository:'), chalk.white(repoPath));
1602
+ console.log(chalk.gray(t('auto.direct.summary.provider')), chalk.white(providerConfig.displayName));
1603
+ console.log(chalk.gray(t('auto.repository')), chalk.white(repoPath));
1579
1604
  console.log();
1580
1605
 
1581
- console.log(chalk.cyan('🔍 Searching for relevant files...\n'));
1606
+ console.log(chalk.cyan(`🔍 ${t('auto.direct.files.searching')}...\n`));
1582
1607
  const relevantFiles = await findRelevantFiles(requirement.text, repoPath);
1583
1608
 
1584
1609
  if (relevantFiles.length > 0) {
1585
- console.log(chalk.white('Found relevant files:'));
1610
+ console.log(chalk.white(`${t('auto.direct.files.found', { count: relevantFiles.length })}:`));
1586
1611
  relevantFiles.forEach((file, i) => {
1587
1612
  console.log(chalk.gray(` ${i + 1}. ${file}`));
1588
1613
  });
@@ -1846,17 +1871,17 @@ Now implement the requirement. Remember: COPY THE SEARCH BLOCK EXACTLY!`;
1846
1871
 
1847
1872
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
1848
1873
 
1849
- console.log(chalk.bold.green('✅ REQUIREMENT COMPLETED!\n'));
1850
- console.log(chalk.white('Requirement:'), chalk.cyan(requirement.text));
1851
- console.log(chalk.white('Files modified:'), chalk.cyan(changes.length));
1852
- console.log(chalk.white('Status:'), chalk.green('Moving to TO VERIFY BY HUMAN'));
1853
- console.log(chalk.white('Time:'), chalk.gray(`${elapsed}s`));
1874
+ console.log(chalk.bold.green(`✅ ${t('auto.direct.requirement.completed')}\n`));
1875
+ console.log(chalk.white(`${t('auto.direct.requirement.title')}`), chalk.cyan(requirement.text));
1876
+ console.log(chalk.white(t('auto.direct.summary.files.modified')), chalk.cyan(changes.length));
1877
+ console.log(chalk.white(t('auto.direct.summary.status')), chalk.green(t('auto.direct.summary.moving.to.verify')));
1878
+ console.log(chalk.white(t('auto.direct.summary.time')), chalk.gray(`${elapsed}s`));
1854
1879
  console.log();
1855
1880
 
1856
1881
  // Move requirement to TO VERIFY section
1857
1882
  const moved = await moveRequirementToVerify(repoPath, requirement.text);
1858
1883
  if (moved) {
1859
- console.log(chalk.green('✓ Requirement moved to TO VERIFY BY HUMAN section'));
1884
+ console.log(chalk.green(`✓ ${t('auto.direct.status.verification.pending')}`));
1860
1885
  } else {
1861
1886
  console.log(chalk.yellow('⚠️ Could not automatically move requirement'));
1862
1887
  }
@@ -1891,7 +1916,7 @@ async function handleAutoStart(options) {
1891
1916
  }
1892
1917
  }
1893
1918
 
1894
- console.log(chalk.bold.cyan('\n🤖 Vibe Coding Machine - Direct API Auto Mode\n'));
1919
+ console.log(chalk.bold.cyan('\n' + t('auto.direct.title') + '\n'));
1895
1920
  console.log(chalk.gray('═'.repeat(80)));
1896
1921
  console.log();
1897
1922
 
@@ -1902,15 +1927,15 @@ async function handleAutoStart(options) {
1902
1927
  const repoPath = await getRepoPath();
1903
1928
  if (!repoPath) {
1904
1929
  console.log(chalk.red('✗ No repository configured'));
1905
- console.log(chalk.gray('Run:'), chalk.cyan('vcm repo:set <path>'));
1930
+ console.log(chalk.gray(t('auto.direct.config.repo.not.set')));
1906
1931
  return;
1907
1932
  }
1908
1933
 
1909
- console.log(chalk.white('Repository:'), chalk.cyan(repoPath));
1934
+ console.log(chalk.white(t('auto.repository')), chalk.cyan(repoPath));
1910
1935
 
1911
1936
  // Get effective agent using centralized selector
1912
1937
  const { getEffectiveAgent } = require('../utils/agent-selector');
1913
- const PROVIDER_DEFINITIONS = require('./auto').PROVIDER_DEFINITIONS;
1938
+ const { PROVIDER_DEFINITIONS } = require('../utils/provider-registry');
1914
1939
  const PROVIDER_DEFINITION_MAP = new Map(PROVIDER_DEFINITIONS.map(def => [def.id, def]));
1915
1940
 
1916
1941
  const { effectiveAgent } = await getEffectiveAgent(options, PROVIDER_DEFINITIONS, PROVIDER_DEFINITION_MAP);
@@ -1927,7 +1952,7 @@ async function handleAutoStart(options) {
1927
1952
  const config = await getAutoConfig();
1928
1953
  const unlimited = !options.maxChats && !config.maxChats && config.neverStop;
1929
1954
  const maxChats = unlimited ? Number.MAX_SAFE_INTEGER : (options.maxChats || config.maxChats || 1);
1930
- console.log(chalk.white('Max iterations:'), unlimited ? chalk.cyan('∞ (never stop)') : chalk.cyan(maxChats));
1955
+ console.log(chalk.white(`${t('auto.direct.config.max.iterations')}`), unlimited ? chalk.cyan('∞ (never stop)') : chalk.cyan(maxChats));
1931
1956
  console.log();
1932
1957
  console.log(chalk.gray('═'.repeat(80)));
1933
1958
 
@@ -1944,7 +1969,7 @@ async function handleAutoStart(options) {
1944
1969
  const requirement = await getCurrentRequirement(repoPath);
1945
1970
  if (!requirement) {
1946
1971
  console.log(chalk.bold.yellow('\n🎉 All requirements completed!'));
1947
- console.log(chalk.gray('No more TODO items found in REQUIREMENTS file\n'));
1972
+ console.log(chalk.gray(`${t('auto.direct.no.more.todo.items')}\n`));
1948
1973
  break;
1949
1974
  }
1950
1975
 
@@ -1953,7 +1978,7 @@ async function handleAutoStart(options) {
1953
1978
  const currentReqNumber = completedCount + failedCount + 1;
1954
1979
 
1955
1980
  console.log(chalk.bold.magenta(`\n${'━'.repeat(80)}`));
1956
- console.log(chalk.bold.magenta(` REQUIREMENT ${currentReqNumber} of ${initialEffectiveMax}`));
1981
+ console.log(chalk.bold.magenta(` ${t('auto.direct.requirement.header', { current: currentReqNumber, total: initialEffectiveMax })}`));
1957
1982
  console.log(chalk.bold.magenta(`${'━'.repeat(80)}\n`));
1958
1983
 
1959
1984
  // Run iteration with full workflow
@@ -1986,7 +2011,7 @@ async function handleAutoStart(options) {
1986
2011
 
1987
2012
  // Handle child errors (but don't wait for completion)
1988
2013
  child.on('error', (err) => {
1989
- console.error(chalk.red('Error restarting CLI:'), err.message);
2014
+ console.error(chalk.red(t('auto.direct.config.restart.error')), err.message);
1990
2015
  });
1991
2016
 
1992
2017
  // Don't wait for child - unref so parent can exit
@@ -2042,20 +2067,20 @@ async function handleAutoStart(options) {
2042
2067
  console.log(chalk.bold.magenta(`${'━'.repeat(80)}\n`));
2043
2068
 
2044
2069
  const totalProcessed = completedCount + failedCount;
2045
- console.log(chalk.white('Total requirements:'), chalk.cyan(totalProcessed));
2046
- console.log(chalk.white('Completed:'), chalk.green(`${completedCount} ✓`));
2070
+ console.log(chalk.white(t('auto.direct.summary.total.requirements')), chalk.cyan(totalProcessed));
2071
+ console.log(chalk.white(t('auto.direct.summary.completed')), chalk.green(`${completedCount} ✓`));
2047
2072
  if (failedCount > 0) {
2048
- console.log(chalk.white('Failed:'), chalk.red(`${failedCount} ✗`));
2073
+ console.log(chalk.white(t('auto.direct.summary.failed')), chalk.red(`${failedCount} ✗`));
2049
2074
  }
2050
- console.log(chalk.white('Provider:'), chalk.cyan(providerConfig.displayName));
2075
+ console.log(chalk.white(t('auto.direct.summary.provider')), chalk.cyan(providerConfig.displayName));
2051
2076
  console.log();
2052
2077
 
2053
2078
  if (completedCount > 0) {
2054
- console.log(chalk.bold.green(`🎉 ${completedCount} requirement${completedCount > 1 ? 's' : ''} moved to TO VERIFY BY HUMAN!`));
2079
+ console.log(chalk.bold.green(`🎉 ${t('auto.direct.summary.final.message', { count: completedCount, plural: completedCount > 1 ? 's' : '' })}`));
2055
2080
  }
2056
2081
 
2057
2082
  } catch (error) {
2058
- console.error(chalk.red('\n Fatal Error:'), error.message);
2083
+ console.error(chalk.red('\n' + t('auto.fatal.error')), error.message);
2059
2084
  if (error.stack) {
2060
2085
  console.log(chalk.gray(error.stack));
2061
2086
  }
@@ -3,7 +3,7 @@ const ora = require('ora');
3
3
  const path = require('path');
4
4
  const os = require('os');
5
5
  const { spawn } = require('child_process');
6
- const { AppleScriptManager, ClineCLIManager, AiderCLIManager, ClaudeCodeCLIManager, logIDEMessage, runContinueCLIAutoMode } = require('vibecodingmachine-core');
6
+ const { AppleScriptManager, ClineCLIManager, AiderCLIManager, ClaudeCodeCLIManager, logIDEMessage, runContinueCLIAutoMode, t } = require('vibecodingmachine-core');
7
7
  const { getRepoPath, getAutoConfig, setAutoConfig, getStages } = require('../utils/config');
8
8
  const { checkAutoModeStatus, startAutoMode, stopAutoMode, updateAutoModeStatus } = require('../utils/auto-mode');
9
9
  const logger = require('../utils/logger');
@@ -723,7 +723,7 @@ async function start(options) {
723
723
  }
724
724
  }
725
725
 
726
- const spinner = ora('Starting autonomous mode...').start();
726
+ const spinner = ora(t('auto.starting.mode')).start();
727
727
 
728
728
  try {
729
729
  const repoPath = await getRepoPath();
@@ -3071,7 +3071,7 @@ Example BAD questions (never ask these):
3071
3071
  // Ask if user wants to stop with countdown
3072
3072
  const readline = require('readline');
3073
3073
  console.log(chalk.yellow('\n⏸️ Continue to next requirement or stop?'));
3074
- console.log(chalk.gray(' Press any key to stop, or wait 10 seconds to continue...'));
3074
+ console.log(chalk.gray(` ${t('auto.press.any.key.stop')}`));
3075
3075
 
3076
3076
  let countdown = 10;
3077
3077
  let dots = '.'.repeat(countdown);
@@ -3162,7 +3162,7 @@ Example BAD questions (never ask these):
3162
3162
  // Ask if user wants to stop with countdown
3163
3163
  const readline = require('readline');
3164
3164
  console.log(chalk.yellow('\n⏸️ Continue to next requirement or stop?'));
3165
- console.log(chalk.gray(' Press any key to stop, or wait 10 seconds to continue...'));
3165
+ console.log(chalk.gray(` ${t('auto.press.any.key.stop')}`));
3166
3166
 
3167
3167
  let countdown = 10;
3168
3168
  let dots = '.'.repeat(countdown);
@@ -4770,7 +4770,7 @@ Example BAD questions (never ask these):
4770
4770
  return;
4771
4771
  }
4772
4772
  } else if (ideAppPath) {
4773
- spinner.succeed(`${config.ide} is installed`);
4773
+ spinner.succeed(t('auto.ide.is.installed', { ide: config.ide }));
4774
4774
  }
4775
4775
 
4776
4776
  // Launch the IDE if it's not already running
@@ -4785,7 +4785,7 @@ Example BAD questions (never ask these):
4785
4785
  config.ide === 'vscode' ? 'Code' : config.ide}"`,
4786
4786
  { encoding: 'utf8', stdio: 'pipe' }).trim();
4787
4787
  if (isRunning) {
4788
- console.log(chalk.gray(` ${config.ide} is already running (PID: ${isRunning.split('\n')[0]})`));
4788
+ console.log(chalk.gray(` ${t('auto.ide.is.running', { ide: config.ide, pid: isRunning.split('\n')[0] })}`));
4789
4789
  }
4790
4790
  } catch (err) {
4791
4791
  // Not running, launch it
@@ -4829,8 +4829,8 @@ Example BAD questions (never ask these):
4829
4829
  console.log(chalk.gray(' Consider using'), chalk.cyan('Cline IDE'), chalk.gray('instead (set with'), chalk.cyan('vcm'), chalk.gray('menu)'));
4830
4830
  } else {
4831
4831
  logIDEMessage(config.ide, textToSend);
4832
- spinner.succeed('Autonomous mode started and initial message sent');
4833
- console.log(chalk.green('\n✓ Vibe Coding Machine is now coding autonomously'));
4832
+ spinner.succeed(t('auto.direct.ide.autonomous.started'));
4833
+ console.log(chalk.green(`\n✓ ${t('auto.coding.autonomously')}`));
4834
4834
  }
4835
4835
  } catch (sendError) {
4836
4836
  logIDEMessage(config.ide, `[ERROR] ${textToSend}`);
@@ -4853,12 +4853,12 @@ Example BAD questions (never ask these):
4853
4853
  };
4854
4854
  return ideNames[ide] || ide;
4855
4855
  };
4856
- console.log(chalk.gray(' IDE:'), chalk.cyan(formatIDEName(config.ide)));
4856
+ console.log(chalk.gray(` ${t('auto.ide.label')}`), chalk.cyan(formatIDEName(config.ide)));
4857
4857
 
4858
4858
  if (config.neverStop) {
4859
4859
  console.log(chalk.gray(' Mode:'), chalk.cyan('Never stop'));
4860
4860
  } else if (config.maxChats) {
4861
- console.log(chalk.gray(' Max chats:'), chalk.cyan(config.maxChats));
4861
+ console.log(chalk.gray(` ${t('auto.max.chats.label')}`), chalk.cyan(config.maxChats));
4862
4862
  }
4863
4863
  } catch (error) {
4864
4864
  spinner.stop();
@@ -4914,7 +4914,7 @@ async function status() {
4914
4914
  if (config.neverStop) {
4915
4915
  console.log(chalk.gray(' Mode:'), chalk.cyan('Never stop'));
4916
4916
  } else if (config.maxChats) {
4917
- console.log(chalk.gray(' Max chats:'), chalk.cyan(config.maxChats));
4917
+ console.log(chalk.gray(` ${t('auto.max.chats.label')}`), chalk.cyan(config.maxChats));
4918
4918
  const remaining = config.maxChats - (autoStatus.chatCount || 0);
4919
4919
  console.log(chalk.gray(' Remaining:'), chalk.cyan(remaining));
4920
4920
  }
@@ -5013,5 +5013,6 @@ module.exports = {
5013
5013
  stop,
5014
5014
  status,
5015
5015
  config,
5016
- listAgents
5016
+ listAgents,
5017
+ PROVIDER_DEFINITIONS
5017
5018
  };