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
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
5
|
+
const { confirmAction } = require('./confirmation-prompts');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Helper to edit clarification responses
|
|
9
|
+
*/
|
|
10
|
+
async function editClarificationResponses(req, tree) {
|
|
11
|
+
const reqPath = await getRequirementsPath();
|
|
12
|
+
|
|
13
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
14
|
+
const lines = content.split('\n');
|
|
15
|
+
|
|
16
|
+
// Find the clarification requirement
|
|
17
|
+
const reqIndex = tree.clarificationReqs.findIndex(r => r.title === req.title);
|
|
18
|
+
if (reqIndex === -1) return;
|
|
19
|
+
|
|
20
|
+
const clarificationReq = tree.clarificationReqs[reqIndex];
|
|
21
|
+
|
|
22
|
+
// Get current responses or initialize empty array
|
|
23
|
+
const currentResponses = clarificationReq.responses || [];
|
|
24
|
+
|
|
25
|
+
console.log(chalk.cyan('\n✍️ Add/Edit Clarification Responses\n'));
|
|
26
|
+
console.log(chalk.gray(`Requirement: ${req.title}\n`));
|
|
27
|
+
|
|
28
|
+
// Show current responses
|
|
29
|
+
if (currentResponses.length > 0) {
|
|
30
|
+
console.log(chalk.yellow('Current responses:'));
|
|
31
|
+
currentResponses.forEach((response, index) => {
|
|
32
|
+
console.log(chalk.white(` ${index + 1}. ${response}`));
|
|
33
|
+
});
|
|
34
|
+
console.log();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const { action } = await inquirer.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'list',
|
|
40
|
+
name: 'action',
|
|
41
|
+
message: 'What would you like to do?',
|
|
42
|
+
choices: [
|
|
43
|
+
{ name: 'Add new response', value: 'add' },
|
|
44
|
+
{ name: 'Edit existing response', value: 'edit' },
|
|
45
|
+
{ name: 'Delete response', value: 'delete' },
|
|
46
|
+
{ name: 'Cancel', value: 'cancel' }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
if (action === 'cancel') return;
|
|
52
|
+
|
|
53
|
+
let updatedResponses = [...currentResponses];
|
|
54
|
+
|
|
55
|
+
if (action === 'add') {
|
|
56
|
+
const { response } = await inquirer.prompt([
|
|
57
|
+
{
|
|
58
|
+
type: 'input',
|
|
59
|
+
name: 'response',
|
|
60
|
+
message: 'Enter your response:'
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
if (response.trim()) {
|
|
65
|
+
updatedResponses.push(response.trim());
|
|
66
|
+
}
|
|
67
|
+
} else if (action === 'edit' && currentResponses.length > 0) {
|
|
68
|
+
const { responseIndex } = await inquirer.prompt([
|
|
69
|
+
{
|
|
70
|
+
type: 'list',
|
|
71
|
+
name: 'responseIndex',
|
|
72
|
+
message: 'Select response to edit:',
|
|
73
|
+
choices: currentResponses.map((resp, index) => ({
|
|
74
|
+
name: `${index + 1}. ${resp}`,
|
|
75
|
+
value: index
|
|
76
|
+
}))
|
|
77
|
+
}
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
const { newResponse } = await inquirer.prompt([
|
|
81
|
+
{
|
|
82
|
+
type: 'input',
|
|
83
|
+
name: 'newResponse',
|
|
84
|
+
message: 'Edit response:',
|
|
85
|
+
default: currentResponses[responseIndex]
|
|
86
|
+
}
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
if (newResponse.trim()) {
|
|
90
|
+
updatedResponses[responseIndex] = newResponse.trim();
|
|
91
|
+
}
|
|
92
|
+
} else if (action === 'delete' && currentResponses.length > 0) {
|
|
93
|
+
const { responseIndex } = await inquirer.prompt([
|
|
94
|
+
{
|
|
95
|
+
type: 'list',
|
|
96
|
+
name: 'responseIndex',
|
|
97
|
+
message: 'Select response to delete:',
|
|
98
|
+
choices: currentResponses.map((resp, index) => ({
|
|
99
|
+
name: `${index + 1}. ${resp}`,
|
|
100
|
+
value: index
|
|
101
|
+
}))
|
|
102
|
+
}
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
const confirmed = await confirmAction(`Delete response "${currentResponses[responseIndex]}"? (r/y/N)`);
|
|
106
|
+
if (confirmed) {
|
|
107
|
+
updatedResponses.splice(responseIndex, 1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Update the requirement with new responses
|
|
112
|
+
clarificationReq.responses = updatedResponses;
|
|
113
|
+
|
|
114
|
+
// Write back to file
|
|
115
|
+
await fs.writeFile(reqPath, content);
|
|
116
|
+
|
|
117
|
+
console.log(chalk.green('✅ Clarification responses updated successfully!'));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Helper to move clarification requirement back to TODO
|
|
122
|
+
*/
|
|
123
|
+
async function moveClarificationToTodo(req, tree) {
|
|
124
|
+
const reqPath = await getRequirementsPath();
|
|
125
|
+
|
|
126
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
127
|
+
const lines = content.split('\n');
|
|
128
|
+
|
|
129
|
+
// Find the clarification requirement
|
|
130
|
+
const reqIndex = tree.clarificationReqs.findIndex(r => r.title === req.title);
|
|
131
|
+
if (reqIndex === -1) return;
|
|
132
|
+
|
|
133
|
+
const clarificationReq = tree.clarificationReqs[reqIndex];
|
|
134
|
+
|
|
135
|
+
// Remove from clarification section
|
|
136
|
+
tree.clarificationReqs.splice(reqIndex, 1);
|
|
137
|
+
|
|
138
|
+
// Add to TODO section
|
|
139
|
+
tree.todoReqs.push({
|
|
140
|
+
...clarificationReq,
|
|
141
|
+
status: 'TODO',
|
|
142
|
+
responses: undefined // Remove responses when moving back to TODO
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Write back to file
|
|
146
|
+
await fs.writeFile(reqPath, content);
|
|
147
|
+
|
|
148
|
+
console.log(chalk.green(`✅ Moved "${req.title}" back to TODO`));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Helper to move clarification requirement to recycled (used to delete)
|
|
153
|
+
*/
|
|
154
|
+
async function deleteClarification(req, tree) {
|
|
155
|
+
const reqPath = await getRequirementsPath();
|
|
156
|
+
|
|
157
|
+
const confirmed = await confirmAction(`Delete "${req.title}"? This cannot be undone. (r/y/N)`);
|
|
158
|
+
if (!confirmed) return;
|
|
159
|
+
|
|
160
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
161
|
+
const lines = content.split('\n');
|
|
162
|
+
|
|
163
|
+
// Find and remove the clarification requirement
|
|
164
|
+
const reqIndex = tree.clarificationReqs.findIndex(r => r.title === req.title);
|
|
165
|
+
if (reqIndex === -1) return;
|
|
166
|
+
|
|
167
|
+
const clarificationReq = tree.clarificationReqs[reqIndex];
|
|
168
|
+
|
|
169
|
+
// Remove from clarification section
|
|
170
|
+
tree.clarificationReqs.splice(reqIndex, 1);
|
|
171
|
+
|
|
172
|
+
// Add to recycled section
|
|
173
|
+
tree.recycledReqs.push({
|
|
174
|
+
...clarificationReq,
|
|
175
|
+
deletedAt: new Date().toISOString()
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Write back to file
|
|
179
|
+
await fs.writeFile(reqPath, content);
|
|
180
|
+
|
|
181
|
+
console.log(chalk.green(`✅ Deleted "${req.title}"`));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Helper to show actions for a requirement
|
|
186
|
+
*/
|
|
187
|
+
async function showClarificationActions(req, tree, loadClarification) {
|
|
188
|
+
const actions = [
|
|
189
|
+
{ label: '✍️ Add/Edit Responses', value: 'edit-responses' },
|
|
190
|
+
{ label: '↩️ Move back to TODO (after clarification)', value: 'move-to-todo' },
|
|
191
|
+
{ label: '🗑️ Delete', value: 'delete' },
|
|
192
|
+
{ label: '❌ Cancel', value: 'cancel' }
|
|
193
|
+
];
|
|
194
|
+
|
|
195
|
+
const { action } = await inquirer.prompt([
|
|
196
|
+
{
|
|
197
|
+
type: 'list',
|
|
198
|
+
name: 'action',
|
|
199
|
+
message: `Select action for "${req.title}":`,
|
|
200
|
+
choices: actions
|
|
201
|
+
}
|
|
202
|
+
]);
|
|
203
|
+
|
|
204
|
+
switch (action) {
|
|
205
|
+
case 'edit-responses':
|
|
206
|
+
await editClarificationResponses(req, tree);
|
|
207
|
+
break;
|
|
208
|
+
case 'move-to-todo':
|
|
209
|
+
await moveClarificationToTodo(req, tree);
|
|
210
|
+
break;
|
|
211
|
+
case 'delete':
|
|
212
|
+
await deleteClarification(req, tree);
|
|
213
|
+
break;
|
|
214
|
+
case 'cancel':
|
|
215
|
+
console.log(chalk.gray('Action cancelled'));
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (action !== 'cancel') {
|
|
220
|
+
await loadClarification();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
module.exports = {
|
|
225
|
+
editClarificationResponses,
|
|
226
|
+
moveClarificationToTodo,
|
|
227
|
+
deleteClarification,
|
|
228
|
+
showClarificationActions,
|
|
229
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
const { t } = require('vibecodingmachine-core');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Helper to show confirmation prompt (r/y for yes, N for no, default N)
|
|
7
|
+
*/
|
|
8
|
+
async function confirmAction(message) {
|
|
9
|
+
console.log();
|
|
10
|
+
process.stdout.write(chalk.yellow(`${message} `));
|
|
11
|
+
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
readline.emitKeypressEvents(process.stdin);
|
|
14
|
+
if (process.stdin.isTTY) {
|
|
15
|
+
process.stdin.setRawMode(true);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const onData = (key) => {
|
|
19
|
+
if (key.name === 'return') {
|
|
20
|
+
process.stdin.setRawMode(false);
|
|
21
|
+
process.stdin.removeListener('data', onData);
|
|
22
|
+
console.log('N'); // Show default
|
|
23
|
+
resolve(false);
|
|
24
|
+
} else if (key.name === 'r' || key.name === 'y') {
|
|
25
|
+
process.stdin.setRawMode(false);
|
|
26
|
+
process.stdin.removeListener('data', onData);
|
|
27
|
+
console.log(key.name.toUpperCase()); // Show the key pressed
|
|
28
|
+
resolve(true);
|
|
29
|
+
} else if (key.name === 'n') {
|
|
30
|
+
process.stdin.setRawMode(false);
|
|
31
|
+
process.stdin.removeListener('data', onData);
|
|
32
|
+
console.log('N');
|
|
33
|
+
resolve(false);
|
|
34
|
+
} else if (key.ctrl && key.name === 'c') {
|
|
35
|
+
process.stdin.setRawMode(false);
|
|
36
|
+
process.stdin.removeListener('data', onData);
|
|
37
|
+
console.log('^C');
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
process.stdin.on('data', onData);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Helper to confirm exit and exit if confirmed (default N)
|
|
48
|
+
*/
|
|
49
|
+
async function confirmAndExit() {
|
|
50
|
+
console.log(chalk.gray('\n[DEBUG] confirmAndExit called'));
|
|
51
|
+
console.log();
|
|
52
|
+
process.stdout.write(chalk.yellow(`${t('interactive.confirm.exit')} `));
|
|
53
|
+
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
readline.emitKeypressEvents(process.stdin);
|
|
56
|
+
if (process.stdin.isTTY) {
|
|
57
|
+
process.stdin.setRawMode(true);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const onData = (key) => {
|
|
61
|
+
if (key.name === 'return') {
|
|
62
|
+
process.stdin.setRawMode(false);
|
|
63
|
+
process.stdin.removeListener('data', onData);
|
|
64
|
+
console.log('N'); // Show default
|
|
65
|
+
showGoodbyeMessage();
|
|
66
|
+
process.exit(0);
|
|
67
|
+
} else if (key.name === 'r' || key.name === 'y') {
|
|
68
|
+
process.stdin.setRawMode(false);
|
|
69
|
+
process.stdin.removeListener('data', onData);
|
|
70
|
+
console.log(key.name.toUpperCase()); // Show the key pressed
|
|
71
|
+
showGoodbyeMessage();
|
|
72
|
+
process.exit(0);
|
|
73
|
+
} else if (key.name === 'n') {
|
|
74
|
+
process.stdin.setRawMode(false);
|
|
75
|
+
process.stdin.removeListener('data', onData);
|
|
76
|
+
console.log('N');
|
|
77
|
+
resolve(false);
|
|
78
|
+
} else if (key.ctrl && key.name === 'c') {
|
|
79
|
+
process.stdin.setRawMode(false);
|
|
80
|
+
process.stdin.removeListener('data', onData);
|
|
81
|
+
console.log('^C');
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
process.stdin.on('data', onData);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
confirmAction,
|
|
92
|
+
confirmAndExit,
|
|
93
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Helper to move requirement to recycled section
|
|
6
|
+
*/
|
|
7
|
+
async function moveRequirementToRecycled(reqPath, requirementTitle, fromSection) {
|
|
8
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
9
|
+
const lines = content.split('\n');
|
|
10
|
+
|
|
11
|
+
// Find the requirement in the current section
|
|
12
|
+
let reqIndex = -1;
|
|
13
|
+
let reqContent = '';
|
|
14
|
+
|
|
15
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16
|
+
if (lines[i].includes(`- ${requirementTitle}`)) {
|
|
17
|
+
reqIndex = i;
|
|
18
|
+
// Collect the requirement content (including description)
|
|
19
|
+
reqContent = lines[i];
|
|
20
|
+
if (i + 1 < lines.length && lines[i + 1].startsWith(' ')) {
|
|
21
|
+
reqContent += '\n' + lines[i + 1];
|
|
22
|
+
}
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (reqIndex === -1) return;
|
|
28
|
+
|
|
29
|
+
// Remove from current section
|
|
30
|
+
lines.splice(reqIndex, reqContent.includes('\n') ? 2 : 1);
|
|
31
|
+
|
|
32
|
+
// Find recycled section
|
|
33
|
+
let recycledIndex = -1;
|
|
34
|
+
for (let i = 0; i < lines.length; i++) {
|
|
35
|
+
if (lines[i].includes('♻️ Recycled')) {
|
|
36
|
+
recycledIndex = i;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (recycledIndex === -1) {
|
|
42
|
+
// Create recycled section if it doesn't exist
|
|
43
|
+
lines.push('\n## ♻️ Recycled\n');
|
|
44
|
+
recycledIndex = lines.length - 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Add to recycled section with timestamp
|
|
48
|
+
const recycledEntry = `- ${requirementTitle} (deleted from ${fromSection} on ${new Date().toISOString()})`;
|
|
49
|
+
lines.splice(recycledIndex + 1, 0, recycledEntry);
|
|
50
|
+
|
|
51
|
+
// Write back to file
|
|
52
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Helper to handle adding requirements
|
|
57
|
+
*/
|
|
58
|
+
async function handleAddRequirement(type) {
|
|
59
|
+
const reqCommands = require('../commands/requirements');
|
|
60
|
+
const packages = ['all', 'cli', 'core', 'electron-app', 'web', 'mobile'];
|
|
61
|
+
|
|
62
|
+
if (type === 'single') {
|
|
63
|
+
const { package: pkg } = await inquirer.prompt([
|
|
64
|
+
{
|
|
65
|
+
type: 'list',
|
|
66
|
+
name: 'package',
|
|
67
|
+
message: 'Select package:',
|
|
68
|
+
choices: packages
|
|
69
|
+
}
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
await reqCommands.addRequirement(pkg);
|
|
73
|
+
} else if (type === 'plural') {
|
|
74
|
+
const { packages: selectedPackages } = await inquirer.prompt([
|
|
75
|
+
{
|
|
76
|
+
type: 'checkbox',
|
|
77
|
+
name: 'packages',
|
|
78
|
+
message: 'Select packages:',
|
|
79
|
+
choices: packages
|
|
80
|
+
}
|
|
81
|
+
]);
|
|
82
|
+
|
|
83
|
+
for (const pkg of selectedPackages) {
|
|
84
|
+
await reqCommands.addRequirement(pkg);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
moveRequirementToRecycled,
|
|
91
|
+
handleAddRequirement,
|
|
92
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { t } = require('vibecodingmachine-core');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Helper to show goodbye message
|
|
6
|
+
*/
|
|
7
|
+
function showGoodbyeMessage() {
|
|
8
|
+
const hour = new Date().getHours();
|
|
9
|
+
const message = hour < 21
|
|
10
|
+
? '\n👋 ' + t('interactive.goodbye') + '\n'
|
|
11
|
+
: '\n👋 Goodbye! Go get some sleep!\n';
|
|
12
|
+
console.log(chalk.cyan(message));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Helper to get section title from section key
|
|
17
|
+
*/
|
|
18
|
+
function getSectionTitle(sectionKey) {
|
|
19
|
+
if (sectionKey === 'todo') return '⏳ Requirements not yet completed';
|
|
20
|
+
if (sectionKey === 'verify') return '✅ Verified by AI screenshot';
|
|
21
|
+
if (sectionKey === 'recycled') return '♻️ Recycled';
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Helper to get requirement list from tree by section key
|
|
27
|
+
*/
|
|
28
|
+
function getRequirementList(tree, sectionKey) {
|
|
29
|
+
if (sectionKey === 'todo') return tree.todoReqs;
|
|
30
|
+
if (sectionKey === 'verify') return tree.verifyReqs;
|
|
31
|
+
if (sectionKey === 'clarification') return tree.clarificationReqs;
|
|
32
|
+
if (sectionKey === 'recycled') return tree.recycledReqs;
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
showGoodbyeMessage,
|
|
38
|
+
getSectionTitle,
|
|
39
|
+
getRequirementList,
|
|
40
|
+
};
|