@wundr.io/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +551 -0
- package/bin/wundr.js +39 -0
- package/dist/ai/ai-service.d.ts +152 -0
- package/dist/ai/ai-service.d.ts.map +1 -0
- package/dist/ai/ai-service.js +430 -0
- package/dist/ai/ai-service.js.map +1 -0
- package/dist/ai/claude-client.d.ts +130 -0
- package/dist/ai/claude-client.d.ts.map +1 -0
- package/dist/ai/claude-client.js +339 -0
- package/dist/ai/claude-client.js.map +1 -0
- package/dist/ai/conversation-manager.d.ts +164 -0
- package/dist/ai/conversation-manager.d.ts.map +1 -0
- package/dist/ai/conversation-manager.js +612 -0
- package/dist/ai/conversation-manager.js.map +1 -0
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/cli.d.ts +36 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +173 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ai.d.ts +89 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +735 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/analyze-optimized.d.ts +14 -0
- package/dist/commands/analyze-optimized.d.ts.map +1 -0
- package/dist/commands/analyze-optimized.js +437 -0
- package/dist/commands/analyze-optimized.js.map +1 -0
- package/dist/commands/analyze.d.ts +65 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +435 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/batch.d.ts +71 -0
- package/dist/commands/batch.d.ts.map +1 -0
- package/dist/commands/batch.js +738 -0
- package/dist/commands/batch.js.map +1 -0
- package/dist/commands/chat.d.ts +71 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +674 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/claude-init.d.ts +28 -0
- package/dist/commands/claude-init.d.ts.map +1 -0
- package/dist/commands/claude-init.js +587 -0
- package/dist/commands/claude-init.js.map +1 -0
- package/dist/commands/claude-setup.d.ts +32 -0
- package/dist/commands/claude-setup.d.ts.map +1 -0
- package/dist/commands/claude-setup.js +570 -0
- package/dist/commands/claude-setup.js.map +1 -0
- package/dist/commands/computer-setup-commands.d.ts +39 -0
- package/dist/commands/computer-setup-commands.d.ts.map +1 -0
- package/dist/commands/computer-setup-commands.js +563 -0
- package/dist/commands/computer-setup-commands.js.map +1 -0
- package/dist/commands/computer-setup.d.ts +7 -0
- package/dist/commands/computer-setup.d.ts.map +1 -0
- package/dist/commands/computer-setup.js +481 -0
- package/dist/commands/computer-setup.js.map +1 -0
- package/dist/commands/create-command.d.ts +7 -0
- package/dist/commands/create-command.d.ts.map +1 -0
- package/dist/commands/create-command.js +158 -0
- package/dist/commands/create-command.js.map +1 -0
- package/dist/commands/create.d.ts +74 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +556 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dashboard.d.ts +91 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +537 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/govern.d.ts +70 -0
- package/dist/commands/govern.d.ts.map +1 -0
- package/dist/commands/govern.js +480 -0
- package/dist/commands/govern.js.map +1 -0
- package/dist/commands/init.d.ts +55 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +584 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/performance-optimizer.d.ts +30 -0
- package/dist/commands/performance-optimizer.d.ts.map +1 -0
- package/dist/commands/performance-optimizer.js +649 -0
- package/dist/commands/performance-optimizer.js.map +1 -0
- package/dist/commands/plugins.d.ts +87 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +685 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/setup.d.ts +29 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +399 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/test-init.d.ts +9 -0
- package/dist/commands/test-init.d.ts.map +1 -0
- package/dist/commands/test-init.js +222 -0
- package/dist/commands/test-init.js.map +1 -0
- package/dist/commands/test.d.ts +25 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +217 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/watch.d.ts +76 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +610 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/context/context-manager.d.ts +155 -0
- package/dist/context/context-manager.d.ts.map +1 -0
- package/dist/context/context-manager.js +383 -0
- package/dist/context/context-manager.js.map +1 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +6 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/session-manager.d.ts +207 -0
- package/dist/context/session-manager.d.ts.map +1 -0
- package/dist/context/session-manager.js +682 -0
- package/dist/context/session-manager.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive/interactive-mode.d.ts +76 -0
- package/dist/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/interactive/interactive-mode.js +730 -0
- package/dist/interactive/interactive-mode.js.map +1 -0
- package/dist/nlp/command-mapper.d.ts +174 -0
- package/dist/nlp/command-mapper.d.ts.map +1 -0
- package/dist/nlp/command-mapper.js +623 -0
- package/dist/nlp/command-mapper.js.map +1 -0
- package/dist/nlp/command-parser.d.ts +106 -0
- package/dist/nlp/command-parser.d.ts.map +1 -0
- package/dist/nlp/command-parser.js +416 -0
- package/dist/nlp/command-parser.js.map +1 -0
- package/dist/nlp/index.d.ts +5 -0
- package/dist/nlp/index.d.ts.map +1 -0
- package/dist/nlp/index.js +8 -0
- package/dist/nlp/index.js.map +1 -0
- package/dist/nlp/intent-classifier.d.ts +59 -0
- package/dist/nlp/intent-classifier.d.ts.map +1 -0
- package/dist/nlp/intent-classifier.js +384 -0
- package/dist/nlp/intent-classifier.js.map +1 -0
- package/dist/nlp/intent-parser.d.ts +152 -0
- package/dist/nlp/intent-parser.d.ts.map +1 -0
- package/dist/nlp/intent-parser.js +739 -0
- package/dist/nlp/intent-parser.js.map +1 -0
- package/dist/plugins/plugin-manager.d.ts +120 -0
- package/dist/plugins/plugin-manager.d.ts.map +1 -0
- package/dist/plugins/plugin-manager.js +595 -0
- package/dist/plugins/plugin-manager.js.map +1 -0
- package/dist/types/index.d.ts +224 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config-manager.d.ts +73 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +339 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/error-handler.d.ts +46 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +169 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +94 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +119 -0
- package/src/ai/ai-service.ts +595 -0
- package/src/ai/claude-client.ts +490 -0
- package/src/ai/conversation-manager.ts +907 -0
- package/src/ai/index.ts +8 -0
- package/src/cli.ts +202 -0
- package/src/commands/ai.ts +995 -0
- package/src/commands/analyze-optimized.ts +641 -0
- package/src/commands/analyze.ts +576 -0
- package/src/commands/batch.ts +935 -0
- package/src/commands/chat.ts +876 -0
- package/src/commands/claude-init.ts +715 -0
- package/src/commands/claude-setup.ts +697 -0
- package/src/commands/computer-setup-commands.ts +709 -0
- package/src/commands/computer-setup.ts +565 -0
- package/src/commands/create-command.ts +175 -0
- package/src/commands/create.ts +727 -0
- package/src/commands/dashboard.ts +691 -0
- package/src/commands/govern.ts +635 -0
- package/src/commands/init.ts +677 -0
- package/src/commands/performance-optimizer.ts +864 -0
- package/src/commands/plugins.ts +848 -0
- package/src/commands/setup.ts +508 -0
- package/src/commands/test-init.ts +242 -0
- package/src/commands/test.ts +264 -0
- package/src/commands/watch.ts +755 -0
- package/src/context/context-manager.ts +546 -0
- package/src/context/index.ts +9 -0
- package/src/context/session-manager.ts +1019 -0
- package/src/index.ts +64 -0
- package/src/interactive/interactive-mode.ts +830 -0
- package/src/nlp/command-mapper.ts +885 -0
- package/src/nlp/command-parser.ts +564 -0
- package/src/nlp/index.ts +4 -0
- package/src/nlp/intent-classifier.ts +458 -0
- package/src/nlp/intent-parser.ts +1101 -0
- package/src/plugins/plugin-manager.ts +744 -0
- package/src/types/index.ts +252 -0
- package/src/types/modules.d.ts +56 -0
- package/src/utils/config-manager.ts +391 -0
- package/src/utils/error-handler.ts +192 -0
- package/src/utils/logger.ts +104 -0
- package/templates/batch/ci-cd.yaml +62 -0
- package/templates/component/{{fileName}}.test.tsx +17 -0
- package/templates/component/{{fileName}}.tsx +21 -0
- package/templates/service/{{fileName}}.ts +98 -0
- package/templates/wundr-test.config.js +0 -0
- package/test-suites/api/health.spec.ts +134 -0
- package/test-suites/helpers/test-config.ts +84 -0
- package/test-suites/ui/accessibility.spec.ts +102 -0
- package/test-suites/ui/smoke.spec.ts +92 -0
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import blessed from 'blessed';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { ConfigManager } from '../utils/config-manager';
|
|
5
|
+
import { PluginManager } from '../plugins/plugin-manager';
|
|
6
|
+
import { logger } from '../utils/logger';
|
|
7
|
+
import { errorHandler } from '../utils/error-handler';
|
|
8
|
+
import { InteractiveSession, TUILayout, ChatSession } from '../types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Interactive mode manager for wizard, TUI, and chat interfaces
|
|
12
|
+
*/
|
|
13
|
+
export class InteractiveMode {
|
|
14
|
+
private activeSessions: Map<string, InteractiveSession> = new Map();
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
private configManager: ConfigManager,
|
|
18
|
+
private pluginManager: PluginManager
|
|
19
|
+
) {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Launch interactive wizard mode
|
|
23
|
+
*/
|
|
24
|
+
async launchWizard(mode: string = 'setup'): Promise<void> {
|
|
25
|
+
try {
|
|
26
|
+
logger.info('Launching interactive wizard...');
|
|
27
|
+
|
|
28
|
+
const session: InteractiveSession = {
|
|
29
|
+
mode: 'wizard',
|
|
30
|
+
config: { wizardMode: mode },
|
|
31
|
+
state: {},
|
|
32
|
+
active: true,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
this.activeSessions.set(`wizard-${Date.now()}`, session);
|
|
36
|
+
|
|
37
|
+
switch (mode) {
|
|
38
|
+
case 'setup':
|
|
39
|
+
await this.setupWizard();
|
|
40
|
+
break;
|
|
41
|
+
case 'analyze':
|
|
42
|
+
await this.analyzeWizard();
|
|
43
|
+
break;
|
|
44
|
+
case 'create':
|
|
45
|
+
await this.createWizard();
|
|
46
|
+
break;
|
|
47
|
+
case 'govern':
|
|
48
|
+
await this.governWizard();
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
await this.generalWizard();
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
throw errorHandler.createError(
|
|
55
|
+
'WUNDR_WIZARD_FAILED',
|
|
56
|
+
'Failed to launch wizard',
|
|
57
|
+
{ mode },
|
|
58
|
+
true
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Launch chat interface
|
|
65
|
+
*/
|
|
66
|
+
async launchChat(options: any): Promise<void> {
|
|
67
|
+
try {
|
|
68
|
+
logger.info('Launching chat interface...');
|
|
69
|
+
|
|
70
|
+
// This would integrate with the chat commands
|
|
71
|
+
const { spawn } = await import('child_process');
|
|
72
|
+
const chatArgs = ['chat', 'start'];
|
|
73
|
+
|
|
74
|
+
if (options.model) chatArgs.push('--model', options.model);
|
|
75
|
+
if (options.context) chatArgs.push('--context', options.context);
|
|
76
|
+
|
|
77
|
+
const child = spawn('wundr', chatArgs, {
|
|
78
|
+
stdio: 'inherit',
|
|
79
|
+
shell: true,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
child.on('exit', code => {
|
|
83
|
+
if (code !== 0) {
|
|
84
|
+
logger.error(`Chat interface exited with code ${code}`);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
throw errorHandler.createError(
|
|
89
|
+
'WUNDR_CHAT_LAUNCH_FAILED',
|
|
90
|
+
'Failed to launch chat interface',
|
|
91
|
+
{ options },
|
|
92
|
+
true
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Launch Terminal User Interface (TUI)
|
|
99
|
+
*/
|
|
100
|
+
async launchTUI(layout: string = 'dashboard'): Promise<void> {
|
|
101
|
+
try {
|
|
102
|
+
logger.info(`Launching TUI with layout: ${layout}`);
|
|
103
|
+
|
|
104
|
+
const screen = blessed.screen({
|
|
105
|
+
smartCSR: true,
|
|
106
|
+
title: 'Wundr CLI Dashboard',
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
await this.setupTUILayout(screen, layout);
|
|
110
|
+
|
|
111
|
+
// Handle exit
|
|
112
|
+
screen.key(['escape', 'q', 'C-c'], () => {
|
|
113
|
+
return process.exit(0);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
screen.render();
|
|
117
|
+
} catch (error) {
|
|
118
|
+
throw errorHandler.createError(
|
|
119
|
+
'WUNDR_TUI_LAUNCH_FAILED',
|
|
120
|
+
'Failed to launch TUI',
|
|
121
|
+
{ layout },
|
|
122
|
+
true
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Setup wizard for initial configuration
|
|
129
|
+
*/
|
|
130
|
+
private async setupWizard(): Promise<void> {
|
|
131
|
+
console.log(chalk.cyan('\n🚀 Welcome to Wundr CLI Setup Wizard\n'));
|
|
132
|
+
|
|
133
|
+
const answers = await inquirer.prompt([
|
|
134
|
+
{
|
|
135
|
+
type: 'confirm',
|
|
136
|
+
name: 'initialize',
|
|
137
|
+
message: 'Initialize Wundr in this directory?',
|
|
138
|
+
default: true,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'list',
|
|
142
|
+
name: 'projectType',
|
|
143
|
+
message: 'What type of project is this?',
|
|
144
|
+
choices: [
|
|
145
|
+
{ name: 'Single Package', value: 'single' },
|
|
146
|
+
{ name: 'Monorepo', value: 'monorepo' },
|
|
147
|
+
{ name: 'Workspace', value: 'workspace' },
|
|
148
|
+
],
|
|
149
|
+
when: answers => answers.initialize,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'checkbox',
|
|
153
|
+
name: 'features',
|
|
154
|
+
message: 'Select features to enable:',
|
|
155
|
+
choices: [
|
|
156
|
+
{ name: 'Code Analysis', value: 'analysis', checked: true },
|
|
157
|
+
{ name: 'Governance Rules', value: 'governance', checked: true },
|
|
158
|
+
{ name: 'AI Assistance', value: 'ai', checked: false },
|
|
159
|
+
{ name: 'Dashboard', value: 'dashboard', checked: true },
|
|
160
|
+
{ name: 'Watch Mode', value: 'watch', checked: false },
|
|
161
|
+
],
|
|
162
|
+
when: answers => answers.initialize,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'input',
|
|
166
|
+
name: 'aiProvider',
|
|
167
|
+
message: 'AI Provider:',
|
|
168
|
+
default: 'claude',
|
|
169
|
+
when: answers => answers.features?.includes('ai'),
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
type: 'password',
|
|
173
|
+
name: 'aiApiKey',
|
|
174
|
+
message: 'AI API Key (optional):',
|
|
175
|
+
mask: '*',
|
|
176
|
+
when: answers => answers.features?.includes('ai'),
|
|
177
|
+
},
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
if (!answers.initialize) {
|
|
181
|
+
console.log(chalk.yellow('Setup cancelled'));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Execute setup commands based on answers
|
|
186
|
+
console.log(chalk.green('\n✨ Setting up your project...\n'));
|
|
187
|
+
|
|
188
|
+
const setupCommands = [
|
|
189
|
+
`wundr init ${answers.projectType === 'single' ? 'project' : answers.projectType}`,
|
|
190
|
+
'wundr init config',
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
if (answers.features?.includes('governance')) {
|
|
194
|
+
setupCommands.push('wundr govern rules add no-console');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (answers.features?.includes('dashboard')) {
|
|
198
|
+
setupCommands.push('wundr dashboard config set theme default');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
for (const command of setupCommands) {
|
|
202
|
+
console.log(chalk.blue(`Running: ${command}`));
|
|
203
|
+
// Execute command (simplified for demo)
|
|
204
|
+
await this.simulateCommand(command);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.log(
|
|
208
|
+
chalk.green('\n🎉 Setup complete! Your Wundr project is ready.')
|
|
209
|
+
);
|
|
210
|
+
console.log(chalk.gray('\nNext steps:'));
|
|
211
|
+
console.log(chalk.gray(' • Run "wundr analyze" to analyze your code'));
|
|
212
|
+
console.log(
|
|
213
|
+
chalk.gray(' • Run "wundr dashboard start" to launch the dashboard')
|
|
214
|
+
);
|
|
215
|
+
console.log(
|
|
216
|
+
chalk.gray(' • Run "wundr --help" to see all available commands')
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Analysis wizard
|
|
222
|
+
*/
|
|
223
|
+
private async analyzeWizard(): Promise<void> {
|
|
224
|
+
console.log(chalk.cyan('\n🔍 Code Analysis Wizard\n'));
|
|
225
|
+
|
|
226
|
+
const answers = await inquirer.prompt([
|
|
227
|
+
{
|
|
228
|
+
type: 'checkbox',
|
|
229
|
+
name: 'analysisTypes',
|
|
230
|
+
message: 'What would you like to analyze?',
|
|
231
|
+
choices: [
|
|
232
|
+
{ name: 'Dependencies', value: 'deps', checked: true },
|
|
233
|
+
{ name: 'Code Quality', value: 'quality', checked: true },
|
|
234
|
+
{ name: 'Performance', value: 'perf', checked: false },
|
|
235
|
+
{ name: 'Architecture', value: 'arch', checked: false },
|
|
236
|
+
{ name: 'Security', value: 'security', checked: true },
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
type: 'list',
|
|
241
|
+
name: 'outputFormat',
|
|
242
|
+
message: 'Output format:',
|
|
243
|
+
choices: [
|
|
244
|
+
{ name: 'Table (Console)', value: 'table' },
|
|
245
|
+
{ name: 'JSON File', value: 'json' },
|
|
246
|
+
{ name: 'HTML Report', value: 'html' },
|
|
247
|
+
],
|
|
248
|
+
default: 'table',
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
type: 'confirm',
|
|
252
|
+
name: 'autoFix',
|
|
253
|
+
message: 'Automatically fix issues where possible?',
|
|
254
|
+
default: false,
|
|
255
|
+
},
|
|
256
|
+
]);
|
|
257
|
+
|
|
258
|
+
console.log(chalk.green('\n🔬 Running analysis...\n'));
|
|
259
|
+
|
|
260
|
+
for (const analysisType of answers.analysisTypes) {
|
|
261
|
+
let command = `wundr analyze ${analysisType}`;
|
|
262
|
+
if (answers.outputFormat !== 'table') {
|
|
263
|
+
command += ` --format ${answers.outputFormat}`;
|
|
264
|
+
}
|
|
265
|
+
if (answers.autoFix) {
|
|
266
|
+
command += ' --fix';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
console.log(chalk.blue(`Running: ${command}`));
|
|
270
|
+
await this.simulateCommand(command);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
console.log(chalk.green('\n✅ Analysis complete!'));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Creation wizard
|
|
278
|
+
*/
|
|
279
|
+
private async createWizard(): Promise<void> {
|
|
280
|
+
console.log(chalk.cyan('\n🛠️ Code Generation Wizard\n'));
|
|
281
|
+
|
|
282
|
+
const answers = await inquirer.prompt([
|
|
283
|
+
{
|
|
284
|
+
type: 'list',
|
|
285
|
+
name: 'createType',
|
|
286
|
+
message: 'What would you like to create?',
|
|
287
|
+
choices: [
|
|
288
|
+
{ name: 'Component', value: 'component' },
|
|
289
|
+
{ name: 'Service', value: 'service' },
|
|
290
|
+
{ name: 'Package (Monorepo)', value: 'package' },
|
|
291
|
+
{ name: 'Template', value: 'template' },
|
|
292
|
+
{ name: 'Workflow', value: 'workflow' },
|
|
293
|
+
{ name: 'Configuration', value: 'config' },
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
type: 'input',
|
|
298
|
+
name: 'name',
|
|
299
|
+
message: 'Name:',
|
|
300
|
+
validate: input => input.length > 0 || 'Name is required',
|
|
301
|
+
},
|
|
302
|
+
]);
|
|
303
|
+
|
|
304
|
+
// Get specific options based on type
|
|
305
|
+
let specificAnswers = {};
|
|
306
|
+
|
|
307
|
+
switch (answers.createType) {
|
|
308
|
+
case 'component':
|
|
309
|
+
specificAnswers = await this.getComponentOptions();
|
|
310
|
+
break;
|
|
311
|
+
case 'service':
|
|
312
|
+
specificAnswers = await this.getServiceOptions();
|
|
313
|
+
break;
|
|
314
|
+
case 'package':
|
|
315
|
+
specificAnswers = await this.getPackageOptions();
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
specificAnswers = {};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
console.log(
|
|
322
|
+
chalk.green(`\n🏗️ Creating ${answers.createType}: ${answers.name}\n`)
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
let command = `wundr create ${answers.createType} ${answers.name}`;
|
|
326
|
+
|
|
327
|
+
// Add specific options to command
|
|
328
|
+
Object.entries(specificAnswers).forEach(([key, value]) => {
|
|
329
|
+
if (typeof value === 'boolean' && value) {
|
|
330
|
+
command += ` --${key}`;
|
|
331
|
+
} else if (typeof value === 'string' && value) {
|
|
332
|
+
command += ` --${key} ${value}`;
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
console.log(chalk.blue(`Running: ${command}`));
|
|
337
|
+
await this.simulateCommand(command);
|
|
338
|
+
|
|
339
|
+
console.log(
|
|
340
|
+
chalk.green(`\n🎉 ${answers.createType} created successfully!`)
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Governance wizard
|
|
346
|
+
*/
|
|
347
|
+
private async governWizard(): Promise<void> {
|
|
348
|
+
console.log(chalk.cyan('\n⚖️ Governance Setup Wizard\n'));
|
|
349
|
+
|
|
350
|
+
const answers = await inquirer.prompt([
|
|
351
|
+
{
|
|
352
|
+
type: 'checkbox',
|
|
353
|
+
name: 'ruleCategories',
|
|
354
|
+
message: 'Select rule categories to enable:',
|
|
355
|
+
choices: [
|
|
356
|
+
{ name: 'Code Quality', value: 'quality', checked: true },
|
|
357
|
+
{ name: 'Security', value: 'security', checked: true },
|
|
358
|
+
{ name: 'Performance', value: 'performance', checked: false },
|
|
359
|
+
{ name: 'Testing', value: 'testing', checked: true },
|
|
360
|
+
{ name: 'Documentation', value: 'docs', checked: false },
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
type: 'list',
|
|
365
|
+
name: 'severity',
|
|
366
|
+
message: 'Default severity level:',
|
|
367
|
+
choices: [
|
|
368
|
+
{ name: 'Error (Strict)', value: 'error' },
|
|
369
|
+
{ name: 'Warning (Balanced)', value: 'warning' },
|
|
370
|
+
{ name: 'Info (Lenient)', value: 'info' },
|
|
371
|
+
],
|
|
372
|
+
default: 'warning',
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
type: 'confirm',
|
|
376
|
+
name: 'createQualityGate',
|
|
377
|
+
message: 'Create a quality gate?',
|
|
378
|
+
default: true,
|
|
379
|
+
},
|
|
380
|
+
]);
|
|
381
|
+
|
|
382
|
+
console.log(chalk.green('\n⚙️ Setting up governance rules...\n'));
|
|
383
|
+
|
|
384
|
+
// Add rules based on categories
|
|
385
|
+
for (const category of answers.ruleCategories) {
|
|
386
|
+
const rules = this.getRulesForCategory(category);
|
|
387
|
+
for (const rule of rules) {
|
|
388
|
+
const command = `wundr govern rules add ${rule}`;
|
|
389
|
+
console.log(chalk.blue(`Running: ${command}`));
|
|
390
|
+
await this.simulateCommand(command);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Set severity
|
|
395
|
+
const severityCommand = `wundr govern config set severity ${answers.severity}`;
|
|
396
|
+
console.log(chalk.blue(`Running: ${severityCommand}`));
|
|
397
|
+
await this.simulateCommand(severityCommand);
|
|
398
|
+
|
|
399
|
+
// Create quality gate
|
|
400
|
+
if (answers.createQualityGate) {
|
|
401
|
+
const gateCommand =
|
|
402
|
+
'wundr govern gate create default --conditions "coverage>80,complexity<10"';
|
|
403
|
+
console.log(chalk.blue(`Running: ${gateCommand}`));
|
|
404
|
+
await this.simulateCommand(gateCommand);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
console.log(chalk.green('\n✅ Governance setup complete!'));
|
|
408
|
+
console.log(
|
|
409
|
+
chalk.gray(
|
|
410
|
+
'\nRun "wundr govern check" to validate your code against the rules.'
|
|
411
|
+
)
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* General purpose wizard
|
|
417
|
+
*/
|
|
418
|
+
private async generalWizard(): Promise<void> {
|
|
419
|
+
console.log(chalk.cyan('\n🧙 Wundr CLI Wizard\n'));
|
|
420
|
+
|
|
421
|
+
const answers = await inquirer.prompt([
|
|
422
|
+
{
|
|
423
|
+
type: 'list',
|
|
424
|
+
name: 'action',
|
|
425
|
+
message: 'What would you like to do?',
|
|
426
|
+
choices: [
|
|
427
|
+
{ name: 'Setup a new project', value: 'setup' },
|
|
428
|
+
{ name: 'Analyze existing code', value: 'analyze' },
|
|
429
|
+
{ name: 'Create new code', value: 'create' },
|
|
430
|
+
{ name: 'Setup governance', value: 'govern' },
|
|
431
|
+
{ name: 'Configure AI features', value: 'ai' },
|
|
432
|
+
{ name: 'Launch dashboard', value: 'dashboard' },
|
|
433
|
+
],
|
|
434
|
+
},
|
|
435
|
+
]);
|
|
436
|
+
|
|
437
|
+
switch (answers.action) {
|
|
438
|
+
case 'setup':
|
|
439
|
+
await this.setupWizard();
|
|
440
|
+
break;
|
|
441
|
+
case 'analyze':
|
|
442
|
+
await this.analyzeWizard();
|
|
443
|
+
break;
|
|
444
|
+
case 'create':
|
|
445
|
+
await this.createWizard();
|
|
446
|
+
break;
|
|
447
|
+
case 'govern':
|
|
448
|
+
await this.governWizard();
|
|
449
|
+
break;
|
|
450
|
+
case 'ai':
|
|
451
|
+
await this.aiConfigWizard();
|
|
452
|
+
break;
|
|
453
|
+
case 'dashboard':
|
|
454
|
+
await this.launchDashboard();
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* AI configuration wizard
|
|
461
|
+
*/
|
|
462
|
+
private async aiConfigWizard(): Promise<void> {
|
|
463
|
+
console.log(chalk.cyan('\n🤖 AI Configuration Wizard\n'));
|
|
464
|
+
|
|
465
|
+
const answers = await inquirer.prompt([
|
|
466
|
+
{
|
|
467
|
+
type: 'list',
|
|
468
|
+
name: 'provider',
|
|
469
|
+
message: 'AI Provider:',
|
|
470
|
+
choices: [
|
|
471
|
+
{ name: 'Claude (Anthropic)', value: 'claude' },
|
|
472
|
+
{ name: 'ChatGPT (OpenAI)', value: 'openai' },
|
|
473
|
+
{ name: 'Local Model', value: 'local' },
|
|
474
|
+
],
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
type: 'list',
|
|
478
|
+
name: 'model',
|
|
479
|
+
message: 'Model:',
|
|
480
|
+
choices: answers => {
|
|
481
|
+
switch (answers.provider) {
|
|
482
|
+
case 'claude':
|
|
483
|
+
return ['claude-3', 'claude-3-haiku', 'claude-3-sonnet'];
|
|
484
|
+
case 'openai':
|
|
485
|
+
return ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo'];
|
|
486
|
+
case 'local':
|
|
487
|
+
return ['llama2', 'codellama', 'custom'];
|
|
488
|
+
default:
|
|
489
|
+
return ['claude-3'];
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
type: 'password',
|
|
495
|
+
name: 'apiKey',
|
|
496
|
+
message: 'API Key:',
|
|
497
|
+
mask: '*',
|
|
498
|
+
when: answers => answers.provider !== 'local',
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
type: 'checkbox',
|
|
502
|
+
name: 'features',
|
|
503
|
+
message: 'Enable AI features:',
|
|
504
|
+
choices: [
|
|
505
|
+
{ name: 'Code Generation', value: 'generate', checked: true },
|
|
506
|
+
{ name: 'Code Review', value: 'review', checked: true },
|
|
507
|
+
{ name: 'Refactoring', value: 'refactor', checked: false },
|
|
508
|
+
{ name: 'Documentation', value: 'docs', checked: true },
|
|
509
|
+
{ name: 'Test Generation', value: 'test', checked: false },
|
|
510
|
+
],
|
|
511
|
+
},
|
|
512
|
+
]);
|
|
513
|
+
|
|
514
|
+
console.log(chalk.green('\n🔧 Configuring AI features...\n'));
|
|
515
|
+
|
|
516
|
+
// Set AI configuration
|
|
517
|
+
const commands = [
|
|
518
|
+
`wundr ai config set provider ${answers.provider}`,
|
|
519
|
+
`wundr ai config set model ${answers.model}`,
|
|
520
|
+
];
|
|
521
|
+
|
|
522
|
+
if (answers.apiKey) {
|
|
523
|
+
commands.push(`wundr ai config set apiKey ${answers.apiKey}`);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
for (const command of commands) {
|
|
527
|
+
console.log(chalk.blue(`Running: ${command}`));
|
|
528
|
+
await this.simulateCommand(command);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
console.log(chalk.green('\n✅ AI configuration complete!'));
|
|
532
|
+
console.log(chalk.gray('\nTry "wundr ai ask" to start chatting with AI.'));
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Launch dashboard shortcut
|
|
537
|
+
*/
|
|
538
|
+
private async launchDashboard(): Promise<void> {
|
|
539
|
+
console.log(chalk.green('\n📊 Launching Wundr Dashboard...\n'));
|
|
540
|
+
|
|
541
|
+
const command = 'wundr dashboard start --open';
|
|
542
|
+
console.log(chalk.blue(`Running: ${command}`));
|
|
543
|
+
await this.simulateCommand(command);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Setup TUI layout
|
|
548
|
+
*/
|
|
549
|
+
private async setupTUILayout(screen: any, layoutType: string): Promise<void> {
|
|
550
|
+
switch (layoutType) {
|
|
551
|
+
case 'dashboard':
|
|
552
|
+
await this.setupDashboardLayout(screen);
|
|
553
|
+
break;
|
|
554
|
+
case 'monitor':
|
|
555
|
+
await this.setupMonitorLayout(screen);
|
|
556
|
+
break;
|
|
557
|
+
case 'debug':
|
|
558
|
+
await this.setupDebugLayout(screen);
|
|
559
|
+
break;
|
|
560
|
+
default:
|
|
561
|
+
await this.setupDashboardLayout(screen);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Setup dashboard TUI layout
|
|
567
|
+
*/
|
|
568
|
+
private async setupDashboardLayout(screen: any): Promise<void> {
|
|
569
|
+
// Header
|
|
570
|
+
const header = blessed.box({
|
|
571
|
+
top: 0,
|
|
572
|
+
left: 0,
|
|
573
|
+
width: '100%',
|
|
574
|
+
height: 3,
|
|
575
|
+
content: `{center}${chalk.cyan('🚀 Wundr CLI Dashboard')}{/center}`,
|
|
576
|
+
tags: true,
|
|
577
|
+
border: {
|
|
578
|
+
type: 'line',
|
|
579
|
+
},
|
|
580
|
+
style: {
|
|
581
|
+
fg: 'white',
|
|
582
|
+
bg: 'blue',
|
|
583
|
+
border: {
|
|
584
|
+
fg: '#f0f0f0',
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
// Sidebar
|
|
590
|
+
const sidebar = blessed.box({
|
|
591
|
+
top: 3,
|
|
592
|
+
left: 0,
|
|
593
|
+
width: '25%',
|
|
594
|
+
height: '100%-6',
|
|
595
|
+
content:
|
|
596
|
+
'Navigation\n\n→ Overview\n Analysis\n Governance\n AI Tools\n Settings',
|
|
597
|
+
border: {
|
|
598
|
+
type: 'line',
|
|
599
|
+
},
|
|
600
|
+
style: {
|
|
601
|
+
fg: 'white',
|
|
602
|
+
border: {
|
|
603
|
+
fg: '#f0f0f0',
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
// Main content
|
|
609
|
+
const main = blessed.box({
|
|
610
|
+
top: 3,
|
|
611
|
+
left: '25%',
|
|
612
|
+
width: '75%',
|
|
613
|
+
height: '100%-6',
|
|
614
|
+
content:
|
|
615
|
+
'Project Overview\n\n' +
|
|
616
|
+
'📁 Files: 1,234\n' +
|
|
617
|
+
'🔍 Issues: 5\n' +
|
|
618
|
+
'✅ Tests: 98% coverage\n' +
|
|
619
|
+
'📦 Dependencies: 45\n' +
|
|
620
|
+
'🚀 Performance: Good',
|
|
621
|
+
border: {
|
|
622
|
+
type: 'line',
|
|
623
|
+
},
|
|
624
|
+
style: {
|
|
625
|
+
fg: 'white',
|
|
626
|
+
border: {
|
|
627
|
+
fg: '#f0f0f0',
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
// Footer
|
|
633
|
+
const footer = blessed.box({
|
|
634
|
+
bottom: 0,
|
|
635
|
+
left: 0,
|
|
636
|
+
width: '100%',
|
|
637
|
+
height: 3,
|
|
638
|
+
content: '{center}Press q or Esc to exit{/center}',
|
|
639
|
+
tags: true,
|
|
640
|
+
border: {
|
|
641
|
+
type: 'line',
|
|
642
|
+
},
|
|
643
|
+
style: {
|
|
644
|
+
fg: 'white',
|
|
645
|
+
bg: 'black',
|
|
646
|
+
border: {
|
|
647
|
+
fg: '#f0f0f0',
|
|
648
|
+
},
|
|
649
|
+
},
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
screen.append(header);
|
|
653
|
+
screen.append(sidebar);
|
|
654
|
+
screen.append(main);
|
|
655
|
+
screen.append(footer);
|
|
656
|
+
|
|
657
|
+
// Focus handling
|
|
658
|
+
main.focus();
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Setup monitor TUI layout
|
|
663
|
+
*/
|
|
664
|
+
private async setupMonitorLayout(screen: any): Promise<void> {
|
|
665
|
+
// Real-time monitoring layout with logs and metrics
|
|
666
|
+
const log = blessed.log({
|
|
667
|
+
top: 0,
|
|
668
|
+
left: 0,
|
|
669
|
+
width: '100%',
|
|
670
|
+
height: '100%',
|
|
671
|
+
border: {
|
|
672
|
+
type: 'line',
|
|
673
|
+
},
|
|
674
|
+
style: {
|
|
675
|
+
fg: 'white',
|
|
676
|
+
border: {
|
|
677
|
+
fg: '#f0f0f0',
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
scrollable: true,
|
|
681
|
+
alwaysScroll: true,
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
screen.append(log);
|
|
685
|
+
|
|
686
|
+
// Simulate log entries
|
|
687
|
+
setInterval(() => {
|
|
688
|
+
log.log(`[${new Date().toLocaleTimeString()}] Monitoring active...`);
|
|
689
|
+
}, 2000);
|
|
690
|
+
|
|
691
|
+
log.focus();
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Setup debug TUI layout
|
|
696
|
+
*/
|
|
697
|
+
private async setupDebugLayout(screen: any): Promise<void> {
|
|
698
|
+
// Debug information layout
|
|
699
|
+
const debugInfo = blessed.box({
|
|
700
|
+
top: 0,
|
|
701
|
+
left: 0,
|
|
702
|
+
width: '100%',
|
|
703
|
+
height: '100%',
|
|
704
|
+
content:
|
|
705
|
+
'Debug Information\n\n' +
|
|
706
|
+
'CLI Version: 1.0.0\n' +
|
|
707
|
+
'Node Version: ' +
|
|
708
|
+
process.version +
|
|
709
|
+
'\n' +
|
|
710
|
+
'Platform: ' +
|
|
711
|
+
process.platform +
|
|
712
|
+
'\n' +
|
|
713
|
+
'Working Directory: ' +
|
|
714
|
+
process.cwd() +
|
|
715
|
+
'\n' +
|
|
716
|
+
'Arguments: ' +
|
|
717
|
+
process.argv.join(' '),
|
|
718
|
+
border: {
|
|
719
|
+
type: 'line',
|
|
720
|
+
},
|
|
721
|
+
style: {
|
|
722
|
+
fg: 'white',
|
|
723
|
+
border: {
|
|
724
|
+
fg: '#f0f0f0',
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
screen.append(debugInfo);
|
|
730
|
+
debugInfo.focus();
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Helper methods for wizard options
|
|
735
|
+
*/
|
|
736
|
+
private async getComponentOptions(): Promise<any> {
|
|
737
|
+
return await inquirer.prompt([
|
|
738
|
+
{
|
|
739
|
+
type: 'list',
|
|
740
|
+
name: 'type',
|
|
741
|
+
message: 'Component type:',
|
|
742
|
+
choices: ['react', 'vue', 'angular'],
|
|
743
|
+
default: 'react',
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
type: 'confirm',
|
|
747
|
+
name: 'withTests',
|
|
748
|
+
message: 'Generate test files?',
|
|
749
|
+
default: true,
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
type: 'confirm',
|
|
753
|
+
name: 'withStories',
|
|
754
|
+
message: 'Generate Storybook stories?',
|
|
755
|
+
default: false,
|
|
756
|
+
},
|
|
757
|
+
]);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
private async getServiceOptions(): Promise<any> {
|
|
761
|
+
return await inquirer.prompt([
|
|
762
|
+
{
|
|
763
|
+
type: 'list',
|
|
764
|
+
name: 'type',
|
|
765
|
+
message: 'Service type:',
|
|
766
|
+
choices: ['api', 'worker', 'microservice'],
|
|
767
|
+
default: 'api',
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
type: 'list',
|
|
771
|
+
name: 'framework',
|
|
772
|
+
message: 'Framework:',
|
|
773
|
+
choices: ['express', 'fastify', 'nest'],
|
|
774
|
+
default: 'express',
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
type: 'confirm',
|
|
778
|
+
name: 'withTests',
|
|
779
|
+
message: 'Generate test files?',
|
|
780
|
+
default: true,
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
type: 'confirm',
|
|
784
|
+
name: 'withDocs',
|
|
785
|
+
message: 'Generate API documentation?',
|
|
786
|
+
default: true,
|
|
787
|
+
},
|
|
788
|
+
]);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
private async getPackageOptions(): Promise<any> {
|
|
792
|
+
return await inquirer.prompt([
|
|
793
|
+
{
|
|
794
|
+
type: 'list',
|
|
795
|
+
name: 'type',
|
|
796
|
+
message: 'Package type:',
|
|
797
|
+
choices: ['library', 'app', 'tool'],
|
|
798
|
+
default: 'library',
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
type: 'confirm',
|
|
802
|
+
name: 'public',
|
|
803
|
+
message: 'Make package public?',
|
|
804
|
+
default: false,
|
|
805
|
+
},
|
|
806
|
+
]);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
private getRulesForCategory(category: string): string[] {
|
|
810
|
+
const rulesByCategory = {
|
|
811
|
+
quality: ['no-console', 'no-debugger', 'prefer-const'],
|
|
812
|
+
security: ['no-eval', 'no-unsafe-inline'],
|
|
813
|
+
performance: ['no-inefficient-loops', 'prefer-map-over-loop'],
|
|
814
|
+
testing: ['require-tests', 'no-skip-tests'],
|
|
815
|
+
docs: ['require-jsdoc', 'require-readme'],
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
return rulesByCategory[category as keyof typeof rulesByCategory] || [];
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
private async simulateCommand(command: string): Promise<void> {
|
|
822
|
+
// Simulate command execution with a delay
|
|
823
|
+
return new Promise(resolve => {
|
|
824
|
+
setTimeout(() => {
|
|
825
|
+
console.log(chalk.green(` ✓ ${command}`));
|
|
826
|
+
resolve();
|
|
827
|
+
}, 500);
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
}
|