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,480 @@
|
|
|
1
|
+
const { t } = require('vibecodingmachine-core');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const inquirer = require('inquirer');
|
|
4
|
+
const boxen = require('boxen');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Show welcome screen with system information
|
|
9
|
+
*/
|
|
10
|
+
async function showWelcomeScreen() {
|
|
11
|
+
const repoPath = process.cwd(); // Always use current working directory
|
|
12
|
+
|
|
13
|
+
// System information
|
|
14
|
+
const platform = os.platform();
|
|
15
|
+
const arch = os.arch();
|
|
16
|
+
const nodeVersion = process.version;
|
|
17
|
+
const hostname = os.hostname();
|
|
18
|
+
|
|
19
|
+
// Package information
|
|
20
|
+
const pkg = require('../../package.json');
|
|
21
|
+
const version = pkg.version;
|
|
22
|
+
|
|
23
|
+
// Check if in Vibe Coding Machine directory
|
|
24
|
+
const { checkVibeCodingMachineExists, requirementsExists, isComputerNameEnabled } = require('vibecodingmachine-core');
|
|
25
|
+
const isVCMDir = await checkVibeCodingMachineExists(repoPath);
|
|
26
|
+
const hasRequirements = await requirementsExists();
|
|
27
|
+
const computerNameEnabled = isComputerNameEnabled();
|
|
28
|
+
|
|
29
|
+
console.clear();
|
|
30
|
+
|
|
31
|
+
const welcomeText = chalk.bold.cyan(`
|
|
32
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
33
|
+
║ 🚀 Vibe Coding Machine ║
|
|
34
|
+
║ Version ${version.padEnd(10)} ║
|
|
35
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
36
|
+
|
|
37
|
+
${chalk.bold('📍 Current Directory:')} ${repoPath}
|
|
38
|
+
${chalk.bold('🖥️ System:')} ${platform}-${arch} | Node ${nodeVersion} | Host: ${hostname}
|
|
39
|
+
${chalk.bold('📁 VCM Directory:')} ${isVCMDir ? chalk.green('✅ Yes') : chalk.red('❌ No')}
|
|
40
|
+
${chalk.bold('📋 Requirements:')} ${hasRequirements ? chalk.green('✅ Found') : chalk.yellow('⚠️ Not found')}
|
|
41
|
+
${chalk.bold('🏷️ Computer Name:')} ${computerNameEnabled ? chalk.green('✅ Enabled') : chalk.yellow('⚠️ Disabled')}
|
|
42
|
+
`);
|
|
43
|
+
|
|
44
|
+
console.log(welcomeText);
|
|
45
|
+
|
|
46
|
+
if (!isVCMDir) {
|
|
47
|
+
console.log(chalk.yellow('\n⚠️ You are not in a Vibe Coding Machine directory.'));
|
|
48
|
+
console.log(chalk.gray(' Some features may not be available.\n'));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!hasRequirements && isVCMDir) {
|
|
52
|
+
console.log(chalk.yellow('\n⚠️ No requirements file found.'));
|
|
53
|
+
console.log(chalk.gray(' Run "vibe init" to create one.\n'));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Show main menu
|
|
59
|
+
*/
|
|
60
|
+
async function showMainMenu() {
|
|
61
|
+
const { checkAutoModeStatus } = require('../auto-mode');
|
|
62
|
+
const autoModeStatus = await checkAutoModeStatus();
|
|
63
|
+
|
|
64
|
+
const choices = [
|
|
65
|
+
{ name: '📋 Navigate Requirements', value: 'requirements' },
|
|
66
|
+
{ name: '🔍 Search Requirements', value: 'search' },
|
|
67
|
+
{ name: '📝 Add Requirement', value: 'add' },
|
|
68
|
+
{ name: '📊 Show Statistics', value: 'stats' },
|
|
69
|
+
{ name: '⚙️ Settings', value: 'settings' },
|
|
70
|
+
{ name: '🔄 Sync Status', value: 'sync' },
|
|
71
|
+
{ name: '🚪 Exit', value: 'exit' }
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
// Add auto mode option if available
|
|
75
|
+
if (autoModeStatus.available) {
|
|
76
|
+
choices.splice(-2, 0, {
|
|
77
|
+
name: autoModeStatus.running ? '⏹️ Stop Auto Mode' : '▶️ Start Auto Mode',
|
|
78
|
+
value: 'auto-mode'
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { choice } = await inquirer.prompt([
|
|
83
|
+
{
|
|
84
|
+
type: 'list',
|
|
85
|
+
name: 'choice',
|
|
86
|
+
message: 'What would you like to do?',
|
|
87
|
+
choices,
|
|
88
|
+
pageSize: 10
|
|
89
|
+
}
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
return choice;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Show settings menu
|
|
97
|
+
*/
|
|
98
|
+
async function showSettingsMenu() {
|
|
99
|
+
const choices = [
|
|
100
|
+
{ name: '🏷️ Computer Name Settings', value: 'computer-name' },
|
|
101
|
+
{ name: '🌐 Language Settings', value: 'language' },
|
|
102
|
+
{ name: '📊 Statistics Settings', value: 'statistics' },
|
|
103
|
+
{ name: '🔄 Sync Settings', value: 'sync' },
|
|
104
|
+
{ name: '⬅️ Back', value: 'back' }
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
const { choice } = await inquirer.prompt([
|
|
108
|
+
{
|
|
109
|
+
type: 'list',
|
|
110
|
+
name: 'choice',
|
|
111
|
+
message: 'Settings:',
|
|
112
|
+
choices
|
|
113
|
+
}
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
return choice;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Show computer name settings
|
|
121
|
+
*/
|
|
122
|
+
async function showComputerNameSettings() {
|
|
123
|
+
const { getHostname, setHostname, isComputerNameEnabled, enableComputerName, disableComputerName } = require('vibecodingmachine-core');
|
|
124
|
+
|
|
125
|
+
const currentHostname = getHostname();
|
|
126
|
+
const isEnabled = isComputerNameEnabled();
|
|
127
|
+
|
|
128
|
+
console.log(chalk.bold('\n🏷️ Computer Name Settings\n'));
|
|
129
|
+
console.log(chalk.gray(`Current hostname: ${currentHostname}`));
|
|
130
|
+
console.log(chalk.gray(`Computer name enabled: ${isEnabled ? 'Yes' : 'No'}\n`));
|
|
131
|
+
|
|
132
|
+
const choices = [
|
|
133
|
+
{ name: '✏️ Change hostname', value: 'change-hostname' },
|
|
134
|
+
...(isEnabled ? [{ name: '🔴 Disable computer name', value: 'disable' }] : [{ name: '🟢 Enable computer name', value: 'enable' }]),
|
|
135
|
+
{ name: '⬅️ Back', value: 'back' }
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
const { choice } = await inquirer.prompt([
|
|
139
|
+
{
|
|
140
|
+
type: 'list',
|
|
141
|
+
name: 'choice',
|
|
142
|
+
message: 'What would you like to do?',
|
|
143
|
+
choices
|
|
144
|
+
}
|
|
145
|
+
]);
|
|
146
|
+
|
|
147
|
+
switch (choice) {
|
|
148
|
+
case 'change-hostname':
|
|
149
|
+
await changeHostname();
|
|
150
|
+
break;
|
|
151
|
+
case 'enable':
|
|
152
|
+
await enableComputerName();
|
|
153
|
+
console.log(chalk.green('✅ Computer name enabled'));
|
|
154
|
+
break;
|
|
155
|
+
case 'disable':
|
|
156
|
+
await disableComputerName();
|
|
157
|
+
console.log(chalk.green('✅ Computer name disabled'));
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Change hostname
|
|
164
|
+
*/
|
|
165
|
+
async function changeHostname() {
|
|
166
|
+
const { getHostname, setHostname } = require('vibecodingmachine-core');
|
|
167
|
+
|
|
168
|
+
const { newHostname } = await inquirer.prompt([
|
|
169
|
+
{
|
|
170
|
+
type: 'input',
|
|
171
|
+
name: 'newHostname',
|
|
172
|
+
message: 'Enter new hostname:',
|
|
173
|
+
default: getHostname(),
|
|
174
|
+
validate: input => {
|
|
175
|
+
if (!input.trim()) return 'Hostname cannot be empty';
|
|
176
|
+
if (!/^[a-zA-Z0-9-]+$/.test(input.trim())) {
|
|
177
|
+
return 'Hostname can only contain letters, numbers, and hyphens';
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
]);
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
await setHostname(newHostname.trim());
|
|
186
|
+
console.log(chalk.green(`✅ Hostname changed to: ${newHostname}`));
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error(chalk.red('❌ Error changing hostname:'), error.message);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Show statistics
|
|
194
|
+
*/
|
|
195
|
+
async function showStatistics() {
|
|
196
|
+
console.log(chalk.bold('\n📊 Project Statistics\n'));
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const { countRequirements, getCurrentProgress } = require('./core-ui');
|
|
200
|
+
const stats = await countRequirements();
|
|
201
|
+
const progress = await getCurrentProgress();
|
|
202
|
+
|
|
203
|
+
console.log(chalk.yellow('Requirements:'));
|
|
204
|
+
console.log(chalk.gray(` • Todo: ${stats.todo} items`));
|
|
205
|
+
console.log(chalk.gray(` • Completed: ${stats.completed} items`));
|
|
206
|
+
console.log(chalk.gray(` • Total: ${stats.total} items`));
|
|
207
|
+
console.log(chalk.gray(` • Progress: ${progress.progress}%`));
|
|
208
|
+
console.log(chalk.gray(` • Current Stage: ${progress.stage}\n`));
|
|
209
|
+
|
|
210
|
+
// Show file statistics
|
|
211
|
+
const fs = require('fs-extra');
|
|
212
|
+
const path = require('path');
|
|
213
|
+
|
|
214
|
+
const countFiles = async (dir, pattern = /\.js$/) => {
|
|
215
|
+
let count = 0;
|
|
216
|
+
const items = await fs.readdir(dir);
|
|
217
|
+
|
|
218
|
+
for (const item of items) {
|
|
219
|
+
const fullPath = path.join(dir, item);
|
|
220
|
+
const stat = await fs.stat(fullPath);
|
|
221
|
+
|
|
222
|
+
if (stat.isDirectory() && !item.startsWith('.') && item !== 'node_modules') {
|
|
223
|
+
count += await countFiles(fullPath, pattern);
|
|
224
|
+
} else if (stat.isFile() && pattern.test(item)) {
|
|
225
|
+
count++;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return count;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const repoPath = process.cwd();
|
|
233
|
+
const jsFiles = await countFiles(repoPath);
|
|
234
|
+
const jsxFiles = await countFiles(repoPath, /\.jsx$/);
|
|
235
|
+
const mdFiles = await countFiles(repoPath, /\.md$/);
|
|
236
|
+
|
|
237
|
+
console.log(chalk.yellow('Files:'));
|
|
238
|
+
console.log(chalk.gray(` • JavaScript files: ${jsFiles}`));
|
|
239
|
+
console.log(chalk.gray(` • JSX files: ${jsxFiles}`));
|
|
240
|
+
console.log(chalk.gray(` • Markdown files: ${mdFiles}\n`));
|
|
241
|
+
|
|
242
|
+
} catch (error) {
|
|
243
|
+
console.error(chalk.red('❌ Error getting statistics:'), error.message);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Show sync status
|
|
249
|
+
*/
|
|
250
|
+
async function showSyncStatus() {
|
|
251
|
+
console.log(chalk.bold('\n🔄 Sync Status\n'));
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
const { getSyncStatus } = require('./core-ui');
|
|
255
|
+
const status = await getSyncStatus();
|
|
256
|
+
|
|
257
|
+
console.log(chalk.yellow('Sync Status:'));
|
|
258
|
+
console.log(chalk.gray(` • Status: ${status.status}`));
|
|
259
|
+
if (status.message) {
|
|
260
|
+
console.log(chalk.gray(` • Message: ${status.message}`));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (status.lastSync) {
|
|
264
|
+
console.log(chalk.gray(` • Last sync: ${new Date(status.lastSync).toLocaleString()}`));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log();
|
|
268
|
+
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error(chalk.red('❌ Error getting sync status:'), error.message);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Search requirements
|
|
276
|
+
*/
|
|
277
|
+
async function searchRequirements() {
|
|
278
|
+
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
279
|
+
const fs = require('fs-extra');
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
const { query } = await inquirer.prompt([
|
|
283
|
+
{
|
|
284
|
+
type: 'input',
|
|
285
|
+
name: 'query',
|
|
286
|
+
message: 'Search for:',
|
|
287
|
+
validate: input => input.trim().length > 0 || 'Search query cannot be empty'
|
|
288
|
+
}
|
|
289
|
+
]);
|
|
290
|
+
|
|
291
|
+
const reqPath = await getRequirementsPath();
|
|
292
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
293
|
+
const lines = content.split('\n');
|
|
294
|
+
|
|
295
|
+
const searchTerm = query.toLowerCase();
|
|
296
|
+
const matches = [];
|
|
297
|
+
|
|
298
|
+
for (let i = 0; i < lines.length; i++) {
|
|
299
|
+
const line = lines[i];
|
|
300
|
+
if (line.startsWith('- ') && line.toLowerCase().includes(searchTerm)) {
|
|
301
|
+
matches.push({
|
|
302
|
+
line: i + 1,
|
|
303
|
+
content: line.substring(2) // Remove "- " prefix
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
console.log(chalk.bold(`\n🔍 Search Results for "${query}"\n`));
|
|
309
|
+
|
|
310
|
+
if (matches.length === 0) {
|
|
311
|
+
console.log(chalk.gray('No matches found.\n'));
|
|
312
|
+
} else {
|
|
313
|
+
console.log(chalk.yellow(`Found ${matches.length} match(es):\n`));
|
|
314
|
+
|
|
315
|
+
matches.forEach((match, index) => {
|
|
316
|
+
console.log(chalk.cyan(`${index + 1}. Line ${match.line}:`));
|
|
317
|
+
console.log(chalk.gray(` ${match.content}\n`));
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
} catch (error) {
|
|
322
|
+
console.error(chalk.red('❌ Error searching requirements:'), error.message);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Show confirmation dialog
|
|
328
|
+
*/
|
|
329
|
+
async function showConfirmDialog(message, defaultValue = false) {
|
|
330
|
+
const { confirmed } = await inquirer.prompt([
|
|
331
|
+
{
|
|
332
|
+
type: 'confirm',
|
|
333
|
+
name: 'confirmed',
|
|
334
|
+
message,
|
|
335
|
+
default: defaultValue
|
|
336
|
+
}
|
|
337
|
+
]);
|
|
338
|
+
|
|
339
|
+
return confirmed;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Show input dialog
|
|
344
|
+
*/
|
|
345
|
+
async function showInputDialog(message, defaultValue = '', validate = null) {
|
|
346
|
+
const { input } = await inquirer.prompt([
|
|
347
|
+
{
|
|
348
|
+
type: 'input',
|
|
349
|
+
name: 'input',
|
|
350
|
+
message,
|
|
351
|
+
default: defaultValue,
|
|
352
|
+
validate: validate || ((input) => input.trim().length > 0 || 'Input cannot be empty')
|
|
353
|
+
}
|
|
354
|
+
]);
|
|
355
|
+
|
|
356
|
+
return input;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Show select dialog
|
|
361
|
+
*/
|
|
362
|
+
async function showSelectDialog(message, choices, pageSize = 10) {
|
|
363
|
+
const { choice } = await inquirer.prompt([
|
|
364
|
+
{
|
|
365
|
+
type: 'list',
|
|
366
|
+
name: 'choice',
|
|
367
|
+
message,
|
|
368
|
+
choices,
|
|
369
|
+
pageSize
|
|
370
|
+
}
|
|
371
|
+
]);
|
|
372
|
+
|
|
373
|
+
return choice;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Show multi-select dialog
|
|
378
|
+
*/
|
|
379
|
+
async function showMultiSelectDialog(message, choices, pageSize = 10) {
|
|
380
|
+
const { selected } = await inquirer.prompt([
|
|
381
|
+
{
|
|
382
|
+
type: 'checkbox',
|
|
383
|
+
name: 'selected',
|
|
384
|
+
message,
|
|
385
|
+
choices,
|
|
386
|
+
pageSize
|
|
387
|
+
}
|
|
388
|
+
]);
|
|
389
|
+
|
|
390
|
+
return selected;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Show error message
|
|
395
|
+
*/
|
|
396
|
+
function showError(message, error = null) {
|
|
397
|
+
const errorMessage = error ? `${message}\n\n${chalk.red(error.message || error)}` : message;
|
|
398
|
+
|
|
399
|
+
console.log(
|
|
400
|
+
boxen(
|
|
401
|
+
chalk.red(errorMessage),
|
|
402
|
+
{
|
|
403
|
+
padding: 1,
|
|
404
|
+
borderStyle: 'double',
|
|
405
|
+
borderColor: 'red',
|
|
406
|
+
align: 'center'
|
|
407
|
+
}
|
|
408
|
+
)
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Show success message
|
|
414
|
+
*/
|
|
415
|
+
function showSuccess(message) {
|
|
416
|
+
console.log(
|
|
417
|
+
boxen(
|
|
418
|
+
chalk.green(message),
|
|
419
|
+
{
|
|
420
|
+
padding: 1,
|
|
421
|
+
borderStyle: 'double',
|
|
422
|
+
borderColor: 'green',
|
|
423
|
+
align: 'center'
|
|
424
|
+
}
|
|
425
|
+
)
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Show warning message
|
|
431
|
+
*/
|
|
432
|
+
function showWarning(message) {
|
|
433
|
+
console.log(
|
|
434
|
+
boxen(
|
|
435
|
+
chalk.yellow(message),
|
|
436
|
+
{
|
|
437
|
+
padding: 1,
|
|
438
|
+
borderStyle: 'double',
|
|
439
|
+
borderColor: 'yellow',
|
|
440
|
+
align: 'center'
|
|
441
|
+
}
|
|
442
|
+
)
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Show info message
|
|
448
|
+
*/
|
|
449
|
+
function showInfo(message) {
|
|
450
|
+
console.log(
|
|
451
|
+
boxen(
|
|
452
|
+
chalk.blue(message),
|
|
453
|
+
{
|
|
454
|
+
padding: 1,
|
|
455
|
+
borderStyle: 'double',
|
|
456
|
+
borderColor: 'blue',
|
|
457
|
+
align: 'center'
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
module.exports = {
|
|
464
|
+
showWelcomeScreen,
|
|
465
|
+
showMainMenu,
|
|
466
|
+
showSettingsMenu,
|
|
467
|
+
showComputerNameSettings,
|
|
468
|
+
showStatistics,
|
|
469
|
+
showSyncStatus,
|
|
470
|
+
searchRequirements,
|
|
471
|
+
showConfirmDialog,
|
|
472
|
+
showInputDialog,
|
|
473
|
+
showSelectDialog,
|
|
474
|
+
showMultiSelectDialog,
|
|
475
|
+
showError,
|
|
476
|
+
showSuccess,
|
|
477
|
+
showWarning,
|
|
478
|
+
showInfo,
|
|
479
|
+
changeHostname
|
|
480
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requirement Actions - Orchestrates requirement operations
|
|
3
|
+
*
|
|
4
|
+
* This module coordinates between CRUD operations and clarification actions.
|
|
5
|
+
* It serves as the main entry point for requirement-related actions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const inquirer = require('inquirer');
|
|
10
|
+
|
|
11
|
+
// Import split modules
|
|
12
|
+
const {
|
|
13
|
+
renameRequirement,
|
|
14
|
+
deleteRequirement,
|
|
15
|
+
permanentlyDeleteRequirement,
|
|
16
|
+
moveRequirementDown,
|
|
17
|
+
moveRequirementUp,
|
|
18
|
+
promoteRequirement,
|
|
19
|
+
demoteRequirement,
|
|
20
|
+
restoreRequirement,
|
|
21
|
+
moveRequirementToClarification,
|
|
22
|
+
confirmAction,
|
|
23
|
+
getSectionTitle,
|
|
24
|
+
getRequirementList
|
|
25
|
+
} = require('./requirement-crud');
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
editClarificationResponses,
|
|
29
|
+
moveClarificationToTodo,
|
|
30
|
+
deleteClarification,
|
|
31
|
+
showClarificationActions,
|
|
32
|
+
confirmAndExit,
|
|
33
|
+
moveRequirementToRecycled
|
|
34
|
+
} = require('./clarification-actions');
|
|
35
|
+
|
|
36
|
+
// Helper to perform action on requirement
|
|
37
|
+
async function performRequirementAction(action, req, sectionKey, tree) {
|
|
38
|
+
const reqList = getRequirementList(tree, sectionKey);
|
|
39
|
+
const sectionTitle = getSectionTitle(sectionKey);
|
|
40
|
+
const reqIndex = reqList.findIndex(r => r.title === req.title);
|
|
41
|
+
|
|
42
|
+
if (reqIndex === -1) {
|
|
43
|
+
console.error(chalk.red('❌ Requirement not found'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
switch (action) {
|
|
48
|
+
case 'rename':
|
|
49
|
+
await renameRequirement(req, sectionKey, tree);
|
|
50
|
+
break;
|
|
51
|
+
case 'thumbs-up':
|
|
52
|
+
await promoteRequirement(req, sectionKey, tree, loadSection, loadVerified);
|
|
53
|
+
break;
|
|
54
|
+
case 'needs-clarification':
|
|
55
|
+
await moveRequirementToClarification(req, sectionKey, tree);
|
|
56
|
+
break;
|
|
57
|
+
case 'delete':
|
|
58
|
+
await deleteRequirement(req, sectionKey, tree);
|
|
59
|
+
break;
|
|
60
|
+
case 'move-up':
|
|
61
|
+
await moveRequirementUp(req, sectionKey, tree);
|
|
62
|
+
break;
|
|
63
|
+
case 'move-down':
|
|
64
|
+
await moveRequirementDown(req, sectionKey, tree);
|
|
65
|
+
break;
|
|
66
|
+
case 'move-to-todo':
|
|
67
|
+
if (sectionKey === 'verify') {
|
|
68
|
+
await demoteRequirement(req.title, sectionKey, tree, loadSection, loadVerified);
|
|
69
|
+
} else if (sectionKey === 'clarification') {
|
|
70
|
+
await moveClarificationToTodo(req, tree);
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
case 'restore':
|
|
74
|
+
await restoreRequirement(req, sectionKey, tree);
|
|
75
|
+
break;
|
|
76
|
+
case 'permanent-delete':
|
|
77
|
+
await permanentlyDeleteRequirement(req, sectionKey, tree);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Helper functions for loading sections (placeholders for now)
|
|
85
|
+
async function loadSection() {
|
|
86
|
+
// TODO: Implement section loading
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function loadVerified() {
|
|
91
|
+
// TODO: Implement verified loading
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Re-export all functions for backward compatibility
|
|
96
|
+
module.exports = {
|
|
97
|
+
// Main orchestrator
|
|
98
|
+
performRequirementAction,
|
|
99
|
+
|
|
100
|
+
// CRUD operations
|
|
101
|
+
renameRequirement,
|
|
102
|
+
deleteRequirement,
|
|
103
|
+
permanentlyDeleteRequirement,
|
|
104
|
+
moveRequirementDown,
|
|
105
|
+
moveRequirementUp,
|
|
106
|
+
promoteRequirement,
|
|
107
|
+
demoteRequirement,
|
|
108
|
+
restoreRequirement,
|
|
109
|
+
moveRequirementToClarification,
|
|
110
|
+
|
|
111
|
+
// Clarification actions
|
|
112
|
+
editClarificationResponses,
|
|
113
|
+
moveClarificationToTodo,
|
|
114
|
+
deleteClarification,
|
|
115
|
+
showClarificationActions,
|
|
116
|
+
|
|
117
|
+
// Utilities
|
|
118
|
+
confirmAction,
|
|
119
|
+
confirmAndExit,
|
|
120
|
+
getSectionTitle,
|
|
121
|
+
getRequirementList,
|
|
122
|
+
moveRequirementToRecycled,
|
|
123
|
+
|
|
124
|
+
// Loaders (placeholders)
|
|
125
|
+
loadSection,
|
|
126
|
+
loadVerified
|
|
127
|
+
};
|