vibecodingmachine-cli 2026.3.9-907 → 2026.3.10-1548
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/README.md +85 -85
- package/bin/commands/agent-commands.js +295 -28
- package/bin/vibecodingmachine.js +0 -0
- package/package.json +2 -2
- package/scripts/postinstall.js +161 -161
- package/src/commands/auth.js +100 -100
- package/src/commands/auto-execution.js +120 -32
- package/src/commands/auto-requirement-management.js +9 -9
- package/src/commands/auto-status-helpers.js +6 -12
- package/src/commands/computers.js +318 -318
- package/src/commands/feature.js +123 -123
- package/src/commands/locale.js +72 -72
- package/src/commands/repo.js +163 -163
- package/src/commands/setup.js +93 -93
- package/src/commands/sync.js +287 -287
- package/src/index.js +5 -5
- package/src/utils/agent-selector.js +50 -50
- package/src/utils/asset-cleanup.js +60 -60
- package/src/utils/auth.js +6 -0
- package/src/utils/auto-mode-ansi-ui.js +237 -237
- package/src/utils/auto-mode-simple-ui.js +141 -141
- package/src/utils/copy-with-progress.js +167 -167
- package/src/utils/download-with-progress.js +84 -84
- package/src/utils/keyboard-handler.js +153 -153
- package/src/utils/kiro-installer.js +178 -178
- package/src/utils/logger.js +4 -4
- package/src/utils/persistent-header.js +114 -114
- package/src/utils/prompt-helper.js +63 -63
- package/src/utils/provider-checker/agent-runner.js +110 -31
- package/src/utils/provider-checker/ide-manager.js +37 -8
- package/src/utils/provider-checker/provider-validator.js +50 -0
- package/src/utils/provider-checker/requirements-manager.js +21 -6
- package/src/utils/status-card.js +121 -121
- package/src/utils/stdout-interceptor.js +127 -127
- package/src/utils/trui-main-handlers.js +41 -8
- package/src/utils/trui-main-menu.js +10 -3
- package/src/utils/trui-nav-agents.js +23 -33
- package/src/utils/trui-navigation.js +2 -2
- package/src/utils/user-tracking.js +299 -299
package/scripts/postinstall.js
CHANGED
|
@@ -1,161 +1,161 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Post-install script to check if 'vcm' command exists
|
|
5
|
-
* and warn users if there's a conflict
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { execSync } = require('child_process');
|
|
9
|
-
const chalk = require('chalk');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Detect if user is using asdf for Node.js version management
|
|
15
|
-
*/
|
|
16
|
-
function detectAsdf() {
|
|
17
|
-
try {
|
|
18
|
-
const nodePath = execSync('which node 2>/dev/null || true', { encoding: 'utf8' }).trim();
|
|
19
|
-
return nodePath.includes('/.asdf/');
|
|
20
|
-
} catch (error) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Attempt to reshim asdf to make vcm command immediately available
|
|
27
|
-
*/
|
|
28
|
-
function reshimAsdf() {
|
|
29
|
-
try {
|
|
30
|
-
execSync('asdf reshim nodejs 2>/dev/null', { encoding: 'utf8' });
|
|
31
|
-
return true;
|
|
32
|
-
} catch (error) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function checkForExistingAna() {
|
|
38
|
-
try {
|
|
39
|
-
// Check if 'vcm' command exists in PATH before installation
|
|
40
|
-
// We need to check the actual binary, not symlinks
|
|
41
|
-
const result = execSync('which vcm 2>/dev/null || true', { encoding: 'utf8' });
|
|
42
|
-
const vcmPath = result.trim();
|
|
43
|
-
|
|
44
|
-
if (!vcmPath) {
|
|
45
|
-
// No vcm found - safe to install
|
|
46
|
-
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
47
|
-
console.log(chalk.gray(' You can use either:'));
|
|
48
|
-
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
49
|
-
|
|
50
|
-
// Check if user is using asdf and attempt to reshim
|
|
51
|
-
const isAsdf = detectAsdf();
|
|
52
|
-
if (isAsdf) {
|
|
53
|
-
const reshimSuccess = reshimAsdf();
|
|
54
|
-
if (reshimSuccess) {
|
|
55
|
-
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
56
|
-
} else {
|
|
57
|
-
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
58
|
-
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
59
|
-
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
console.log();
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Check if it's a real file (not a broken symlink from previous install)
|
|
68
|
-
try {
|
|
69
|
-
fs.accessSync(vcmPath, fs.constants.X_OK);
|
|
70
|
-
|
|
71
|
-
// Read the file to see if it's ours
|
|
72
|
-
const content = fs.readFileSync(vcmPath, 'utf8');
|
|
73
|
-
|
|
74
|
-
// Check if this is our VibeCodingMachine binary
|
|
75
|
-
if (content.includes('VibeCodingMachine CLI') || content.includes('vibecodingmachine')) {
|
|
76
|
-
// It's ours, all good
|
|
77
|
-
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
78
|
-
console.log(chalk.gray(' You can use either:'));
|
|
79
|
-
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
80
|
-
|
|
81
|
-
// Check if user is using asdf and attempt to reshim
|
|
82
|
-
const isAsdf = detectAsdf();
|
|
83
|
-
if (isAsdf) {
|
|
84
|
-
const reshimSuccess = reshimAsdf();
|
|
85
|
-
if (reshimSuccess) {
|
|
86
|
-
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
87
|
-
} else {
|
|
88
|
-
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
89
|
-
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
90
|
-
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
console.log();
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// It's NOT ours - there's a conflict
|
|
99
|
-
console.log(chalk.yellow('\n⚠️ Warning: An existing "vcm" command was detected at:'));
|
|
100
|
-
console.log(chalk.yellow(` ${vcmPath}`));
|
|
101
|
-
console.log(chalk.yellow('\n The "vcm" shortcut will NOT be installed to avoid conflicts.'));
|
|
102
|
-
console.log(chalk.cyan(' You can still use the full command: ') + chalk.bold('vibecodingmachine'));
|
|
103
|
-
console.log();
|
|
104
|
-
|
|
105
|
-
// Remove vcm from bin to prevent conflict
|
|
106
|
-
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
107
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
108
|
-
|
|
109
|
-
if (packageJson.bin && packageJson.bin.vcm) {
|
|
110
|
-
delete packageJson.bin.vcm;
|
|
111
|
-
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
112
|
-
console.log(chalk.gray(' ✓ Removed "vcm" from bin configuration to prevent conflict\n'));
|
|
113
|
-
}
|
|
114
|
-
} catch (err) {
|
|
115
|
-
// File doesn't exist or can't be read - probably safe to install
|
|
116
|
-
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
117
|
-
console.log(chalk.gray(' You can use either:'));
|
|
118
|
-
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
119
|
-
|
|
120
|
-
// Check if user is using asdf and attempt to reshim
|
|
121
|
-
const isAsdf = detectAsdf();
|
|
122
|
-
if (isAsdf) {
|
|
123
|
-
const reshimSuccess = reshimAsdf();
|
|
124
|
-
if (reshimSuccess) {
|
|
125
|
-
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
126
|
-
} else {
|
|
127
|
-
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
128
|
-
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
129
|
-
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
console.log();
|
|
134
|
-
}
|
|
135
|
-
} catch (error) {
|
|
136
|
-
// Error running which - assume no vcm exists
|
|
137
|
-
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
138
|
-
console.log(chalk.gray(' You can use either:'));
|
|
139
|
-
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
140
|
-
|
|
141
|
-
// Check if user is using asdf and attempt to reshim
|
|
142
|
-
const isAsdf = detectAsdf();
|
|
143
|
-
if (isAsdf) {
|
|
144
|
-
const reshimSuccess = reshimAsdf();
|
|
145
|
-
if (reshimSuccess) {
|
|
146
|
-
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
147
|
-
} else {
|
|
148
|
-
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
149
|
-
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
150
|
-
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
console.log();
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Only run if not being installed as a dependency
|
|
159
|
-
if (process.env.npm_config_global || process.env.npm_config_prefix) {
|
|
160
|
-
checkForExistingAna();
|
|
161
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post-install script to check if 'vcm' command exists
|
|
5
|
+
* and warn users if there's a conflict
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Detect if user is using asdf for Node.js version management
|
|
15
|
+
*/
|
|
16
|
+
function detectAsdf() {
|
|
17
|
+
try {
|
|
18
|
+
const nodePath = execSync('which node 2>/dev/null || true', { encoding: 'utf8' }).trim();
|
|
19
|
+
return nodePath.includes('/.asdf/');
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Attempt to reshim asdf to make vcm command immediately available
|
|
27
|
+
*/
|
|
28
|
+
function reshimAsdf() {
|
|
29
|
+
try {
|
|
30
|
+
execSync('asdf reshim nodejs 2>/dev/null', { encoding: 'utf8' });
|
|
31
|
+
return true;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function checkForExistingAna() {
|
|
38
|
+
try {
|
|
39
|
+
// Check if 'vcm' command exists in PATH before installation
|
|
40
|
+
// We need to check the actual binary, not symlinks
|
|
41
|
+
const result = execSync('which vcm 2>/dev/null || true', { encoding: 'utf8' });
|
|
42
|
+
const vcmPath = result.trim();
|
|
43
|
+
|
|
44
|
+
if (!vcmPath) {
|
|
45
|
+
// No vcm found - safe to install
|
|
46
|
+
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
47
|
+
console.log(chalk.gray(' You can use either:'));
|
|
48
|
+
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
49
|
+
|
|
50
|
+
// Check if user is using asdf and attempt to reshim
|
|
51
|
+
const isAsdf = detectAsdf();
|
|
52
|
+
if (isAsdf) {
|
|
53
|
+
const reshimSuccess = reshimAsdf();
|
|
54
|
+
if (reshimSuccess) {
|
|
55
|
+
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
56
|
+
} else {
|
|
57
|
+
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
58
|
+
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
59
|
+
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check if it's a real file (not a broken symlink from previous install)
|
|
68
|
+
try {
|
|
69
|
+
fs.accessSync(vcmPath, fs.constants.X_OK);
|
|
70
|
+
|
|
71
|
+
// Read the file to see if it's ours
|
|
72
|
+
const content = fs.readFileSync(vcmPath, 'utf8');
|
|
73
|
+
|
|
74
|
+
// Check if this is our VibeCodingMachine binary
|
|
75
|
+
if (content.includes('VibeCodingMachine CLI') || content.includes('vibecodingmachine')) {
|
|
76
|
+
// It's ours, all good
|
|
77
|
+
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
78
|
+
console.log(chalk.gray(' You can use either:'));
|
|
79
|
+
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
80
|
+
|
|
81
|
+
// Check if user is using asdf and attempt to reshim
|
|
82
|
+
const isAsdf = detectAsdf();
|
|
83
|
+
if (isAsdf) {
|
|
84
|
+
const reshimSuccess = reshimAsdf();
|
|
85
|
+
if (reshimSuccess) {
|
|
86
|
+
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
87
|
+
} else {
|
|
88
|
+
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
89
|
+
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
90
|
+
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// It's NOT ours - there's a conflict
|
|
99
|
+
console.log(chalk.yellow('\n⚠️ Warning: An existing "vcm" command was detected at:'));
|
|
100
|
+
console.log(chalk.yellow(` ${vcmPath}`));
|
|
101
|
+
console.log(chalk.yellow('\n The "vcm" shortcut will NOT be installed to avoid conflicts.'));
|
|
102
|
+
console.log(chalk.cyan(' You can still use the full command: ') + chalk.bold('vibecodingmachine'));
|
|
103
|
+
console.log();
|
|
104
|
+
|
|
105
|
+
// Remove vcm from bin to prevent conflict
|
|
106
|
+
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
107
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
108
|
+
|
|
109
|
+
if (packageJson.bin && packageJson.bin.vcm) {
|
|
110
|
+
delete packageJson.bin.vcm;
|
|
111
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
112
|
+
console.log(chalk.gray(' ✓ Removed "vcm" from bin configuration to prevent conflict\n'));
|
|
113
|
+
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
// File doesn't exist or can't be read - probably safe to install
|
|
116
|
+
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
117
|
+
console.log(chalk.gray(' You can use either:'));
|
|
118
|
+
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
119
|
+
|
|
120
|
+
// Check if user is using asdf and attempt to reshim
|
|
121
|
+
const isAsdf = detectAsdf();
|
|
122
|
+
if (isAsdf) {
|
|
123
|
+
const reshimSuccess = reshimAsdf();
|
|
124
|
+
if (reshimSuccess) {
|
|
125
|
+
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
126
|
+
} else {
|
|
127
|
+
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
128
|
+
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
129
|
+
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.log();
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
// Error running which - assume no vcm exists
|
|
137
|
+
console.log(chalk.green('\n✓ Vibe Coding Machine CLI installed successfully!'));
|
|
138
|
+
console.log(chalk.gray(' You can use either:'));
|
|
139
|
+
console.log(chalk.cyan(' vibecodingmachine') + chalk.gray(' or ') + chalk.cyan('vcm'));
|
|
140
|
+
|
|
141
|
+
// Check if user is using asdf and attempt to reshim
|
|
142
|
+
const isAsdf = detectAsdf();
|
|
143
|
+
if (isAsdf) {
|
|
144
|
+
const reshimSuccess = reshimAsdf();
|
|
145
|
+
if (reshimSuccess) {
|
|
146
|
+
console.log(chalk.gray(' ✓ asdf reshimmed successfully'));
|
|
147
|
+
} else {
|
|
148
|
+
console.log(chalk.yellow('\n ⚠️ Note: You appear to be using asdf.'));
|
|
149
|
+
console.log(chalk.yellow(' If "vcm" command is not found, run:'));
|
|
150
|
+
console.log(chalk.cyan(' asdf reshim nodejs'));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Only run if not being installed as a dependency
|
|
159
|
+
if (process.env.npm_config_global || process.env.npm_config_prefix) {
|
|
160
|
+
checkForExistingAna();
|
|
161
|
+
}
|
package/src/commands/auth.js
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const auth = require('../utils/auth');
|
|
3
|
-
const { t, errorReporter } = require('vibecodingmachine-core');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Login command
|
|
7
|
-
* @param {Object} options - Command options
|
|
8
|
-
* @param {boolean} options.headless - Force headless mode (manual URL paste)
|
|
9
|
-
*/
|
|
10
|
-
async function login(options = {}) {
|
|
11
|
-
try {
|
|
12
|
-
// Check if already authenticated
|
|
13
|
-
const isAuth = await auth.isAuthenticated();
|
|
14
|
-
if (isAuth) {
|
|
15
|
-
const profile = await auth.getUserProfile();
|
|
16
|
-
console.log(chalk.green(`\n✓ ${t('auth.login.already', { email: chalk.bold(profile.email) })}`));
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Start login flow (auto-detects headless or use explicit flag)
|
|
21
|
-
const result = await auth.login({ headless: options.headless });
|
|
22
|
-
|
|
23
|
-
// After successful authentication, start interactive mode
|
|
24
|
-
if (result) {
|
|
25
|
-
console.log(chalk.cyan(`\n🚀 ${t('auth.starting.interactive')}\n`));
|
|
26
|
-
const { startInteractive } = require('../utils/interactive');
|
|
27
|
-
await startInteractive();
|
|
28
|
-
}
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error(chalk.red(`\n✗ ${t('auth.login.failed')}:`), error.message);
|
|
31
|
-
await errorReporter.reportError(error, {
|
|
32
|
-
command: 'auth:login',
|
|
33
|
-
headless: options.headless
|
|
34
|
-
});
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Logout command
|
|
41
|
-
*/
|
|
42
|
-
async function logout() {
|
|
43
|
-
try {
|
|
44
|
-
await auth.logout();
|
|
45
|
-
console.log(chalk.green(`\n✓ ${t('auth.logout.success')}`));
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error(chalk.red(`\n✗ ${t('auth.logout.failed')}:`), error.message);
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Status command
|
|
54
|
-
*/
|
|
55
|
-
async function status() {
|
|
56
|
-
try {
|
|
57
|
-
const isAuth = await auth.isAuthenticated();
|
|
58
|
-
|
|
59
|
-
if (!isAuth) {
|
|
60
|
-
console.log(chalk.yellow(`\n${t('auth.not.authenticated')}`));
|
|
61
|
-
console.log(t('auth.run.login', { command: chalk.cyan('vcm auth:login') }));
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const profile = await auth.getUserProfile();
|
|
66
|
-
|
|
67
|
-
// Get usage stats
|
|
68
|
-
const canRun = await auth.canRunAutoMode();
|
|
69
|
-
|
|
70
|
-
console.log(chalk.bold(`\n👤 ${t('profile.name')}:`));
|
|
71
|
-
console.log(` ${t('profile.name')}: ${profile.name}`);
|
|
72
|
-
console.log(` ${t('profile.email')}: ${profile.email}`);
|
|
73
|
-
console.log(` ${t('profile.tier')}: ${profile.tier === 'premium' ? chalk.green(t('profile.tier.premium')) : t('profile.tier.free')}`);
|
|
74
|
-
|
|
75
|
-
console.log(chalk.bold(`\n📊 ${t('profile.usage')}:`));
|
|
76
|
-
if (canRun.features && canRun.features.unlimitedIterations) {
|
|
77
|
-
console.log(` ${t('profile.daily.usage')}: ${canRun.todayUsage} ${t('profile.iterations')}`);
|
|
78
|
-
console.log(` ${t('profile.limit')}: ${chalk.green(t('profile.unlimited'))}`);
|
|
79
|
-
} else {
|
|
80
|
-
const limitColor = canRun.todayUsage >= canRun.maxIterations ? chalk.red : chalk.green;
|
|
81
|
-
console.log(` ${t('profile.daily.usage')}: ${limitColor(`${canRun.todayUsage}/${canRun.maxIterations}`)} ${t('profile.iterations')}`);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!canRun.canRun) {
|
|
85
|
-
console.log(chalk.red(`\n⚠️ ${t('quota.exceeded.warning', { reason: canRun.reason })}`));
|
|
86
|
-
if (profile.tier !== 'premium') {
|
|
87
|
-
console.log(chalk.gray(t('profile.upgrade.suggestion')));
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(chalk.red(`\n✗ ${t('status.check.failed')}:`), error.message);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
module.exports = {
|
|
97
|
-
login,
|
|
98
|
-
logout,
|
|
99
|
-
status
|
|
100
|
-
};
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const auth = require('../utils/auth');
|
|
3
|
+
const { t, errorReporter } = require('vibecodingmachine-core');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Login command
|
|
7
|
+
* @param {Object} options - Command options
|
|
8
|
+
* @param {boolean} options.headless - Force headless mode (manual URL paste)
|
|
9
|
+
*/
|
|
10
|
+
async function login(options = {}) {
|
|
11
|
+
try {
|
|
12
|
+
// Check if already authenticated
|
|
13
|
+
const isAuth = await auth.isAuthenticated();
|
|
14
|
+
if (isAuth) {
|
|
15
|
+
const profile = await auth.getUserProfile();
|
|
16
|
+
console.log(chalk.green(`\n✓ ${t('auth.login.already', { email: chalk.bold(profile.email) })}`));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Start login flow (auto-detects headless or use explicit flag)
|
|
21
|
+
const result = await auth.login({ headless: options.headless });
|
|
22
|
+
|
|
23
|
+
// After successful authentication, start interactive mode
|
|
24
|
+
if (result) {
|
|
25
|
+
console.log(chalk.cyan(`\n🚀 ${t('auth.starting.interactive')}\n`));
|
|
26
|
+
const { startInteractive } = require('../utils/interactive');
|
|
27
|
+
await startInteractive();
|
|
28
|
+
}
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error(chalk.red(`\n✗ ${t('auth.login.failed')}:`), error.message);
|
|
31
|
+
await errorReporter.reportError(error, {
|
|
32
|
+
command: 'auth:login',
|
|
33
|
+
headless: options.headless
|
|
34
|
+
});
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Logout command
|
|
41
|
+
*/
|
|
42
|
+
async function logout() {
|
|
43
|
+
try {
|
|
44
|
+
await auth.logout();
|
|
45
|
+
console.log(chalk.green(`\n✓ ${t('auth.logout.success')}`));
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error(chalk.red(`\n✗ ${t('auth.logout.failed')}:`), error.message);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Status command
|
|
54
|
+
*/
|
|
55
|
+
async function status() {
|
|
56
|
+
try {
|
|
57
|
+
const isAuth = await auth.isAuthenticated();
|
|
58
|
+
|
|
59
|
+
if (!isAuth) {
|
|
60
|
+
console.log(chalk.yellow(`\n${t('auth.not.authenticated')}`));
|
|
61
|
+
console.log(t('auth.run.login', { command: chalk.cyan('vcm auth:login') }));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const profile = await auth.getUserProfile();
|
|
66
|
+
|
|
67
|
+
// Get usage stats
|
|
68
|
+
const canRun = await auth.canRunAutoMode();
|
|
69
|
+
|
|
70
|
+
console.log(chalk.bold(`\n👤 ${t('profile.name')}:`));
|
|
71
|
+
console.log(` ${t('profile.name')}: ${profile.name}`);
|
|
72
|
+
console.log(` ${t('profile.email')}: ${profile.email}`);
|
|
73
|
+
console.log(` ${t('profile.tier')}: ${profile.tier === 'premium' ? chalk.green(t('profile.tier.premium')) : t('profile.tier.free')}`);
|
|
74
|
+
|
|
75
|
+
console.log(chalk.bold(`\n📊 ${t('profile.usage')}:`));
|
|
76
|
+
if (canRun.features && canRun.features.unlimitedIterations) {
|
|
77
|
+
console.log(` ${t('profile.daily.usage')}: ${canRun.todayUsage} ${t('profile.iterations')}`);
|
|
78
|
+
console.log(` ${t('profile.limit')}: ${chalk.green(t('profile.unlimited'))}`);
|
|
79
|
+
} else {
|
|
80
|
+
const limitColor = canRun.todayUsage >= canRun.maxIterations ? chalk.red : chalk.green;
|
|
81
|
+
console.log(` ${t('profile.daily.usage')}: ${limitColor(`${canRun.todayUsage}/${canRun.maxIterations}`)} ${t('profile.iterations')}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!canRun.canRun) {
|
|
85
|
+
console.log(chalk.red(`\n⚠️ ${t('quota.exceeded.warning', { reason: canRun.reason })}`));
|
|
86
|
+
if (profile.tier !== 'premium') {
|
|
87
|
+
console.log(chalk.gray(t('profile.upgrade.suggestion')));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(chalk.red(`\n✗ ${t('status.check.failed')}:`), error.message);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
login,
|
|
98
|
+
logout,
|
|
99
|
+
status
|
|
100
|
+
};
|