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.
- package/bin/vibecodingmachine.js +57 -50
- package/logs/audit/2025-12-24.jsonl +2 -0
- package/package.json +2 -2
- package/src/commands/auth.js +19 -18
- package/src/commands/auto-direct.js +81 -56
- package/src/commands/auto.js +13 -12
- package/src/commands/computers.js +58 -55
- package/src/commands/locale.js +73 -0
- package/src/commands/requirements-remote.js +4 -3
- package/src/commands/setup.js +14 -13
- package/src/commands/status.js +17 -17
- package/src/commands/sync.js +68 -67
- package/src/utils/first-run.js +4 -3
- package/src/utils/interactive.js +178 -117
- package/src/utils/provider-registry.js +38 -1
|
@@ -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(`
|
|
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(`✅ ${
|
|
205
|
+
return chalk.grey(`✅ ${translatedStage}`);
|
|
182
206
|
} else if (idx === currentIndex) {
|
|
183
207
|
// CURRENT stage - BRIGHT WHITE with hammer
|
|
184
|
-
return chalk.bold.white(`🔨 ${
|
|
208
|
+
return chalk.bold.white(`🔨 ${translatedStage}`);
|
|
185
209
|
} else {
|
|
186
210
|
// Future stages - grey with hourglass
|
|
187
|
-
return chalk.grey(`⏳ ${
|
|
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
|
|
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(
|
|
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('
|
|
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('
|
|
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(`⚠️
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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(
|
|
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(
|
|
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(
|
|
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('
|
|
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(` 🔍
|
|
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(` 🔍
|
|
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(`⚠️
|
|
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(`⚙️
|
|
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(
|
|
1372
|
-
console.log(chalk.gray(`
|
|
1373
|
-
console.log(chalk.gray(`
|
|
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(`
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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(
|
|
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('
|
|
1578
|
-
console.log(chalk.gray('
|
|
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('
|
|
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('
|
|
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(
|
|
1850
|
-
console.log(chalk.white('
|
|
1851
|
-
console.log(chalk.white('
|
|
1852
|
-
console.log(chalk.white('
|
|
1853
|
-
console.log(chalk.white('
|
|
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(
|
|
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
|
|
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('
|
|
1930
|
+
console.log(chalk.gray(t('auto.direct.config.repo.not.set')));
|
|
1906
1931
|
return;
|
|
1907
1932
|
}
|
|
1908
1933
|
|
|
1909
|
-
console.log(chalk.white('
|
|
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('
|
|
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('
|
|
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('
|
|
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(`
|
|
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('
|
|
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('
|
|
2046
|
-
console.log(chalk.white('
|
|
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('
|
|
2073
|
+
console.log(chalk.white(t('auto.direct.summary.failed')), chalk.red(`${failedCount} ✗`));
|
|
2049
2074
|
}
|
|
2050
|
-
console.log(chalk.white('
|
|
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(`🎉 ${
|
|
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
|
|
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
|
}
|
package/src/commands/auto.js
CHANGED
|
@@ -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('
|
|
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('
|
|
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('
|
|
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(
|
|
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(` ${
|
|
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('
|
|
4833
|
-
console.log(chalk.green(
|
|
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(
|
|
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('
|
|
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('
|
|
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
|
};
|