ultra-dex 1.7.3 → 2.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 (119) hide show
  1. package/README.md +160 -127
  2. package/assets/agents/0-orchestration/orchestrator.md +225 -0
  3. package/assets/agents/00-AGENT_INDEX.md +138 -0
  4. package/assets/agents/1-leadership/cto.md +186 -0
  5. package/assets/agents/1-leadership/planner.md +205 -0
  6. package/assets/agents/1-leadership/research.md +285 -0
  7. package/assets/agents/2-development/backend.md +472 -0
  8. package/assets/agents/2-development/database.md +516 -0
  9. package/assets/agents/2-development/frontend.md +144 -0
  10. package/assets/agents/3-security/auth.md +168 -0
  11. package/assets/agents/3-security/security.md +335 -0
  12. package/assets/agents/4-devops/devops.md +587 -0
  13. package/assets/agents/5-quality/debugger.md +188 -0
  14. package/assets/agents/5-quality/documentation.md +167 -0
  15. package/assets/agents/5-quality/reviewer.md +213 -0
  16. package/assets/agents/5-quality/testing.md +280 -0
  17. package/assets/agents/6-specialist/performance.md +323 -0
  18. package/assets/agents/6-specialist/refactoring.md +343 -0
  19. package/assets/agents/AGENT-INSTRUCTIONS.md +315 -0
  20. package/assets/agents/README.md +232 -0
  21. package/assets/cursor-rules/00-ultra-dex-core.mdc +48 -0
  22. package/assets/cursor-rules/01-database.mdc +50 -0
  23. package/assets/cursor-rules/02-api.mdc +81 -0
  24. package/assets/cursor-rules/03-auth.mdc +70 -0
  25. package/assets/cursor-rules/04-frontend.mdc +92 -0
  26. package/assets/cursor-rules/05-payments.mdc +88 -0
  27. package/assets/cursor-rules/06-testing.mdc +104 -0
  28. package/assets/cursor-rules/07-security.mdc +94 -0
  29. package/assets/cursor-rules/08-deployment.mdc +92 -0
  30. package/assets/cursor-rules/09-error-handling.mdc +137 -0
  31. package/assets/cursor-rules/10-performance.mdc +123 -0
  32. package/assets/cursor-rules/11-nextjs-v15.mdc +307 -0
  33. package/assets/cursor-rules/12-multi-tenancy.mdc +282 -0
  34. package/assets/cursor-rules/README.md +78 -0
  35. package/assets/cursor-rules/load.ps1 +108 -0
  36. package/assets/cursor-rules/load.sh +102 -0
  37. package/assets/docs/BUILD-AUTH-30M.md +113 -0
  38. package/assets/docs/CHECKLIST-21-STEP.md +86 -0
  39. package/assets/docs/CODEMAP.md +229 -0
  40. package/assets/docs/CUSTOMIZATION.md +127 -0
  41. package/assets/docs/LAUNCH-POSTS.md +238 -0
  42. package/assets/docs/QUICK-REFERENCE.md +338 -0
  43. package/assets/docs/README.md +21 -0
  44. package/assets/docs/ROADMAP.md +480 -0
  45. package/assets/docs/TROUBLESHOOTING.md +148 -0
  46. package/assets/docs/TUTORIAL.md +182 -0
  47. package/assets/docs/VERIFICATION.md +108 -0
  48. package/assets/docs/VISION-V2.md +187 -0
  49. package/assets/docs/WORKFLOW-DIAGRAMS.md +463 -0
  50. package/assets/docs/index.html +550 -0
  51. package/assets/live-templates/next15-prisma-clerk/.env.example +3 -0
  52. package/assets/live-templates/next15-prisma-clerk/README.md +10 -0
  53. package/assets/live-templates/next15-prisma-clerk/app/layout.tsx +7 -0
  54. package/assets/live-templates/next15-prisma-clerk/app/page.tsx +8 -0
  55. package/assets/live-templates/next15-prisma-clerk/next.config.js +6 -0
  56. package/assets/live-templates/next15-prisma-clerk/package.json +22 -0
  57. package/assets/live-templates/next15-prisma-clerk/prisma/schema.prisma +34 -0
  58. package/assets/live-templates/remix-supabase/.env.example +2 -0
  59. package/assets/live-templates/remix-supabase/README.md +9 -0
  60. package/assets/live-templates/remix-supabase/app/root.tsx +19 -0
  61. package/assets/live-templates/remix-supabase/app/routes/_index.tsx +8 -0
  62. package/assets/live-templates/remix-supabase/app/utils/supabase.server.ts +6 -0
  63. package/assets/live-templates/remix-supabase/package.json +20 -0
  64. package/assets/live-templates/remix-supabase/remix.config.js +6 -0
  65. package/assets/live-templates/sveltekit-drizzle/.env.example +1 -0
  66. package/assets/live-templates/sveltekit-drizzle/README.md +9 -0
  67. package/assets/live-templates/sveltekit-drizzle/drizzle/schema.ts +7 -0
  68. package/assets/live-templates/sveltekit-drizzle/drizzle.config.ts +5 -0
  69. package/assets/live-templates/sveltekit-drizzle/package.json +21 -0
  70. package/assets/live-templates/sveltekit-drizzle/src/lib/db.ts +5 -0
  71. package/assets/live-templates/sveltekit-drizzle/src/routes/+page.svelte +2 -0
  72. package/assets/live-templates/sveltekit-drizzle/svelte.config.js +5 -0
  73. package/assets/live-templates/sveltekit-drizzle/vite.config.js +5 -0
  74. package/assets/saas-plan/04-Imp-Template.md +5546 -0
  75. package/assets/templates/CASE-STUDY-TEMPLATE.md +139 -0
  76. package/assets/templates/MASTER-PLAN-TEMPLATE.md +647 -0
  77. package/assets/templates/ORDER-TRACKER-TEMPLATE.md +731 -0
  78. package/assets/templates/PHASE-TRACKER-TEMPLATE.md +577 -0
  79. package/assets/templates/README.md +419 -0
  80. package/bin/ultra-dex.js +1078 -422
  81. package/lib/commands/agents.js +154 -0
  82. package/lib/commands/audit.js +135 -0
  83. package/lib/commands/banner.js +21 -0
  84. package/lib/commands/build.js +214 -0
  85. package/lib/commands/examples.js +34 -0
  86. package/lib/commands/fetch.js +186 -0
  87. package/lib/commands/generate.js +217 -0
  88. package/lib/commands/hooks.js +105 -0
  89. package/lib/commands/init.js +337 -0
  90. package/lib/commands/placeholders.js +11 -0
  91. package/lib/commands/review.js +287 -0
  92. package/lib/commands/serve.js +56 -0
  93. package/lib/commands/suggest.js +126 -0
  94. package/lib/commands/validate.js +140 -0
  95. package/lib/commands/workflows.js +185 -0
  96. package/lib/config/paths.js +9 -0
  97. package/lib/config/urls.js +16 -0
  98. package/lib/providers/base.js +82 -0
  99. package/lib/providers/claude.js +177 -0
  100. package/lib/providers/gemini.js +170 -0
  101. package/lib/providers/index.js +93 -0
  102. package/lib/providers/openai.js +163 -0
  103. package/lib/templates/context.js +26 -0
  104. package/lib/templates/embedded.js +141 -0
  105. package/lib/templates/prompts/generate-plan.js +147 -0
  106. package/lib/templates/prompts/review-code.js +57 -0
  107. package/lib/templates/prompts/section-prompts.js +275 -0
  108. package/lib/templates/prompts/system-prompt.md +58 -0
  109. package/lib/templates/quick-start.js +43 -0
  110. package/lib/utils/build-helpers.js +257 -0
  111. package/lib/utils/fallback.js +36 -0
  112. package/lib/utils/files.js +67 -0
  113. package/lib/utils/network.js +18 -0
  114. package/lib/utils/output.js +20 -0
  115. package/lib/utils/parser.js +155 -0
  116. package/lib/utils/prompt-builder.js +93 -0
  117. package/lib/utils/review-helpers.js +334 -0
  118. package/lib/utils/validation.js +34 -0
  119. package/package.json +19 -5
@@ -0,0 +1,154 @@
1
+ import chalk from 'chalk';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { ASSETS_ROOT, ROOT_FALLBACK } from '../config/paths.js';
5
+ import { githubBlobUrl } from '../config/urls.js';
6
+
7
+ export const AGENTS = [
8
+ { name: 'cto', description: 'Architecture & tech decisions', file: '1-leadership/cto.md', tier: 'Leadership' },
9
+ { name: 'planner', description: 'Task breakdown & planning', file: '1-leadership/planner.md', tier: 'Leadership' },
10
+ { name: 'research', description: 'Technology evaluation & comparison', file: '1-leadership/research.md', tier: 'Leadership' },
11
+ { name: 'backend', description: 'API & server logic', file: '2-development/backend.md', tier: 'Development' },
12
+ { name: 'database', description: 'Schema design & queries', file: '2-development/database.md', tier: 'Development' },
13
+ { name: 'frontend', description: 'UI & components', file: '2-development/frontend.md', tier: 'Development' },
14
+ { name: 'auth', description: 'Authentication & authorization', file: '3-security/auth.md', tier: 'Security' },
15
+ { name: 'security', description: 'Security audits & vulnerability fixes', file: '3-security/security.md', tier: 'Security' },
16
+ { name: 'devops', description: 'Deployment & infrastructure', file: '4-devops/devops.md', tier: 'DevOps' },
17
+ { name: 'debugger', description: 'Bug fixing & troubleshooting', file: '5-quality/debugger.md', tier: 'Quality' },
18
+ { name: 'documentation', description: 'Technical writing & docs maintenance', file: '5-quality/documentation.md', tier: 'Quality' },
19
+ { name: 'reviewer', description: 'Code review & quality check', file: '5-quality/reviewer.md', tier: 'Quality' },
20
+ { name: 'testing', description: 'QA & test automation', file: '5-quality/testing.md', tier: 'Quality' },
21
+ { name: 'performance', description: 'Performance optimization', file: '6-specialist/performance.md', tier: 'Specialist' },
22
+ { name: 'refactoring', description: 'Code quality & design patterns', file: '6-specialist/refactoring.md', tier: 'Specialist' },
23
+ ];
24
+
25
+ async function readAgentPrompt(agent) {
26
+ const agentPath = path.join(ASSETS_ROOT, 'agents', agent.file);
27
+ try {
28
+ return await fs.readFile(agentPath, 'utf-8');
29
+ } catch (err) {
30
+ const fallbackPath = path.join(ROOT_FALLBACK, 'agents', agent.file);
31
+ return await fs.readFile(fallbackPath, 'utf-8');
32
+ }
33
+ }
34
+
35
+ export function registerAgentsCommand(program) {
36
+ program
37
+ .command('agents')
38
+ .description('List available AI agent prompts')
39
+ .action(() => {
40
+ console.log(chalk.bold('\nšŸ¤– Ultra-Dex AI Agents (15 Total)\n'));
41
+ console.log(chalk.gray('Organized by tier for production pipeline\n'));
42
+
43
+ let currentTier = '';
44
+ AGENTS.forEach((agent) => {
45
+ if (agent.tier !== currentTier) {
46
+ currentTier = agent.tier;
47
+ console.log(chalk.bold(`\n ${currentTier} Tier:`));
48
+ }
49
+ console.log(chalk.cyan(` ${agent.name}`) + chalk.gray(` - ${agent.description}`));
50
+ });
51
+
52
+ console.log('\n' + chalk.bold('Usage:'));
53
+ console.log(chalk.gray(' ultra-dex agent <name> Show agent prompt'));
54
+ console.log(chalk.gray(' ultra-dex agent backend Example: show backend agent'));
55
+
56
+ console.log(`\n${chalk.gray(`Agent Index: ${githubBlobUrl('agents/00-AGENT_INDEX.md')}\n`)}`);
57
+ });
58
+
59
+ program
60
+ .command('agent <name>')
61
+ .description('Show a specific agent prompt')
62
+ .action(async (name) => {
63
+ const agent = AGENTS.find(a => a.name.toLowerCase() === name.toLowerCase());
64
+
65
+ if (!agent) {
66
+ console.log(chalk.red(`\nāŒ Agent "${name}" not found.\n`));
67
+ console.log(chalk.gray('Available agents:'));
68
+ AGENTS.forEach(a => console.log(chalk.cyan(` - ${a.name}`)));
69
+ console.log('\n' + chalk.gray('Run "ultra-dex agents" to see all agents.\n'));
70
+ process.exit(1);
71
+ }
72
+
73
+ try {
74
+ const content = await readAgentPrompt(agent);
75
+ console.log(chalk.bold(`\nšŸ¤– ${agent.name.toUpperCase()} Agent\n`));
76
+ console.log(chalk.gray('─'.repeat(60)));
77
+ console.log(content);
78
+ console.log(chalk.gray('─'.repeat(60)));
79
+ console.log(chalk.bold('\nšŸ“‹ Copy the above prompt and paste into your AI tool.\n'));
80
+ } catch (err) {
81
+ console.log(chalk.bold(`\nšŸ¤– ${agent.name.toUpperCase()} Agent\n`));
82
+ console.log(chalk.gray('View full prompt on GitHub:'));
83
+ console.log(chalk.blue(` ${githubBlobUrl(`agents/${agent.file}`)}\n`));
84
+ }
85
+ });
86
+ }
87
+
88
+ export function registerPackCommand(program) {
89
+ program
90
+ .command('pack <agent>')
91
+ .description('Package project context + agent prompt for any AI tool')
92
+ .option('-c, --clipboard', 'Copy to clipboard (requires pbcopy/xclip)')
93
+ .action(async (agentName, options) => {
94
+ const agent = AGENTS.find(a => a.name.toLowerCase() === agentName.toLowerCase());
95
+ if (!agent) {
96
+ console.log(chalk.red(`\nāŒ Agent "${agentName}" not found.\n`));
97
+ console.log(chalk.gray('Available agents:'));
98
+ AGENTS.forEach(a => console.log(chalk.cyan(` - ${a.name}`)));
99
+ process.exit(1);
100
+ }
101
+
102
+ let output = '';
103
+
104
+ try {
105
+ const agentPrompt = await readAgentPrompt(agent);
106
+ output += agentPrompt + '\n\n';
107
+ } catch (err) {
108
+ output += `# ${agent.name.toUpperCase()} Agent\n\nSee: ${githubBlobUrl(`agents/${agent.file}`)}\n\n`;
109
+ }
110
+
111
+ output += '---\n\n';
112
+
113
+ try {
114
+ const context = await fs.readFile('CONTEXT.md', 'utf-8');
115
+ output += '# PROJECT CONTEXT\n\n' + context + '\n\n';
116
+ } catch (err) {
117
+ output += '# PROJECT CONTEXT\n\n*No CONTEXT.md found. Run `ultra-dex init` first.*\n\n';
118
+ }
119
+
120
+ output += '---\n\n';
121
+
122
+ try {
123
+ const plan = await fs.readFile('IMPLEMENTATION-PLAN.md', 'utf-8');
124
+ output += '# IMPLEMENTATION PLAN\n\n' + plan + '\n';
125
+ } catch (err) {
126
+ output += '# IMPLEMENTATION PLAN\n\n*No IMPLEMENTATION-PLAN.md found. Run `ultra-dex init` first.*\n';
127
+ }
128
+
129
+ console.log(chalk.bold(`\nšŸ“¦ Packed context for @${agent.name}\n`));
130
+ console.log(chalk.gray('─'.repeat(60)));
131
+ console.log(output);
132
+ console.log(chalk.gray('─'.repeat(60)));
133
+
134
+ if (options.clipboard) {
135
+ try {
136
+ const { execSync } = await import('child_process');
137
+ const platform = process.platform;
138
+ if (platform === 'darwin') {
139
+ execSync('pbcopy', { input: output });
140
+ console.log(chalk.green('\nāœ… Copied to clipboard!\n'));
141
+ } else if (platform === 'linux') {
142
+ execSync('xclip -selection clipboard', { input: output });
143
+ console.log(chalk.green('\nāœ… Copied to clipboard!\n'));
144
+ } else {
145
+ console.log(chalk.yellow('\nāš ļø Clipboard not supported on this platform. Copy manually.\n'));
146
+ }
147
+ } catch (err) {
148
+ console.log(chalk.yellow('\nāš ļø Could not copy to clipboard. Copy manually.\n'));
149
+ }
150
+ } else {
151
+ console.log(chalk.cyan('\nšŸ’” Tip: Use --clipboard flag to copy directly\n'));
152
+ }
153
+ });
154
+ }
@@ -0,0 +1,135 @@
1
+ import chalk from 'chalk';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ import { validateSafePath } from '../utils/validation.js';
5
+ import { githubWebUrl } from '../config/urls.js';
6
+
7
+ export function registerAuditCommand(program) {
8
+ program
9
+ .command('audit')
10
+ .description('Audit your Ultra-Dex project for completeness')
11
+ .option('-d, --dir <directory>', 'Project directory to audit', '.')
12
+ .action(async (options) => {
13
+ console.log(chalk.cyan('\nšŸ” Ultra-Dex Project Audit\n'));
14
+
15
+ const dirValidation = validateSafePath(options.dir, 'Project directory');
16
+ if (dirValidation !== true) {
17
+ console.log(chalk.red(dirValidation));
18
+ process.exit(1);
19
+ }
20
+
21
+ const projectDir = path.resolve(options.dir);
22
+ let score = 0;
23
+ let maxScore = 0;
24
+ const results = [];
25
+
26
+ async function checkFile(filePath, description, points) {
27
+ maxScore += points;
28
+ try {
29
+ const content = await fs.readFile(path.join(projectDir, filePath), 'utf-8');
30
+ if (content.length > 50) {
31
+ score += points;
32
+ results.push({ status: 'āœ…', item: description, points: `+${points}` });
33
+ return content;
34
+ } else {
35
+ results.push({ status: 'āš ļø', item: `${description} (empty/too short)`, points: '0' });
36
+ return null;
37
+ }
38
+ } catch {
39
+ results.push({ status: 'āŒ', item: `${description} (missing)`, points: '0' });
40
+ return null;
41
+ }
42
+ }
43
+
44
+ function hasSection(content, sectionName, points) {
45
+ maxScore += points;
46
+ if (content && content.toLowerCase().includes(sectionName.toLowerCase())) {
47
+ score += points;
48
+ results.push({ status: 'āœ…', item: `Has ${sectionName}`, points: `+${points}` });
49
+ return true;
50
+ } else {
51
+ results.push({ status: 'āŒ', item: `Missing ${sectionName}`, points: '0' });
52
+ return false;
53
+ }
54
+ }
55
+
56
+ console.log(chalk.bold('Checking project files...\n'));
57
+
58
+ const quickStart = await checkFile('QUICK-START.md', 'QUICK-START.md', 10);
59
+ await checkFile('CONTEXT.md', 'CONTEXT.md', 5);
60
+ const implPlan = await checkFile('IMPLEMENTATION-PLAN.md', 'IMPLEMENTATION-PLAN.md', 5);
61
+ await checkFile('04-Imp-Template.md', '04-Imp-Template.md', 10);
62
+ await checkFile('README.md', 'README.md', 5);
63
+
64
+ if (quickStart) {
65
+ hasSection(quickStart, 'idea', 5);
66
+ hasSection(quickStart, 'problem', 5);
67
+ hasSection(quickStart, 'mvp', 5);
68
+ hasSection(quickStart, 'tech stack', 10);
69
+ hasSection(quickStart, 'feature', 5);
70
+ }
71
+
72
+ if (implPlan) {
73
+ hasSection(implPlan, 'database', 5);
74
+ hasSection(implPlan, 'api', 5);
75
+ hasSection(implPlan, 'auth', 5);
76
+ }
77
+
78
+ try {
79
+ await fs.access(path.join(projectDir, 'docs'));
80
+ score += 5;
81
+ maxScore += 5;
82
+ results.push({ status: 'āœ…', item: 'docs/ folder exists', points: '+5' });
83
+ } catch {
84
+ maxScore += 5;
85
+ results.push({ status: 'āš ļø', item: 'docs/ folder (optional)', points: '0' });
86
+ }
87
+
88
+ console.log(chalk.bold('Audit Results:\n'));
89
+ results.forEach(r => {
90
+ const statusColor = r.status === 'āœ…' ? chalk.green : r.status === 'āŒ' ? chalk.red : chalk.yellow;
91
+ console.log(` ${statusColor(r.status)} ${r.item} ${chalk.gray(r.points)}`);
92
+ });
93
+
94
+ const percentage = Math.round((score / maxScore) * 100);
95
+
96
+ console.log('\n' + chalk.bold('─'.repeat(50)));
97
+ console.log(chalk.bold(`\nScore: ${score}/${maxScore} (${percentage}%)\n`));
98
+
99
+ let grade, gradeColor, message;
100
+ if (percentage >= 90) {
101
+ grade = 'A';
102
+ gradeColor = chalk.green;
103
+ message = 'Excellent! Your project is well-documented.';
104
+ } else if (percentage >= 75) {
105
+ grade = 'B';
106
+ gradeColor = chalk.green;
107
+ message = 'Good! A few more sections would help.';
108
+ } else if (percentage >= 60) {
109
+ grade = 'C';
110
+ gradeColor = chalk.yellow;
111
+ message = 'Fair. Consider filling more sections before coding.';
112
+ } else if (percentage >= 40) {
113
+ grade = 'D';
114
+ gradeColor = chalk.yellow;
115
+ message = 'Needs work. Use QUICK-START.md to define your project.';
116
+ } else {
117
+ grade = 'F';
118
+ gradeColor = chalk.red;
119
+ message = 'Run "npx ultra-dex init" to get started properly.';
120
+ }
121
+
122
+ console.log(gradeColor(`Grade: ${grade}`));
123
+ console.log(chalk.gray(message));
124
+
125
+ const missing = results.filter(r => r.status === 'āŒ');
126
+ if (missing.length > 0) {
127
+ console.log(chalk.bold('\nšŸ“‹ To improve your score:\n'));
128
+ missing.slice(0, 5).forEach(m => {
129
+ console.log(chalk.cyan(` → Add ${m.item.replace(' (missing)', '')}`));
130
+ });
131
+ }
132
+
133
+ console.log(`\n${chalk.gray(`Learn more: ${githubWebUrl()}`)}\n`);
134
+ });
135
+ }
@@ -0,0 +1,21 @@
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
+ `;
@@ -0,0 +1,214 @@
1
+ /**
2
+ * ultra-dex build command
3
+ * Auto-loads context and starts AI-assisted development
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ import inquirer from 'inquirer';
9
+ import fs from 'fs/promises';
10
+ import path from 'path';
11
+ import { exec } from 'child_process';
12
+ import { promisify } from 'util';
13
+
14
+ const execAsync = promisify(exec);
15
+
16
+ // Agent configurations
17
+ const AGENTS = {
18
+ planner: { name: '@Planner', tier: 'Leadership', task: 'Break down features into atomic tasks' },
19
+ cto: { name: '@CTO', tier: 'Leadership', task: 'Architecture decisions' },
20
+ backend: { name: '@Backend', tier: 'Development', task: 'API endpoints and business logic' },
21
+ frontend: { name: '@Frontend', tier: 'Development', task: 'UI components and pages' },
22
+ database: { name: '@Database', tier: 'Development', task: 'Schema design and migrations' },
23
+ auth: { name: '@Auth', tier: 'Security', task: 'Authentication and authorization' },
24
+ security: { name: '@Security', tier: 'Security', task: 'Security audit' },
25
+ testing: { name: '@Testing', tier: 'Quality', task: 'Write and run tests' },
26
+ reviewer: { name: '@Reviewer', tier: 'Quality', task: 'Code review' },
27
+ devops: { name: '@DevOps', tier: 'DevOps', task: 'Deployment and CI/CD' },
28
+ };
29
+
30
+ async function readFileSafe(filePath) {
31
+ try {
32
+ return await fs.readFile(filePath, 'utf-8');
33
+ } catch {
34
+ return null;
35
+ }
36
+ }
37
+
38
+ async function fileExists(filePath) {
39
+ try {
40
+ await fs.access(filePath);
41
+ return true;
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ export function registerBuildCommand(program) {
48
+ program
49
+ .command('build')
50
+ .description('Start AI-assisted development with auto-loaded context')
51
+ .option('-a, --agent <agent>', 'Agent to use (planner, backend, frontend, etc.)')
52
+ .option('-t, --task <task>', 'Specific task to work on')
53
+ .option('--copy', 'Copy prompt to clipboard instead of displaying')
54
+ .option('--cursor', 'Open in Cursor IDE')
55
+ .action(async (options) => {
56
+ console.log(chalk.cyan('\nšŸ”§ Ultra-Dex Build Mode\n'));
57
+
58
+ // Check for required files
59
+ const hasContext = await fileExists('CONTEXT.md');
60
+ const hasPlan = await fileExists('IMPLEMENTATION-PLAN.md');
61
+ const hasQuickStart = await fileExists('QUICK-START.md');
62
+
63
+ if (!hasContext && !hasPlan) {
64
+ console.log(chalk.yellow('āš ļø No Ultra-Dex project found in current directory.\n'));
65
+ console.log(chalk.white('Run one of these first:'));
66
+ console.log(chalk.gray(' npx ultra-dex init # Create from template'));
67
+ console.log(chalk.gray(' npx ultra-dex generate # Generate from idea\n'));
68
+ return;
69
+ }
70
+
71
+ // Load context files
72
+ const spinner = ora('Loading project context...').start();
73
+
74
+ const context = await readFileSafe('CONTEXT.md');
75
+ const plan = await readFileSafe('IMPLEMENTATION-PLAN.md');
76
+ const quickStart = await readFileSafe('QUICK-START.md');
77
+
78
+ spinner.succeed('Context loaded');
79
+
80
+ // Select agent if not provided
81
+ let agent = options.agent;
82
+ if (!agent) {
83
+ const { selectedAgent } = await inquirer.prompt([
84
+ {
85
+ type: 'list',
86
+ name: 'selectedAgent',
87
+ message: 'Select an agent:',
88
+ choices: [
89
+ new inquirer.Separator('── Leadership ──'),
90
+ { name: 'šŸ“‹ @Planner - Break down tasks', value: 'planner' },
91
+ { name: 'šŸ—ļø @CTO - Architecture decisions', value: 'cto' },
92
+ new inquirer.Separator('── Development ──'),
93
+ { name: 'āš™ļø @Backend - API endpoints', value: 'backend' },
94
+ { name: 'šŸŽØ @Frontend - UI components', value: 'frontend' },
95
+ { name: 'šŸ—„ļø @Database - Schema design', value: 'database' },
96
+ new inquirer.Separator('── Security ──'),
97
+ { name: 'šŸ” @Auth - Authentication', value: 'auth' },
98
+ { name: 'šŸ›”ļø @Security - Security audit', value: 'security' },
99
+ new inquirer.Separator('── Quality ──'),
100
+ { name: '🧪 @Testing - Write tests', value: 'testing' },
101
+ { name: 'šŸ‘ļø @Reviewer - Code review', value: 'reviewer' },
102
+ new inquirer.Separator('── DevOps ──'),
103
+ { name: 'šŸš€ @DevOps - Deployment', value: 'devops' },
104
+ ],
105
+ },
106
+ ]);
107
+ agent = selectedAgent;
108
+ }
109
+
110
+ const agentConfig = AGENTS[agent];
111
+ if (!agentConfig) {
112
+ console.log(chalk.red(`Unknown agent: ${agent}`));
113
+ console.log(chalk.gray(`Available: ${Object.keys(AGENTS).join(', ')}`));
114
+ return;
115
+ }
116
+
117
+ // Get task if not provided
118
+ let task = options.task;
119
+ if (!task) {
120
+ const { taskInput } = await inquirer.prompt([
121
+ {
122
+ type: 'input',
123
+ name: 'taskInput',
124
+ message: `What should ${agentConfig.name} do?`,
125
+ default: agentConfig.task,
126
+ },
127
+ ]);
128
+ task = taskInput;
129
+ }
130
+
131
+ // Build the prompt
132
+ const contextSection = context ? `## Project Context\n${context}\n` : '';
133
+ const planSection = plan ? `## Implementation Plan (Summary)\n${plan.slice(0, 8000)}...\n[Full plan in IMPLEMENTATION-PLAN.md]\n` : '';
134
+
135
+ const prompt = `# ${agentConfig.name} Agent Session
136
+
137
+ You are acting as ${agentConfig.name} for this project.
138
+
139
+ ${contextSection}
140
+ ${planSection}
141
+
142
+ ## Your Task
143
+ ${task}
144
+
145
+ ## Instructions
146
+ 1. Read the context and plan carefully
147
+ 2. Focus ONLY on your assigned task
148
+ 3. Follow Ultra-Dex 21-step verification for any code changes
149
+ 4. Document your work in a way the next agent can continue
150
+
151
+ ## Output Format
152
+ - For code: Include full file paths and production-ready code
153
+ - For plans: Use atomic tasks (4-9 hours each)
154
+ - For reviews: Use severity levels (critical, warning, info)
155
+
156
+ Begin working on: ${task}
157
+ `;
158
+
159
+ // Output the prompt
160
+ console.log(chalk.green(`\nāœ… ${agentConfig.name} prompt ready\n`));
161
+
162
+ if (options.copy) {
163
+ // Copy to clipboard
164
+ try {
165
+ const platform = process.platform;
166
+ if (platform === 'darwin') {
167
+ await execAsync(`echo ${JSON.stringify(prompt)} | pbcopy`);
168
+ } else if (platform === 'linux') {
169
+ await execAsync(`echo ${JSON.stringify(prompt)} | xclip -selection clipboard`);
170
+ } else if (platform === 'win32') {
171
+ await execAsync(`echo ${JSON.stringify(prompt)} | clip`);
172
+ }
173
+ console.log(chalk.cyan('šŸ“‹ Prompt copied to clipboard!'));
174
+ console.log(chalk.gray('Paste into your AI tool (Cursor, Claude, ChatGPT)\n'));
175
+ } catch {
176
+ console.log(chalk.yellow('Could not copy to clipboard. Displaying prompt instead:\n'));
177
+ console.log(chalk.gray('─'.repeat(60)));
178
+ console.log(prompt);
179
+ console.log(chalk.gray('─'.repeat(60)));
180
+ }
181
+ } else if (options.cursor) {
182
+ // Save prompt and open Cursor
183
+ const promptPath = path.join('.ultra-dex', 'current-prompt.md');
184
+ await fs.mkdir('.ultra-dex', { recursive: true });
185
+ await fs.writeFile(promptPath, prompt);
186
+
187
+ console.log(chalk.gray(`Prompt saved to: ${promptPath}`));
188
+ console.log(chalk.cyan('Opening Cursor...\n'));
189
+
190
+ try {
191
+ await execAsync('cursor .');
192
+ } catch {
193
+ console.log(chalk.yellow('Could not open Cursor. Is it installed?'));
194
+ console.log(chalk.gray('Install: https://cursor.sh'));
195
+ }
196
+ } else {
197
+ // Display the prompt
198
+ console.log(chalk.gray('─'.repeat(60)));
199
+ console.log(prompt);
200
+ console.log(chalk.gray('─'.repeat(60)));
201
+
202
+ console.log(chalk.cyan('\nšŸ“‹ Copy this prompt into your AI tool'));
203
+ console.log(chalk.gray('Or use --copy to copy to clipboard\n'));
204
+ }
205
+
206
+ // Show next steps
207
+ console.log(chalk.white('Tips:'));
208
+ console.log(chalk.gray(' • Paste the prompt into Cursor, Claude, or ChatGPT'));
209
+ console.log(chalk.gray(' • Use "npx ultra-dex serve" for MCP-compatible context'));
210
+ console.log(chalk.gray(' • Run "npx ultra-dex review" after making changes\n'));
211
+ });
212
+ }
213
+
214
+ export default { registerBuildCommand };
@@ -0,0 +1,34 @@
1
+ import chalk from 'chalk';
2
+ import { githubBlobUrl } from '../config/urls.js';
3
+
4
+ export function registerExamplesCommand(program) {
5
+ program
6
+ .command('examples')
7
+ .description('List available examples')
8
+ .action(() => {
9
+ console.log(chalk.bold('\nAvailable Ultra-Dex Examples:\n'));
10
+
11
+ const examples = [
12
+ {
13
+ name: 'TaskFlow',
14
+ type: 'Task Management',
15
+ url: githubBlobUrl('@%20Ultra%20DeX/Saas%20plan/Examples/TaskFlow-Complete.md'),
16
+ },
17
+ {
18
+ name: 'InvoiceFlow',
19
+ type: 'Invoicing',
20
+ url: githubBlobUrl('@%20Ultra%20DeX/Saas%20plan/Examples/InvoiceFlow-Complete.md'),
21
+ },
22
+ {
23
+ name: 'HabitStack',
24
+ type: 'Habit Tracking',
25
+ url: githubBlobUrl('@%20Ultra%20DeX/Saas%20plan/Examples/HabitStack-Complete.md'),
26
+ },
27
+ ];
28
+
29
+ examples.forEach((ex, i) => {
30
+ console.log(chalk.cyan(`${i + 1}. ${ex.name}`) + chalk.gray(` (${ex.type})`));
31
+ console.log(chalk.gray(` ${ex.url}\n`));
32
+ });
33
+ });
34
+ }