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.
- package/README.md +79 -74
- package/assets/code-patterns/clerk-middleware.ts +138 -0
- package/assets/code-patterns/prisma-schema.prisma +224 -0
- package/assets/code-patterns/rls-policies.sql +246 -0
- package/assets/code-patterns/server-actions.ts +191 -0
- package/assets/code-patterns/trpc-router.ts +258 -0
- package/assets/cursor-rules/13-ai-integration.mdc +155 -0
- package/assets/cursor-rules/14-server-components.mdc +81 -0
- package/assets/cursor-rules/15-server-actions.mdc +102 -0
- package/assets/cursor-rules/16-edge-middleware.mdc +105 -0
- package/assets/cursor-rules/17-streaming-ssr.mdc +138 -0
- package/bin/ultra-dex.js +38 -1
- package/lib/commands/agents.js +16 -13
- package/lib/commands/banner.js +43 -21
- package/lib/commands/build.js +26 -17
- package/lib/commands/doctor.js +98 -79
- package/lib/commands/generate.js +19 -16
- package/lib/commands/init.js +52 -56
- package/lib/commands/scaffold.js +151 -0
- package/lib/commands/serve.js +15 -13
- package/lib/commands/state.js +43 -70
- package/lib/commands/swarm.js +31 -9
- package/lib/config/theme.js +47 -0
- package/lib/templates/code/clerk-middleware.ts +138 -0
- package/lib/templates/code/prisma-schema.prisma +224 -0
- package/lib/templates/code/rls-policies.sql +246 -0
- package/lib/templates/code/server-actions.ts +191 -0
- package/lib/templates/code/trpc-router.ts +258 -0
- package/lib/themes/doomsday.js +229 -0
- package/lib/ui/index.js +5 -0
- package/lib/ui/interface.js +241 -0
- package/lib/ui/spinners.js +116 -0
- package/lib/ui/theme.js +183 -0
- package/lib/utils/agents.js +32 -0
- package/lib/utils/help.js +64 -0
- package/lib/utils/messages.js +35 -0
- package/lib/utils/progress.js +24 -0
- package/lib/utils/prompts.js +47 -0
- package/lib/utils/spinners.js +46 -0
- package/lib/utils/status.js +31 -0
- package/lib/utils/tables.js +41 -0
- package/lib/utils/theme-state.js +9 -0
- package/lib/utils/version-display.js +32 -0
- package/package.json +10 -1
package/lib/commands/banner.js
CHANGED
|
@@ -1,21 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
+
}
|
package/lib/commands/build.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ultra-dex build command
|
|
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
|
|
31
|
-
|
|
32
|
+
console.log(chalk.cyan('\n⚡ Ultra-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
|
|
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!
|
|
64
|
+
console.log(chalk.green('✅ All phases completed! The project is ready.'));
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
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(`
|
|
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
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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 };
|
package/lib/commands/doctor.js
CHANGED
|
@@ -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('
|
|
59
|
+
.description('System Diagnostics - Check System Health')
|
|
59
60
|
.option('--fix', 'Attempt to fix issues automatically')
|
|
60
61
|
.action(async (options) => {
|
|
61
|
-
|
|
62
|
-
console.log(chalk.gray('
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(`
|
|
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
|
|
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 =
|
|
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(`
|
|
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(`
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
166
|
+
const configSpinner = createSpinner('Reading Configuration...');
|
|
167
|
+
configSpinner.start();
|
|
161
168
|
const config = await loadConfig();
|
|
162
|
-
configSpinner.succeed(`
|
|
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 =
|
|
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}
|
|
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(`
|
|
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
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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❌
|
|
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⚠️
|
|
217
|
+
console.log(chalk.yellow('\n⚠️ System operational but has warnings.\n'));
|
|
209
218
|
} else {
|
|
210
|
-
console.log(chalk.green('\n✅ All
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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 };
|
package/lib/commands/generate.js
CHANGED
|
@@ -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('
|
|
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
|
|
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
|
|
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('
|
|
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('📝
|
|
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('
|
|
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.
|
|
238
|
+
console.log(chalk.cyan(' 4. Summon Avengers (AI agents) for guidance\n'));
|
|
236
239
|
} catch (err) {
|
|
237
|
-
spinner.fail('Failed to
|
|
240
|
+
spinner.fail(chalk.red('Failed to manifest reality'));
|
|
238
241
|
console.error(chalk.red('Error:'), err.message);
|
|
239
242
|
}
|
|
240
243
|
});
|