ultra-dex 3.1.0 → 3.2.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.
Files changed (44) hide show
  1. package/README.md +79 -74
  2. package/assets/code-patterns/clerk-middleware.ts +138 -0
  3. package/assets/code-patterns/prisma-schema.prisma +224 -0
  4. package/assets/code-patterns/rls-policies.sql +246 -0
  5. package/assets/code-patterns/server-actions.ts +191 -0
  6. package/assets/code-patterns/trpc-router.ts +258 -0
  7. package/assets/cursor-rules/13-ai-integration.mdc +155 -0
  8. package/assets/cursor-rules/14-server-components.mdc +81 -0
  9. package/assets/cursor-rules/15-server-actions.mdc +102 -0
  10. package/assets/cursor-rules/16-edge-middleware.mdc +105 -0
  11. package/assets/cursor-rules/17-streaming-ssr.mdc +138 -0
  12. package/bin/ultra-dex.js +38 -1
  13. package/lib/commands/agents.js +16 -13
  14. package/lib/commands/banner.js +43 -21
  15. package/lib/commands/build.js +26 -17
  16. package/lib/commands/doctor.js +98 -79
  17. package/lib/commands/generate.js +19 -16
  18. package/lib/commands/init.js +52 -56
  19. package/lib/commands/scaffold.js +151 -0
  20. package/lib/commands/serve.js +15 -13
  21. package/lib/commands/state.js +43 -70
  22. package/lib/commands/swarm.js +31 -9
  23. package/lib/config/theme.js +47 -0
  24. package/lib/templates/code/clerk-middleware.ts +138 -0
  25. package/lib/templates/code/prisma-schema.prisma +224 -0
  26. package/lib/templates/code/rls-policies.sql +246 -0
  27. package/lib/templates/code/server-actions.ts +191 -0
  28. package/lib/templates/code/trpc-router.ts +258 -0
  29. package/lib/themes/doomsday.js +229 -0
  30. package/lib/ui/index.js +5 -0
  31. package/lib/ui/interface.js +241 -0
  32. package/lib/ui/spinners.js +116 -0
  33. package/lib/ui/theme.js +183 -0
  34. package/lib/utils/agents.js +32 -0
  35. package/lib/utils/help.js +64 -0
  36. package/lib/utils/messages.js +35 -0
  37. package/lib/utils/progress.js +24 -0
  38. package/lib/utils/prompts.js +47 -0
  39. package/lib/utils/spinners.js +46 -0
  40. package/lib/utils/status.js +31 -0
  41. package/lib/utils/tables.js +41 -0
  42. package/lib/utils/theme-state.js +9 -0
  43. package/lib/utils/version-display.js +32 -0
  44. package/package.json +10 -1
@@ -1,21 +1,43 @@
1
- export const banner = `
2
- ╔═══════════════════════════════════════════════════════════╗
3
- ║ ║
4
- ║ ██╗ ██╗██╗ ████████╗██████╗ █████╗ ║
5
- ║ ██║ ██║██║ ╚══██╔══╝██╔══██╗██╔══██╗ ║
6
- ║ ██║ ██║██║ ██║ ██████╔╝███████║ ║
7
- ║ ██║ ██║██║ ██║ ██╔══██╗██╔══██║ ║
8
- ╚██████╔╝███████╗██║ ██║ ██║██║ ██║ ║
9
- ║ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ║
10
- ║ ║
11
- ██████╗ ███████╗██╗ ██╗ ║
12
- ██╔══██╗██╔════╝╚██╗██╔╝ ║
13
- ██║ ██║█████╗ ╚███╔╝ ║
14
- ║ ██║ ██║██╔══╝ ██╔██╗ ║
15
- ║ ██████╔╝███████╗██╔╝ ██╗ ║
16
- ║ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ║
17
- ║ ║
18
- ║ From Idea to Production-Ready SaaS ║
19
- ║ ║
20
- ╚═══════════════════════════════════════════════════════════╝
21
- `;
1
+ import gradient from 'gradient-string';
2
+ import boxen from 'boxen';
3
+ import chalk from 'chalk';
4
+
5
+ const ultraGradient = gradient(['#6366f1', '#8b5cf6', '#d946ef']);
6
+
7
+ const asciiLogo = `
8
+ ██╗ ██╗██╗ ████████╗██████╗ █████╗ ██████╗ ███████╗██╗ ██╗
9
+ ██║ ██║██║ ╚══██╔══╝██╔══██╗██╔══██╗ ██╔══██╗██╔════╝╚██╗██╔╝
10
+ ██║ ██║██║ ██║ ██████╔╝███████║█████╗██║ ██║█████╗ ╚███╔╝
11
+ ██║ ██║██║ ██║ ██╔══██╗██╔══██║╚════╝██║ ██║██╔══╝ ██╔██╗
12
+ ╚██████╔╝███████╗██║ ██║ ██║██║ ██║ ██████╔╝███████╗██╔╝ ██╗
13
+ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝`;
14
+
15
+ export const banner = asciiLogo;
16
+
17
+ export function showBanner(version = '3.2.0') {
18
+ console.log(ultraGradient(asciiLogo));
19
+ console.log(boxen(
20
+ `${chalk.hex('#8b5cf6').bold('🪐 Ultra-Dex')} ${chalk.dim('v' + version)}
21
+
22
+ ` +
23
+ `${chalk.hex('#6366f1')('AI Orchestration Meta-Layer')}
24
+
25
+ ` +
26
+ `${chalk.dim('github.com/Srujan0798/Ultra-Dex')}`,
27
+ {
28
+ padding: 1,
29
+ margin: 1,
30
+ borderStyle: 'round',
31
+ borderColor: '#8b5cf6',
32
+ dimBorder: true
33
+ }
34
+ ));
35
+ }
36
+
37
+ export function showCompactBanner() {
38
+ console.log(` ${chalk.hex('#8b5cf6').bold('🪐 Ultra-Dex')} ${chalk.dim('v3.2.0')}`);
39
+ }
40
+
41
+ export function showWelcome() {
42
+ showBanner();
43
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ultra-dex build command (GOD MODE)
2
+ * ultra-dex build command
3
3
  * Auto-Pilot: Finds the next pending task and executes it using Agents.
4
4
  */
5
5
 
@@ -10,6 +10,8 @@ import path from 'path';
10
10
  import { loadState } from './plan.js';
11
11
  import { runAgentLoop } from './run.js';
12
12
  import { createProvider, getDefaultProvider, checkConfiguredProviders } from '../providers/index.js';
13
+ import { showProgress } from '../utils/progress.js';
14
+ import { getRandomMessage } from '../utils/messages.js';
13
15
 
14
16
  async function readProjectContext() {
15
17
  const context = {};
@@ -27,21 +29,21 @@ export function registerBuildCommand(program) {
27
29
  .option('-k, --key <apiKey>', 'API key')
28
30
  .option('--dry-run', 'Preview the task without executing')
29
31
  .action(async (options) => {
30
- console.log(chalk.cyan('\n\u{1F30B} Ultra-Dex Auto-Pilot (Build Mode)\n'));
31
-
32
+ console.log(chalk.cyan('\nUltra-Dex Auto-Pilot\n'));
33
+
32
34
  // Check for API key
33
35
  const configured = checkConfiguredProviders();
34
36
  const hasProvider = configured.some(p => p.configured) || options.key;
35
37
 
36
38
  if (!hasProvider && !options.dryRun) {
37
- console.log(chalk.yellow('⚠️ No AI provider configured.'));
39
+ console.log(chalk.yellow('⚠️ No API keys found.'));
38
40
  console.log(chalk.white('Set an API key to enable Auto-Pilot.'));
39
41
  return;
40
42
  }
41
43
 
42
44
  const state = await loadState();
43
45
  if (!state) {
44
- console.log(chalk.red('❌ No state found. Run "ultra-dex init" first.'));
46
+ console.log(chalk.red('❌ No project state found. Run "ultra-dex init" first.'));
45
47
  return;
46
48
  }
47
49
 
@@ -59,12 +61,12 @@ export function registerBuildCommand(program) {
59
61
  }
60
62
 
61
63
  if (!nextTask) {
62
- console.log(chalk.green('✅ All phases completed! You are ready to launch.'));
64
+ console.log(chalk.green('✅ All phases completed! The project is ready.'));
63
65
  return;
64
66
  }
65
67
 
66
- console.log(chalk.bold(`Phase: ${currentPhase.name}`));
67
- console.log(chalk.bold(`Task: ${nextTask.task}`));
68
+ // Show Progress
69
+ showProgress([`Phase: ${currentPhase.name}`, `Target: ${nextTask.task}`]);
68
70
 
69
71
  // Heuristic to pick agent (naive)
70
72
  let agentName = 'backend'; // default
@@ -74,7 +76,7 @@ export function registerBuildCommand(program) {
74
76
  if (taskLower.includes('plan') || taskLower.includes('break down')) agentName = 'planner';
75
77
  if (taskLower.includes('test')) agentName = 'testing';
76
78
 
77
- console.log(chalk.gray(`Selected Agent: @${agentName}`));
79
+ console.log(chalk.gray(`Activating Agent: @${agentName}`));
78
80
 
79
81
  if (options.dryRun) {
80
82
  console.log(chalk.yellow('\nDry run mode. Exiting.'));
@@ -87,14 +89,21 @@ export function registerBuildCommand(program) {
87
89
 
88
90
  console.log(chalk.gray('─'.repeat(50)));
89
91
 
90
- const result = await runAgentLoop(agentName, nextTask.task, provider, context);
91
-
92
- // Save output
93
- const filename = `task-${nextTask.id}-${agentName}.md`;
94
- await fs.writeFile(filename, result);
95
- console.log(chalk.green(`\n✅ Task output saved to ${filename}`));
96
- console.log(chalk.gray('Review the code and mark the task as completed in .ultra/state.json'));
92
+ const spinner = ora(getRandomMessage('loading')).start();
93
+ try {
94
+ const result = await runAgentLoop(agentName, nextTask.task, provider, context);
95
+ spinner.succeed(chalk.green('Task execution completed'));
96
+
97
+ // Save output
98
+ const filename = `task-${nextTask.id}-${agentName}.md`;
99
+ await fs.writeFile(filename, result);
100
+ console.log(chalk.green(`\n✅ Task output saved to ${filename}`));
101
+ console.log(chalk.gray('Review the code and mark the task as completed in .ultra/state.json'));
102
+ } catch (error) {
103
+ spinner.fail(chalk.red('Task execution failed'));
104
+ console.error(error);
105
+ }
97
106
  });
98
107
  }
99
108
 
100
- export default { registerBuildCommand };
109
+ export default { registerBuildCommand };
@@ -4,12 +4,13 @@
4
4
  */
5
5
 
6
6
  import chalk from 'chalk';
7
- import ora from 'ora';
8
7
  import inquirer from 'inquirer';
9
8
  import fs from 'fs/promises';
10
9
  import path from 'path';
11
10
  import { execSync } from 'child_process';
12
11
  import { checkConfiguredProviders } from '../providers/index.js';
12
+ import { icons, header, statusLine } from '../utils/status.js';
13
+ import { createSpinner } from '../utils/spinners.js';
13
14
 
14
15
  // Default configuration
15
16
  const DEFAULT_CONFIG = {
@@ -55,17 +56,18 @@ async function saveConfig(config, global = false) {
55
56
  export function registerDoctorCommand(program) {
56
57
  program
57
58
  .command('doctor')
58
- .description('Diagnose Ultra-Dex setup and configuration')
59
+ .description('System Diagnostics - Check System Health')
59
60
  .option('--fix', 'Attempt to fix issues automatically')
60
61
  .action(async (options) => {
61
- console.log(chalk.cyan('\n🩺 Ultra-Dex Doctor\n'));
62
- console.log(chalk.gray('Checking your setup...\n'));
62
+ header('System Health Diagnostics');
63
+ console.log(chalk.gray(' Analyzing system components...\n'));
63
64
 
64
65
  const checks = [];
65
66
  let hasErrors = false;
66
67
 
67
68
  // Check 1: Node.js version
68
- const nodeSpinner = ora('Checking Node.js version...').start();
69
+ const nodeSpinner = createSpinner('Scanning Node.js environment...');
70
+ nodeSpinner.start();
69
71
  try {
70
72
  const nodeVersion = process.version;
71
73
  const major = parseInt(nodeVersion.slice(1).split('.')[0]);
@@ -83,7 +85,8 @@ export function registerDoctorCommand(program) {
83
85
  }
84
86
 
85
87
  // Check 2: Git
86
- const gitSpinner = ora('Checking Git...').start();
88
+ const gitSpinner = createSpinner('Checking Git repository...');
89
+ gitSpinner.start();
87
90
  try {
88
91
  const gitVersion = execSync('git --version', { encoding: 'utf8' }).trim();
89
92
  gitSpinner.succeed(`${gitVersion} ✓`);
@@ -95,20 +98,22 @@ export function registerDoctorCommand(program) {
95
98
  }
96
99
 
97
100
  // Check 3: AI Providers
98
- const providerSpinner = ora('Checking AI providers...').start();
101
+ const providerSpinner = createSpinner('Locating AI Providers...');
102
+ providerSpinner.start();
99
103
  const providers = checkConfiguredProviders();
100
104
  const configuredProviders = providers.filter(p => p.configured);
101
105
 
102
106
  if (configuredProviders.length > 0) {
103
- providerSpinner.succeed(`AI providers: ${configuredProviders.map(p => p.name).join(', ')} ✓`);
107
+ providerSpinner.succeed(`Providers found: ${configuredProviders.map(p => p.name).join(', ')} ✓`);
104
108
  checks.push({ name: 'AI Providers', status: 'ok', detail: configuredProviders.map(p => p.name).join(', ') });
105
109
  } else {
106
- providerSpinner.warn('No AI providers configured');
110
+ providerSpinner.warn('No AI Providers found');
107
111
  checks.push({ name: 'AI Providers', status: 'warn', detail: 'Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY' });
108
112
  }
109
113
 
110
114
  // Check 4: Project structure
111
- const structureSpinner = ora('Checking project structure...').start();
115
+ const structureSpinner = createSpinner('Verifying Project Structure...');
116
+ structureSpinner.start();
112
117
  const requiredFiles = ['CONTEXT.md', 'IMPLEMENTATION-PLAN.md'];
113
118
  const optionalFiles = ['CHECKLIST.md', 'QUICK-START.md', '.ultra/state.json'];
114
119
  const foundRequired = [];
@@ -129,26 +134,27 @@ export function registerDoctorCommand(program) {
129
134
  }
130
135
 
131
136
  if (foundRequired.length === requiredFiles.length) {
132
- structureSpinner.succeed(`Project structure: ${foundRequired.length}/${requiredFiles.length} required files ✓`);
137
+ structureSpinner.succeed(`Structure valid: ${foundRequired.length}/${requiredFiles.length} required artifacts ✓`);
133
138
  checks.push({ name: 'Project Structure', status: 'ok', detail: `${foundRequired.join(', ')}` });
134
139
  } else if (foundRequired.length > 0) {
135
- structureSpinner.warn(`Project structure: ${foundRequired.length}/${requiredFiles.length} required files`);
140
+ structureSpinner.warn(`Structure incomplete: ${foundRequired.length}/${requiredFiles.length} required artifacts`);
136
141
  checks.push({ name: 'Project Structure', status: 'warn', detail: `Missing: ${requiredFiles.filter(f => !foundRequired.includes(f)).join(', ')}` });
137
142
  } else {
138
143
  structureSpinner.info('No Ultra-Dex project found');
139
- checks.push({ name: 'Project Structure', status: 'info', detail: 'Run `ultra-dex init` to create a project' });
144
+ checks.push({ name: 'Project Structure', status: 'info', detail: 'Run `ultra-dex init` to create a new project' });
140
145
  }
141
146
 
142
147
  // Check 5: Git hooks
143
- const hooksSpinner = ora('Checking git hooks...').start();
148
+ const hooksSpinner = createSpinner('Checking Git hooks...');
149
+ hooksSpinner.start();
144
150
  try {
145
151
  const hookPath = path.resolve(process.cwd(), '.git/hooks/pre-commit');
146
152
  const hookContent = await fs.readFile(hookPath, 'utf8');
147
153
  if (hookContent.includes('ultra-dex')) {
148
- hooksSpinner.succeed('Pre-commit hook installed ✓');
154
+ hooksSpinner.succeed('Pre-commit active ✓');
149
155
  checks.push({ name: 'Git Hooks', status: 'ok', detail: 'Pre-commit active' });
150
156
  } else {
151
- hooksSpinner.info('Pre-commit hook exists but not Ultra-Dex');
157
+ hooksSpinner.info('Pre-commit active but not Ultra-Dex');
152
158
  checks.push({ name: 'Git Hooks', status: 'info', detail: 'Custom hook present' });
153
159
  }
154
160
  } catch {
@@ -157,13 +163,15 @@ export function registerDoctorCommand(program) {
157
163
  }
158
164
 
159
165
  // Check 6: Configuration
160
- const configSpinner = ora('Checking configuration...').start();
166
+ const configSpinner = createSpinner('Reading Configuration...');
167
+ configSpinner.start();
161
168
  const config = await loadConfig();
162
- configSpinner.succeed(`Config loaded from: ${config.source}`);
169
+ configSpinner.succeed(`Configuration loaded from: ${config.source}`);
163
170
  checks.push({ name: 'Configuration', status: 'ok', detail: `Source: ${config.source}` });
164
171
 
165
172
  // Check 7: MCP Server port
166
- const portSpinner = ora('Checking MCP server port...').start();
173
+ const portSpinner = createSpinner('Checking MCP Port...');
174
+ portSpinner.start();
167
175
  try {
168
176
  const net = await import('net');
169
177
  const server = net.createServer();
@@ -175,51 +183,52 @@ export function registerDoctorCommand(program) {
175
183
  });
176
184
  server.listen(config.mcpPort);
177
185
  });
178
- portSpinner.succeed(`Port ${config.mcpPort} available ✓`);
186
+ portSpinner.succeed(`Port ${config.mcpPort} open ✓`);
179
187
  checks.push({ name: 'MCP Port', status: 'ok', detail: `Port ${config.mcpPort} free` });
180
188
  } catch {
181
- portSpinner.warn(`Port ${config.mcpPort} in use`);
189
+ portSpinner.warn(`Portal ${config.mcpPort} blocked`);
182
190
  checks.push({ name: 'MCP Port', status: 'warn', detail: `Port ${config.mcpPort} busy - change with config` });
183
191
  }
184
192
 
185
193
  // Summary
186
- console.log(chalk.bold('\n📋 Summary\n'));
187
- console.log(chalk.gray('─'.repeat(50)));
194
+ header('Diagnostics Report');
188
195
 
189
196
  const okCount = checks.filter(c => c.status === 'ok').length;
190
197
  const warnCount = checks.filter(c => c.status === 'warn').length;
191
198
  const errorCount = checks.filter(c => c.status === 'error').length;
192
199
 
193
200
  checks.forEach(check => {
194
- const icon = check.status === 'ok' ? chalk.green('✓') :
195
- check.status === 'warn' ? chalk.yellow('⚠') :
196
- check.status === 'error' ? chalk.red('✗') :
197
- chalk.blue('');
198
- console.log(` ${icon} ${check.name.padEnd(18)} ${chalk.gray(check.detail)}`);
201
+ let icon;
202
+ if (check.status === 'ok') icon = icons.success;
203
+ else if (check.status === 'warn') icon = icons.warning;
204
+ else if (check.status === 'error') icon = icons.error;
205
+ else icon = icons.info;
206
+
207
+ statusLine(icon, `${check.name.padEnd(18)} ${chalk.gray(check.detail)}`);
199
208
  });
200
209
 
201
- console.log(chalk.gray('─'.repeat(50)));
210
+ console.log(chalk.gray(' ' + '─'.repeat(50)));
202
211
  console.log(` ${chalk.green(okCount + ' passed')} ${chalk.yellow(warnCount + ' warnings')} ${chalk.red(errorCount + ' errors')}`);
203
212
 
204
213
  if (hasErrors) {
205
- console.log(chalk.red('\n❌ Some checks failed. Fix issues above.\n'));
214
+ console.log(chalk.red('\n❌ System check failed. Fix issues above.\n'));
206
215
  process.exit(1);
207
216
  } else if (warnCount > 0) {
208
- console.log(chalk.yellow('\n⚠️ Some warnings. Setup works but could be improved.\n'));
217
+ console.log(chalk.yellow('\n⚠️ System operational but has warnings.\n'));
209
218
  } else {
210
- console.log(chalk.green('\n✅ All checks passed! Ultra-Dex is ready.\n'));
219
+ console.log(chalk.green('\n✅ All systems operational.\n'));
211
220
  }
212
221
 
213
222
  // Suggestions
214
223
  if (configuredProviders.length === 0) {
215
- console.log(chalk.cyan('💡 To enable AI features, set an API key:'));
224
+ console.log(chalk.cyan('💡 To configure AI providers, set an API key:'));
216
225
  console.log(chalk.gray(' export ANTHROPIC_API_KEY=sk-ant-...'));
217
226
  console.log(chalk.gray(' export OPENAI_API_KEY=sk-...'));
218
227
  console.log(chalk.gray(' export GEMINI_API_KEY=...\n'));
219
228
  }
220
229
 
221
230
  if (foundRequired.length === 0) {
222
- console.log(chalk.cyan('💡 To start a new project:'));
231
+ console.log(chalk.cyan('💡 To initialize a new project:'));
223
232
  console.log(chalk.gray(' ultra-dex init\n'));
224
233
  }
225
234
  });
@@ -257,7 +266,7 @@ export function registerConfigCommand(program) {
257
266
 
258
267
  console.log(chalk.cyan('\n📍 Config file locations:'));
259
268
  console.log(chalk.gray(' macOS: ~/Library/Application Support/Claude/claude_desktop_config.json'));
260
- console.log(chalk.gray(' Windows: %APPDATA%\\Claude\\claude_desktop_config.json'));
269
+ console.log(chalk.gray(' Windows: %APPDATA%\Claude\claude_desktop_config.json'));
261
270
  console.log(chalk.gray(' Linux: ~/.config/Claude/claude_desktop_config.json\n'));
262
271
  return;
263
272
  }
@@ -313,19 +322,21 @@ export function registerConfigCommand(program) {
313
322
  // Interactive mode
314
323
  console.log(chalk.cyan('\n⚙️ Ultra-Dex Configuration\n'));
315
324
 
316
- const { action } = await inquirer.prompt([{
317
- type: 'list',
318
- name: 'action',
319
- message: 'What would you like to do?',
320
- choices: [
321
- { name: 'View current config', value: 'view' },
322
- { name: 'Set default AI provider', value: 'provider' },
323
- { name: 'Set minimum alignment score', value: 'minScore' },
324
- { name: 'Set MCP server port', value: 'mcpPort' },
325
- { name: 'Generate MCP config for Claude', value: 'mcp' },
326
- { name: 'Create new config file', value: 'init' },
327
- ]
328
- }]);
325
+ const { action } = await inquirer.prompt([
326
+ {
327
+ type: 'list',
328
+ name: 'action',
329
+ message: 'What would you like to do?',
330
+ choices: [
331
+ { name: 'View current config', value: 'view' },
332
+ { name: 'Set default AI provider', value: 'provider' },
333
+ { name: 'Set minimum alignment score', value: 'minScore' },
334
+ { name: 'Set MCP server port', value: 'mcpPort' },
335
+ { name: 'Generate MCP config for Claude', value: 'mcp' },
336
+ { name: 'Create new config file', value: 'init' },
337
+ ]
338
+ }
339
+ ]);
329
340
 
330
341
  switch (action) {
331
342
  case 'view':
@@ -333,39 +344,45 @@ export function registerConfigCommand(program) {
333
344
  break;
334
345
 
335
346
  case 'provider':
336
- const { provider } = await inquirer.prompt([{
337
- type: 'list',
338
- name: 'provider',
339
- message: 'Select default AI provider:',
340
- choices: ['claude', 'openai', 'gemini'],
341
- default: config.provider
342
- }]);
347
+ const { provider } = await inquirer.prompt([
348
+ {
349
+ type: 'list',
350
+ name: 'provider',
351
+ message: 'Select default AI provider:',
352
+ choices: ['claude', 'openai', 'gemini'],
353
+ default: config.provider
354
+ }
355
+ ]);
343
356
  config.provider = provider;
344
357
  await saveConfig(config, options.global);
345
358
  console.log(chalk.green(`\n✅ Default provider set to: ${provider}\n`));
346
359
  break;
347
360
 
348
361
  case 'minScore':
349
- const { minScore } = await inquirer.prompt([{
350
- type: 'number',
351
- name: 'minScore',
352
- message: 'Minimum alignment score (0-100):',
353
- default: config.minScore,
354
- validate: n => n >= 0 && n <= 100 || 'Must be 0-100'
355
- }]);
362
+ const { minScore } = await inquirer.prompt([
363
+ {
364
+ type: 'number',
365
+ name: 'minScore',
366
+ message: 'Minimum alignment score (0-100):',
367
+ default: config.minScore,
368
+ validate: n => n >= 0 && n <= 100 || 'Must be 0-100'
369
+ }
370
+ ]);
356
371
  config.minScore = minScore;
357
372
  await saveConfig(config, options.global);
358
373
  console.log(chalk.green(`\n✅ Minimum score set to: ${minScore}\n`));
359
374
  break;
360
375
 
361
376
  case 'mcpPort':
362
- const { mcpPort } = await inquirer.prompt([{
363
- type: 'number',
364
- name: 'mcpPort',
365
- message: 'MCP server port:',
366
- default: config.mcpPort,
367
- validate: n => n > 0 && n < 65536 || 'Invalid port'
368
- }]);
377
+ const { mcpPort } = await inquirer.prompt([
378
+ {
379
+ type: 'number',
380
+ name: 'mcpPort',
381
+ message: 'MCP server port:',
382
+ default: config.mcpPort,
383
+ validate: n => n > 0 && n < 65536 || 'Invalid port'
384
+ }
385
+ ]);
369
386
  config.mcpPort = mcpPort;
370
387
  await saveConfig(config, options.global);
371
388
  console.log(chalk.green(`\n✅ MCP port set to: ${mcpPort}\n`));
@@ -378,15 +395,17 @@ export function registerConfigCommand(program) {
378
395
  break;
379
396
 
380
397
  case 'init':
381
- const { scope } = await inquirer.prompt([{
382
- type: 'list',
383
- name: 'scope',
384
- message: 'Create config in:',
385
- choices: [
386
- { name: 'This project (.ultra-dex.json)', value: 'project' },
387
- { name: 'Global (~/.ultra-dex.json)', value: 'global' },
388
- ]
389
- }]);
398
+ const { scope } = await inquirer.prompt([
399
+ {
400
+ type: 'list',
401
+ name: 'scope',
402
+ message: 'Create config in:',
403
+ choices: [
404
+ { name: 'This project (.ultra-dex.json)', value: 'project' },
405
+ { name: 'Global (~/.ultra-dex.json)', value: 'global' },
406
+ ]
407
+ }
408
+ ]);
390
409
  const configPath = await saveConfig(DEFAULT_CONFIG, scope === 'global');
391
410
  console.log(chalk.green(`\n✅ Config created: ${configPath}\n`));
392
411
  break;
@@ -394,4 +413,4 @@ export function registerConfigCommand(program) {
394
413
  });
395
414
  }
396
415
 
397
- export default { registerDoctorCommand, registerConfigCommand };
416
+ export default { registerDoctorCommand, registerConfigCommand };
@@ -13,11 +13,12 @@ import { SYSTEM_PROMPT, generateUserPrompt } from '../templates/prompts/generate
13
13
  import { validateSafePath } from '../utils/validation.js';
14
14
  import { githubTreeUrl, githubWebUrl } from '../config/urls.js';
15
15
  import { saveState } from './plan.js';
16
+ import { getRandomMessage } from '../utils/messages.js';
16
17
 
17
18
  export function registerGenerateCommand(program) {
18
19
  program
19
20
  .command('generate [idea]')
20
- .description('Generate a full implementation plan from an idea using AI')
21
+ .description('Create the plan (Thanos style) - AI Generates Full Plan')
21
22
  .option('-p, --provider <provider>', 'AI provider (claude, openai, gemini)')
22
23
  .option('-m, --model <model>', 'Specific model to use')
23
24
  .option('-o, --output <directory>', 'Output directory', '.')
@@ -25,7 +26,9 @@ export function registerGenerateCommand(program) {
25
26
  .option('--stream', 'Stream output in real-time', true)
26
27
  .option('--no-stream', 'Disable streaming')
27
28
  .action(async (idea, options) => {
28
- console.log(chalk.cyan('\n🚀 Ultra-Dex Plan Generator\n'));
29
+ console.log(chalk.cyan('\n🚀 Ultra-Dex Plan Generator (Reality Stone Mode)\n'));
30
+ console.log(chalk.hex('#7c3aed').italic(`"${getRandomMessage('start')}"`));
31
+ console.log('');
29
32
 
30
33
  const dirValidation = validateSafePath(options.output, 'Output directory');
31
34
  if (dirValidation !== true) {
@@ -38,7 +41,7 @@ export function registerGenerateCommand(program) {
38
41
  const hasProvider = configured.some(p => p.configured) || options.key;
39
42
 
40
43
  if (!hasProvider) {
41
- console.log(chalk.yellow('⚠️ No AI provider configured.\n'));
44
+ console.log(chalk.yellow('⚠️ No Infinity Stones (AI Keys) configured.\n'));
42
45
  console.log(chalk.white('Set one of these environment variables:'));
43
46
  configured.forEach(p => {
44
47
  console.log(chalk.gray(` export ${p.envKey}=your-key-here`));
@@ -54,7 +57,7 @@ export function registerGenerateCommand(program) {
54
57
  {
55
58
  type: 'input',
56
59
  name: 'idea',
57
- message: 'Describe your SaaS idea:',
60
+ message: 'Describe the reality you wish to create:',
58
61
  validate: input => input.trim().length > 10 || 'Please provide a more detailed description',
59
62
  },
60
63
  ]);
@@ -85,7 +88,7 @@ export function registerGenerateCommand(program) {
85
88
  }
86
89
 
87
90
  // Generate the plan
88
- const spinner = ora('Generating your implementation plan...').start();
91
+ const spinner = ora('Reshaping reality (Generating Plan)...').start();
89
92
  const startTime = Date.now();
90
93
 
91
94
  try {
@@ -94,7 +97,7 @@ export function registerGenerateCommand(program) {
94
97
 
95
98
  if (options.stream) {
96
99
  spinner.stop();
97
- console.log(chalk.cyan('📝 Generating plan:\n'));
100
+ console.log(chalk.cyan('📝 Manifesting Reality:\n'));
98
101
  console.log(chalk.gray('─'.repeat(60)));
99
102
 
100
103
  result = await provider.generateStream(
@@ -128,7 +131,7 @@ export function registerGenerateCommand(program) {
128
131
  // Add header to plan
129
132
  const header = `# Implementation Plan
130
133
 
131
- > Generated by Ultra-Dex AI Plan Generator
134
+ > Generated by Ultra-Dex AI Plan Generator (Doomsday Edition)
132
135
 
133
136
  `;
134
137
  if (!planContent.startsWith('#')) {
@@ -208,17 +211,17 @@ ${idea}
208
211
  2. Start with the first feature
209
212
  3. Use Ultra-Dex agents for guidance
210
213
 
211
- ## AI Agents
212
- - @Planner: Break down tasks
213
- - @CTO: Architecture decisions
214
- - @Backend: API logic
215
- - @Frontend: UI components
216
- - @Testing: QA and tests
214
+ ## AI Agents (The Avengers)
215
+ - @Planner (Nick Fury): Break down tasks
216
+ - @CTO (Iron Man): Architecture decisions
217
+ - @Backend (Thor): API logic
218
+ - @Frontend (Spider-Man): UI components
219
+ - @Testing (Ant-Man): QA and tests
217
220
  `;
218
221
 
219
222
  await fs.writeFile(quickStartPath, quickStartContent);
220
223
 
221
- spinner.succeed('Plan generated successfully!');
224
+ spinner.succeed(chalk.green('Reality successfully rewritten!'));
222
225
 
223
226
  console.log(chalk.green('\n✅ Files created:'));
224
227
  console.log(chalk.gray(` ${planPath}`));
@@ -232,9 +235,9 @@ ${idea}
232
235
  console.log(chalk.cyan(' 1. Review IMPLEMENTATION-PLAN.md'));
233
236
  console.log(chalk.cyan(' 2. Run `ultra-dex dashboard` to visualize your progress'));
234
237
  console.log(chalk.cyan(' 3. Run `ultra-dex build` to let Auto-Pilot take the first task'));
235
- console.log(chalk.cyan(' 4. Use AI agents for specialized guidance\n'));
238
+ console.log(chalk.cyan(' 4. Summon Avengers (AI agents) for guidance\n'));
236
239
  } catch (err) {
237
- spinner.fail('Failed to generate plan');
240
+ spinner.fail(chalk.red('Failed to manifest reality'));
238
241
  console.error(chalk.red('Error:'), err.message);
239
242
  }
240
243
  });