vibecodingmachine-cli 2026.1.29-713 → 2026.2.20-423

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 (45) hide show
  1. package/bin/vibecodingmachine.js +124 -0
  2. package/package.json +3 -2
  3. package/src/commands/agents-check.js +69 -0
  4. package/src/commands/auto-direct.js +930 -145
  5. package/src/commands/auto.js +26 -4
  6. package/src/commands/ide.js +2 -1
  7. package/src/commands/requirements.js +23 -27
  8. package/src/utils/auto-mode.js +4 -1
  9. package/src/utils/cline-js-handler.js +218 -0
  10. package/src/utils/config.js +22 -0
  11. package/src/utils/display-formatters-complete.js +229 -0
  12. package/src/utils/display-formatters-extracted.js +219 -0
  13. package/src/utils/display-formatters.js +157 -0
  14. package/src/utils/feedback-handler.js +143 -0
  15. package/src/utils/ide-detection-complete.js +126 -0
  16. package/src/utils/ide-detection-extracted.js +116 -0
  17. package/src/utils/ide-detection.js +124 -0
  18. package/src/utils/interactive-backup.js +5664 -0
  19. package/src/utils/interactive-broken.js +280 -0
  20. package/src/utils/interactive.js +31 -5534
  21. package/src/utils/provider-checker.js +410 -0
  22. package/src/utils/provider-manager.js +251 -0
  23. package/src/utils/provider-registry.js +18 -9
  24. package/src/utils/requirement-actions.js +884 -0
  25. package/src/utils/requirements-navigator.js +585 -0
  26. package/src/utils/rui-trui-adapter.js +311 -0
  27. package/src/utils/simple-trui.js +204 -0
  28. package/src/utils/status-helpers-extracted.js +125 -0
  29. package/src/utils/status-helpers.js +107 -0
  30. package/src/utils/trui-debug.js +261 -0
  31. package/src/utils/trui-feedback.js +133 -0
  32. package/src/utils/trui-nav-agents.js +119 -0
  33. package/src/utils/trui-nav-requirements.js +268 -0
  34. package/src/utils/trui-nav-settings.js +157 -0
  35. package/src/utils/trui-nav-specifications.js +139 -0
  36. package/src/utils/trui-navigation.js +303 -0
  37. package/src/utils/trui-provider-manager.js +182 -0
  38. package/src/utils/trui-quick-menu.js +365 -0
  39. package/src/utils/trui-req-actions.js +372 -0
  40. package/src/utils/trui-req-tree.js +534 -0
  41. package/src/utils/trui-specifications.js +359 -0
  42. package/src/utils/trui-text-editor.js +350 -0
  43. package/src/utils/trui-windsurf.js +336 -0
  44. package/src/utils/welcome-screen-extracted.js +135 -0
  45. package/src/utils/welcome-screen.js +134 -0
@@ -0,0 +1,143 @@
1
+ const chalk = require('chalk');
2
+ const inquirer = require('inquirer');
3
+ const readline = require('readline');
4
+ const { t } = require('vibecodingmachine-core');
5
+ const pkg = require('../../package.json');
6
+
7
+ /**
8
+ * Handle feedback submission
9
+ */
10
+ async function handleFeedbackSubmission() {
11
+ console.log(chalk.bold.cyan('\nšŸ“£ ' + t('interactive.feedback.title')));
12
+ console.log(chalk.gray(t('interactive.feedback.instructions') + '\n'));
13
+
14
+ const { getUserProfile } = require('./auth');
15
+ const userProfile = await getUserProfile();
16
+ const userEmail = userProfile ? userProfile.email : 'anonymous';
17
+
18
+ // Ask if user wants to include a screenshot
19
+ let includeScreenshot = false;
20
+ let screenshotData = null;
21
+
22
+ try {
23
+ const { screenshot } = await inquirer.prompt([{
24
+ type: 'confirm',
25
+ name: 'screenshot',
26
+ message: 'Include a screenshot with your feedback?',
27
+ default: false
28
+ }]);
29
+
30
+ includeScreenshot = screenshot;
31
+
32
+ if (includeScreenshot) {
33
+ console.log(chalk.gray('šŸ“ø Capturing screenshot...'));
34
+ try {
35
+ const screenshot = require('screenshot-desktop');
36
+ const imgBuffer = await screenshot({ format: 'png' });
37
+
38
+ // Convert to base64 and check size
39
+ const base64 = imgBuffer.toString('base64');
40
+ const dataUrl = `data:image/png;base64,${base64}`;
41
+ const size = Buffer.byteLength(dataUrl, 'utf8');
42
+
43
+ // Much stricter size limit - 100KB max
44
+ if (size > 100 * 1024) {
45
+ console.log(chalk.yellow('āš ļø Screenshot is too large, submitting feedback without screenshot'));
46
+ includeScreenshot = false;
47
+ } else {
48
+ screenshotData = dataUrl;
49
+ console.log(chalk.green(`āœ… Screenshot captured (${(size / 1024).toFixed(2)} KB)`));
50
+ }
51
+ } catch (screenshotError) {
52
+ console.log(chalk.yellow('āš ļø Failed to capture screenshot, continuing without it'));
53
+ includeScreenshot = false;
54
+ }
55
+ }
56
+ } catch (err) {
57
+ // User cancelled or error occurred
58
+ includeScreenshot = false;
59
+ }
60
+
61
+ console.log(chalk.gray('\n' + t('interactive.feedback.comment.instructions') + '\n'));
62
+
63
+ const commentLines = [];
64
+ let emptyLineCount = 0;
65
+ let isFirstLine = true;
66
+
67
+ while (true) {
68
+ try {
69
+ const { line } = await inquirer.prompt([{
70
+ type: 'input',
71
+ name: 'line',
72
+ message: isFirstLine ? t('interactive.feedback.comment') : ''
73
+ }]);
74
+
75
+ isFirstLine = false;
76
+
77
+ if (line.trim() === '') {
78
+ emptyLineCount++;
79
+ if (emptyLineCount >= 2) break;
80
+ } else {
81
+ emptyLineCount = 0;
82
+ commentLines.push(line);
83
+ }
84
+ } catch (err) {
85
+ break;
86
+ }
87
+ }
88
+
89
+ const comment = commentLines.join('\n');
90
+
91
+ if (!comment || comment.trim().length === 0) {
92
+ console.log(chalk.yellow('\nāš ļø ' + t('interactive.feedback.cancelled')));
93
+ return;
94
+ }
95
+
96
+ try {
97
+ console.log(chalk.gray('\n' + t('interactive.feedback.submitting') + '...'));
98
+
99
+ const auth = require('./auth');
100
+ const UserDatabase = require('vibecodingmachine-core/src/database/user-schema');
101
+ const userDb = new UserDatabase();
102
+
103
+ // Set auth token for API requests
104
+ const token = await auth.getAuthToken();
105
+ if (token) {
106
+ userDb.setAuthToken(token);
107
+ }
108
+
109
+ const feedbackData = {
110
+ email: userEmail,
111
+ comment: comment,
112
+ interface: 'cli',
113
+ version: pkg.version,
114
+ type: 'cli_feedback'
115
+ };
116
+
117
+ if (includeScreenshot && screenshotData) {
118
+ feedbackData.screenshot = screenshotData;
119
+ }
120
+
121
+ await userDb.submitFeedback(feedbackData);
122
+
123
+ console.log(chalk.green('\nāœ“ ' + t('interactive.feedback.success')));
124
+ } catch (error) {
125
+ console.log(chalk.red('\nāœ— ' + t('interactive.feedback.error') + ': ') + error.message);
126
+ }
127
+
128
+ console.log(chalk.gray(`\n${t('interactive.press.enter.continue')}`));
129
+ await new Promise(resolve => {
130
+ const rl = readline.createInterface({
131
+ input: process.stdin,
132
+ output: process.stdout
133
+ });
134
+ rl.question('', () => {
135
+ rl.close();
136
+ resolve();
137
+ });
138
+ });
139
+ }
140
+
141
+ module.exports = {
142
+ handleFeedbackSubmission
143
+ };
@@ -0,0 +1,126 @@
1
+ const os = require('os');
2
+ const path = require('path');
3
+ const fs = require('fs-extra');
4
+ const { exec } = require('child_process');
5
+ const util = require('util');
6
+ const execAsync = util.promisify(exec);
7
+
8
+ /**
9
+ * Check if a VS Code extension is installed
10
+ * @param {string} extensionId - Extension ID to check
11
+ * @returns {boolean} - Whether extension is installed
12
+ */
13
+ async function checkVSCodeExtension(extensionId) {
14
+ // Check if a VS Code extension is installed
15
+ try {
16
+ const { stdout } = await execAsync('code --list-extensions', { timeout: 5000 });
17
+ const extensions = stdout.toLowerCase().split('\n').map(e => e.trim());
18
+
19
+ // Map common extension IDs to their actual extension IDs
20
+ const extensionMap = {
21
+ 'github-copilot': 'github.copilot',
22
+ 'amazon-q': 'amazonwebservices.amazon-q-vscode'
23
+ };
24
+
25
+ const actualExtensionId = extensionMap[extensionId] || extensionId;
26
+ return extensions.includes(actualExtensionId.toLowerCase());
27
+ } catch (error) {
28
+ // If code CLI is not available or command fails, return false
29
+ return false;
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Check if applications or binaries exist on the system
35
+ * @param {string[]} names - App bundle base names (e.g., 'Cursor' -> /Applications/Cursor.app)
36
+ * @param {string[]} binaries - CLI binary names to check on PATH (e.g., 'code')
37
+ * @returns {boolean} - Whether any of the specified apps/bins are found
38
+ */
39
+ async function checkAppOrBinary(names = [], binaries = []) {
40
+ // names: app bundle base names (e.g., 'Cursor' -> /Applications/Cursor.app)
41
+ // binaries: CLI binary names to check on PATH (e.g., 'code')
42
+ const platform = os.platform();
43
+ // Check common application directories
44
+ if (platform === 'darwin') {
45
+ const appDirs = ['/Applications', path.join(os.homedir(), 'Applications')];
46
+ for (const appName of names) {
47
+ for (const dir of appDirs) {
48
+ try {
49
+ const p = path.join(dir, `${appName}.app`);
50
+ if (await fs.pathExists(p)) {
51
+ // Ensure this is a real application bundle (has Contents/MacOS executable)
52
+ try {
53
+ const macosDir = path.join(p, 'Contents', 'MacOS');
54
+ const exists = await fs.pathExists(macosDir);
55
+ if (exists) {
56
+ const files = await fs.readdir(macosDir);
57
+ if (files && files.length > 0) {
58
+ // Prefer to ensure the app is usable: use spctl to assess, fallback to quarantine xattr
59
+ try {
60
+ // spctl returns non-zero on rejected/invalid apps
61
+ // Use async exec to avoid blocking the event loop
62
+ await execAsync(`spctl --assess -v "${p}"`, { timeout: 5000 });
63
+
64
+ // additionally validate codesign quickly (timeout to avoid hangs)
65
+ try {
66
+ await execAsync(`codesign -v --deep --strict "${p}"`, { timeout: 5000 });
67
+ return true;
68
+ } catch (csErr) {
69
+ // codesign failed or timed out — treat as not usable/damaged
70
+ return false;
71
+ }
72
+ } catch (e) {
73
+ // spctl failed or timed out — check if app has quarantine attribute
74
+ try {
75
+ const { stdout } = await execAsync(`xattr -p com.apple.quarantine "${p}" 2>/dev/null || true`, { encoding: 'utf8' });
76
+ const out = stdout.trim();
77
+ if (!out) {
78
+ // no quarantine attribute but spctl failed — be conservative and treat as not installed
79
+ return false;
80
+ }
81
+ // If quarantine attribute exists, treat as not installed (damaged/not allowed)
82
+ return false;
83
+ } catch (e2) {
84
+ return false;
85
+ }
86
+ }
87
+ }
88
+ }
89
+ } catch (e) {
90
+ // if we can't stat inside, be conservative and continue searching
91
+ }
92
+ }
93
+ } catch (e) {
94
+ /* ignore */
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // Check PATH for known binaries
101
+ for (const bin of binaries) {
102
+ try {
103
+ await execAsync(`which ${bin}`, { timeout: 2000 });
104
+ return true;
105
+ } catch (e) {
106
+ /* not found */
107
+ }
108
+ }
109
+
110
+ // Check common Homebrew bin locations
111
+ const brewPaths = ['/opt/homebrew/bin', '/usr/local/bin'];
112
+ for (const bin of binaries) {
113
+ for (const brew of brewPaths) {
114
+ try {
115
+ if (await fs.pathExists(path.join(brew, bin))) return true;
116
+ } catch (e) { /* ignore */ }
117
+ }
118
+ }
119
+
120
+ return false;
121
+ }
122
+
123
+ module.exports = {
124
+ checkVSCodeExtension,
125
+ checkAppOrBinary
126
+ };
@@ -0,0 +1,116 @@
1
+ const os = require('os');
2
+ const path = require('path');
3
+ const fs = require('fs-extra');
4
+ const { exec } = require('child_process');
5
+ const util = require('util');
6
+ const execAsync = util.promisify(exec);
7
+
8
+ async function checkVSCodeExtension(extensionId) {
9
+ // Check if a VS Code extension is installed
10
+ try {
11
+ const { stdout } = await execAsync('code --list-extensions', { timeout: 5000 });
12
+ const extensions = stdout.toLowerCase().split('\n').map(e => e.trim());
13
+
14
+ // Map common extension IDs to their actual extension IDs
15
+ const extensionMap = {
16
+ 'github-copilot': 'github.copilot',
17
+ 'amazon-q': 'amazonwebservices.amazon-q-vscode',
18
+ 'cline': 'saoudrizwan.claude-dev'
19
+ };
20
+
21
+ const actualExtensionId = extensionMap[extensionId] || extensionId;
22
+ return extensions.includes(actualExtensionId.toLowerCase());
23
+ } catch (error) {
24
+ // If code CLI is not available or command fails, return false
25
+ return false;
26
+ }
27
+ }
28
+
29
+ async function checkAppOrBinary(names = [], binaries = []) {
30
+ // names: app bundle base names (e.g., 'Cursor' -> /Applications/Cursor.app)
31
+ // binaries: CLI binary names to check on PATH (e.g., 'code')
32
+ const platform = os.platform();
33
+ // Check common application directories
34
+ if (platform === 'darwin') {
35
+ const appDirs = ['/Applications', path.join(os.homedir(), 'Applications')];
36
+ for (const appName of names) {
37
+ for (const dir of appDirs) {
38
+ try {
39
+ const p = path.join(dir, `${appName}.app`);
40
+ if (await fs.pathExists(p)) {
41
+ // Ensure this is a real application bundle (has Contents/MacOS executable)
42
+ try {
43
+ const macosDir = path.join(p, 'Contents', 'MacOS');
44
+ const exists = await fs.pathExists(macosDir);
45
+ if (exists) {
46
+ const files = await fs.readdir(macosDir);
47
+ if (files && files.length > 0) {
48
+ // Prefer to ensure the app is usable: use spctl to assess, fallback to quarantine xattr
49
+ try {
50
+ // spctl returns non-zero on rejected/invalid apps
51
+ // Use async exec to avoid blocking the event loop
52
+ await execAsync(`spctl --assess -v "${p}"`, { timeout: 5000 });
53
+
54
+ // additionally validate codesign quickly (timeout to avoid hangs)
55
+ try {
56
+ await execAsync(`codesign -v --deep --strict "${p}"`, { timeout: 5000 });
57
+ return true;
58
+ } catch (csErr) {
59
+ // codesign failed or timed out — treat as not usable/damaged
60
+ return false;
61
+ }
62
+ } catch (e) {
63
+ // spctl failed or timed out — check if app has quarantine attribute
64
+ try {
65
+ const { stdout } = await execAsync(`xattr -p com.apple.quarantine "${p}" 2>/dev/null || true`, { encoding: 'utf8' });
66
+ const out = stdout.trim();
67
+ if (!out) {
68
+ // no quarantine attribute but spctl failed — be conservative and treat as not installed
69
+ return false;
70
+ }
71
+ // If quarantine attribute exists, treat as not installed (damaged/not allowed)
72
+ return false;
73
+ } catch (e2) {
74
+ return false;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ } catch (e) {
80
+ // if we can't stat inside, be conservative and continue searching
81
+ }
82
+ }
83
+ } catch (e) {
84
+ /* ignore */
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ // Check PATH for known binaries
91
+ for (const bin of binaries) {
92
+ try {
93
+ await execAsync(`which ${bin}`, { timeout: 2000 });
94
+ return true;
95
+ } catch (e) {
96
+ /* not found */
97
+ }
98
+ }
99
+
100
+ // Check common Homebrew bin locations
101
+ const brewPaths = ['/opt/homebrew/bin', '/usr/local/bin'];
102
+ for (const bin of binaries) {
103
+ for (const brew of brewPaths) {
104
+ try {
105
+ if (await fs.pathExists(path.join(brew, bin))) return true;
106
+ } catch (e) { /* ignore */ }
107
+ }
108
+ }
109
+
110
+ return false;
111
+ }
112
+
113
+ module.exports = {
114
+ checkVSCodeExtension,
115
+ checkAppOrBinary
116
+ };
@@ -0,0 +1,124 @@
1
+ const os = require('os');
2
+ const path = require('path');
3
+ const fs = require('fs-extra');
4
+ const { exec } = require('child_process');
5
+ const util = require('util');
6
+ const execAsync = util.promisify(exec);
7
+
8
+ /**
9
+ * Check if a VS Code extension is installed
10
+ * @param {string} extensionId - Extension ID to check
11
+ * @returns {boolean} - Whether extension is installed
12
+ */
13
+ async function checkVSCodeExtension(extensionId) {
14
+ try {
15
+ const { stdout } = await execAsync('code --list-extensions', { timeout: 5000 });
16
+ const extensions = stdout.toLowerCase().split('\n').map(e => e.trim());
17
+
18
+ // Map common extension IDs to their actual extension IDs
19
+ const extensionMap = {
20
+ 'github-copilot': 'github.copilot',
21
+ 'amazon-q': 'amazonwebservices.amazon-q-vscode'
22
+ };
23
+
24
+ const actualExtensionId = extensionMap[extensionId] || extensionId;
25
+ return extensions.includes(actualExtensionId.toLowerCase());
26
+ } catch (error) {
27
+ // If code CLI is not available or command fails, return false
28
+ return false;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Check if applications or binaries exist on the system
34
+ * @param {string[]} names - App bundle base names (e.g., 'Cursor' -> /Applications/Cursor.app)
35
+ * @param {string[]} binaries - CLI binary names to check on PATH (e.g., 'code')
36
+ * @returns {boolean} - Whether any of the specified apps/bins are found
37
+ */
38
+ async function checkAppOrBinary(names = [], binaries = []) {
39
+ const platform = os.platform();
40
+
41
+ // Check common application directories
42
+ if (platform === 'darwin') {
43
+ const appDirs = ['/Applications', path.join(os.homedir(), 'Applications')];
44
+ for (const appName of names) {
45
+ for (const dir of appDirs) {
46
+ try {
47
+ const p = path.join(dir, `${appName}.app`);
48
+ if (await fs.pathExists(p)) {
49
+ // Ensure this is a real application bundle (has Contents/MacOS executable)
50
+ try {
51
+ const macosDir = path.join(p, 'Contents', 'MacOS');
52
+ const exists = await fs.pathExists(macosDir);
53
+ if (exists) {
54
+ const files = await fs.readdir(macosDir);
55
+ if (files && files.length > 0) {
56
+ // Prefer to ensure the app is usable: use spctl to assess, fallback to quarantine xattr
57
+ try {
58
+ // spctl returns non-zero on rejected/invalid apps
59
+ // Use async exec to avoid blocking the event loop
60
+ await execAsync(`spctl --assess -v "${p}"`, { timeout: 5000 });
61
+
62
+ // additionally validate codesign quickly (timeout to avoid hangs)
63
+ try {
64
+ await execAsync(`codesign -v --deep --strict "${p}"`, { timeout: 5000 });
65
+ return true;
66
+ } catch (csErr) {
67
+ // codesign failed or timed out — treat as not usable/damaged
68
+ return false;
69
+ }
70
+ } catch (e) {
71
+ // spctl failed or timed out — check if app has quarantine attribute
72
+ try {
73
+ const { stdout } = await execAsync(`xattr -p com.apple.quarantine "${p}" 2>/dev/null || true`, { encoding: 'utf8' });
74
+ const out = stdout.trim();
75
+ if (!out) {
76
+ // no quarantine attribute but spctl failed — be conservative and treat as not installed
77
+ return false;
78
+ }
79
+ // If quarantine attribute exists, treat as not installed (damaged/not allowed)
80
+ return false;
81
+ } catch (e2) {
82
+ return false;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ } catch (e) {
88
+ // if we can't stat inside, be conservative and continue searching
89
+ }
90
+ }
91
+ } catch (e) {
92
+ /* ignore */
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ // Check PATH for known binaries
99
+ for (const bin of binaries) {
100
+ try {
101
+ await execAsync(`which ${bin}`, { timeout: 2000 });
102
+ return true;
103
+ } catch (e) {
104
+ /* not found */
105
+ }
106
+ }
107
+
108
+ // Check common Homebrew bin locations
109
+ const brewPaths = ['/opt/homebrew/bin', '/usr/local/bin'];
110
+ for (const bin of binaries) {
111
+ for (const brew of brewPaths) {
112
+ try {
113
+ if (await fs.pathExists(path.join(brew, bin))) return true;
114
+ } catch (e) { /* ignore */ }
115
+ }
116
+ }
117
+
118
+ return false;
119
+ }
120
+
121
+ module.exports = {
122
+ checkVSCodeExtension,
123
+ checkAppOrBinary
124
+ };