vibecodingmachine-cli 2025.12.1-534 ā 2025.12.6-1702
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 +92 -4
- package/package.json +5 -2
- package/repro_open.js +13 -0
- package/scripts/postinstall.js +80 -0
- package/src/commands/auto-direct.js +401 -97
- package/src/commands/auto.js +343 -115
- package/src/commands/computers.js +306 -0
- package/src/commands/requirements-remote.js +304 -0
- package/src/commands/requirements.js +204 -13
- package/src/commands/sync.js +280 -0
- package/src/utils/asset-cleanup.js +61 -0
- package/src/utils/auth.js +84 -7
- package/src/utils/auto-mode-simple-ui.js +2 -22
- package/src/utils/first-run.js +293 -0
- package/src/utils/interactive.js +1027 -217
- package/src/utils/kiro-installer.js +146 -0
- package/src/utils/provider-registry.js +8 -0
- package/src/utils/status-card.js +2 -1
package/src/commands/auto.js
CHANGED
|
@@ -421,60 +421,229 @@ async function moveCompletedRequirement(repoPath, completedRequirement) {
|
|
|
421
421
|
const content = await fs.readFile(reqPath, 'utf8');
|
|
422
422
|
const lines = content.split('\n');
|
|
423
423
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
424
|
+
// First, check if requirement is already in TO VERIFY section
|
|
425
|
+
const verifySectionVariants = [
|
|
426
|
+
'## š TO VERIFY BY HUMAN',
|
|
427
|
+
'## š TO VERIFY',
|
|
428
|
+
'## TO VERIFY',
|
|
429
|
+
'## ā
TO VERIFY',
|
|
430
|
+
'## ā
Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG'
|
|
431
|
+
];
|
|
432
|
+
|
|
433
|
+
let inVerifySection = false;
|
|
434
|
+
let alreadyInVerify = false;
|
|
435
|
+
const normalizedCompleted = completedRequirement.trim();
|
|
436
|
+
const snippet = normalizedCompleted.substring(0, 80);
|
|
429
437
|
|
|
430
|
-
for (
|
|
438
|
+
for (let i = 0; i < lines.length; i++) {
|
|
439
|
+
const line = lines[i];
|
|
431
440
|
const trimmed = line.trim();
|
|
432
441
|
|
|
433
|
-
//
|
|
442
|
+
// Check if we're entering TO VERIFY section
|
|
443
|
+
if (trimmed.startsWith('##')) {
|
|
444
|
+
inVerifySection = verifySectionVariants.some(variant => {
|
|
445
|
+
const variantTrimmed = variant.trim();
|
|
446
|
+
return trimmed === variantTrimmed || trimmed.startsWith(variantTrimmed);
|
|
447
|
+
}) && !trimmed.includes('## š VERIFIED') && !trimmed.match(/^##\s+VERIFIED$/i);
|
|
448
|
+
|
|
449
|
+
if (inVerifySection && trimmed.includes('TO VERIFY') || trimmed.includes('Verified by AI screenshot')) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Check if we're leaving TO VERIFY section
|
|
455
|
+
if (inVerifySection && trimmed.startsWith('##') && !trimmed.startsWith('###')) {
|
|
456
|
+
const isVerifyHeader = verifySectionVariants.some(variant => {
|
|
457
|
+
const variantTrimmed = variant.trim();
|
|
458
|
+
return trimmed === variantTrimmed || trimmed.startsWith(variantTrimmed);
|
|
459
|
+
});
|
|
460
|
+
if (!isVerifyHeader) {
|
|
461
|
+
inVerifySection = false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Check if requirement is already in TO VERIFY
|
|
466
|
+
if (inVerifySection && trimmed.startsWith('###')) {
|
|
467
|
+
const title = trimmed.replace(/^###\s*/, '').trim();
|
|
468
|
+
if (title) {
|
|
469
|
+
const normalizedTitle = title.trim();
|
|
470
|
+
if (normalizedTitle === normalizedCompleted ||
|
|
471
|
+
normalizedTitle.includes(normalizedCompleted) ||
|
|
472
|
+
normalizedCompleted.includes(normalizedTitle) ||
|
|
473
|
+
normalizedTitle.includes(snippet) ||
|
|
474
|
+
snippet.includes(normalizedTitle.substring(0, 80))) {
|
|
475
|
+
alreadyInVerify = true;
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (alreadyInVerify) {
|
|
483
|
+
return { success: true }; // Already in TO VERIFY, nothing to do
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Find the requirement by its title (in ### header format)
|
|
487
|
+
// Normalize the completed requirement text for matching
|
|
488
|
+
let requirementStartIndex = -1;
|
|
489
|
+
let requirementEndIndex = -1;
|
|
490
|
+
|
|
491
|
+
// Try to find the requirement in TODO section first
|
|
492
|
+
let inTodoSection = false;
|
|
493
|
+
for (let i = 0; i < lines.length; i++) {
|
|
494
|
+
const line = lines[i];
|
|
495
|
+
const trimmed = line.trim();
|
|
496
|
+
|
|
497
|
+
// Check if we're entering TODO section
|
|
434
498
|
if (trimmed.startsWith('##') && trimmed.includes('Requirements not yet completed')) {
|
|
435
499
|
inTodoSection = true;
|
|
436
|
-
inVerifiedSection = false;
|
|
437
|
-
updatedLines.push(line);
|
|
438
500
|
continue;
|
|
439
501
|
}
|
|
440
502
|
|
|
441
|
-
//
|
|
442
|
-
if (trimmed.startsWith('##') &&
|
|
503
|
+
// Check if we're leaving TODO section
|
|
504
|
+
if (inTodoSection && trimmed.startsWith('##') && !trimmed.startsWith('###') && !trimmed.includes('Requirements not yet completed')) {
|
|
443
505
|
inTodoSection = false;
|
|
444
|
-
|
|
445
|
-
updatedLines.push(line);
|
|
506
|
+
}
|
|
446
507
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
508
|
+
// Only look for requirements in TODO section
|
|
509
|
+
if (inTodoSection && trimmed.startsWith('###')) {
|
|
510
|
+
const title = trimmed.replace(/^###\s*/, '').trim();
|
|
511
|
+
if (title) {
|
|
512
|
+
// Try multiple matching strategies
|
|
513
|
+
const normalizedTitle = title.trim();
|
|
514
|
+
const titleSnippet = normalizedTitle.substring(0, 80);
|
|
515
|
+
|
|
516
|
+
// Exact match
|
|
517
|
+
if (normalizedTitle === normalizedCompleted) {
|
|
518
|
+
requirementStartIndex = i;
|
|
519
|
+
}
|
|
520
|
+
// Check if either contains the other (for partial matches)
|
|
521
|
+
else if (normalizedTitle.includes(normalizedCompleted) || normalizedCompleted.includes(normalizedTitle)) {
|
|
522
|
+
requirementStartIndex = i;
|
|
523
|
+
}
|
|
524
|
+
// Check snippet matches
|
|
525
|
+
else if (normalizedTitle.includes(snippet) || snippet.includes(titleSnippet)) {
|
|
526
|
+
requirementStartIndex = i;
|
|
527
|
+
}
|
|
528
|
+
// Check if they start the same (for REGRESSION: prefix issues)
|
|
529
|
+
else if (normalizedTitle.replace(/^REGRESSION:\s*/i, '') === normalizedCompleted.replace(/^REGRESSION:\s*/i, '') ||
|
|
530
|
+
normalizedTitle.replace(/^REGRESSION:\s*/i, '').includes(snippet.replace(/^REGRESSION:\s*/i, '')) ||
|
|
531
|
+
snippet.replace(/^REGRESSION:\s*/i, '').includes(normalizedTitle.replace(/^REGRESSION:\s*/i, ''))) {
|
|
532
|
+
requirementStartIndex = i;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (requirementStartIndex !== -1) {
|
|
536
|
+
// Find the end of this requirement (next ### or ## header)
|
|
537
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
538
|
+
const nextLine = lines[j].trim();
|
|
539
|
+
if (nextLine.startsWith('###') || (nextLine.startsWith('##') && !nextLine.startsWith('###'))) {
|
|
540
|
+
requirementEndIndex = j;
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (requirementEndIndex === -1) {
|
|
545
|
+
requirementEndIndex = lines.length;
|
|
546
|
+
}
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
452
549
|
}
|
|
453
|
-
continue;
|
|
454
550
|
}
|
|
551
|
+
}
|
|
455
552
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
inVerifiedSection = false;
|
|
460
|
-
}
|
|
553
|
+
if (requirementStartIndex === -1) {
|
|
554
|
+
return { success: false, error: `Could not find requirement "${completedRequirement.substring(0, 60)}..." in TODO section` };
|
|
555
|
+
}
|
|
461
556
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
557
|
+
// Extract the entire requirement block
|
|
558
|
+
const requirementBlock = lines.slice(requirementStartIndex, requirementEndIndex);
|
|
559
|
+
|
|
560
|
+
// Remove the requirement from its current location
|
|
561
|
+
lines.splice(requirementStartIndex, requirementEndIndex - requirementStartIndex);
|
|
562
|
+
|
|
563
|
+
// Find or create TO VERIFY BY HUMAN section (reuse the variants we defined earlier)
|
|
564
|
+
let verifyIndex = -1;
|
|
565
|
+
for (let i = 0; i < lines.length; i++) {
|
|
566
|
+
const line = lines[i];
|
|
567
|
+
const trimmed = line.trim();
|
|
568
|
+
|
|
569
|
+
// Check each variant more carefully
|
|
570
|
+
for (const variant of verifySectionVariants) {
|
|
571
|
+
const variantTrimmed = variant.trim();
|
|
572
|
+
// Exact match or line starts with variant
|
|
573
|
+
if (trimmed === variantTrimmed || trimmed.startsWith(variantTrimmed)) {
|
|
574
|
+
// Double-check: make sure it's NOT a VERIFIED section (without TO VERIFY)
|
|
575
|
+
if (!trimmed.includes('## š VERIFIED') && !trimmed.match(/^##\s+VERIFIED$/i) &&
|
|
576
|
+
(trimmed.includes('TO VERIFY') || trimmed.includes('Verified by AI screenshot'))) {
|
|
577
|
+
verifyIndex = i;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
471
580
|
}
|
|
472
581
|
}
|
|
582
|
+
if (verifyIndex !== -1) break;
|
|
583
|
+
}
|
|
473
584
|
|
|
474
|
-
|
|
585
|
+
if (verifyIndex === -1) {
|
|
586
|
+
// Create TO VERIFY section - place it BEFORE VERIFIED section if one exists, otherwise before CHANGELOG
|
|
587
|
+
const verifiedIndex = lines.findIndex(line => {
|
|
588
|
+
const trimmed = line.trim();
|
|
589
|
+
return trimmed === '## š VERIFIED' || trimmed.startsWith('## š VERIFIED') ||
|
|
590
|
+
(trimmed.startsWith('##') && trimmed.includes('VERIFIED') && !trimmed.includes('TO VERIFY'));
|
|
591
|
+
});
|
|
592
|
+
const changelogIndex = lines.findIndex(line => line.includes('## CHANGELOG'));
|
|
593
|
+
const manualFeedbackIndex = lines.findIndex(line => line.trim().startsWith('## ā'));
|
|
594
|
+
|
|
595
|
+
// Prefer: before VERIFIED > before CHANGELOG > before manual feedback > at end
|
|
596
|
+
let insertionIndex = lines.length;
|
|
597
|
+
if (verifiedIndex > 0) {
|
|
598
|
+
insertionIndex = verifiedIndex;
|
|
599
|
+
} else if (changelogIndex > 0) {
|
|
600
|
+
insertionIndex = changelogIndex;
|
|
601
|
+
} else if (manualFeedbackIndex > 0) {
|
|
602
|
+
insertionIndex = manualFeedbackIndex;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const block = [];
|
|
606
|
+
if (insertionIndex > 0 && lines[insertionIndex - 1].trim() !== '') {
|
|
607
|
+
block.push('');
|
|
608
|
+
}
|
|
609
|
+
block.push('## š TO VERIFY BY HUMAN', '');
|
|
610
|
+
lines.splice(insertionIndex, 0, ...block);
|
|
611
|
+
verifyIndex = lines.findIndex(line => {
|
|
612
|
+
const trimmed = line.trim();
|
|
613
|
+
return trimmed === '## š TO VERIFY BY HUMAN' || trimmed.startsWith('## š TO VERIFY BY HUMAN');
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
if (verifyIndex === -1) {
|
|
617
|
+
return { success: false, error: 'Failed to create TO VERIFY BY HUMAN section' };
|
|
618
|
+
}
|
|
475
619
|
}
|
|
476
620
|
|
|
477
|
-
|
|
621
|
+
// Safety check: verify we're not inserting into a VERIFIED section
|
|
622
|
+
const verifyLine = lines[verifyIndex] || '';
|
|
623
|
+
if (verifyLine.includes('## š VERIFIED') || (verifyLine.trim().startsWith('##') && verifyLine.includes('VERIFIED') && !verifyLine.includes('TO VERIFY'))) {
|
|
624
|
+
return { success: false, error: 'Attempted to insert into VERIFIED section instead of TO VERIFY' };
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Insert requirement block at TOP of TO VERIFY section (right after section header)
|
|
628
|
+
let insertIndex = verifyIndex + 1;
|
|
629
|
+
|
|
630
|
+
// Ensure there's a blank line after the section header
|
|
631
|
+
if (lines[insertIndex]?.trim() !== '') {
|
|
632
|
+
lines.splice(insertIndex, 0, '');
|
|
633
|
+
insertIndex++;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Insert the requirement block
|
|
637
|
+
lines.splice(insertIndex, 0, ...requirementBlock);
|
|
638
|
+
|
|
639
|
+
// Ensure there's a blank line after the requirement block
|
|
640
|
+
const afterIndex = insertIndex + requirementBlock.length;
|
|
641
|
+
if (afterIndex < lines.length && lines[afterIndex]?.trim() !== '') {
|
|
642
|
+
lines.splice(afterIndex, 0, '');
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Write the file
|
|
646
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
478
647
|
return { success: true };
|
|
479
648
|
} catch (error) {
|
|
480
649
|
return { success: false, error: error.message };
|
|
@@ -499,6 +668,14 @@ function getTimestamp() {
|
|
|
499
668
|
}
|
|
500
669
|
|
|
501
670
|
async function start(options) {
|
|
671
|
+
// First Run Check
|
|
672
|
+
try {
|
|
673
|
+
const { checkFirstRun } = require('../utils/first-run');
|
|
674
|
+
await checkFirstRun();
|
|
675
|
+
} catch (e) {
|
|
676
|
+
// Continue if check fails
|
|
677
|
+
}
|
|
678
|
+
|
|
502
679
|
// STRICT AUTH CHECK
|
|
503
680
|
const auth = require('../utils/auth');
|
|
504
681
|
const isAuth = await auth.isAuthenticated();
|
|
@@ -888,20 +1065,29 @@ async function start(options) {
|
|
|
888
1065
|
let status = 'PREPARE';
|
|
889
1066
|
let inTodoSection = false;
|
|
890
1067
|
|
|
891
|
-
for (
|
|
892
|
-
|
|
1068
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1069
|
+
const line = lines[i].trim();
|
|
1070
|
+
|
|
1071
|
+
// Check if we're in the TODO section
|
|
1072
|
+
if (line.includes('## ā³ Requirements not yet completed') ||
|
|
1073
|
+
(line.includes('Requirements not yet completed') && line.startsWith('##'))) {
|
|
893
1074
|
inTodoSection = true;
|
|
894
1075
|
continue;
|
|
895
1076
|
}
|
|
896
1077
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
status = 'PREPARE';
|
|
1078
|
+
// If we hit another section header, stop looking
|
|
1079
|
+
if (inTodoSection && line.startsWith('##') && !line.startsWith('###')) {
|
|
900
1080
|
break;
|
|
901
1081
|
}
|
|
902
1082
|
|
|
903
|
-
|
|
904
|
-
|
|
1083
|
+
// If we're in TODO section and find a requirement header (###)
|
|
1084
|
+
if (inTodoSection && line.startsWith('###')) {
|
|
1085
|
+
title = line.replace(/^###\s*/, '').trim();
|
|
1086
|
+
// Skip empty titles
|
|
1087
|
+
if (title && title.length > 0) {
|
|
1088
|
+
status = 'PREPARE';
|
|
1089
|
+
break;
|
|
1090
|
+
}
|
|
905
1091
|
}
|
|
906
1092
|
}
|
|
907
1093
|
|
|
@@ -1789,25 +1975,30 @@ Please implement this requirement now.`;
|
|
|
1789
1975
|
let status = 'PREPARE';
|
|
1790
1976
|
let inTodoSection = false;
|
|
1791
1977
|
|
|
1792
|
-
// Read from TODO list
|
|
1793
|
-
for (
|
|
1794
|
-
|
|
1795
|
-
|
|
1978
|
+
// Read from TODO list - requirements are in ### format
|
|
1979
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1980
|
+
const line = lines[i].trim();
|
|
1981
|
+
|
|
1982
|
+
// Check if we're in the TODO section
|
|
1983
|
+
if (line.includes('## ā³ Requirements not yet completed') ||
|
|
1984
|
+
(line.includes('Requirements not yet completed') && line.startsWith('##'))) {
|
|
1796
1985
|
inTodoSection = true;
|
|
1797
1986
|
continue;
|
|
1798
1987
|
}
|
|
1799
1988
|
|
|
1800
|
-
//
|
|
1801
|
-
if (inTodoSection && line.
|
|
1802
|
-
title = line.substring(2).trim();
|
|
1803
|
-
// Always start at PREPARE for TODO items
|
|
1804
|
-
status = 'PREPARE';
|
|
1989
|
+
// If we hit another section header, stop looking
|
|
1990
|
+
if (inTodoSection && line.startsWith('##') && !line.startsWith('###')) {
|
|
1805
1991
|
break;
|
|
1806
1992
|
}
|
|
1807
1993
|
|
|
1808
|
-
//
|
|
1809
|
-
if (inTodoSection && line.
|
|
1810
|
-
|
|
1994
|
+
// If we're in TODO section and find a requirement header (###)
|
|
1995
|
+
if (inTodoSection && line.startsWith('###')) {
|
|
1996
|
+
title = line.replace(/^###\s*/, '').trim();
|
|
1997
|
+
// Skip empty titles
|
|
1998
|
+
if (title && title.length > 0) {
|
|
1999
|
+
status = 'PREPARE';
|
|
2000
|
+
break;
|
|
2001
|
+
}
|
|
1811
2002
|
}
|
|
1812
2003
|
}
|
|
1813
2004
|
|
|
@@ -2646,11 +2837,43 @@ NOW: Search for and make the minimal code changes needed.`;
|
|
|
2646
2837
|
} else {
|
|
2647
2838
|
console.log(chalk.yellow(`\nā ļø Aider did not complete implementation.\n`));
|
|
2648
2839
|
|
|
2649
|
-
// Check if
|
|
2650
|
-
console.log(chalk.cyan(`\n[${getTimestamp()}] š
|
|
2840
|
+
// Check if any code changes were made during implementation attempt
|
|
2841
|
+
console.log(chalk.cyan(`\n[${getTimestamp()}] š Checking for code changes...\n`));
|
|
2651
2842
|
|
|
2652
|
-
|
|
2653
|
-
|
|
2843
|
+
let hasCodeChanges = false;
|
|
2844
|
+
try {
|
|
2845
|
+
const { execSync } = require('child_process');
|
|
2846
|
+
const gitStatus = execSync('git status --porcelain', { cwd: repoPath, encoding: 'utf8' });
|
|
2847
|
+
hasCodeChanges = gitStatus.trim().length > 0;
|
|
2848
|
+
|
|
2849
|
+
if (hasCodeChanges) {
|
|
2850
|
+
console.log(chalk.cyan(`ā Code changes detected. Will move to TO VERIFY.\n`));
|
|
2851
|
+
} else {
|
|
2852
|
+
console.log(chalk.gray(`No code changes detected.\n`));
|
|
2853
|
+
}
|
|
2854
|
+
} catch (err) {
|
|
2855
|
+
console.log(chalk.gray(`Could not check git status: ${err.message}\n`));
|
|
2856
|
+
}
|
|
2857
|
+
|
|
2858
|
+
// If code changes were made, move to TO VERIFY (even if incomplete)
|
|
2859
|
+
if (hasCodeChanges) {
|
|
2860
|
+
console.log(chalk.cyan(`\n[${getTimestamp()}] Moving requirement to TO VERIFY (code changes were made): "${currentTitle.substring(0, 60)}..."`));
|
|
2861
|
+
const moveResult = await moveCompletedRequirement(repoPath, currentTitle);
|
|
2862
|
+
|
|
2863
|
+
if (moveResult.success) {
|
|
2864
|
+
console.log(chalk.green(`\nā Successfully moved requirement to TO VERIFY section (code changes made, needs human verification)`));
|
|
2865
|
+
requirementsCompleted++; // Count as "completed" so we move to next requirement
|
|
2866
|
+
} else {
|
|
2867
|
+
console.log(chalk.red(`\nā Error moving requirement: ${moveResult.error}`));
|
|
2868
|
+
console.log(chalk.yellow(` Requirement title: "${currentTitle}"`));
|
|
2869
|
+
console.log(chalk.gray(' Requirement remains in TODO for retry.\n'));
|
|
2870
|
+
}
|
|
2871
|
+
} else {
|
|
2872
|
+
// No code changes made - check if requirement might be too vague by having Aider search the codebase first
|
|
2873
|
+
console.log(chalk.cyan(`\n[${getTimestamp()}] š Searching codebase for relevant code...\n`));
|
|
2874
|
+
|
|
2875
|
+
// STEP 1: Have Aider search the codebase for relevant files
|
|
2876
|
+
const searchPrompt = `Search the codebase to understand this requirement:
|
|
2654
2877
|
|
|
2655
2878
|
"${currentTitle}"
|
|
2656
2879
|
|
|
@@ -2659,30 +2882,30 @@ Focus on: What files/functions are related? What patterns exist?
|
|
|
2659
2882
|
|
|
2660
2883
|
If you cannot find any relevant code, say "NO RELEVANT CODE FOUND".`;
|
|
2661
2884
|
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2885
|
+
const searchResult = await aiderManager.sendText(
|
|
2886
|
+
searchPrompt,
|
|
2887
|
+
repoPath,
|
|
2888
|
+
provider,
|
|
2889
|
+
modelName,
|
|
2890
|
+
null,
|
|
2891
|
+
[], // No files - let Aider search
|
|
2892
|
+
(output) => {
|
|
2893
|
+
// Show search progress
|
|
2894
|
+
if (output.includes('Searching') || output.includes('Found')) {
|
|
2895
|
+
process.stdout.write(chalk.gray(output));
|
|
2896
|
+
}
|
|
2897
|
+
},
|
|
2898
|
+
() => { },
|
|
2899
|
+
90000 // 1.5 minute timeout for search
|
|
2900
|
+
);
|
|
2678
2901
|
|
|
2679
|
-
|
|
2680
|
-
|
|
2902
|
+
const searchFindings = searchResult.output || 'Search completed but no findings reported.';
|
|
2903
|
+
console.log(chalk.gray(`\nFindings: ${searchFindings}\n`));
|
|
2681
2904
|
|
|
2682
|
-
|
|
2683
|
-
|
|
2905
|
+
// STEP 2: Check if requirement is vague and generate questions focused on USER INTENT
|
|
2906
|
+
console.log(chalk.cyan(`\n[${getTimestamp()}] š¤ Analyzing if clarification is needed...\n`));
|
|
2684
2907
|
|
|
2685
|
-
|
|
2908
|
+
const vagueCheckPrompt = `Based on these findings from the codebase:
|
|
2686
2909
|
"${searchFindings}"
|
|
2687
2910
|
|
|
2688
2911
|
Analyze if this requirement needs clarification:
|
|
@@ -2709,45 +2932,46 @@ Example BAD questions (never ask these):
|
|
|
2709
2932
|
- What file contains the confirmation prompt? (You should search for this yourself)
|
|
2710
2933
|
- Which component needs to be modified? (You should find this yourself)`;
|
|
2711
2934
|
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2935
|
+
const vagueCheckResult = await aiderManager.sendText(
|
|
2936
|
+
vagueCheckPrompt,
|
|
2937
|
+
repoPath,
|
|
2938
|
+
provider,
|
|
2939
|
+
modelName,
|
|
2940
|
+
null,
|
|
2941
|
+
[], // No files needed for vague check
|
|
2942
|
+
() => { }, // Silent mode
|
|
2943
|
+
() => { },
|
|
2944
|
+
60000 // 1 minute timeout
|
|
2945
|
+
);
|
|
2723
2946
|
|
|
2724
|
-
|
|
2725
|
-
|
|
2947
|
+
const vagueCheckOutput = vagueCheckResult.output || '';
|
|
2948
|
+
const isVague = vagueCheckOutput.toUpperCase().includes('REQUIREMENT NEEDS CLARIFICATION');
|
|
2726
2949
|
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2950
|
+
if (isVague) {
|
|
2951
|
+
// Extract clarifying questions from output
|
|
2952
|
+
const questionMatch = vagueCheckOutput.match(/\d+\.\s*(.+)/g);
|
|
2953
|
+
const questions = questionMatch ? questionMatch.map(q => q.trim()).join('\n') :
|
|
2954
|
+
'1. What is the desired behavior for this feature?\n2. Should this apply to all cases or specific scenarios?';
|
|
2732
2955
|
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2956
|
+
console.log(chalk.yellow(`\nā Requirement flagged as TOO VAGUE (and no code changes made). Moving to "Requirements needing manual feedback" section.\n`));
|
|
2957
|
+
console.log(chalk.gray('AI Findings:'));
|
|
2958
|
+
console.log(chalk.white(searchFindings));
|
|
2959
|
+
console.log(chalk.gray('\nClarifying questions:'));
|
|
2960
|
+
console.log(chalk.white(questions));
|
|
2738
2961
|
|
|
2739
|
-
|
|
2740
|
-
|
|
2962
|
+
// Move requirement to "Requirements needing manual feedback" section with findings
|
|
2963
|
+
const moveToFeedbackResult = await moveRequirementToFeedback(repoPath, currentTitle, questions, searchFindings);
|
|
2741
2964
|
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2965
|
+
if (moveToFeedbackResult.success) {
|
|
2966
|
+
console.log(chalk.green(`\nā Requirement moved to feedback section. Please provide clarification.\n`));
|
|
2967
|
+
requirementsCompleted++; // Count as "completed" so we move to next requirement
|
|
2968
|
+
} else {
|
|
2969
|
+
console.log(chalk.yellow(`\nā ļø Could not move requirement: ${moveToFeedbackResult.error}\n`));
|
|
2970
|
+
console.log(chalk.gray(' Requirement remains in TODO for retry.\n'));
|
|
2971
|
+
}
|
|
2745
2972
|
} else {
|
|
2746
|
-
console.log(chalk.
|
|
2747
|
-
console.log(chalk.gray(' Requirement remains in TODO for retry.\n'));
|
|
2973
|
+
console.log(chalk.cyan(`\nā Requirement appears clear. Will retry on next run.\n`));
|
|
2748
2974
|
}
|
|
2749
|
-
} else {
|
|
2750
|
-
console.log(chalk.cyan(`\nā Requirement appears clear. Will retry on next run.\n`));
|
|
2751
2975
|
}
|
|
2752
2976
|
}
|
|
2753
2977
|
|
|
@@ -2766,16 +2990,18 @@ Example BAD questions (never ask these):
|
|
|
2766
2990
|
console.log(chalk.green('\nā
Requirement marked as DONE and verified complete!'));
|
|
2767
2991
|
|
|
2768
2992
|
// Move completed requirement to TO VERIFY section (for human verification)
|
|
2993
|
+
console.log(chalk.cyan(`\n[${getTimestamp()}] Moving requirement to TO VERIFY: "${currentTitle.substring(0, 60)}..."`));
|
|
2769
2994
|
const moveResult = await moveCompletedRequirement(repoPath, currentTitle);
|
|
2770
2995
|
|
|
2771
2996
|
if (!moveResult.success) {
|
|
2772
|
-
console.log(chalk.
|
|
2997
|
+
console.log(chalk.red(`\nā Error moving requirement: ${moveResult.error}`));
|
|
2998
|
+
console.log(chalk.yellow(` Requirement title: "${currentTitle}"`));
|
|
2773
2999
|
console.log(' Auto mode stopping.');
|
|
2774
3000
|
exitReason = 'error';
|
|
2775
3001
|
break;
|
|
2776
3002
|
}
|
|
2777
3003
|
|
|
2778
|
-
console.log(chalk.green(`\nā
|
|
3004
|
+
console.log(chalk.green(`\nā Successfully moved requirement to TO VERIFY section (awaiting human verification)`));
|
|
2779
3005
|
|
|
2780
3006
|
// Increment requirements completed counter
|
|
2781
3007
|
requirementsCompleted++;
|
|
@@ -2855,16 +3081,18 @@ Example BAD questions (never ask these):
|
|
|
2855
3081
|
console.log(chalk.gray(' Marking as complete and moving to next requirement...'));
|
|
2856
3082
|
|
|
2857
3083
|
// Move completed requirement to TO VERIFY section (for human verification)
|
|
3084
|
+
console.log(chalk.cyan(`\n[${getTimestamp()}] Moving requirement to TO VERIFY: "${currentTitle.substring(0, 60)}..."`));
|
|
2858
3085
|
const moveResult = await moveCompletedRequirement(repoPath, currentTitle);
|
|
2859
3086
|
|
|
2860
3087
|
if (!moveResult.success) {
|
|
2861
|
-
console.log(chalk.
|
|
3088
|
+
console.log(chalk.red(`\nā Error moving requirement: ${moveResult.error}`));
|
|
3089
|
+
console.log(chalk.yellow(` Requirement title: "${currentTitle}"`));
|
|
2862
3090
|
console.log(' Auto mode stopping.');
|
|
2863
3091
|
exitReason = 'error';
|
|
2864
3092
|
break;
|
|
2865
3093
|
}
|
|
2866
3094
|
|
|
2867
|
-
console.log(chalk.green(`\nā
|
|
3095
|
+
console.log(chalk.green(`\nā Successfully moved requirement to TO VERIFY section (awaiting human verification)`));
|
|
2868
3096
|
|
|
2869
3097
|
// Increment requirements completed counter
|
|
2870
3098
|
requirementsCompleted++;
|