@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,565 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computer setup command for provisioning new developer machines
|
|
3
|
+
* Integrates new-starter functionality into the unified wundr CLI
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import inquirer from 'inquirer';
|
|
10
|
+
import { ComputerSetupManager } from '@wundr.io/computer-setup';
|
|
11
|
+
// import { getLogger } from '@wundr/core';
|
|
12
|
+
const logger = { info: console.log, error: console.error, warn: console.warn };
|
|
13
|
+
|
|
14
|
+
// const logger = getLogger('cli:computer-setup');
|
|
15
|
+
|
|
16
|
+
export function createComputerSetupCommand(): Command {
|
|
17
|
+
const command = new Command('computer-setup')
|
|
18
|
+
.alias('setup-machine')
|
|
19
|
+
.alias('provision')
|
|
20
|
+
.description(
|
|
21
|
+
'Set up a new developer machine with all required tools and configurations'
|
|
22
|
+
)
|
|
23
|
+
.option(
|
|
24
|
+
'-p, --profile <profile>',
|
|
25
|
+
'Use a specific profile (frontend, backend, fullstack, devops, ml)'
|
|
26
|
+
)
|
|
27
|
+
.option('-t, --team <team>', 'Apply team-specific configurations')
|
|
28
|
+
.option(
|
|
29
|
+
'-m, --mode <mode>',
|
|
30
|
+
'Setup mode (interactive, automated, minimal)',
|
|
31
|
+
'interactive'
|
|
32
|
+
)
|
|
33
|
+
.option('--dry-run', 'Show what would be installed without making changes')
|
|
34
|
+
.option('--skip-existing', 'Skip tools that are already installed')
|
|
35
|
+
.option('--parallel', 'Install tools in parallel where possible')
|
|
36
|
+
.option('--verbose', 'Show detailed output')
|
|
37
|
+
.option('--report', 'Generate a detailed setup report')
|
|
38
|
+
.action(async options => {
|
|
39
|
+
await runComputerSetup(options);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Subcommands
|
|
43
|
+
command
|
|
44
|
+
.command('profile')
|
|
45
|
+
.description('Manage developer profiles')
|
|
46
|
+
.action(async () => {
|
|
47
|
+
await manageProfiles();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
command
|
|
51
|
+
.command('validate')
|
|
52
|
+
.description('Validate current machine setup')
|
|
53
|
+
.action(async () => {
|
|
54
|
+
await validateSetup();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
command
|
|
58
|
+
.command('doctor')
|
|
59
|
+
.description('Diagnose and fix common setup issues')
|
|
60
|
+
.action(async () => {
|
|
61
|
+
await runDoctor();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
command
|
|
65
|
+
.command('team-config')
|
|
66
|
+
.description('Download and apply team configuration')
|
|
67
|
+
.argument('<team>', 'Team identifier')
|
|
68
|
+
.action(async team => {
|
|
69
|
+
await applyTeamConfig(team);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return command;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function runComputerSetup(options: any): Promise<void> {
|
|
76
|
+
const spinner = ora('Initializing computer setup...').start();
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const manager = new ComputerSetupManager();
|
|
80
|
+
await manager.initialize();
|
|
81
|
+
|
|
82
|
+
spinner.stop();
|
|
83
|
+
|
|
84
|
+
// Get or create profile
|
|
85
|
+
let profile;
|
|
86
|
+
if (options.profile) {
|
|
87
|
+
// Get profile by name - ProfileManager will handle normalization
|
|
88
|
+
profile = await manager.getProfile(options.profile);
|
|
89
|
+
if (!profile) {
|
|
90
|
+
console.log(
|
|
91
|
+
chalk.yellow(`Profile '${options.profile}' not found. Using default.`)
|
|
92
|
+
);
|
|
93
|
+
profile = await manager.getDefaultProfile();
|
|
94
|
+
}
|
|
95
|
+
} else if (options.mode === 'interactive' || options.interactive) {
|
|
96
|
+
profile = await createInteractiveProfile();
|
|
97
|
+
} else {
|
|
98
|
+
profile = await manager.getDefaultProfile();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Detect platform
|
|
102
|
+
const platform = {
|
|
103
|
+
os: process.platform as 'darwin' | 'linux' | 'win32',
|
|
104
|
+
arch: process.arch as 'x64' | 'arm64',
|
|
105
|
+
version: process.version,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
console.log(chalk.cyan('\nš„ļø Computer Setup for Engineering Teams\n'));
|
|
109
|
+
console.log(chalk.gray('ā'.repeat(50)));
|
|
110
|
+
console.log(chalk.white('Profile:'), chalk.green(profile.name));
|
|
111
|
+
console.log(chalk.white('Role:'), chalk.green(profile.role));
|
|
112
|
+
console.log(
|
|
113
|
+
chalk.white('Platform:'),
|
|
114
|
+
chalk.green(`${platform.os} ${platform.arch}`)
|
|
115
|
+
);
|
|
116
|
+
console.log(chalk.white('Mode:'), chalk.green(options.mode));
|
|
117
|
+
console.log(chalk.gray('ā'.repeat(50)));
|
|
118
|
+
|
|
119
|
+
if (options.dryRun) {
|
|
120
|
+
console.log(
|
|
121
|
+
chalk.yellow('\nā ļø DRY RUN MODE - No changes will be made\n')
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Confirm before proceeding
|
|
126
|
+
if (options.mode === 'interactive' && !options.dryRun) {
|
|
127
|
+
const { proceed } = await inquirer.prompt([
|
|
128
|
+
{
|
|
129
|
+
type: 'confirm',
|
|
130
|
+
name: 'proceed',
|
|
131
|
+
message: 'Ready to set up your machine?',
|
|
132
|
+
default: true,
|
|
133
|
+
},
|
|
134
|
+
]);
|
|
135
|
+
|
|
136
|
+
if (!proceed) {
|
|
137
|
+
console.log(chalk.yellow('Setup cancelled'));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Set up progress monitoring
|
|
143
|
+
manager.on('progress', progress => {
|
|
144
|
+
const bar = generateProgressBar(progress.percentage);
|
|
145
|
+
console.log(chalk.cyan(`\n[${bar}] ${progress.percentage}%`));
|
|
146
|
+
console.log(chalk.gray(`Current: ${progress.currentStep}`));
|
|
147
|
+
console.log(
|
|
148
|
+
chalk.gray(`Steps: ${progress.completedSteps}/${progress.totalSteps}`)
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Run setup
|
|
153
|
+
spinner.text = 'Setting up your machine...';
|
|
154
|
+
spinner.start();
|
|
155
|
+
|
|
156
|
+
const result = await manager.setup({
|
|
157
|
+
profile,
|
|
158
|
+
platform,
|
|
159
|
+
mode: options.mode,
|
|
160
|
+
skipExisting: options.skipExisting || false,
|
|
161
|
+
dryRun: options.dryRun || false,
|
|
162
|
+
verbose: options.verbose || false,
|
|
163
|
+
parallel: options.parallel || false,
|
|
164
|
+
generateReport: options.report || false,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
spinner.stop();
|
|
168
|
+
|
|
169
|
+
// Display results
|
|
170
|
+
if (result.success) {
|
|
171
|
+
console.log(chalk.green('\nā
Computer setup completed successfully!\n'));
|
|
172
|
+
} else {
|
|
173
|
+
console.log(chalk.red('\nā Computer setup completed with errors\n'));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
console.log(chalk.white('Summary:'));
|
|
177
|
+
console.log(
|
|
178
|
+
chalk.green(` ā Completed: ${result.completedSteps?.length || 0} steps`)
|
|
179
|
+
);
|
|
180
|
+
if (result.skippedSteps && result.skippedSteps.length > 0) {
|
|
181
|
+
console.log(
|
|
182
|
+
chalk.yellow(` ā Skipped: ${result.skippedSteps.length} steps`)
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
if (result.failedSteps && result.failedSteps.length > 0) {
|
|
186
|
+
console.log(chalk.red(` ā Failed: ${result.failedSteps.length} steps`));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
190
|
+
console.log(chalk.yellow('\nā ļø Warnings:'));
|
|
191
|
+
result.warnings.forEach(w => console.log(chalk.yellow(` - ${w}`)));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (result.errors && result.errors.length > 0) {
|
|
195
|
+
console.log(chalk.red('\nā Errors:'));
|
|
196
|
+
result.errors.forEach(e =>
|
|
197
|
+
console.log(chalk.red(` - ${(e as any)?.message || e}`))
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (result.report) {
|
|
202
|
+
console.log(chalk.cyan(`\nš Setup report generated successfully`));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Display next steps
|
|
206
|
+
console.log(chalk.cyan('\nš Next Steps:'));
|
|
207
|
+
const nextSteps = [
|
|
208
|
+
'Restart your terminal to apply configurations',
|
|
209
|
+
'Run "wundr computer-setup validate" to verify',
|
|
210
|
+
'Sign in to your team communication tools',
|
|
211
|
+
'Clone your team repositories',
|
|
212
|
+
'Review team onboarding documentation',
|
|
213
|
+
];
|
|
214
|
+
nextSteps.forEach((step, i) => {
|
|
215
|
+
console.log(chalk.white(` ${i + 1}. ${step}`));
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
console.log(chalk.gray('\nā'.repeat(50)));
|
|
219
|
+
console.log(chalk.cyan('Welcome to the team! š'));
|
|
220
|
+
console.log(chalk.gray('ā'.repeat(50)));
|
|
221
|
+
} catch (error) {
|
|
222
|
+
spinner.stop();
|
|
223
|
+
logger.error('Computer setup failed', error);
|
|
224
|
+
console.error(chalk.red('Setup failed:'), error);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function createInteractiveProfile(): Promise<any> {
|
|
230
|
+
console.log(chalk.cyan("\nš¤ Let's create your developer profile\n"));
|
|
231
|
+
|
|
232
|
+
const answers = await inquirer.prompt([
|
|
233
|
+
{
|
|
234
|
+
type: 'input',
|
|
235
|
+
name: 'name',
|
|
236
|
+
message: 'What is your name?',
|
|
237
|
+
validate: input => input.length > 0,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
type: 'input',
|
|
241
|
+
name: 'email',
|
|
242
|
+
message: 'What is your email?',
|
|
243
|
+
validate: input => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input),
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
type: 'list',
|
|
247
|
+
name: 'role',
|
|
248
|
+
message: 'What is your role?',
|
|
249
|
+
choices: [
|
|
250
|
+
{ name: 'Frontend Developer', value: 'frontend' },
|
|
251
|
+
{ name: 'Backend Developer', value: 'backend' },
|
|
252
|
+
{ name: 'Full Stack Developer', value: 'fullstack' },
|
|
253
|
+
{ name: 'DevOps Engineer', value: 'devops' },
|
|
254
|
+
{ name: 'Machine Learning Engineer', value: 'ml' },
|
|
255
|
+
{ name: 'Mobile Developer', value: 'mobile' },
|
|
256
|
+
],
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
type: 'input',
|
|
260
|
+
name: 'team',
|
|
261
|
+
message: 'What team are you joining? (optional)',
|
|
262
|
+
default: '',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
type: 'list',
|
|
266
|
+
name: 'shell',
|
|
267
|
+
message: 'Which shell do you prefer?',
|
|
268
|
+
choices: ['zsh', 'bash', 'fish'],
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
type: 'list',
|
|
272
|
+
name: 'editor',
|
|
273
|
+
message: 'Which editor do you use?',
|
|
274
|
+
choices: [
|
|
275
|
+
{ name: 'Visual Studio Code', value: 'vscode' },
|
|
276
|
+
{ name: 'Vim', value: 'vim' },
|
|
277
|
+
{ name: 'Neovim', value: 'neovim' },
|
|
278
|
+
{ name: 'Sublime Text', value: 'sublime' },
|
|
279
|
+
{ name: 'IntelliJ IDEA', value: 'intellij' },
|
|
280
|
+
],
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
type: 'checkbox',
|
|
284
|
+
name: 'languages',
|
|
285
|
+
message: 'Which programming languages do you need?',
|
|
286
|
+
choices: [
|
|
287
|
+
{ name: 'Node.js', value: 'node', checked: true },
|
|
288
|
+
{ name: 'Python', value: 'python' },
|
|
289
|
+
{ name: 'Go', value: 'go' },
|
|
290
|
+
{ name: 'Rust', value: 'rust' },
|
|
291
|
+
{ name: 'Java', value: 'java' },
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
type: 'checkbox',
|
|
296
|
+
name: 'tools',
|
|
297
|
+
message: 'Which tools do you need?',
|
|
298
|
+
choices: [
|
|
299
|
+
{ name: 'Docker', value: 'docker', checked: true },
|
|
300
|
+
{ name: 'Kubernetes', value: 'kubernetes' },
|
|
301
|
+
{ name: 'AWS CLI', value: 'aws' },
|
|
302
|
+
{ name: 'Google Cloud SDK', value: 'gcloud' },
|
|
303
|
+
{ name: 'PostgreSQL', value: 'postgresql' },
|
|
304
|
+
{ name: 'Redis', value: 'redis' },
|
|
305
|
+
],
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
type: 'confirm',
|
|
309
|
+
name: 'aiTools',
|
|
310
|
+
message:
|
|
311
|
+
'Do you want to set up AI development tools (Claude Code, Claude Flow)?',
|
|
312
|
+
default: true,
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
type: 'confirm',
|
|
316
|
+
name: 'slack',
|
|
317
|
+
message: 'Do you need Slack configuration?',
|
|
318
|
+
default: true,
|
|
319
|
+
},
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
// Build profile from answers
|
|
323
|
+
return {
|
|
324
|
+
name: answers.name,
|
|
325
|
+
email: answers.email,
|
|
326
|
+
role: answers.role,
|
|
327
|
+
team: answers.team,
|
|
328
|
+
preferences: {
|
|
329
|
+
shell: answers.shell,
|
|
330
|
+
editor: answers.editor,
|
|
331
|
+
theme: 'auto',
|
|
332
|
+
gitConfig: {
|
|
333
|
+
userName: answers.name,
|
|
334
|
+
userEmail: answers.email,
|
|
335
|
+
signCommits: true,
|
|
336
|
+
defaultBranch: 'main',
|
|
337
|
+
aliases: {},
|
|
338
|
+
},
|
|
339
|
+
aiTools: {
|
|
340
|
+
claudeCode: answers.aiTools,
|
|
341
|
+
claudeFlow: answers.aiTools,
|
|
342
|
+
mcpTools: answers.aiTools ? ['all'] : [],
|
|
343
|
+
swarmAgents: answers.aiTools ? ['default'] : [],
|
|
344
|
+
memoryAllocation: '2GB',
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
tools: {
|
|
348
|
+
languages: buildLanguageConfig(answers.languages),
|
|
349
|
+
packageManagers: {
|
|
350
|
+
npm: true,
|
|
351
|
+
pnpm: true,
|
|
352
|
+
yarn: false,
|
|
353
|
+
brew: process.platform === 'darwin',
|
|
354
|
+
},
|
|
355
|
+
containers: {
|
|
356
|
+
docker: answers.tools.includes('docker'),
|
|
357
|
+
dockerCompose: answers.tools.includes('docker'),
|
|
358
|
+
kubernetes: answers.tools.includes('kubernetes'),
|
|
359
|
+
},
|
|
360
|
+
cloudCLIs: {
|
|
361
|
+
aws: answers.tools.includes('aws'),
|
|
362
|
+
gcloud: answers.tools.includes('gcloud'),
|
|
363
|
+
},
|
|
364
|
+
databases: {
|
|
365
|
+
postgresql: answers.tools.includes('postgresql'),
|
|
366
|
+
redis: answers.tools.includes('redis'),
|
|
367
|
+
},
|
|
368
|
+
monitoring: {},
|
|
369
|
+
communication: {
|
|
370
|
+
slack: answers.slack
|
|
371
|
+
? {
|
|
372
|
+
workspaces: [],
|
|
373
|
+
profile: {
|
|
374
|
+
displayName: answers.name,
|
|
375
|
+
statusText: 'New team member',
|
|
376
|
+
statusEmoji: ':wave:',
|
|
377
|
+
},
|
|
378
|
+
}
|
|
379
|
+
: undefined,
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function buildLanguageConfig(languages: string[]): any {
|
|
386
|
+
const config: any = {};
|
|
387
|
+
|
|
388
|
+
if (languages.includes('node')) {
|
|
389
|
+
config.node = {
|
|
390
|
+
versions: ['20', '18'],
|
|
391
|
+
defaultVersion: '20',
|
|
392
|
+
globalPackages: ['pnpm', 'typescript', 'tsx'],
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (languages.includes('python')) {
|
|
397
|
+
config.python = {
|
|
398
|
+
versions: ['3.11', '3.10'],
|
|
399
|
+
defaultVersion: '3.11',
|
|
400
|
+
virtualEnv: 'venv',
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (languages.includes('go')) {
|
|
405
|
+
config.go = {
|
|
406
|
+
version: 'latest',
|
|
407
|
+
goPath: '$HOME/go',
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (languages.includes('rust')) {
|
|
412
|
+
config.rust = {
|
|
413
|
+
version: 'stable',
|
|
414
|
+
components: ['rustfmt', 'clippy'],
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (languages.includes('java')) {
|
|
419
|
+
config.java = {
|
|
420
|
+
version: '17',
|
|
421
|
+
jdk: 'adoptium',
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return config;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
async function manageProfiles(): Promise<void> {
|
|
429
|
+
const manager = new ComputerSetupManager();
|
|
430
|
+
await manager.initialize();
|
|
431
|
+
|
|
432
|
+
const profiles = await manager.getAvailableProfiles();
|
|
433
|
+
|
|
434
|
+
console.log(chalk.cyan('\nš Developer Profiles\n'));
|
|
435
|
+
|
|
436
|
+
if (profiles.length === 0) {
|
|
437
|
+
console.log(
|
|
438
|
+
chalk.yellow('No profiles found. Create one with "wundr computer-setup"')
|
|
439
|
+
);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
profiles.forEach((profile, i) => {
|
|
444
|
+
console.log(chalk.white(`${i + 1}. ${profile.name}`));
|
|
445
|
+
console.log(chalk.gray(` Role: ${profile.role}`));
|
|
446
|
+
console.log(chalk.gray(` Email: ${profile.email}`));
|
|
447
|
+
if (profile.team) {
|
|
448
|
+
console.log(chalk.gray(` Team: ${profile.team}`));
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async function validateSetup(): Promise<void> {
|
|
454
|
+
const spinner = ora('Validating machine setup...').start();
|
|
455
|
+
|
|
456
|
+
try {
|
|
457
|
+
const manager = new ComputerSetupManager();
|
|
458
|
+
await manager.initialize();
|
|
459
|
+
|
|
460
|
+
// Get current profile
|
|
461
|
+
const profiles = await manager.getAvailableProfiles();
|
|
462
|
+
if (profiles.length === 0) {
|
|
463
|
+
spinner.stop();
|
|
464
|
+
console.log(
|
|
465
|
+
chalk.yellow('No profile found. Run "wundr computer-setup" first.')
|
|
466
|
+
);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const profile = profiles[0]; // Use most recent
|
|
471
|
+
if (!profile) {
|
|
472
|
+
console.log(
|
|
473
|
+
chalk.yellow('No profile found. Run "wundr computer-setup" first.')
|
|
474
|
+
);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const isValid = await manager.validateSetup(profile);
|
|
478
|
+
|
|
479
|
+
spinner.stop();
|
|
480
|
+
|
|
481
|
+
if (isValid) {
|
|
482
|
+
console.log(chalk.green('ā
Machine setup is valid!'));
|
|
483
|
+
} else {
|
|
484
|
+
console.log(chalk.red('ā Machine setup has issues'));
|
|
485
|
+
console.log(
|
|
486
|
+
chalk.yellow(
|
|
487
|
+
'\nRun "wundr computer-setup doctor" to diagnose and fix issues'
|
|
488
|
+
)
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
} catch (error) {
|
|
492
|
+
spinner.stop();
|
|
493
|
+
console.error(chalk.red('Validation failed:'), error);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
async function runDoctor(): Promise<void> {
|
|
498
|
+
console.log(chalk.cyan('\nš„ Computer Setup Doctor\n'));
|
|
499
|
+
console.log(chalk.gray('Diagnosing your machine setup...\n'));
|
|
500
|
+
|
|
501
|
+
const checks = [
|
|
502
|
+
{ name: 'Node.js', command: 'node --version', required: true },
|
|
503
|
+
{ name: 'npm', command: 'npm --version', required: true },
|
|
504
|
+
{ name: 'pnpm', command: 'pnpm --version', required: false },
|
|
505
|
+
{ name: 'Git', command: 'git --version', required: true },
|
|
506
|
+
{ name: 'Docker', command: 'docker --version', required: false },
|
|
507
|
+
{ name: 'Claude Code', command: 'claude --version', required: false },
|
|
508
|
+
{ name: 'GitHub CLI', command: 'gh --version', required: false },
|
|
509
|
+
];
|
|
510
|
+
|
|
511
|
+
for (const check of checks) {
|
|
512
|
+
const spinner = ora(`Checking ${check.name}...`).start();
|
|
513
|
+
|
|
514
|
+
try {
|
|
515
|
+
const { execa } = (await import('execa')) as any;
|
|
516
|
+
const { stdout } = await execa(
|
|
517
|
+
check.command.split(' ')[0],
|
|
518
|
+
check.command.split(' ').slice(1)
|
|
519
|
+
);
|
|
520
|
+
spinner.succeed(`${check.name}: ${stdout.trim()}`);
|
|
521
|
+
} catch (error) {
|
|
522
|
+
if (check.required) {
|
|
523
|
+
spinner.fail(`${check.name}: Not found (REQUIRED)`);
|
|
524
|
+
} else {
|
|
525
|
+
spinner.warn(`${check.name}: Not found (optional)`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
console.log(chalk.cyan('\nš Recommendations:\n'));
|
|
531
|
+
console.log('1. Install missing required tools');
|
|
532
|
+
console.log('2. Run "wundr computer-setup" to complete setup');
|
|
533
|
+
console.log('3. Check PATH environment variable');
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
async function applyTeamConfig(team: string): Promise<void> {
|
|
537
|
+
console.log(chalk.cyan(`\nš„ Applying team configuration: ${team}\n`));
|
|
538
|
+
|
|
539
|
+
const spinner = ora('Downloading team configuration...').start();
|
|
540
|
+
|
|
541
|
+
try {
|
|
542
|
+
// This would fetch team config from a central repository
|
|
543
|
+
// For now, we'll simulate it
|
|
544
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
545
|
+
|
|
546
|
+
spinner.succeed('Team configuration downloaded');
|
|
547
|
+
console.log(chalk.green('ā
Team configuration applied successfully!'));
|
|
548
|
+
|
|
549
|
+
console.log(chalk.cyan('\nTeam tools installed:'));
|
|
550
|
+
console.log(' - Internal CLI tools');
|
|
551
|
+
console.log(' - Team-specific VS Code extensions');
|
|
552
|
+
console.log(' - Pre-commit hooks');
|
|
553
|
+
console.log(' - Team aliases and scripts');
|
|
554
|
+
} catch (error) {
|
|
555
|
+
spinner.fail('Failed to apply team configuration');
|
|
556
|
+
console.error(chalk.red('Error:'), error);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function generateProgressBar(percentage: number): string {
|
|
561
|
+
const width = 30;
|
|
562
|
+
const filled = Math.round((width * percentage) / 100);
|
|
563
|
+
const empty = width - filled;
|
|
564
|
+
return 'ā'.repeat(filled) + 'ā'.repeat(empty);
|
|
565
|
+
}
|