vibecodingmachine-cli 2026.3.9-850 → 2026.3.10-1547

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.
Files changed (39) hide show
  1. package/README.md +85 -85
  2. package/bin/commands/agent-commands.js +295 -28
  3. package/bin/vibecodingmachine.js +0 -0
  4. package/package.json +2 -2
  5. package/scripts/postinstall.js +161 -161
  6. package/src/commands/auth.js +100 -100
  7. package/src/commands/auto-execution.js +120 -32
  8. package/src/commands/auto-requirement-management.js +9 -9
  9. package/src/commands/auto-status-helpers.js +6 -12
  10. package/src/commands/computers.js +318 -318
  11. package/src/commands/feature.js +123 -123
  12. package/src/commands/locale.js +72 -72
  13. package/src/commands/repo.js +163 -163
  14. package/src/commands/setup.js +93 -93
  15. package/src/commands/sync.js +287 -287
  16. package/src/index.js +5 -5
  17. package/src/utils/agent-selector.js +50 -50
  18. package/src/utils/asset-cleanup.js +60 -60
  19. package/src/utils/auth.js +6 -0
  20. package/src/utils/auto-mode-ansi-ui.js +237 -237
  21. package/src/utils/auto-mode-simple-ui.js +141 -141
  22. package/src/utils/copy-with-progress.js +167 -167
  23. package/src/utils/download-with-progress.js +84 -84
  24. package/src/utils/keyboard-handler.js +153 -153
  25. package/src/utils/kiro-installer.js +178 -178
  26. package/src/utils/logger.js +4 -4
  27. package/src/utils/persistent-header.js +114 -114
  28. package/src/utils/prompt-helper.js +63 -63
  29. package/src/utils/provider-checker/agent-runner.js +110 -31
  30. package/src/utils/provider-checker/ide-manager.js +37 -8
  31. package/src/utils/provider-checker/provider-validator.js +50 -0
  32. package/src/utils/provider-checker/requirements-manager.js +21 -6
  33. package/src/utils/status-card.js +121 -121
  34. package/src/utils/stdout-interceptor.js +127 -127
  35. package/src/utils/trui-main-handlers.js +41 -8
  36. package/src/utils/trui-main-menu.js +10 -3
  37. package/src/utils/trui-nav-agents.js +23 -33
  38. package/src/utils/trui-navigation.js +2 -2
  39. package/src/utils/user-tracking.js +299 -299
@@ -1,163 +1,163 @@
1
- const path = require('path');
2
- const fs = require('fs-extra');
3
- const chalk = require('chalk');
4
- const inquirer = require('inquirer');
5
- const { getRepoPath, setRepoPath } = require('../utils/config');
6
- const {
7
- getHostname,
8
- getRequirementsFilename,
9
- isComputerNameEnabled
10
- } = require('vibecodingmachine-core');
11
-
12
- async function setRepo(repoPath) {
13
- try {
14
- const absolutePath = path.resolve(repoPath);
15
-
16
- if (!await fs.pathExists(absolutePath)) {
17
- console.error(chalk.red(`Error: Directory does not exist: ${absolutePath}`));
18
- process.exit(1);
19
- }
20
-
21
- await setRepoPath(absolutePath);
22
- console.log(chalk.green('✓'), `Repository path set to: ${chalk.cyan(absolutePath)}`);
23
- } catch (error) {
24
- console.error(chalk.red('Error setting repository path:'), error.message);
25
- process.exit(1);
26
- }
27
- }
28
-
29
- async function getRepo() {
30
- try {
31
- const repoPath = await getRepoPath();
32
-
33
- if (!repoPath) {
34
- console.log(chalk.yellow('No repository path configured'));
35
- console.log(chalk.gray('Use'), chalk.cyan('vcm repo:set <path>'), chalk.gray('to set repository path'));
36
- return;
37
- }
38
-
39
- console.log(chalk.cyan(repoPath));
40
- } catch (error) {
41
- console.error(chalk.red('Error getting repository path:'), error.message);
42
- process.exit(1);
43
- }
44
- }
45
-
46
- async function initRepo(options = {}) {
47
- try {
48
- const cwd = process.cwd();
49
- const repoName = path.basename(cwd);
50
- const insideDir = path.join(cwd, '.vibecodingmachine');
51
- const siblingDir = path.join(path.dirname(cwd), `.vibecodingmachine-${repoName}`);
52
-
53
- let location = options.location;
54
-
55
- if (location !== 'inside' && location !== 'sibling') {
56
- // Ask user where to create the directory
57
- const answer = await inquirer.prompt([
58
- {
59
- type: 'list',
60
- name: 'location',
61
- message: 'Where would you like to create the VibeCodingMachine directory?',
62
- choices: [
63
- {
64
- name: `Inside this repository (${chalk.cyan('.vibecodingmachine')}) - suggested`,
65
- value: 'inside',
66
- short: 'Inside repository'
67
- },
68
- {
69
- name: `As a sibling directory (${chalk.cyan(`../.vibecodingmachine-${repoName}`)}) - keeps configs separate from code`,
70
- value: 'sibling',
71
- short: 'Sibling directory'
72
- }
73
- ],
74
- default: 'inside'
75
- }
76
- ]);
77
- location = answer.location;
78
- }
79
-
80
- const allnightDir = location === 'inside' ? insideDir : siblingDir;
81
-
82
- console.log(chalk.blue('\nInitializing VibeCodingMachine in:'), chalk.cyan(allnightDir));
83
-
84
- await fs.ensureDir(allnightDir);
85
- await fs.ensureDir(path.join(allnightDir, 'temp'));
86
- await fs.ensureDir(path.join(allnightDir, 'temp', 'screenshots'));
87
-
88
- // Check if computer name is enabled and use appropriate filename
89
- const useHostname = await isComputerNameEnabled();
90
- const hostname = getHostname();
91
- const requirementsFilename = await getRequirementsFilename();
92
- const requirementsPath = path.join(allnightDir, requirementsFilename);
93
-
94
- if (!await fs.pathExists(requirementsPath)) {
95
- const titleSuffix = useHostname ? ` (${hostname})` : '';
96
- const requirementsTemplate = `# VibeCodingMachine Requirements${titleSuffix}
97
-
98
- ## 🚦 Current Status
99
- PREPARE
100
-
101
- ## ⏳ Requirements not yet completed
102
-
103
- ### Example Requirement
104
- Add your requirements here...
105
-
106
- ## ✅ Verified by AI
107
-
108
- ## ⚠️ Issues Found
109
- `;
110
- await fs.writeFile(requirementsPath, requirementsTemplate);
111
- console.log(chalk.green('✓'), `Created ${requirementsFilename}`);
112
- }
113
-
114
- const instructionsPath = path.join(allnightDir, 'INSTRUCTIONS.md');
115
- if (!await fs.pathExists(instructionsPath)) {
116
- const fileNote = useHostname
117
- ? `**ALWAYS** use the hostname-specific requirements file:
118
- - File: \`${requirementsFilename}\`
119
- - This ensures each computer has its own requirements and progress tracking`
120
- : `**Requirements file:** \`REQUIREMENTS.md\``;
121
-
122
- const instructionsTemplate = `# Development Instructions
123
-
124
- ## Important: Requirements File
125
-
126
- ${fileNote}
127
-
128
- ## Guidelines
129
- - Follow the status progression: PREPARE → ACT → CLEAN UP → VERIFY → DONE
130
- - Update status in ${requirementsFilename} at each stage
131
- - Take screenshots during VERIFY phase
132
- - Mark requirement as DONE when complete
133
-
134
- ## Code Standards
135
- - Keep files under 250 lines
136
- - Follow DRY principles
137
- - Keep it simple (KISS)
138
- - No placeholder code
139
- - Prefix temporary files with TEMP_
140
- `;
141
- await fs.writeFile(instructionsPath, instructionsTemplate);
142
- console.log(chalk.green('✓'), 'Created INSTRUCTIONS.md');
143
- }
144
-
145
- await setRepoPath(cwd);
146
- console.log(chalk.green('✓'), 'Set repository path to current directory');
147
-
148
- console.log(chalk.green('\n✓ VibeCodingMachine initialized successfully!'));
149
- console.log(chalk.gray('\nNext steps:'));
150
- const configPath = location === 'inside' ? `.vibecodingmachine/${requirementsFilename}` : `../.vibecodingmachine-${repoName}/${requirementsFilename}`;
151
- console.log(chalk.gray(' 1. Edit'), chalk.cyan(configPath), chalk.gray('with your requirements'));
152
- console.log(chalk.gray(' 2. Run'), chalk.cyan('vcm auto:start'), chalk.gray('to begin autonomous development'));
153
- } catch (error) {
154
- console.error(chalk.red('Error initializing repository:'), error.message);
155
- process.exit(1);
156
- }
157
- }
158
-
159
- module.exports = {
160
- setRepo,
161
- getRepo,
162
- initRepo
163
- };
1
+ const path = require('path');
2
+ const fs = require('fs-extra');
3
+ const chalk = require('chalk');
4
+ const inquirer = require('inquirer');
5
+ const { getRepoPath, setRepoPath } = require('../utils/config');
6
+ const {
7
+ getHostname,
8
+ getRequirementsFilename,
9
+ isComputerNameEnabled
10
+ } = require('vibecodingmachine-core');
11
+
12
+ async function setRepo(repoPath) {
13
+ try {
14
+ const absolutePath = path.resolve(repoPath);
15
+
16
+ if (!await fs.pathExists(absolutePath)) {
17
+ console.error(chalk.red(`Error: Directory does not exist: ${absolutePath}`));
18
+ process.exit(1);
19
+ }
20
+
21
+ await setRepoPath(absolutePath);
22
+ console.log(chalk.green('✓'), `Repository path set to: ${chalk.cyan(absolutePath)}`);
23
+ } catch (error) {
24
+ console.error(chalk.red('Error setting repository path:'), error.message);
25
+ process.exit(1);
26
+ }
27
+ }
28
+
29
+ async function getRepo() {
30
+ try {
31
+ const repoPath = await getRepoPath();
32
+
33
+ if (!repoPath) {
34
+ console.log(chalk.yellow('No repository path configured'));
35
+ console.log(chalk.gray('Use'), chalk.cyan('vcm repo:set <path>'), chalk.gray('to set repository path'));
36
+ return;
37
+ }
38
+
39
+ console.log(chalk.cyan(repoPath));
40
+ } catch (error) {
41
+ console.error(chalk.red('Error getting repository path:'), error.message);
42
+ process.exit(1);
43
+ }
44
+ }
45
+
46
+ async function initRepo(options = {}) {
47
+ try {
48
+ const cwd = process.cwd();
49
+ const repoName = path.basename(cwd);
50
+ const insideDir = path.join(cwd, '.vibecodingmachine');
51
+ const siblingDir = path.join(path.dirname(cwd), `.vibecodingmachine-${repoName}`);
52
+
53
+ let location = options.location;
54
+
55
+ if (location !== 'inside' && location !== 'sibling') {
56
+ // Ask user where to create the directory
57
+ const answer = await inquirer.prompt([
58
+ {
59
+ type: 'list',
60
+ name: 'location',
61
+ message: 'Where would you like to create the VibeCodingMachine directory?',
62
+ choices: [
63
+ {
64
+ name: `Inside this repository (${chalk.cyan('.vibecodingmachine')}) - suggested`,
65
+ value: 'inside',
66
+ short: 'Inside repository'
67
+ },
68
+ {
69
+ name: `As a sibling directory (${chalk.cyan(`../.vibecodingmachine-${repoName}`)}) - keeps configs separate from code`,
70
+ value: 'sibling',
71
+ short: 'Sibling directory'
72
+ }
73
+ ],
74
+ default: 'inside'
75
+ }
76
+ ]);
77
+ location = answer.location;
78
+ }
79
+
80
+ const allnightDir = location === 'inside' ? insideDir : siblingDir;
81
+
82
+ console.log(chalk.blue('\nInitializing VibeCodingMachine in:'), chalk.cyan(allnightDir));
83
+
84
+ await fs.ensureDir(allnightDir);
85
+ await fs.ensureDir(path.join(allnightDir, 'temp'));
86
+ await fs.ensureDir(path.join(allnightDir, 'temp', 'screenshots'));
87
+
88
+ // Check if computer name is enabled and use appropriate filename
89
+ const useHostname = await isComputerNameEnabled();
90
+ const hostname = getHostname();
91
+ const requirementsFilename = await getRequirementsFilename();
92
+ const requirementsPath = path.join(allnightDir, requirementsFilename);
93
+
94
+ if (!await fs.pathExists(requirementsPath)) {
95
+ const titleSuffix = useHostname ? ` (${hostname})` : '';
96
+ const requirementsTemplate = `# VibeCodingMachine Requirements${titleSuffix}
97
+
98
+ ## 🚦 Current Status
99
+ PREPARE
100
+
101
+ ## ⏳ Requirements not yet completed
102
+
103
+ ### Example Requirement
104
+ Add your requirements here...
105
+
106
+ ## ✅ Verified by AI
107
+
108
+ ## ⚠️ Issues Found
109
+ `;
110
+ await fs.writeFile(requirementsPath, requirementsTemplate);
111
+ console.log(chalk.green('✓'), `Created ${requirementsFilename}`);
112
+ }
113
+
114
+ const instructionsPath = path.join(allnightDir, 'INSTRUCTIONS.md');
115
+ if (!await fs.pathExists(instructionsPath)) {
116
+ const fileNote = useHostname
117
+ ? `**ALWAYS** use the hostname-specific requirements file:
118
+ - File: \`${requirementsFilename}\`
119
+ - This ensures each computer has its own requirements and progress tracking`
120
+ : `**Requirements file:** \`REQUIREMENTS.md\``;
121
+
122
+ const instructionsTemplate = `# Development Instructions
123
+
124
+ ## Important: Requirements File
125
+
126
+ ${fileNote}
127
+
128
+ ## Guidelines
129
+ - Follow the status progression: PREPARE → ACT → CLEAN UP → VERIFY → DONE
130
+ - Update status in ${requirementsFilename} at each stage
131
+ - Take screenshots during VERIFY phase
132
+ - Mark requirement as DONE when complete
133
+
134
+ ## Code Standards
135
+ - Keep files under 250 lines
136
+ - Follow DRY principles
137
+ - Keep it simple (KISS)
138
+ - No placeholder code
139
+ - Prefix temporary files with TEMP_
140
+ `;
141
+ await fs.writeFile(instructionsPath, instructionsTemplate);
142
+ console.log(chalk.green('✓'), 'Created INSTRUCTIONS.md');
143
+ }
144
+
145
+ await setRepoPath(cwd);
146
+ console.log(chalk.green('✓'), 'Set repository path to current directory');
147
+
148
+ console.log(chalk.green('\n✓ VibeCodingMachine initialized successfully!'));
149
+ console.log(chalk.gray('\nNext steps:'));
150
+ const configPath = location === 'inside' ? `.vibecodingmachine/${requirementsFilename}` : `../.vibecodingmachine-${repoName}/${requirementsFilename}`;
151
+ console.log(chalk.gray(' 1. Edit'), chalk.cyan(configPath), chalk.gray('with your requirements'));
152
+ console.log(chalk.gray(' 2. Run'), chalk.cyan('vcm auto:start'), chalk.gray('to begin autonomous development'));
153
+ } catch (error) {
154
+ console.error(chalk.red('Error initializing repository:'), error.message);
155
+ process.exit(1);
156
+ }
157
+ }
158
+
159
+ module.exports = {
160
+ setRepo,
161
+ getRepo,
162
+ initRepo
163
+ };
@@ -1,93 +1,93 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
- const chalk = require('chalk');
5
- const inquirer = require('inquirer');
6
- const { t } = require('vibecodingmachine-core');
7
- const { promptWithDefaultsOnce } = require('../utils/prompt-helper');
8
-
9
- async function setupAlias() {
10
- console.log(chalk.bold.cyan(`\n🛠️ ${t('setup.alias.title')}\n`));
11
-
12
- // Detect shell
13
- const shell = process.env.SHELL;
14
- let configFile = '';
15
- let shellName = '';
16
-
17
- if (shell.includes('zsh')) {
18
- shellName = 'zsh';
19
- configFile = path.join(os.homedir(), '.zshrc');
20
- } else if (shell.includes('bash')) {
21
- shellName = 'bash';
22
- configFile = path.join(os.homedir(), '.bashrc');
23
- // On Mac, .bash_profile is often used instead of .bashrc for login shells
24
- if (process.platform === 'darwin' && !fs.existsSync(configFile)) {
25
- const profile = path.join(os.homedir(), '.bash_profile');
26
- if (fs.existsSync(profile)) {
27
- configFile = profile;
28
- }
29
- }
30
- } else if (shell.includes('fish')) {
31
- shellName = 'fish';
32
- configFile = path.join(os.homedir(), '.config', 'fish', 'config.fish');
33
- } else {
34
- console.log(chalk.yellow(`⚠️ ${t('setup.shell.unsupported', { shell })}`));
35
- console.log(chalk.gray(`${t('setup.manual.alias')}\n`));
36
- console.log(chalk.cyan(` ${t('cli.alias.manual')}`));
37
- return;
38
- }
39
-
40
- console.log(chalk.gray(t('setup.alias.detected', { shell: chalk.cyan(shellName) })));
41
- console.log(chalk.gray(t('setup.alias.config', { file: chalk.cyan(configFile) })));
42
-
43
- // Check if config file exists
44
- if (!fs.existsSync(configFile)) {
45
- // For fish, ensure directory exists
46
- if (shellName === 'fish') {
47
- const configDir = path.dirname(configFile);
48
- if (!fs.existsSync(configDir)) {
49
- fs.mkdirSync(configDir, { recursive: true });
50
- }
51
- }
52
- // Create empty file if it doesn't exist
53
- fs.writeFileSync(configFile, '', 'utf8');
54
- }
55
-
56
- // Read config file
57
- let content = fs.readFileSync(configFile, 'utf8');
58
-
59
- // Check if alias already exists
60
- if (content.includes('alias vcm="vibecodingmachine"') || content.includes("alias vcm='vibecodingmachine'")) {
61
- console.log(chalk.green(`\n✓ ${t('setup.alias.exists')}`));
62
- return;
63
- }
64
-
65
- // Confirm with user
66
- const { confirm } = await promptWithDefaultsOnce([
67
- {
68
- type: 'confirm',
69
- name: 'confirm',
70
- message: t('setup.alias.confirm', { file: path.basename(configFile) }),
71
- default: true
72
- }
73
- ]);
74
-
75
- if (!confirm) {
76
- console.log(chalk.yellow(`\n${t('setup.alias.cancelled')}`));
77
- return;
78
- }
79
-
80
- // Add alias
81
- const aliasCommand = '\n# Vibe Coding Machine Alias\nalias vcm="vibecodingmachine"\n';
82
-
83
- try {
84
- fs.appendFileSync(configFile, aliasCommand, 'utf8');
85
- console.log(chalk.green(`\n✓ ${t('setup.alias.added', { file: path.basename(configFile) })}`));
86
- console.log(chalk.gray(`\n${t('setup.alias.restart')}`));
87
- console.log(chalk.cyan(` ${t('setup.alias.source', { file: configFile })}`));
88
- } catch (error) {
89
- console.log(chalk.red(`\n✗ ${t('setup.alias.error', { error: error.message })}`));
90
- }
91
- }
92
-
93
- module.exports = { setupAlias };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+ const chalk = require('chalk');
5
+ const inquirer = require('inquirer');
6
+ const { t } = require('vibecodingmachine-core');
7
+ const { promptWithDefaultsOnce } = require('../utils/prompt-helper');
8
+
9
+ async function setupAlias() {
10
+ console.log(chalk.bold.cyan(`\n🛠️ ${t('setup.alias.title')}\n`));
11
+
12
+ // Detect shell
13
+ const shell = process.env.SHELL;
14
+ let configFile = '';
15
+ let shellName = '';
16
+
17
+ if (shell.includes('zsh')) {
18
+ shellName = 'zsh';
19
+ configFile = path.join(os.homedir(), '.zshrc');
20
+ } else if (shell.includes('bash')) {
21
+ shellName = 'bash';
22
+ configFile = path.join(os.homedir(), '.bashrc');
23
+ // On Mac, .bash_profile is often used instead of .bashrc for login shells
24
+ if (process.platform === 'darwin' && !fs.existsSync(configFile)) {
25
+ const profile = path.join(os.homedir(), '.bash_profile');
26
+ if (fs.existsSync(profile)) {
27
+ configFile = profile;
28
+ }
29
+ }
30
+ } else if (shell.includes('fish')) {
31
+ shellName = 'fish';
32
+ configFile = path.join(os.homedir(), '.config', 'fish', 'config.fish');
33
+ } else {
34
+ console.log(chalk.yellow(`⚠️ ${t('setup.shell.unsupported', { shell })}`));
35
+ console.log(chalk.gray(`${t('setup.manual.alias')}\n`));
36
+ console.log(chalk.cyan(` ${t('cli.alias.manual')}`));
37
+ return;
38
+ }
39
+
40
+ console.log(chalk.gray(t('setup.alias.detected', { shell: chalk.cyan(shellName) })));
41
+ console.log(chalk.gray(t('setup.alias.config', { file: chalk.cyan(configFile) })));
42
+
43
+ // Check if config file exists
44
+ if (!fs.existsSync(configFile)) {
45
+ // For fish, ensure directory exists
46
+ if (shellName === 'fish') {
47
+ const configDir = path.dirname(configFile);
48
+ if (!fs.existsSync(configDir)) {
49
+ fs.mkdirSync(configDir, { recursive: true });
50
+ }
51
+ }
52
+ // Create empty file if it doesn't exist
53
+ fs.writeFileSync(configFile, '', 'utf8');
54
+ }
55
+
56
+ // Read config file
57
+ let content = fs.readFileSync(configFile, 'utf8');
58
+
59
+ // Check if alias already exists
60
+ if (content.includes('alias vcm="vibecodingmachine"') || content.includes("alias vcm='vibecodingmachine'")) {
61
+ console.log(chalk.green(`\n✓ ${t('setup.alias.exists')}`));
62
+ return;
63
+ }
64
+
65
+ // Confirm with user
66
+ const { confirm } = await promptWithDefaultsOnce([
67
+ {
68
+ type: 'confirm',
69
+ name: 'confirm',
70
+ message: t('setup.alias.confirm', { file: path.basename(configFile) }),
71
+ default: true
72
+ }
73
+ ]);
74
+
75
+ if (!confirm) {
76
+ console.log(chalk.yellow(`\n${t('setup.alias.cancelled')}`));
77
+ return;
78
+ }
79
+
80
+ // Add alias
81
+ const aliasCommand = '\n# Vibe Coding Machine Alias\nalias vcm="vibecodingmachine"\n';
82
+
83
+ try {
84
+ fs.appendFileSync(configFile, aliasCommand, 'utf8');
85
+ console.log(chalk.green(`\n✓ ${t('setup.alias.added', { file: path.basename(configFile) })}`));
86
+ console.log(chalk.gray(`\n${t('setup.alias.restart')}`));
87
+ console.log(chalk.cyan(` ${t('setup.alias.source', { file: configFile })}`));
88
+ } catch (error) {
89
+ console.log(chalk.red(`\n✗ ${t('setup.alias.error', { error: error.message })}`));
90
+ }
91
+ }
92
+
93
+ module.exports = { setupAlias };