vibecodingmachine-cli 2026.2.20-438 → 2026.2.26-1739
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/auth/auth-compliance.js +126 -0
- package/bin/cli-program.js +104 -0
- package/bin/cli-setup.js +52 -0
- package/bin/commands/agent-commands.js +310 -0
- package/bin/commands/auto-commands.js +70 -0
- package/bin/commands/command-aliases.js +118 -0
- package/bin/commands/repo-commands.js +39 -0
- package/bin/commands/rui-commands.js +152 -0
- package/bin/config/cli-config.js +394 -0
- package/bin/init/environment-setup.js +84 -0
- package/bin/update/update-checker.js +126 -0
- package/bin/vibecodingmachine-new.js +50 -0
- package/bin/vibecodingmachine.js +29 -663
- package/package.json +8 -2
- package/src/commands/agents/add.js +277 -0
- package/src/commands/agents/check.js +380 -0
- package/src/commands/agents/list.js +471 -0
- package/src/commands/agents/remove.js +351 -0
- package/src/commands/analyze-file-sizes.js +428 -0
- package/src/commands/auto-direct/code-processor.js +282 -0
- package/src/commands/auto-direct/file-scanner.js +266 -0
- package/src/commands/auto-direct/provider-config.js +178 -0
- package/src/commands/auto-direct/provider-manager.js +219 -0
- package/src/commands/auto-direct/requirement-manager.js +172 -0
- package/src/commands/auto-direct/status-display.js +91 -0
- package/src/commands/auto-direct/utils.js +106 -0
- package/src/commands/auto-direct.js +875 -488
- package/src/commands/auto-execution.js +342 -0
- package/src/commands/auto-provider-management.js +102 -0
- package/src/commands/auto-requirement-management.js +161 -0
- package/src/commands/auto-status-helpers.js +141 -0
- package/src/commands/auto.js +105 -5155
- package/src/commands/check-compliance.js +536 -0
- package/src/commands/continuous-scan.js +119 -0
- package/src/commands/ide.js +16 -4
- package/src/commands/refactor-file.js +486 -0
- package/src/commands/requirements.js +301 -2
- package/src/commands/timeout.js +290 -0
- package/src/trui/TruiInterface.js +108 -0
- package/src/trui/agents/AgentInterface.js +580 -0
- package/src/utils/antigravity-installer.js +60 -6
- package/src/utils/clarification-actions.js +290 -0
- package/src/utils/config.js +123 -2
- package/src/utils/first-run.js +5 -5
- package/src/utils/ide-handlers.js +212 -0
- package/src/utils/interactive/clarification-actions.js +348 -0
- package/src/utils/interactive/core-ui.js +265 -0
- package/src/utils/interactive/file-backup.js +237 -0
- package/src/utils/interactive/file-import-export.js +305 -0
- package/src/utils/interactive/file-operations.js +49 -0
- package/src/utils/interactive/file-validation.js +276 -0
- package/src/utils/interactive/interactive-prompts.js +480 -0
- package/src/utils/interactive/requirement-actions.js +127 -0
- package/src/utils/interactive/requirement-crud.js +356 -0
- package/src/utils/interactive/requirements-navigation.js +286 -0
- package/src/utils/interactive.js +390 -3459
- package/src/utils/provider-checker/agent-checker.js +250 -0
- package/src/utils/provider-checker/agent-runner.js +450 -0
- package/src/utils/provider-checker/cli-installer.js +123 -0
- package/src/utils/provider-checker/cli-utils.js +15 -0
- package/src/utils/provider-checker/format-utils.js +32 -0
- package/src/utils/provider-checker/ide-manager.js +72 -0
- package/src/utils/provider-checker/ide-utils.js +71 -0
- package/src/utils/provider-checker/node-detector.js +56 -0
- package/src/utils/provider-checker/node-utils.js +61 -0
- package/src/utils/provider-checker/process-spawn.js +22 -0
- package/src/utils/provider-checker/process-utils.js +37 -0
- package/src/utils/provider-checker/provider-validator.js +160 -0
- package/src/utils/provider-checker/quota-checker.js +54 -0
- package/src/utils/provider-checker/quota-detector.js +44 -0
- package/src/utils/provider-checker/requirements-manager.js +94 -0
- package/src/utils/provider-checker/test-requirements.js +95 -0
- package/src/utils/provider-checker/time-formatter.js +18 -0
- package/src/utils/provider-checker-new.js +14 -0
- package/src/utils/provider-checker.js +12 -407
- package/src/utils/provider-checkers/ide-manager.js +128 -0
- package/src/utils/provider-checkers/node-executable-finder.js +51 -0
- package/src/utils/provider-checkers/provider-checker-core.js +172 -0
- package/src/utils/provider-checkers/provider-checker-main.js +107 -0
- package/src/utils/provider-manager.js +60 -4
- package/src/utils/provider-registry.js +26 -3
- package/src/utils/provider-utils.js +173 -0
- package/src/utils/quota-detectors.js +212 -0
- package/src/utils/requirement-action-handlers.js +288 -0
- package/src/utils/requirement-actions/clarification-actions.js +229 -0
- package/src/utils/requirement-actions/confirmation-prompts.js +93 -0
- package/src/utils/requirement-actions/file-operations.js +92 -0
- package/src/utils/requirement-actions/helpers.js +40 -0
- package/src/utils/requirement-actions/requirement-operations.js +335 -0
- package/src/utils/requirement-actions.js +46 -856
- package/src/utils/requirement-file-operations.js +259 -0
- package/src/utils/requirement-helpers.js +128 -0
- package/src/utils/requirement-management.js +279 -0
- package/src/utils/requirement-navigation.js +146 -0
- package/src/utils/requirement-organization.js +271 -0
- package/src/utils/simple-trui.js +75 -1
- package/src/utils/trui-navigation.js +28 -2
- package/src/utils/trui-req-tree.js +196 -11
- package/src/utils/trui-specifications.js +31 -1
- package/src/utils/interactive-backup.js +0 -5664
- package/src/utils/trui-provider-manager.js +0 -182
|
@@ -3,7 +3,7 @@ const fs = require('fs-extra');
|
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const chokidar = require('chokidar');
|
|
5
5
|
const { getRepoPath, setRepoPath } = require('../utils/config');
|
|
6
|
-
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
6
|
+
const { getRequirementsPath, DefaultRequirementManager, JSONStorage } = require('vibecodingmachine-core');
|
|
7
7
|
|
|
8
8
|
async function getReqPathOrExit() {
|
|
9
9
|
let repoPath = await getRepoPath();
|
|
@@ -478,6 +478,297 @@ async function numberAll() {
|
|
|
478
478
|
}
|
|
479
479
|
}
|
|
480
480
|
|
|
481
|
+
// Default Requirement Management Functions
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Create a new default requirement
|
|
485
|
+
*/
|
|
486
|
+
async function createDefault(title, options = {}) {
|
|
487
|
+
const { description, maxIterations } = options;
|
|
488
|
+
const repoPath = await getRepoPath();
|
|
489
|
+
|
|
490
|
+
if (!repoPath) {
|
|
491
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (!title) {
|
|
496
|
+
console.log(chalk.red('✗ Title is required'));
|
|
497
|
+
console.log(chalk.gray('Usage: vcm req:default create "Title" --description "Description" --max-iterations 10'));
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (!description) {
|
|
502
|
+
console.log(chalk.red('✗ Description is required'));
|
|
503
|
+
console.log(chalk.gray('Usage: vcm req:default create "Title" --description "Description" --max-iterations 10'));
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const iterations = maxIterations || 10;
|
|
508
|
+
|
|
509
|
+
try {
|
|
510
|
+
const storage = new JSONStorage();
|
|
511
|
+
const manager = new DefaultRequirementManager(storage);
|
|
512
|
+
|
|
513
|
+
const requirement = await manager.create({
|
|
514
|
+
title: title.trim(),
|
|
515
|
+
description: description.trim(),
|
|
516
|
+
maxIterations: iterations
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
console.log(chalk.bold.green('✅ Default requirement created'));
|
|
520
|
+
console.log(chalk.cyan(` Title: ${requirement.title}`));
|
|
521
|
+
console.log(chalk.cyan(` Description: ${requirement.description}`));
|
|
522
|
+
console.log(chalk.cyan(` Max Iterations: ${requirement.maxIterations}`));
|
|
523
|
+
console.log(chalk.cyan(` Status: ${requirement.status}`));
|
|
524
|
+
console.log();
|
|
525
|
+
} catch (error) {
|
|
526
|
+
console.log(chalk.red('✗ Failed to create default requirement:'), error.message);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Edit existing default requirement
|
|
532
|
+
*/
|
|
533
|
+
async function editDefault(options = {}) {
|
|
534
|
+
const { title, description, maxIterations } = options;
|
|
535
|
+
const repoPath = await getRepoPath();
|
|
536
|
+
|
|
537
|
+
if (!repoPath) {
|
|
538
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (!title && !description && !maxIterations) {
|
|
543
|
+
console.log(chalk.red('✗ At least one field to update is required'));
|
|
544
|
+
console.log(chalk.gray('Usage: vcm req:default edit --title "New Title" --description "New Description" --max-iterations 20'));
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
try {
|
|
549
|
+
const storage = new JSONStorage();
|
|
550
|
+
const manager = new DefaultRequirementManager(storage);
|
|
551
|
+
|
|
552
|
+
const updates = {};
|
|
553
|
+
if (title !== undefined) updates.title = title.trim();
|
|
554
|
+
if (description !== undefined) updates.description = description.trim();
|
|
555
|
+
if (maxIterations !== undefined) updates.maxIterations = maxIterations;
|
|
556
|
+
|
|
557
|
+
const requirement = await manager.edit(updates);
|
|
558
|
+
|
|
559
|
+
console.log(chalk.bold.green('✅ Default requirement updated'));
|
|
560
|
+
console.log(chalk.cyan(` Title: ${requirement.title}`));
|
|
561
|
+
console.log(chalk.cyan(` Description: ${requirement.description}`));
|
|
562
|
+
console.log(chalk.cyan(` Max Iterations: ${requirement.maxIterations}`));
|
|
563
|
+
console.log(chalk.cyan(` Status: ${requirement.status}`));
|
|
564
|
+
if (requirement.updatedAt) {
|
|
565
|
+
console.log(chalk.gray(` Updated: ${new Date(requirement.updatedAt).toLocaleString()}`));
|
|
566
|
+
}
|
|
567
|
+
console.log();
|
|
568
|
+
} catch (error) {
|
|
569
|
+
console.log(chalk.red('✗ Failed to edit default requirement:'), error.message);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Delete default requirement
|
|
575
|
+
*/
|
|
576
|
+
async function deleteDefault() {
|
|
577
|
+
const repoPath = await getRepoPath();
|
|
578
|
+
|
|
579
|
+
if (!repoPath) {
|
|
580
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
try {
|
|
585
|
+
const storage = new JSONStorage();
|
|
586
|
+
const manager = new DefaultRequirementManager(storage);
|
|
587
|
+
|
|
588
|
+
const status = await manager.getStatus();
|
|
589
|
+
if (!status) {
|
|
590
|
+
console.log(chalk.yellow('⚠️ No default requirement exists'));
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
console.log(chalk.bold.yellow(`Deleting default requirement: ${status.title}`));
|
|
595
|
+
|
|
596
|
+
await manager.delete();
|
|
597
|
+
|
|
598
|
+
console.log(chalk.bold.green('✅ Default requirement deleted'));
|
|
599
|
+
console.log();
|
|
600
|
+
} catch (error) {
|
|
601
|
+
console.log(chalk.red('✗ Failed to delete default requirement:'), error.message);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Show current default requirement status
|
|
607
|
+
*/
|
|
608
|
+
async function showDefault() {
|
|
609
|
+
const repoPath = await getRepoPath();
|
|
610
|
+
|
|
611
|
+
if (!repoPath) {
|
|
612
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
try {
|
|
617
|
+
const storage = new JSONStorage();
|
|
618
|
+
const manager = new DefaultRequirementManager(storage);
|
|
619
|
+
|
|
620
|
+
const status = await manager.getStatus();
|
|
621
|
+
if (!status) {
|
|
622
|
+
console.log(chalk.yellow('⚠️ No default requirement exists'));
|
|
623
|
+
console.log(chalk.gray('Create one with: vcm req:default create "Title" --description "Description" --max-iterations 10'));
|
|
624
|
+
console.log();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const statistics = await manager.getStatistics();
|
|
629
|
+
|
|
630
|
+
console.log(chalk.bold.cyan('📋 Default Requirement Status'));
|
|
631
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
632
|
+
console.log(chalk.cyan(`Title: ${status.title}`));
|
|
633
|
+
console.log(chalk.cyan(`Description: ${status.description}`));
|
|
634
|
+
console.log(chalk.cyan(`Status: ${status.status}`));
|
|
635
|
+
console.log(chalk.cyan(`Iterations: ${status.iterationCount}/${status.maxIterations}`));
|
|
636
|
+
console.log(chalk.cyan(`Consecutive Failures: ${status.consecutiveFailures}`));
|
|
637
|
+
|
|
638
|
+
if (statistics) {
|
|
639
|
+
console.log(chalk.cyan(`Completion: ${statistics.completionPercentage}%`));
|
|
640
|
+
console.log(chalk.cyan(`Age: ${statistics.ageHours}h`));
|
|
641
|
+
if (statistics.iterationsPerHour > 0) {
|
|
642
|
+
console.log(chalk.cyan(`Rate: ${statistics.iterationsPerHour} iterations/hour`));
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (status.createdAt) {
|
|
647
|
+
console.log(chalk.gray(`Created: ${new Date(status.createdAt).toLocaleString()}`));
|
|
648
|
+
}
|
|
649
|
+
if (status.lastIterationAt) {
|
|
650
|
+
console.log(chalk.gray(`Last iteration: ${new Date(status.lastIterationAt).toLocaleString()}`));
|
|
651
|
+
}
|
|
652
|
+
if (status.pausedAt) {
|
|
653
|
+
console.log(chalk.yellow(`Paused: ${new Date(status.pausedAt).toLocaleString()}`));
|
|
654
|
+
}
|
|
655
|
+
if (status.resumedAt) {
|
|
656
|
+
console.log(chalk.green(`Resumed: ${new Date(status.resumedAt).toLocaleString()}`));
|
|
657
|
+
}
|
|
658
|
+
if (status.completedAt) {
|
|
659
|
+
console.log(chalk.green(`Completed: ${new Date(status.completedAt).toLocaleString()}`));
|
|
660
|
+
console.log(chalk.green(`Reason: ${status.completionReason}`));
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
console.log();
|
|
664
|
+
} catch (error) {
|
|
665
|
+
console.log(chalk.red('✗ Failed to get default requirement status:'), error.message);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Pause default requirement
|
|
671
|
+
*/
|
|
672
|
+
async function pauseDefault() {
|
|
673
|
+
const repoPath = await getRepoPath();
|
|
674
|
+
|
|
675
|
+
if (!repoPath) {
|
|
676
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
try {
|
|
681
|
+
const storage = new JSONStorage();
|
|
682
|
+
const manager = new DefaultRequirementManager(storage);
|
|
683
|
+
|
|
684
|
+
const status = await manager.getStatus();
|
|
685
|
+
if (!status) {
|
|
686
|
+
console.log(chalk.yellow('⚠️ No default requirement exists'));
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (status.status === 'PAUSED') {
|
|
691
|
+
console.log(chalk.yellow('⚠️ Default requirement is already paused'));
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
await manager.pause();
|
|
696
|
+
|
|
697
|
+
console.log(chalk.bold.green('✅ Default requirement paused'));
|
|
698
|
+
console.log(chalk.cyan(` Title: ${status.title}`));
|
|
699
|
+
console.log();
|
|
700
|
+
} catch (error) {
|
|
701
|
+
console.log(chalk.red('✗ Failed to pause default requirement:'), error.message);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Resume default requirement
|
|
707
|
+
*/
|
|
708
|
+
async function resumeDefault() {
|
|
709
|
+
const repoPath = await getRepoPath();
|
|
710
|
+
|
|
711
|
+
if (!repoPath) {
|
|
712
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
try {
|
|
717
|
+
const storage = new JSONStorage();
|
|
718
|
+
const manager = new DefaultRequirementManager(storage);
|
|
719
|
+
|
|
720
|
+
const status = await manager.getStatus();
|
|
721
|
+
if (!status) {
|
|
722
|
+
console.log(chalk.yellow('⚠️ No default requirement exists'));
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
if (status.status === 'ACTIVE') {
|
|
727
|
+
console.log(chalk.yellow('⚠️ Default requirement is already active'));
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
await manager.resume();
|
|
732
|
+
|
|
733
|
+
console.log(chalk.bold.green('✅ Default requirement resumed'));
|
|
734
|
+
console.log(chalk.cyan(` Title: ${status.title}`));
|
|
735
|
+
console.log();
|
|
736
|
+
} catch (error) {
|
|
737
|
+
console.log(chalk.red('✗ Failed to resume default requirement:'), error.message);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Set max iterations for default requirement
|
|
743
|
+
*/
|
|
744
|
+
async function setMaxIterations(maxIterations) {
|
|
745
|
+
const repoPath = await getRepoPath();
|
|
746
|
+
|
|
747
|
+
if (!repoPath) {
|
|
748
|
+
console.log(chalk.red('✗ No repository configured'));
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
if (!maxIterations || maxIterations < 1 || maxIterations > 1000) {
|
|
753
|
+
console.log(chalk.red('✗ Max iterations must be between 1 and 1000'));
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
try {
|
|
758
|
+
const storage = new JSONStorage();
|
|
759
|
+
const manager = new DefaultRequirementManager(storage);
|
|
760
|
+
|
|
761
|
+
const requirement = await manager.edit({ maxIterations });
|
|
762
|
+
|
|
763
|
+
console.log(chalk.bold.green('✅ Max iterations updated'));
|
|
764
|
+
console.log(chalk.cyan(` Max Iterations: ${requirement.maxIterations}`));
|
|
765
|
+
console.log(chalk.cyan(` Current Iterations: ${requirement.iterationCount}`));
|
|
766
|
+
console.log();
|
|
767
|
+
} catch (error) {
|
|
768
|
+
console.log(chalk.red('✗ Failed to set max iterations:'), error.message);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
481
772
|
module.exports = {
|
|
482
773
|
list,
|
|
483
774
|
add,
|
|
@@ -487,7 +778,15 @@ module.exports = {
|
|
|
487
778
|
edit,
|
|
488
779
|
watch,
|
|
489
780
|
rename,
|
|
490
|
-
numberAll
|
|
781
|
+
numberAll,
|
|
782
|
+
// Default requirement commands
|
|
783
|
+
createDefault,
|
|
784
|
+
editDefault,
|
|
785
|
+
delete: deleteDefault,
|
|
786
|
+
showDefault,
|
|
787
|
+
pauseDefault,
|
|
788
|
+
resumeDefault,
|
|
789
|
+
setMaxIterations
|
|
491
790
|
};
|
|
492
791
|
|
|
493
792
|
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeout Configuration Command
|
|
3
|
+
*
|
|
4
|
+
* Manages adaptive timeout settings for autonomous mode
|
|
5
|
+
* Part of User Story 3: Adaptive Timeout Management
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const { getTimeoutConfig, setTimeoutConfig, resetTimeoutConfig, DEFAULT_TIMEOUT_CONFIG } = require('../utils/config');
|
|
10
|
+
const { TimeoutCalculator } = require('vibecodingmachine-core');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Display current timeout configuration
|
|
14
|
+
*/
|
|
15
|
+
async function showConfig() {
|
|
16
|
+
try {
|
|
17
|
+
const config = await getTimeoutConfig();
|
|
18
|
+
|
|
19
|
+
console.log(chalk.cyan('\n🕐 Timeout Configuration\n'));
|
|
20
|
+
|
|
21
|
+
// Mode
|
|
22
|
+
const modeIcon = config.mode === 'adaptive' ? '🔄' : '⏱️';
|
|
23
|
+
console.log(`${modeIcon} Mode: ${chalk.bold(config.mode)}`);
|
|
24
|
+
|
|
25
|
+
// Timeouts
|
|
26
|
+
console.log(`⏱️ Default: ${chalk.bold(formatDuration(config.defaultTimeout))}`);
|
|
27
|
+
console.log(`⏱️ Minimum: ${chalk.bold(formatDuration(config.minTimeout))}`);
|
|
28
|
+
console.log(`⏱️ Maximum: ${chalk.bold(formatDuration(config.maxTimeout))}`);
|
|
29
|
+
|
|
30
|
+
// Adaptive settings
|
|
31
|
+
if (config.mode === 'adaptive') {
|
|
32
|
+
console.log(`📊 Buffer: ${chalk.bold(config.bufferPercentage * 100)}%`);
|
|
33
|
+
console.log(`📈 EWMA Alpha: ${chalk.bold(config.ewmaAlpha)}`);
|
|
34
|
+
console.log(`📋 Min Samples: ${chalk.bold(config.minSamples)}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error(chalk.red('✗ Failed to get timeout configuration:'), error.message);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Set timeout configuration
|
|
46
|
+
*/
|
|
47
|
+
async function setConfig(key, value) {
|
|
48
|
+
try {
|
|
49
|
+
const currentConfig = await getTimeoutConfig();
|
|
50
|
+
let newConfig = { ...currentConfig };
|
|
51
|
+
|
|
52
|
+
switch (key) {
|
|
53
|
+
case 'mode':
|
|
54
|
+
if (!['fixed', 'adaptive'].includes(value)) {
|
|
55
|
+
console.error(chalk.red('✗ Invalid mode. Use: fixed or adaptive'));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
newConfig.mode = value;
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 'default':
|
|
62
|
+
newConfig.defaultTimeout = parseDuration(value);
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
case 'minimum':
|
|
66
|
+
newConfig.minTimeout = parseDuration(value);
|
|
67
|
+
break;
|
|
68
|
+
|
|
69
|
+
case 'maximum':
|
|
70
|
+
newConfig.maxTimeout = parseDuration(value);
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
case 'buffer':
|
|
74
|
+
const bufferPercent = parseFloat(value);
|
|
75
|
+
if (isNaN(bufferPercent) || bufferPercent < 0 || bufferPercent > 200) {
|
|
76
|
+
console.error(chalk.red('✗ Buffer percentage must be between 0 and 200'));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
newConfig.bufferPercentage = bufferPercent / 100;
|
|
80
|
+
break;
|
|
81
|
+
|
|
82
|
+
case 'ewma':
|
|
83
|
+
const alpha = parseFloat(value);
|
|
84
|
+
if (isNaN(alpha) || alpha < 0 || alpha > 1) {
|
|
85
|
+
console.error(chalk.red('✗ EWMA alpha must be between 0 and 1'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
newConfig.ewmaAlpha = alpha;
|
|
89
|
+
break;
|
|
90
|
+
|
|
91
|
+
case 'samples':
|
|
92
|
+
const samples = parseInt(value);
|
|
93
|
+
if (isNaN(samples) || samples < 1) {
|
|
94
|
+
console.error(chalk.red('✗ Minimum samples must be a positive integer'));
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
newConfig.minSamples = samples;
|
|
98
|
+
break;
|
|
99
|
+
|
|
100
|
+
default:
|
|
101
|
+
console.error(chalk.red(`✗ Unknown setting: ${key}`));
|
|
102
|
+
console.log(chalk.yellow('Available settings: mode, default, minimum, maximum, buffer, ewma, samples'));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
await setTimeoutConfig(newConfig);
|
|
107
|
+
console.log(chalk.green(`✓ Timeout configuration updated: ${key} = ${value}`));
|
|
108
|
+
|
|
109
|
+
// Show updated config
|
|
110
|
+
await showConfig();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error(chalk.red('✗ Failed to set timeout configuration:'), error.message);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Reset timeout configuration to defaults
|
|
119
|
+
*/
|
|
120
|
+
async function resetConfig() {
|
|
121
|
+
try {
|
|
122
|
+
await resetTimeoutConfig();
|
|
123
|
+
console.log(chalk.green('✓ Timeout configuration reset to defaults'));
|
|
124
|
+
await showConfig();
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error(chalk.red('✗ Failed to reset timeout configuration:'), error.message);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Test timeout calculation with sample data
|
|
133
|
+
*/
|
|
134
|
+
async function testConfig(ideId) {
|
|
135
|
+
try {
|
|
136
|
+
const config = await getTimeoutConfig();
|
|
137
|
+
|
|
138
|
+
console.log(chalk.cyan(`\n🧪 Testing Timeout Calculation for ${chalk.bold(ideId)}\n`));
|
|
139
|
+
|
|
140
|
+
// Generate sample response times based on IDE performance characteristics
|
|
141
|
+
const sampleTimes = generateSampleTimes(ideId);
|
|
142
|
+
|
|
143
|
+
if (sampleTimes.length === 0) {
|
|
144
|
+
console.log(chalk.yellow('⚠️ No historical data available for testing'));
|
|
145
|
+
console.log(chalk.gray('Run some autonomous tasks first to generate response time data'));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(chalk.gray('Sample response times:'));
|
|
150
|
+
sampleTimes.forEach((time, index) => {
|
|
151
|
+
console.log(` ${index + 1}. ${formatDuration(time)}`);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Calculate timeout using current configuration
|
|
155
|
+
const timeoutResult = TimeoutCalculator.calculateTimeout(sampleTimes, {
|
|
156
|
+
defaultTimeout: config.defaultTimeout,
|
|
157
|
+
minTimeout: config.minTimeout,
|
|
158
|
+
maxTimeout: config.maxTimeout,
|
|
159
|
+
bufferPercentage: config.bufferPercentage
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
console.log(chalk.green(`\n📊 Calculated timeout: ${chalk.bold(formatDuration(timeoutResult.timeout))}`));
|
|
163
|
+
console.log(chalk.gray(`Based on ${sampleTimes.length} samples with ${config.bufferPercentage * 100}% buffer`));
|
|
164
|
+
|
|
165
|
+
if (timeoutResult.outliersRemoved > 0) {
|
|
166
|
+
console.log(chalk.yellow(`⚠️ Removed ${timeoutResult.outliersRemoved} outliers from calculation`));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.log();
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error(chalk.red('✗ Failed to test timeout configuration:'), error.message);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Format duration in milliseconds to human-readable string
|
|
178
|
+
*/
|
|
179
|
+
function formatDuration(ms) {
|
|
180
|
+
const minutes = Math.floor(ms / 60000);
|
|
181
|
+
const seconds = Math.floor((ms % 60000) / 1000);
|
|
182
|
+
|
|
183
|
+
if (minutes > 0) {
|
|
184
|
+
return `${minutes}m ${seconds}s`;
|
|
185
|
+
} else {
|
|
186
|
+
return `${seconds}s`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Parse duration string to milliseconds
|
|
192
|
+
*/
|
|
193
|
+
function parseDuration(str) {
|
|
194
|
+
const match = str.match(/^(\d+)([smh])$/);
|
|
195
|
+
if (!match) {
|
|
196
|
+
console.error(chalk.red('✗ Invalid duration format. Use: 30s, 5m, 1h'));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const value = parseInt(match[1]);
|
|
201
|
+
const unit = match[2];
|
|
202
|
+
|
|
203
|
+
switch (unit) {
|
|
204
|
+
case 's': return value * 1000;
|
|
205
|
+
case 'm': return value * 60 * 1000;
|
|
206
|
+
case 'h': return value * 60 * 60 * 1000;
|
|
207
|
+
default: return value * 1000;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Generate sample response times for testing
|
|
213
|
+
*/
|
|
214
|
+
function generateSampleTimes(ideId) {
|
|
215
|
+
// Simulate different IDE performance characteristics
|
|
216
|
+
const profiles = {
|
|
217
|
+
'claude-code': [2, 3, 2, 4, 3, 2, 3, 5, 2, 3].map(x => x * 60 * 1000), // 2-5 minutes
|
|
218
|
+
'cline': [3, 4, 3, 5, 4, 3, 4, 6, 3, 4].map(x => x * 60 * 1000), // 3-6 minutes
|
|
219
|
+
'cursor': [4, 5, 4, 6, 5, 4, 5, 7, 4, 5].map(x => x * 60 * 1000), // 4-7 minutes
|
|
220
|
+
'windsurf': [5, 6, 5, 7, 6, 5, 6, 8, 5, 6].map(x => x * 60 * 1000), // 5-8 minutes
|
|
221
|
+
'antigravity': [3, 4, 3, 5, 4, 3, 4, 6, 3, 4].map(x => x * 60 * 1000), // 3-6 minutes
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
return profiles[ideId] || profiles['claude-code'];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Main command handler
|
|
229
|
+
*/
|
|
230
|
+
async function handleCommand(args) {
|
|
231
|
+
const [action, ...restArgs] = args;
|
|
232
|
+
|
|
233
|
+
switch (action) {
|
|
234
|
+
case 'show':
|
|
235
|
+
await showConfig();
|
|
236
|
+
break;
|
|
237
|
+
|
|
238
|
+
case 'set':
|
|
239
|
+
if (restArgs.length !== 2) {
|
|
240
|
+
console.error(chalk.red('✗ Usage: vcm config:timeout set <key> <value>'));
|
|
241
|
+
console.log(chalk.yellow('Available keys: mode, default, minimum, maximum, buffer, ewma, samples'));
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
await setConfig(restArgs[0], restArgs[1]);
|
|
245
|
+
break;
|
|
246
|
+
|
|
247
|
+
case 'reset':
|
|
248
|
+
await resetConfig();
|
|
249
|
+
break;
|
|
250
|
+
|
|
251
|
+
case 'test':
|
|
252
|
+
if (restArgs.length !== 1) {
|
|
253
|
+
console.error(chalk.red('✗ Usage: vcm config:timeout test <ide-id>'));
|
|
254
|
+
console.log(chalk.yellow('Available IDEs: claude-code, cline, cursor, windsurf, antigravity'));
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
await testConfig(restArgs[0]);
|
|
258
|
+
break;
|
|
259
|
+
|
|
260
|
+
default:
|
|
261
|
+
console.log(chalk.cyan('Timeout Configuration Command\n'));
|
|
262
|
+
console.log(chalk.gray('Manages adaptive timeout settings for autonomous mode\n'));
|
|
263
|
+
console.log();
|
|
264
|
+
console.log(chalk.bold('Usage:'));
|
|
265
|
+
console.log(' vcm config:timeout show Show current configuration');
|
|
266
|
+
console.log(' vcm config:timeout set <key> <value> Set a configuration value');
|
|
267
|
+
console.log(' vcm config:timeout reset Reset to defaults');
|
|
268
|
+
console.log(' vcm config:timeout test <ide-id> Test timeout calculation');
|
|
269
|
+
console.log();
|
|
270
|
+
console.log(chalk.bold('Settings:'));
|
|
271
|
+
console.log(' mode fixed | adaptive Timeout mode');
|
|
272
|
+
console.log(' default 30s | 5m | 1h Default timeout');
|
|
273
|
+
console.log(' minimum 5s | 1m | 30m Minimum timeout');
|
|
274
|
+
console.log(' maximum 10m | 30m | 2h Maximum timeout');
|
|
275
|
+
console.log(' buffer 0-200 Buffer percentage');
|
|
276
|
+
console.log(' ewma 0-1 EWMA smoothing factor');
|
|
277
|
+
console.log(' samples 1+ Minimum samples');
|
|
278
|
+
console.log();
|
|
279
|
+
console.log(chalk.bold('Examples:'));
|
|
280
|
+
console.log(' vcm config:timeout set mode adaptive');
|
|
281
|
+
console.log(' vcm config:timeout set default 45m');
|
|
282
|
+
console.log(' vcm config:timeout set buffer 75');
|
|
283
|
+
console.log(' vcm config:timeout test claude-code');
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
module.exports = {
|
|
289
|
+
handleCommand
|
|
290
|
+
};
|