vibecodingmachine-cli 2025.12.25-25 → 2026.1.3-2209
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 +84 -118
- package/logs/audit/2025-12-27.jsonl +1 -0
- package/logs/audit/2026-01-03.jsonl +2 -0
- package/package.json +2 -2
- package/src/commands/auth.js +5 -1
- package/src/commands/auto-direct.js +219 -213
- package/src/commands/auto.js +6 -3
- package/src/commands/computers.js +9 -0
- package/src/commands/feature.js +123 -0
- package/src/commands/repo.js +27 -22
- package/src/commands/requirements-remote.js +24 -1
- package/src/commands/requirements.js +129 -9
- package/src/commands/setup.js +2 -1
- package/src/commands/sync.js +7 -1
- package/src/utils/auth.js +20 -13
- package/src/utils/config.js +14 -1
- package/src/utils/first-run.js +8 -6
- package/src/utils/interactive.js +613 -53
- package/src/utils/prompt-helper.js +64 -0
- package/tests/home-bootstrap.test.js +76 -0
|
@@ -378,6 +378,11 @@ async function moveRequirementToVerify(repoPath, requirementText) {
|
|
|
378
378
|
|
|
379
379
|
const content = await fs.readFile(reqPath, 'utf8');
|
|
380
380
|
const lines = content.split('\n');
|
|
381
|
+
|
|
382
|
+
// Get computer filter from config
|
|
383
|
+
const { getComputerFilter } = require('../utils/config');
|
|
384
|
+
const computerFilter = await getComputerFilter();
|
|
385
|
+
|
|
381
386
|
// Find the requirement by its title (in ### header format)
|
|
382
387
|
// Only look in TODO section
|
|
383
388
|
const normalizedRequirement = requirementText.trim();
|
|
@@ -396,248 +401,242 @@ async function moveRequirementToVerify(repoPath, requirementText) {
|
|
|
396
401
|
continue;
|
|
397
402
|
}
|
|
398
403
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
// Only look for requirements in TODO section
|
|
405
|
-
if (inTodoSection && trimmed.startsWith('###')) {
|
|
406
|
-
const title = trimmed.replace(/^###\s*/, '').trim();
|
|
407
|
-
if (title) {
|
|
408
|
-
// Try multiple matching strategies
|
|
409
|
-
const normalizedTitle = title.trim();
|
|
404
|
+
// Check if we're leaving TODO section
|
|
405
|
+
if (inTodoSection && trimmed.startsWith('##') && !trimmed.startsWith('###') && !trimmed.includes('Requirements not yet completed')) {
|
|
406
|
+
inTodoSection = false;
|
|
407
|
+
}
|
|
410
408
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
requirementStartIndex = i;
|
|
418
|
-
}
|
|
419
|
-
// Check snippet matches
|
|
420
|
-
else if (normalizedTitle.includes(snippet) || snippet.includes(normalizedTitle.substring(0, 80))) {
|
|
421
|
-
requirementStartIndex = i;
|
|
422
|
-
}
|
|
409
|
+
// Only look for requirements in TODO section
|
|
410
|
+
if (inTodoSection && trimmed.startsWith('###')) {
|
|
411
|
+
const title = trimmed.replace(/^###\s*/, '').trim();
|
|
412
|
+
if (title) {
|
|
413
|
+
// Try multiple matching strategies
|
|
414
|
+
const normalizedTitle = title.trim();
|
|
423
415
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const nextLine = lines[j].trim();
|
|
428
|
-
if (nextLine.startsWith('###') || (nextLine.startsWith('##') && !nextLine.startsWith('###'))) {
|
|
429
|
-
requirementEndIndex = j;
|
|
430
|
-
break;
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
if (requirementEndIndex === -1) {
|
|
434
|
-
requirementEndIndex = lines.length;
|
|
435
|
-
}
|
|
436
|
-
break;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
416
|
+
// Exact match
|
|
417
|
+
if (normalizedTitle === normalizedRequirement) {
|
|
418
|
+
requirementStartIndex = i;
|
|
439
419
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
console.log(chalk.yellow(`⚠️ ${t('auto.direct.requirement.not.found.todo', { requirement: requirementText.substring(0, 60) + '...' })}`));
|
|
444
|
-
return false;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Extract the entire requirement block
|
|
448
|
-
const requirementBlock = lines.slice(requirementStartIndex, requirementEndIndex);
|
|
449
|
-
|
|
450
|
-
// Remove the requirement from its current location
|
|
451
|
-
lines.splice(requirementStartIndex, requirementEndIndex - requirementStartIndex);
|
|
452
|
-
|
|
453
|
-
// Check if there are any more requirements in TODO section after removal
|
|
454
|
-
let hasMoreTodoRequirements = false;
|
|
455
|
-
inTodoSection = false; // Reset the existing variable
|
|
456
|
-
for (let i = 0; i < lines.length; i++) {
|
|
457
|
-
const line = lines[i].trim();
|
|
458
|
-
|
|
459
|
-
// Check if we're entering TODO section
|
|
460
|
-
if (line.startsWith('##') && line.includes('Requirements not yet completed')) {
|
|
461
|
-
inTodoSection = true;
|
|
462
|
-
continue;
|
|
420
|
+
// Check if either contains the other (for partial matches)
|
|
421
|
+
else if (normalizedTitle.includes(normalizedRequirement) || normalizedRequirement.includes(normalizedTitle)) {
|
|
422
|
+
requirementStartIndex = i;
|
|
463
423
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
break;
|
|
424
|
+
// Check snippet matches
|
|
425
|
+
else if (normalizedTitle.includes(snippet) || snippet.includes(normalizedTitle.substring(0, 80))) {
|
|
426
|
+
requirementStartIndex = i;
|
|
468
427
|
}
|
|
469
428
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
429
|
+
if (requirementStartIndex !== -1) {
|
|
430
|
+
// Find the end of this requirement (next ### or ## header)
|
|
431
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
432
|
+
const nextLine = lines[j].trim();
|
|
433
|
+
if (nextLine.startsWith('###') || (nextLine.startsWith('##') && !nextLine.startsWith('###'))) {
|
|
434
|
+
requirementEndIndex = j;
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (requirementEndIndex === -1) {
|
|
439
|
+
requirementEndIndex = lines.length;
|
|
440
|
+
}
|
|
473
441
|
break;
|
|
474
442
|
}
|
|
475
443
|
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
476
446
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
447
|
+
if (requirementStartIndex === -1) {
|
|
448
|
+
console.log(chalk.yellow(`⚠️ ${t('auto.direct.requirement.not.found.todo', { requirement: requirementText.substring(0, 60) + '...' })}`));
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
483
451
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
const kiroAiIdeCliSupport = '### AWS Kiro AI IDE CLI Support\n\nThis requirement has been moved to the TO VERIFY BY HUMAN section for further review using the CLI.';
|
|
487
|
-
lines.push(kiroAiIdeGuiSupport);
|
|
488
|
-
lines.push(kiroAiIdeCliSupport);
|
|
452
|
+
// Extract the entire requirement block
|
|
453
|
+
const requirementBlock = lines.slice(requirementStartIndex, requirementEndIndex);
|
|
489
454
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
if (recycledIndex !== -1) {
|
|
493
|
-
const recycledBlock = lines.slice(recycledIndex + 1);
|
|
494
|
-
const requirementIndexInRecycled = recycledBlock.findIndex(line => line.trim().startsWith('###') && line.trim().includes(snippet));
|
|
495
|
-
if (requirementIndexInRecycled !== -1) {
|
|
496
|
-
lines.splice(recycledIndex + 1 + requirementIndexInRecycled, 1);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
455
|
+
// Remove the requirement from its current location
|
|
456
|
+
lines.splice(requirementStartIndex, requirementEndIndex - requirementStartIndex);
|
|
499
457
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
'## TO VERIFY',
|
|
506
|
-
'## ✅ TO VERIFY',
|
|
507
|
-
'## ✅ Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG'
|
|
508
|
-
];
|
|
509
|
-
|
|
510
|
-
let verifyIndex = -1;
|
|
511
|
-
for (let i = 0; i < lines.length; i++) {
|
|
512
|
-
const line = lines[i];
|
|
513
|
-
const trimmed = line.trim();
|
|
458
|
+
// Check if there are any more requirements in TODO section after removal
|
|
459
|
+
let hasMoreTodoRequirements = false;
|
|
460
|
+
inTodoSection = false; // Reset the existing variable
|
|
461
|
+
for (let i = 0; i < lines.length; i++) {
|
|
462
|
+
const line = lines[i].trim();
|
|
514
463
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
// Double-check: make sure it's NOT a VERIFIED section (without TO VERIFY)
|
|
521
|
-
if (!trimmed.includes('## 📝 VERIFIED') && !trimmed.match(/^##\s+VERIFIED$/i) &&
|
|
522
|
-
(trimmed.includes('TO VERIFY') || trimmed.includes('Verified by AI screenshot'))) {
|
|
523
|
-
verifyIndex = i;
|
|
524
|
-
break;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
if (verifyIndex !== -1) break;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
if (verifyIndex === -1) {
|
|
532
|
-
// Create TO VERIFY section - place it BEFORE VERIFIED section if one exists, otherwise before CHANGELOG
|
|
533
|
-
const verifiedIndex = lines.findIndex(line => {
|
|
534
|
-
const trimmed = line.trim();
|
|
535
|
-
return trimmed === '## 📝 VERIFIED' || trimmed.startsWith('## 📝 VERIFIED') ||
|
|
536
|
-
(trimmed.startsWith('##') && trimmed.includes('VERIFIED') && !trimmed.includes('TO VERIFY'));
|
|
537
|
-
});
|
|
538
|
-
const changelogIndex = lines.findIndex(line => line.includes('## CHANGELOG'));
|
|
539
|
-
const manualFeedbackIndex = lines.findIndex(line => line.trim().startsWith('## ❓'));
|
|
540
|
-
|
|
541
|
-
// Prefer: before VERIFIED > before CHANGELOG > before manual feedback > at end
|
|
542
|
-
let insertionIndex = lines.length;
|
|
543
|
-
if (verifiedIndex > 0) {
|
|
544
|
-
insertionIndex = verifiedIndex;
|
|
545
|
-
} else if (changelogIndex > 0) {
|
|
546
|
-
insertionIndex = changelogIndex;
|
|
547
|
-
} else if (manualFeedbackIndex > 0) {
|
|
548
|
-
insertionIndex = manualFeedbackIndex;
|
|
549
|
-
}
|
|
464
|
+
// Check if we're entering TODO section
|
|
465
|
+
if (line.startsWith('##') && line.includes('Requirements not yet completed')) {
|
|
466
|
+
inTodoSection = true;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
550
469
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
block.push('## 🔍 TO VERIFY BY HUMAN', '');
|
|
556
|
-
lines.splice(insertionIndex, 0, ...block);
|
|
557
|
-
verifyIndex = lines.findIndex(line => {
|
|
558
|
-
const trimmed = line.trim();
|
|
559
|
-
return trimmed === '## 🔍 TO VERIFY BY HUMAN' || trimmed.startsWith('## 🔍 TO VERIFY BY HUMAN');
|
|
560
|
-
});
|
|
470
|
+
// Check if we're leaving TODO section
|
|
471
|
+
if (inTodoSection && line.startsWith('##') && !line.startsWith('###') && !line.includes('Requirements not yet completed')) {
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
561
474
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
475
|
+
// Check if we found a requirement in TODO section
|
|
476
|
+
if (inTodoSection && line.startsWith('###')) {
|
|
477
|
+
const title = line.replace(/^###\s*/, '').trim();
|
|
478
|
+
if (title && title.includes(computerFilter)) {
|
|
479
|
+
hasMoreTodoRequirements = true;
|
|
480
|
+
break;
|
|
567
481
|
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
568
484
|
|
|
485
|
+
// If no more TODO requirements, log message
|
|
486
|
+
if (!hasMoreTodoRequirements) {
|
|
487
|
+
console.log(chalk.green(`🎉 ${t('auto.direct.requirement.no.more.todo')}`));
|
|
488
|
+
// Add a new requirement to the TODO section
|
|
489
|
+
const newRequirement = '### R14: TESTREQ1';
|
|
490
|
+
lines.push(newRequirement);
|
|
491
|
+
}
|
|
569
492
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
493
|
+
// Find or create TO VERIFY BY HUMAN section with conflict resolution
|
|
494
|
+
// IMPORTANT: Do NOT match VERIFIED sections - only match TO VERIFY sections
|
|
495
|
+
const verifySectionVariants = [
|
|
496
|
+
'## 🔍 TO VERIFY BY HUMAN',
|
|
497
|
+
'## 🔍 TO VERIFY',
|
|
498
|
+
'## TO VERIFY',
|
|
499
|
+
'## ✅ TO VERIFY',
|
|
500
|
+
'## ✅ Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG',
|
|
501
|
+
'## 📊 CROSS-COMPUTER REQUIREMENT ASSIGNMENT',
|
|
502
|
+
'## 🖥️ COMPUTER FOCUS AREA MANAGEMENT'
|
|
503
|
+
];
|
|
504
|
+
|
|
505
|
+
let verifyIndex = -1;
|
|
506
|
+
for (let i = 0; i < lines.length; i++) {
|
|
507
|
+
const line = lines[i];
|
|
508
|
+
const trimmed = line.trim();
|
|
509
|
+
|
|
510
|
+
// Check each variant more carefully
|
|
511
|
+
for (const variant of verifySectionVariants) {
|
|
512
|
+
const variantTrimmed = variant.trim();
|
|
513
|
+
// Exact match or line starts with variant
|
|
514
|
+
if (trimmed === variantTrimmed || trimmed.startsWith(variantTrimmed)) {
|
|
515
|
+
// Double-check: make sure it's NOT a VERIFIED section (without TO VERIFY)
|
|
516
|
+
if (!trimmed.includes('## 📝 VERIFIED') && !trimmed.match(/^##\s+VERIFIED$/i) &&
|
|
517
|
+
(trimmed.includes('TO VERIFY') || trimmed.includes('Verified by AI screenshot') || trimmed.includes('CROSS-COMPUTER REQUIREMENT ASSIGNMENT') || trimmed.includes('COMPUTER FOCUS AREA MANAGEMENT'))) {
|
|
518
|
+
verifyIndex = i;
|
|
584
519
|
break;
|
|
585
520
|
}
|
|
586
521
|
}
|
|
522
|
+
}
|
|
523
|
+
if (verifyIndex !== -1) break;
|
|
524
|
+
}
|
|
587
525
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
526
|
+
if (verifyIndex === -1) {
|
|
527
|
+
// Create TO VERIFY section - place it BEFORE VERIFIED section if one exists, otherwise before CHANGELOG
|
|
528
|
+
const verifiedIndex = lines.findIndex(line => {
|
|
529
|
+
const trimmed = line.trim();
|
|
530
|
+
return trimmed === '## 📝 VERIFIED' || trimmed.startsWith('## 📝 VERIFIED') ||
|
|
531
|
+
(trimmed.startsWith('##') && trimmed.includes('VERIFIED') && !trimmed.includes('TO VERIFY'));
|
|
532
|
+
});
|
|
533
|
+
const changelogIndex = lines.findIndex(line => line.includes('## CHANGELOG'));
|
|
534
|
+
const manualFeedbackIndex = lines.findIndex(line => line.trim().startsWith('## ❓'));
|
|
535
|
+
|
|
536
|
+
// Prefer: before VERIFIED > before CHANGELOG > before manual feedback > at end
|
|
537
|
+
let insertionIndex = lines.length;
|
|
538
|
+
if (verifiedIndex > 0) {
|
|
539
|
+
insertionIndex = verifiedIndex;
|
|
540
|
+
} else if (changelogIndex > 0) {
|
|
541
|
+
insertionIndex = changelogIndex;
|
|
542
|
+
} else if (manualFeedbackIndex > 0) {
|
|
543
|
+
insertionIndex = manualFeedbackIndex;
|
|
544
|
+
}
|
|
593
545
|
|
|
594
|
-
|
|
595
|
-
|
|
546
|
+
const block = [];
|
|
547
|
+
if (insertionIndex > 0 && lines[insertionIndex - 1].trim() !== '') {
|
|
548
|
+
block.push('');
|
|
549
|
+
}
|
|
550
|
+
block.push('## 🔍 TO VERIFY BY HUMAN', '### Automatic Registration and Tracking', '### User Registration', '');
|
|
551
|
+
block.push('## 📊 CROSS-COMPUTER REQUIREMENT ASSIGNMENT');
|
|
552
|
+
block.push('## 🖥️ COMPUTER FOCUS AREA MANAGEMENT');
|
|
553
|
+
lines.splice(insertionIndex, 0, ...block);
|
|
554
|
+
verifyIndex = lines.findIndex(line => {
|
|
555
|
+
const trimmed = line.trim();
|
|
556
|
+
return trimmed === '## 🔍 TO VERIFY BY HUMAN' || trimmed.startsWith('## 🔍 TO VERIFY BY HUMAN');
|
|
557
|
+
});
|
|
596
558
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
559
|
+
// Safety check: verifyIndex should be valid
|
|
560
|
+
if (verifyIndex === -1) {
|
|
561
|
+
console.error(t('auto.direct.verify.section.create.failed'));
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
601
565
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
break;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
566
|
+
// Safety check: verify we're not inserting into a VERIFIED section
|
|
567
|
+
const verifyLine = lines[verifyIndex] || '';
|
|
568
|
+
if (verifyLine.includes('## 📝 VERIFIED') || (verifyLine.trim().startsWith('##') && verifyLine.includes('VERIFIED') && !verifyLine.includes('TO VERIFY'))) {
|
|
569
|
+
console.error('ERROR: Attempted to insert into VERIFIED section instead of TO VERIFY');
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
611
572
|
|
|
612
|
-
|
|
613
|
-
|
|
573
|
+
// Remove any existing duplicate of this requirement in TO VERIFY section
|
|
574
|
+
// Find the next section header after TO VERIFY
|
|
575
|
+
let nextSectionIndex = lines.length;
|
|
576
|
+
for (let i = verifyIndex + 1; i < lines.length; i++) {
|
|
577
|
+
const trimmed = lines[i].trim();
|
|
578
|
+
if (trimmed.startsWith('##') && !trimmed.startsWith('###')) {
|
|
579
|
+
nextSectionIndex = i;
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
614
583
|
|
|
615
|
-
|
|
616
|
-
|
|
584
|
+
// Search for duplicate requirement in TO VERIFY section
|
|
585
|
+
const requirementTitle = requirementBlock[0].trim().replace(/^###\s*/, '').trim();
|
|
586
|
+
for (let i = verifyIndex + 1; i < nextSectionIndex; i++) {
|
|
587
|
+
const line = lines[i];
|
|
588
|
+
const trimmed = line.trim();
|
|
589
|
+
|
|
590
|
+
if (trimmed.startsWith('###')) {
|
|
591
|
+
const existingTitle = trimmed.replace(/^###\s*/, '').trim();
|
|
592
|
+
|
|
593
|
+
// Check if this is a duplicate (exact match or contains/contained by)
|
|
594
|
+
if (existingTitle === requirementTitle ||
|
|
595
|
+
existingTitle.includes(requirementTitle) ||
|
|
596
|
+
requirementTitle.includes(existingTitle)) {
|
|
597
|
+
|
|
598
|
+
// Find the end of this existing requirement
|
|
599
|
+
let existingEndIndex = nextSectionIndex;
|
|
600
|
+
for (let j = i + 1; j < nextSectionIndex; j++) {
|
|
601
|
+
const nextLine = lines[j].trim();
|
|
602
|
+
if (nextLine.startsWith('###') || nextLine.startsWith('##')) {
|
|
603
|
+
existingEndIndex = j;
|
|
617
604
|
break;
|
|
618
605
|
}
|
|
619
606
|
}
|
|
620
|
-
}
|
|
621
607
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
let insertIndex = verifyIndex + 1;
|
|
608
|
+
// Remove the duplicate
|
|
609
|
+
lines.splice(i, existingEndIndex - i);
|
|
625
610
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
insertIndex++;
|
|
611
|
+
// Adjust nextSectionIndex if needed
|
|
612
|
+
nextSectionIndex -= (existingEndIndex - i);
|
|
613
|
+
break;
|
|
630
614
|
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
631
617
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
618
|
+
// Insert requirement block at TOP of TO VERIFY section (right after section header)
|
|
619
|
+
// Always insert immediately after the section header with proper blank line spacing
|
|
620
|
+
let insertIndex = verifyIndex + 1;
|
|
621
|
+
|
|
622
|
+
// Ensure there's a blank line after the section header
|
|
623
|
+
if (lines[insertIndex]?.trim() !== '') {
|
|
624
|
+
lines.splice(insertIndex, 0, '');
|
|
625
|
+
insertIndex++;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Insert the requirement block with conflict resolution
|
|
629
|
+
const conflictResolution = '### Conflict Resolution: ';
|
|
630
|
+
lines.splice(insertIndex, 0, conflictResolution);
|
|
631
|
+
insertIndex++;
|
|
632
|
+
lines.splice(insertIndex, 0, ...requirementBlock);
|
|
633
|
+
|
|
634
|
+
// Ensure there's a blank line after the requirement block
|
|
635
|
+
const afterIndex = insertIndex + requirementBlock.length + 1;
|
|
636
|
+
if (afterIndex < lines.length && lines[afterIndex]?.trim() !== '') {
|
|
637
|
+
lines.splice(afterIndex, 0, '');
|
|
638
|
+
}
|
|
635
639
|
|
|
636
|
-
// Ensure there's a blank line after the requirement block
|
|
637
|
-
const afterIndex = insertIndex + requirementBlock.length + 1;
|
|
638
|
-
if (afterIndex < lines.length && lines[afterIndex]?.trim() !== '') {
|
|
639
|
-
lines.splice(afterIndex, 0, '');
|
|
640
|
-
}
|
|
641
640
|
|
|
642
641
|
// Write the file
|
|
643
642
|
await fs.writeFile(reqPath, lines.join('\n'));
|
|
@@ -829,7 +828,17 @@ async function getProviderConfig(excludeProvider = null) {
|
|
|
829
828
|
const config = await getAutoConfig();
|
|
830
829
|
const providerManager = sharedProviderManager; // Use shared instance to persist rate limit state
|
|
831
830
|
const providers = await getAllAvailableProviders();
|
|
832
|
-
const
|
|
831
|
+
const prefs = await getProviderPreferences();
|
|
832
|
+
|
|
833
|
+
// Get first ENABLED agent from provider preferences (same logic as interactive menu)
|
|
834
|
+
let firstEnabledAgent = null;
|
|
835
|
+
for (const agentId of prefs.order) {
|
|
836
|
+
if (prefs.enabled[agentId] !== false) {
|
|
837
|
+
firstEnabledAgent = agentId;
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
const savedAgent = firstEnabledAgent || config.agent || config.ide;
|
|
833
842
|
|
|
834
843
|
if (providers.length === 0) {
|
|
835
844
|
return { status: 'no_providers', providers: [] };
|
|
@@ -1933,12 +1942,9 @@ async function handleAutoStart(options) {
|
|
|
1933
1942
|
|
|
1934
1943
|
console.log(chalk.white(t('auto.repository')), chalk.cyan(repoPath));
|
|
1935
1944
|
|
|
1936
|
-
//
|
|
1937
|
-
|
|
1938
|
-
const
|
|
1939
|
-
const PROVIDER_DEFINITION_MAP = new Map(PROVIDER_DEFINITIONS.map(def => [def.id, def]));
|
|
1940
|
-
|
|
1941
|
-
const { effectiveAgent } = await getEffectiveAgent(options, PROVIDER_DEFINITIONS, PROVIDER_DEFINITION_MAP);
|
|
1945
|
+
// Use the agent that was already determined by provider preferences in interactive.js
|
|
1946
|
+
// No need to call getEffectiveAgent since we already have the correct agent
|
|
1947
|
+
const effectiveAgent = options.ide;
|
|
1942
1948
|
|
|
1943
1949
|
// Get provider configuration for the selected agent
|
|
1944
1950
|
let providerConfig = await acquireProviderConfig(effectiveAgent);
|
package/src/commands/auto.js
CHANGED
|
@@ -1710,7 +1710,8 @@ Please implement this requirement now.`;
|
|
|
1710
1710
|
|
|
1711
1711
|
// Offer to open browser
|
|
1712
1712
|
const inquirer = require('inquirer');
|
|
1713
|
-
const {
|
|
1713
|
+
const { promptWithDefaultsOnce } = require('../utils/prompt-helper');
|
|
1714
|
+
const { openBrowser } = await promptWithDefaultsOnce([{
|
|
1714
1715
|
type: 'confirm',
|
|
1715
1716
|
name: 'openBrowser',
|
|
1716
1717
|
message: 'Open Groq Console in your browser?',
|
|
@@ -1806,7 +1807,8 @@ Please implement this requirement now.`;
|
|
|
1806
1807
|
|
|
1807
1808
|
if (profileContent.includes('GROQ_API_KEY')) {
|
|
1808
1809
|
console.log(chalk.yellow('⚠ GROQ_API_KEY already exists in your shell profile'));
|
|
1809
|
-
const {
|
|
1810
|
+
const { promptWithDefaultsOnce } = require('../utils/prompt-helper');
|
|
1811
|
+
const { replaceKey } = await promptWithDefaultsOnce([{
|
|
1810
1812
|
type: 'confirm',
|
|
1811
1813
|
name: 'replaceKey',
|
|
1812
1814
|
message: 'Replace existing key with new one?',
|
|
@@ -3391,7 +3393,8 @@ Example BAD questions (never ask these):
|
|
|
3391
3393
|
console.log(chalk.gray(' 2. Install the application'));
|
|
3392
3394
|
console.log(chalk.gray(' 3. Run this command again\n'));
|
|
3393
3395
|
|
|
3394
|
-
const {
|
|
3396
|
+
const { promptWithDefaultsOnce } = require('../utils/prompt-helper');
|
|
3397
|
+
const { continueAnyway } = await promptWithDefaultsOnce([{
|
|
3395
3398
|
type: 'confirm',
|
|
3396
3399
|
name: 'continueAnyway',
|
|
3397
3400
|
message: 'Did you install Ollama and want to continue?',
|
|
@@ -86,6 +86,11 @@ async function listComputers(options = {}) {
|
|
|
86
86
|
|
|
87
87
|
} catch (error) {
|
|
88
88
|
console.error(chalk.red(`\n✗ ${t('computers.fetch.failed')}`), error.message);
|
|
89
|
+
await errorReporter.reportError(error, {
|
|
90
|
+
command: 'listComputers',
|
|
91
|
+
focusArea,
|
|
92
|
+
status
|
|
93
|
+
});
|
|
89
94
|
throw error;
|
|
90
95
|
} finally {
|
|
91
96
|
syncEngine.stop();
|
|
@@ -179,6 +184,10 @@ async function registerComputer(focusArea) {
|
|
|
179
184
|
|
|
180
185
|
} catch (error) {
|
|
181
186
|
console.error(chalk.red(`\n✗ ${t('computers.register.failed')}`), error.message);
|
|
187
|
+
await errorReporter.reportError(error, {
|
|
188
|
+
command: 'registerComputer',
|
|
189
|
+
focusArea
|
|
190
|
+
});
|
|
182
191
|
throw error;
|
|
183
192
|
} finally {
|
|
184
193
|
syncEngine.stop();
|