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
|
@@ -11,16 +11,70 @@ async function installAntigravity() {
|
|
|
11
11
|
const spinner = ora('Checking system requirements...').start();
|
|
12
12
|
await new Promise((r) => setTimeout(r, 800));
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const platform = os.platform();
|
|
15
|
+
const arch = os.arch();
|
|
16
|
+
const isArm = arch === 'arm64';
|
|
17
|
+
|
|
18
|
+
// Handle Windows platform
|
|
19
|
+
if (platform === 'win32') {
|
|
20
|
+
spinner.succeed(`System OK (${arch === 'x64' ? 'x64' : 'ARM64'})`);
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const cacheDir = path.join(os.homedir(), '.vibecodingmachine', 'cache');
|
|
24
|
+
await fs.ensureDir(cacheDir);
|
|
25
|
+
|
|
26
|
+
// Try to find Antigravity installation on Windows
|
|
27
|
+
const possiblePaths = [
|
|
28
|
+
'C:\\Program Files\\Google\\Antigravity\\Antigravity.exe',
|
|
29
|
+
'C:\\Program Files (x86)\\Google\\Antigravity\\Antigravity.exe',
|
|
30
|
+
path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'Antigravity', 'Antigravity.exe'),
|
|
31
|
+
'antigravity.exe' // Try PATH
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
let antigravityPath = null;
|
|
35
|
+
for (const testPath of possiblePaths) {
|
|
36
|
+
try {
|
|
37
|
+
if (await fs.pathExists(testPath)) {
|
|
38
|
+
antigravityPath = testPath;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
} catch (e) {
|
|
42
|
+
// Continue checking
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (antigravityPath) {
|
|
47
|
+
console.log(chalk.green('\n✅ Antigravity is already installed!'));
|
|
48
|
+
console.log(chalk.gray(`Found at: ${antigravityPath}`));
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.log(chalk.yellow('\n⚠️ Antigravity not found. Please install manually:'));
|
|
53
|
+
console.log(chalk.cyan('1. Download from: https://antigravity.dev'));
|
|
54
|
+
console.log(chalk.cyan('2. Run the installer'));
|
|
55
|
+
console.log(chalk.cyan('3. Antigravity should be automatically detected'));
|
|
56
|
+
|
|
57
|
+
return false;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
spinner.fail('Windows installation check failed');
|
|
60
|
+
console.log(chalk.red('\nInstallation error:'), error.message);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// macOS installation (existing logic)
|
|
66
|
+
if (platform !== 'darwin' && platform !== 'win32') {
|
|
67
|
+
spinner.fail('Automated Antigravity installation is only supported on macOS and Windows');
|
|
16
68
|
return false;
|
|
17
69
|
}
|
|
18
70
|
|
|
19
|
-
|
|
20
|
-
|
|
71
|
+
// macOS-specific installation
|
|
72
|
+
if (platform === 'darwin') {
|
|
73
|
+
const macArch = os.arch();
|
|
74
|
+
const macIsArm = macArch === 'arm64';
|
|
21
75
|
|
|
22
|
-
|
|
23
|
-
|
|
76
|
+
// URLs from electron-app IDE installer
|
|
77
|
+
const downloadUrl = macIsArm
|
|
24
78
|
? 'https://edgedl.me.gvt1.com/edgedl/release2/j0qc3/antigravity/stable/1.11.2-6251250307170304/darwin-arm/Antigravity.dmg'
|
|
25
79
|
: 'https://edgedl.me.gvt1.com/edgedl/release2/j0qc3/antigravity/stable/1.11.2-6251250307170304/darwin-x64/Antigravity.dmg';
|
|
26
80
|
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clarification Actions Module
|
|
3
|
+
*
|
|
4
|
+
* Handles clarification-related requirement actions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const inquirer = require('inquirer');
|
|
9
|
+
const fs = require('fs-extra');
|
|
10
|
+
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
11
|
+
const { confirmAction } = require('./requirement-helpers');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Edit clarification responses
|
|
15
|
+
*/
|
|
16
|
+
async function editClarificationResponses(req, tree) {
|
|
17
|
+
console.log(chalk.bold.cyan(`\n✍️ Editing responses for: ${req.title}\n`));
|
|
18
|
+
|
|
19
|
+
if (!req.questions || req.questions.length === 0) {
|
|
20
|
+
console.log(chalk.yellow('No questions found for this requirement.'));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { questions } = await inquirer.prompt([
|
|
25
|
+
{
|
|
26
|
+
type: 'checkbox',
|
|
27
|
+
name: 'questions',
|
|
28
|
+
message: 'Select questions to respond to:',
|
|
29
|
+
choices: req.questions.map((q, idx) => ({
|
|
30
|
+
name: `${idx + 1}. ${q.question.replace(/^\d+\.\s*/, '')}`,
|
|
31
|
+
value: idx,
|
|
32
|
+
checked: !!q.response
|
|
33
|
+
}))
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
if (questions.length === 0) {
|
|
38
|
+
console.log(chalk.gray('No questions selected.'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const qIdx of questions) {
|
|
43
|
+
const question = req.questions[qIdx];
|
|
44
|
+
console.log(chalk.bold(`\nQuestion ${qIdx + 1}: ${question.question.replace(/^\d+\.\s*/, '')}`));
|
|
45
|
+
|
|
46
|
+
if (question.response) {
|
|
47
|
+
console.log(chalk.gray(`Current response: ${question.response}`));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const { response } = await inquirer.prompt([
|
|
51
|
+
{
|
|
52
|
+
type: 'input',
|
|
53
|
+
name: 'response',
|
|
54
|
+
message: 'Your response:',
|
|
55
|
+
default: question.response || ''
|
|
56
|
+
}
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
question.response = response.trim();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Save the updated requirement
|
|
63
|
+
const reqPath = await getRequirementsPath();
|
|
64
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
65
|
+
const lines = content.split('\n');
|
|
66
|
+
|
|
67
|
+
// Find and update the requirement
|
|
68
|
+
let startIdx = -1;
|
|
69
|
+
let endIdx = -1;
|
|
70
|
+
|
|
71
|
+
for (let i = 0; i < lines.length; i++) {
|
|
72
|
+
if (lines[i].includes(`### ${req.title}`)) {
|
|
73
|
+
startIdx = i;
|
|
74
|
+
// Find the end of this requirement
|
|
75
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
76
|
+
if (lines[j].startsWith('###') || lines[j].startsWith('##')) {
|
|
77
|
+
endIdx = j;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (endIdx === -1) endIdx = lines.length;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (startIdx !== -1) {
|
|
87
|
+
// Build new requirement content
|
|
88
|
+
const newReqContent = [
|
|
89
|
+
`### ${req.title}`,
|
|
90
|
+
''
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
if (req.questions && req.questions.length > 0) {
|
|
94
|
+
newReqContent.push('**Questions:**');
|
|
95
|
+
req.questions.forEach((q, idx) => {
|
|
96
|
+
newReqContent.push(`${idx + 1}. ${q.question}`);
|
|
97
|
+
if (q.response) {
|
|
98
|
+
newReqContent.push(` → ${q.response}`);
|
|
99
|
+
}
|
|
100
|
+
newReqContent.push('');
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (req.details && req.details.length > 0) {
|
|
105
|
+
newReqContent.push('**Details:**');
|
|
106
|
+
req.details.forEach(detail => {
|
|
107
|
+
newReqContent.push(detail);
|
|
108
|
+
});
|
|
109
|
+
newReqContent.push('');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Replace the requirement
|
|
113
|
+
lines.splice(startIdx, endIdx - startIdx, ...newReqContent);
|
|
114
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
115
|
+
console.log(chalk.green('\n✓ Responses updated!'));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Move clarification requirement to TODO
|
|
121
|
+
*/
|
|
122
|
+
async function moveClarificationToTodo(req, tree) {
|
|
123
|
+
const reqPath = await getRequirementsPath();
|
|
124
|
+
|
|
125
|
+
const confirmed = await confirmAction(`Move "${req.title}" back to TODO? (r/y/N)`);
|
|
126
|
+
if (!confirmed) {
|
|
127
|
+
console.log(chalk.gray('Cancelled.'));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
132
|
+
const lines = content.split('\n');
|
|
133
|
+
|
|
134
|
+
// Find and remove from clarification section
|
|
135
|
+
let startIdx = -1;
|
|
136
|
+
let endIdx = -1;
|
|
137
|
+
|
|
138
|
+
for (let i = 0; i < lines.length; i++) {
|
|
139
|
+
if (lines[i].includes(`### ${req.title}`)) {
|
|
140
|
+
startIdx = i;
|
|
141
|
+
// Find the end of this requirement
|
|
142
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
143
|
+
if (lines[j].startsWith('###') || lines[j].startsWith('##')) {
|
|
144
|
+
endIdx = j;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (endIdx === -1) endIdx = lines.length;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (startIdx !== -1) {
|
|
154
|
+
// Extract the requirement content
|
|
155
|
+
const reqContent = lines.slice(startIdx, endIdx);
|
|
156
|
+
|
|
157
|
+
// Remove from clarification section
|
|
158
|
+
lines.splice(startIdx, endIdx - startIdx);
|
|
159
|
+
|
|
160
|
+
// Find TODO section and insert there
|
|
161
|
+
let insertIdx = -1;
|
|
162
|
+
for (let i = 0; i < lines.length; i++) {
|
|
163
|
+
if (lines[i].startsWith('## ⏳ Requirements not yet completed')) {
|
|
164
|
+
insertIdx = i + 2; // After the section header and empty line
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (insertIdx !== -1) {
|
|
170
|
+
lines.splice(insertIdx, 0, ...reqContent);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
174
|
+
console.log(chalk.green('\n✓ Moved to TODO!'));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Delete clarification requirement
|
|
180
|
+
*/
|
|
181
|
+
async function deleteClarification(req, tree) {
|
|
182
|
+
const reqPath = await getRequirementsPath();
|
|
183
|
+
|
|
184
|
+
const confirmed = await confirmAction(`Delete "${req.title}"? This cannot be undone. (r/y/N)`);
|
|
185
|
+
if (!confirmed) {
|
|
186
|
+
console.log(chalk.gray('Cancelled.'));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
191
|
+
const lines = content.split('\n');
|
|
192
|
+
|
|
193
|
+
// Find and remove the clarification requirement
|
|
194
|
+
let startIdx = -1;
|
|
195
|
+
let endIdx = -1;
|
|
196
|
+
|
|
197
|
+
for (let i = 0; i < lines.length; i++) {
|
|
198
|
+
if (lines[i].includes(`### ${req.title}`)) {
|
|
199
|
+
startIdx = i;
|
|
200
|
+
// Find the end of this requirement
|
|
201
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
202
|
+
if (lines[j].startsWith('###') || lines[j].startsWith('##')) {
|
|
203
|
+
endIdx = j;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (endIdx === -1) endIdx = lines.length;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (startIdx !== -1) {
|
|
213
|
+
lines.splice(startIdx, endIdx - startIdx);
|
|
214
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
215
|
+
console.log(chalk.green('\n✓ Requirement deleted!'));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Show clarification actions menu
|
|
221
|
+
*/
|
|
222
|
+
async function showClarificationActions(req, tree, loadClarification) {
|
|
223
|
+
const actions = [
|
|
224
|
+
{ label: '✍️ Add/Edit Responses', value: 'edit-responses' },
|
|
225
|
+
{ label: '↩️ Move back to TODO (after clarification)', value: 'move-to-todo' },
|
|
226
|
+
{ label: '🗑️ Delete', value: 'delete' },
|
|
227
|
+
{ label: '↩️ Back', value: 'back' }
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
console.log(chalk.bold.cyan(`\n❓ ${req.title}\n`));
|
|
231
|
+
|
|
232
|
+
// Show questions and responses
|
|
233
|
+
if (req.questions && req.questions.length > 0) {
|
|
234
|
+
console.log(chalk.gray('Questions:'));
|
|
235
|
+
req.questions.forEach((q, idx) => {
|
|
236
|
+
console.log(chalk.gray(` ${idx + 1}. ${q.question.replace(/^\d+\.\s*/, '')}`));
|
|
237
|
+
if (q.response) {
|
|
238
|
+
console.log(chalk.green(` → ${q.response}`));
|
|
239
|
+
} else {
|
|
240
|
+
console.log(chalk.yellow(' → (no response)'));
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
console.log();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (req.details && req.details.length > 0) {
|
|
247
|
+
console.log(chalk.gray('Details:'));
|
|
248
|
+
req.details.forEach(detail => {
|
|
249
|
+
console.log(chalk.gray(` ${detail}`));
|
|
250
|
+
});
|
|
251
|
+
console.log();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
const { action } = await inquirer.prompt([{
|
|
256
|
+
type: 'list',
|
|
257
|
+
name: 'action',
|
|
258
|
+
message: 'What would you like to do?',
|
|
259
|
+
choices: actions
|
|
260
|
+
}]);
|
|
261
|
+
|
|
262
|
+
switch (action) {
|
|
263
|
+
case 'edit-responses':
|
|
264
|
+
await editClarificationResponses(req, tree);
|
|
265
|
+
break;
|
|
266
|
+
case 'move-to-todo':
|
|
267
|
+
await moveClarificationToTodo(req, tree);
|
|
268
|
+
break;
|
|
269
|
+
case 'delete':
|
|
270
|
+
await deleteClarification(req, tree);
|
|
271
|
+
break;
|
|
272
|
+
case 'back':
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Reload clarification if not going back
|
|
277
|
+
if (action !== 'back' && loadClarification) {
|
|
278
|
+
await loadClarification();
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.error(chalk.red('Error performing clarification action:'), error);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
module.exports = {
|
|
286
|
+
editClarificationResponses,
|
|
287
|
+
moveClarificationToTodo,
|
|
288
|
+
deleteClarification,
|
|
289
|
+
showClarificationActions
|
|
290
|
+
};
|
package/src/utils/config.js
CHANGED
|
@@ -16,7 +16,13 @@ async function ensureConfigFile() {
|
|
|
16
16
|
const cfgPath = getConfigPath();
|
|
17
17
|
await fs.ensureDir(path.dirname(cfgPath));
|
|
18
18
|
if (!await fs.pathExists(cfgPath)) {
|
|
19
|
-
const defaultConfig = {
|
|
19
|
+
const defaultConfig = {
|
|
20
|
+
repoPath: null,
|
|
21
|
+
auto: {
|
|
22
|
+
specProgressTimeoutMinutes: 5, // Default 5 minutes
|
|
23
|
+
maxIdeAttempts: 3 // Default 3 attempts
|
|
24
|
+
}
|
|
25
|
+
};
|
|
20
26
|
await fs.writeJson(cfgPath, defaultConfig, { spaces: 2 });
|
|
21
27
|
}
|
|
22
28
|
}
|
|
@@ -131,6 +137,117 @@ async function setAutoTimeout(timeoutMs) {
|
|
|
131
137
|
await writeConfig(cfg);
|
|
132
138
|
}
|
|
133
139
|
|
|
140
|
+
// Timeout configuration for adaptive timeout management (T052)
|
|
141
|
+
// Using core TimeoutConfigManager for consistency with Electron app
|
|
142
|
+
const { TimeoutConfigManager } = require('../../../core/src/timeout-management');
|
|
143
|
+
|
|
144
|
+
const DEFAULT_TIMEOUT_CONFIG = Object.freeze({
|
|
145
|
+
mode: 'fixed', // 'fixed' or 'adaptive'
|
|
146
|
+
defaultTimeout: 30 * 60 * 1000, // 30 minutes
|
|
147
|
+
minTimeout: 5 * 60 * 1000, // 5 minutes
|
|
148
|
+
maxTimeout: 60 * 60 * 1000, // 60 minutes
|
|
149
|
+
bufferPercentage: 0.5, // 50% buffer
|
|
150
|
+
ewmaAlpha: 0.3, // EWMA smoothing factor
|
|
151
|
+
minSamples: 3 // Minimum samples for adaptive calculation
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
let timeoutConfigManager = null;
|
|
155
|
+
|
|
156
|
+
// Configuration storage path (same as Electron app)
|
|
157
|
+
const getTimeoutConfigPath = () => {
|
|
158
|
+
const os = require('os');
|
|
159
|
+
return path.join(os.homedir(), '.config', 'vibecodingmachine', 'timeout-config.json');
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Initialize timeout configuration manager
|
|
164
|
+
*/
|
|
165
|
+
async function initializeTimeoutConfigManager() {
|
|
166
|
+
if (!timeoutConfigManager) {
|
|
167
|
+
const configPath = getTimeoutConfigPath();
|
|
168
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
169
|
+
|
|
170
|
+
let config = {};
|
|
171
|
+
if (await fs.pathExists(configPath)) {
|
|
172
|
+
config = await fs.readJson(configPath);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
timeoutConfigManager = new TimeoutConfigManager(config);
|
|
176
|
+
}
|
|
177
|
+
return timeoutConfigManager;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function getTimeoutConfig() {
|
|
181
|
+
try {
|
|
182
|
+
const manager = await initializeTimeoutConfigManager();
|
|
183
|
+
const config = manager.getConfig();
|
|
184
|
+
|
|
185
|
+
// Add minSamples for UI compatibility
|
|
186
|
+
return {
|
|
187
|
+
...config,
|
|
188
|
+
minSamples: 3 // Default value
|
|
189
|
+
};
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error('Failed to get timeout configuration:', error);
|
|
192
|
+
return DEFAULT_TIMEOUT_CONFIG;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function setTimeoutConfig(timeoutConfig) {
|
|
197
|
+
try {
|
|
198
|
+
const manager = await initializeTimeoutConfigManager();
|
|
199
|
+
|
|
200
|
+
// Apply updates to the manager
|
|
201
|
+
if (timeoutConfig.mode !== undefined) {
|
|
202
|
+
manager.setMode(timeoutConfig.mode);
|
|
203
|
+
}
|
|
204
|
+
if (timeoutConfig.defaultTimeout !== undefined) {
|
|
205
|
+
manager.setDefaultTimeout(timeoutConfig.defaultTimeout);
|
|
206
|
+
}
|
|
207
|
+
if (timeoutConfig.minTimeout !== undefined) {
|
|
208
|
+
manager.setMinTimeout(timeoutConfig.minTimeout);
|
|
209
|
+
}
|
|
210
|
+
if (timeoutConfig.maxTimeout !== undefined) {
|
|
211
|
+
manager.setMaxTimeout(timeoutConfig.maxTimeout);
|
|
212
|
+
}
|
|
213
|
+
if (timeoutConfig.bufferPercentage !== undefined) {
|
|
214
|
+
manager.setBufferPercentage(timeoutConfig.bufferPercentage);
|
|
215
|
+
}
|
|
216
|
+
if (timeoutConfig.ewmaAlpha !== undefined) {
|
|
217
|
+
manager.setEWMAAlpha(timeoutConfig.ewmaAlpha);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Save to storage
|
|
221
|
+
const newConfig = manager.getConfig();
|
|
222
|
+
const configPath = getTimeoutConfigPath();
|
|
223
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
224
|
+
await fs.writeJson(configPath, newConfig, { spaces: 2 });
|
|
225
|
+
|
|
226
|
+
return newConfig;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error('Failed to set timeout configuration:', error);
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function resetTimeoutConfig() {
|
|
234
|
+
try {
|
|
235
|
+
const manager = await initializeTimeoutConfigManager();
|
|
236
|
+
manager.reset();
|
|
237
|
+
|
|
238
|
+
// Save defaults to storage
|
|
239
|
+
const config = manager.getConfig();
|
|
240
|
+
const configPath = getTimeoutConfigPath();
|
|
241
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
242
|
+
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
243
|
+
|
|
244
|
+
return config;
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error('Failed to reset timeout configuration:', error);
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
134
251
|
module.exports = {
|
|
135
252
|
getRepoPath,
|
|
136
253
|
getEffectiveRepoPath,
|
|
@@ -147,7 +264,11 @@ module.exports = {
|
|
|
147
264
|
getProviderCache,
|
|
148
265
|
setProviderCache,
|
|
149
266
|
getAutoTimeout,
|
|
150
|
-
setAutoTimeout
|
|
267
|
+
setAutoTimeout,
|
|
268
|
+
getTimeoutConfig,
|
|
269
|
+
setTimeoutConfig,
|
|
270
|
+
resetTimeoutConfig,
|
|
271
|
+
DEFAULT_TIMEOUT_CONFIG
|
|
151
272
|
};
|
|
152
273
|
|
|
153
274
|
|
package/src/utils/first-run.js
CHANGED
|
@@ -213,7 +213,7 @@ async function checkFirstRun() {
|
|
|
213
213
|
const choices = otherIDEs.map(ide => ({
|
|
214
214
|
name: ide.name,
|
|
215
215
|
value: ide.id,
|
|
216
|
-
checked:
|
|
216
|
+
checked: false // IDEs must be explicitly selected by user
|
|
217
217
|
}));
|
|
218
218
|
|
|
219
219
|
const response = await inquirer.prompt([{
|
|
@@ -330,12 +330,12 @@ async function checkFirstRun() {
|
|
|
330
330
|
for (const id of defaultOrder) {
|
|
331
331
|
const def = definitions.find(d => d.id === id);
|
|
332
332
|
if (def && def.type === 'ide') {
|
|
333
|
-
|
|
333
|
+
// Only enable IDEs that were explicitly selected by user during first run
|
|
334
334
|
const isSelected = selectedIDEs.includes(id);
|
|
335
|
-
|
|
336
|
-
enabledMap[id] = isDetectedNow || isSelected;
|
|
335
|
+
enabledMap[id] = isSelected;
|
|
337
336
|
} else {
|
|
338
|
-
|
|
337
|
+
// Keep LLMs enabled by default (but not IDEs)
|
|
338
|
+
enabledMap[id] = true;
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|