ultra-dex 1.3.0 ā 1.7.2
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 +39 -0
- package/bin/ultra-dex.js +714 -41
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
> Scaffold Ultra-Dex projects from the command line.
|
|
4
4
|
|
|
5
|
+
## First 10 Minutes
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 1. Create your project (2 min)
|
|
9
|
+
npx ultra-dex init
|
|
10
|
+
|
|
11
|
+
# 2. Open and review QUICK-START.md (3 min)
|
|
12
|
+
cd your-project
|
|
13
|
+
cat QUICK-START.md
|
|
14
|
+
|
|
15
|
+
# 3. Load Cursor rules for AI assistance (1 min)
|
|
16
|
+
npx degit Srujan0798/Ultra-Dex/cursor-rules .cursor/rules
|
|
17
|
+
# Then: cd .cursor/rules && ./load.sh database api auth
|
|
18
|
+
|
|
19
|
+
# 4. Start building with AI agents (4 min)
|
|
20
|
+
# Use @Backend, @Frontend, @Database agents
|
|
21
|
+
npx ultra-dex agents
|
|
22
|
+
|
|
23
|
+
# You're ready to code!
|
|
24
|
+
```
|
|
25
|
+
|
|
5
26
|
## Installation
|
|
6
27
|
|
|
7
28
|
```bash
|
|
@@ -71,6 +92,19 @@ npx ultra-dex agent backend
|
|
|
71
92
|
|
|
72
93
|
Prints the full agent prompt. Copy and paste into your AI tool (Cursor, Claude, ChatGPT).
|
|
73
94
|
|
|
95
|
+
### Set up git hooks
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx ultra-dex hooks
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Installs a pre-commit hook that:
|
|
102
|
+
- Validates project structure before each commit
|
|
103
|
+
- Blocks commits if required files are missing
|
|
104
|
+
- Can be bypassed with `git commit --no-verify`
|
|
105
|
+
|
|
106
|
+
Remove with: `npx ultra-dex hooks --remove`
|
|
107
|
+
|
|
74
108
|
## Commands
|
|
75
109
|
|
|
76
110
|
| Command | Description |
|
|
@@ -80,6 +114,11 @@ Prints the full agent prompt. Copy and paste into your AI tool (Cursor, Claude,
|
|
|
80
114
|
| `ultra-dex examples` | List available examples |
|
|
81
115
|
| `ultra-dex agents` | List available AI agents |
|
|
82
116
|
| `ultra-dex agent <name>` | Show specific agent prompt |
|
|
117
|
+
| `ultra-dex pack <agent>` | Package context + agent for any AI |
|
|
118
|
+
| `ultra-dex hooks` | Set up git pre-commit hooks |
|
|
119
|
+
| `ultra-dex validate` | Validate project structure |
|
|
120
|
+
| `ultra-dex workflow <feature>` | Show workflow for a feature |
|
|
121
|
+
| `ultra-dex suggest` | Get AI agent suggestions |
|
|
83
122
|
| `ultra-dex --help` | Show help |
|
|
84
123
|
| `ultra-dex --version` | Show version |
|
|
85
124
|
|
package/bin/ultra-dex.js
CHANGED
|
@@ -109,7 +109,7 @@ Setting up the implementation plan.
|
|
|
109
109
|
program
|
|
110
110
|
.name('ultra-dex')
|
|
111
111
|
.description('CLI for Ultra-Dex SaaS Implementation Framework')
|
|
112
|
-
.version('1.
|
|
112
|
+
.version('1.7.1');
|
|
113
113
|
|
|
114
114
|
program
|
|
115
115
|
.command('init')
|
|
@@ -300,10 +300,21 @@ ${answers.ideaWhat} for ${answers.ideaFor}.
|
|
|
300
300
|
path.join(rulesDir, file)
|
|
301
301
|
);
|
|
302
302
|
}
|
|
303
|
+
// Also generate .github/copilot-instructions.md for Copilot users
|
|
304
|
+
const coreRulePath = path.join(cursorRulesPath, '00-ultra-dex-core.mdc');
|
|
305
|
+
try {
|
|
306
|
+
const coreContent = await fs.readFile(coreRulePath, 'utf-8');
|
|
307
|
+
const dotGithub = path.join(outputDir, '.github');
|
|
308
|
+
await fs.mkdir(dotGithub, { recursive: true });
|
|
309
|
+
await fs.writeFile(path.join(dotGithub, 'copilot-instructions.md'), coreContent);
|
|
310
|
+
} catch (e) {
|
|
311
|
+
// Core rule not available - skip Copilot setup
|
|
312
|
+
}
|
|
303
313
|
} catch (err) {
|
|
304
|
-
// Cursor rules not
|
|
305
|
-
console.log(chalk.
|
|
306
|
-
console.log(chalk.
|
|
314
|
+
// Cursor rules not bundled - intentional design choice for npm package size
|
|
315
|
+
console.log(chalk.gray('\n š¦ Cursor rules not bundled (keeps npm package <50KB)'));
|
|
316
|
+
console.log(chalk.cyan(' Quick setup: npx degit Srujan0798/Ultra-Dex/cursor-rules .cursor/rules'));
|
|
317
|
+
console.log(chalk.blue(' Or download: https://github.com/Srujan0798/Ultra-Dex/tree/main/cursor-rules'));
|
|
307
318
|
}
|
|
308
319
|
}
|
|
309
320
|
|
|
@@ -313,21 +324,25 @@ ${answers.ideaWhat} for ${answers.ideaFor}.
|
|
|
313
324
|
try {
|
|
314
325
|
await fs.copyFile(templatePath, path.join(outputDir, 'docs', 'MASTER-PLAN.md'));
|
|
315
326
|
} catch (err) {
|
|
316
|
-
|
|
317
|
-
console.log(chalk.
|
|
327
|
+
// Template not bundled - keeps npm package lightweight
|
|
328
|
+
console.log(chalk.gray('\n š¦ Full template not bundled (5,500 lines - too large for npm)'));
|
|
329
|
+
console.log(chalk.cyan(' Quick fetch: curl -O https://raw.githubusercontent.com/Srujan0798/Ultra-Dex/main/%40%20Ultra%20DeX/Saas%20plan/04-Imp-Template.md'));
|
|
330
|
+
console.log(chalk.blue(' Or view: https://github.com/Srujan0798/Ultra-Dex/blob/main/%40%20Ultra%20DeX/Saas%20plan/04-Imp-Template.md'));
|
|
318
331
|
}
|
|
319
332
|
}
|
|
320
333
|
|
|
321
334
|
// Copy docs if requested
|
|
322
335
|
if (answers.includeDocs) {
|
|
323
|
-
const verificationPath = path.resolve(__dirname, '../../VERIFICATION.md');
|
|
324
|
-
const agentPath = path.resolve(__dirname, '../../AGENT-INSTRUCTIONS.md');
|
|
336
|
+
const verificationPath = path.resolve(__dirname, '../../docs/VERIFICATION.md');
|
|
337
|
+
const agentPath = path.resolve(__dirname, '../../agents/AGENT-INSTRUCTIONS.md');
|
|
325
338
|
try {
|
|
326
339
|
await fs.copyFile(verificationPath, path.join(outputDir, 'docs', 'CHECKLIST.md'));
|
|
327
340
|
await fs.copyFile(agentPath, path.join(outputDir, 'docs', 'AI-PROMPTS.md'));
|
|
328
341
|
} catch (err) {
|
|
329
|
-
|
|
330
|
-
console.log(chalk.
|
|
342
|
+
// Docs not bundled - intentional for npm package size
|
|
343
|
+
console.log(chalk.gray('\n š¦ Verification & instructions not bundled (npm size optimization)'));
|
|
344
|
+
console.log(chalk.cyan(' Quick setup: npx degit Srujan0798/Ultra-Dex/docs docs'));
|
|
345
|
+
console.log(chalk.blue(' Or view: https://github.com/Srujan0798/Ultra-Dex/tree/main/docs'));
|
|
331
346
|
}
|
|
332
347
|
}
|
|
333
348
|
|
|
@@ -338,17 +353,36 @@ ${answers.ideaWhat} for ${answers.ideaFor}.
|
|
|
338
353
|
|
|
339
354
|
const agentsSourcePath = path.resolve(__dirname, '../../agents');
|
|
340
355
|
try {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
356
|
+
// Copy tier directories and agent files
|
|
357
|
+
const tiers = ['1-leadership', '2-development', '3-security', '4-devops', '5-quality', '6-specialist'];
|
|
358
|
+
for (const tier of tiers) {
|
|
359
|
+
const tierDir = path.join(agentsDir, tier);
|
|
360
|
+
await fs.mkdir(tierDir, { recursive: true });
|
|
361
|
+
|
|
362
|
+
const tierPath = path.join(agentsSourcePath, tier);
|
|
363
|
+
const tierFiles = await fs.readdir(tierPath);
|
|
364
|
+
for (const file of tierFiles.filter(f => f.endsWith('.md'))) {
|
|
365
|
+
await fs.copyFile(
|
|
366
|
+
path.join(tierPath, file),
|
|
367
|
+
path.join(tierDir, file)
|
|
368
|
+
);
|
|
369
|
+
}
|
|
347
370
|
}
|
|
371
|
+
|
|
372
|
+
// Copy agent index and README
|
|
373
|
+
await fs.copyFile(
|
|
374
|
+
path.join(agentsSourcePath, '00-AGENT_INDEX.md'),
|
|
375
|
+
path.join(agentsDir, '00-AGENT_INDEX.md')
|
|
376
|
+
);
|
|
377
|
+
await fs.copyFile(
|
|
378
|
+
path.join(agentsSourcePath, 'README.md'),
|
|
379
|
+
path.join(agentsDir, 'README.md')
|
|
380
|
+
);
|
|
348
381
|
} catch (err) {
|
|
349
|
-
// Agents not
|
|
350
|
-
console.log(chalk.
|
|
351
|
-
console.log(chalk.
|
|
382
|
+
// Agents not bundled - intentional for npm package size
|
|
383
|
+
console.log(chalk.gray('\n š¦ Agent prompts not bundled (npm size optimization)'));
|
|
384
|
+
console.log(chalk.cyan(' Quick setup: npx degit Srujan0798/Ultra-Dex/agents .agents'));
|
|
385
|
+
console.log(chalk.blue(' Or view: https://github.com/Srujan0798/Ultra-Dex/tree/main/agents'));
|
|
352
386
|
}
|
|
353
387
|
}
|
|
354
388
|
|
|
@@ -370,7 +404,7 @@ ${answers.ideaWhat} for ${answers.ideaFor}.
|
|
|
370
404
|
console.log(chalk.gray(' āāā .cursor/rules/ (11 AI rule files)'));
|
|
371
405
|
}
|
|
372
406
|
if (answers.includeAgents) {
|
|
373
|
-
console.log(chalk.gray(' āāā .agents/ (
|
|
407
|
+
console.log(chalk.gray(' āāā .agents/ (15 AI agent prompts in 6 tiers)'));
|
|
374
408
|
}
|
|
375
409
|
|
|
376
410
|
console.log('\n' + chalk.bold('Next steps:'));
|
|
@@ -552,35 +586,52 @@ program
|
|
|
552
586
|
});
|
|
553
587
|
});
|
|
554
588
|
|
|
555
|
-
// Agent definitions
|
|
589
|
+
// Agent definitions (organized by tier)
|
|
556
590
|
const AGENTS = [
|
|
557
|
-
|
|
558
|
-
{ name: '
|
|
559
|
-
{ name: '
|
|
560
|
-
{ name: '
|
|
561
|
-
|
|
562
|
-
{ name: '
|
|
563
|
-
{ name: '
|
|
564
|
-
{ name: '
|
|
565
|
-
|
|
591
|
+
// Leadership Tier
|
|
592
|
+
{ name: 'cto', description: 'Architecture & tech decisions', file: '1-leadership/cto.md', tier: 'Leadership' },
|
|
593
|
+
{ name: 'planner', description: 'Task breakdown & planning', file: '1-leadership/planner.md', tier: 'Leadership' },
|
|
594
|
+
{ name: 'research', description: 'Technology evaluation & comparison', file: '1-leadership/research.md', tier: 'Leadership' },
|
|
595
|
+
// Development Tier
|
|
596
|
+
{ name: 'backend', description: 'API & server logic', file: '2-development/backend.md', tier: 'Development' },
|
|
597
|
+
{ name: 'database', description: 'Schema design & queries', file: '2-development/database.md', tier: 'Development' },
|
|
598
|
+
{ name: 'frontend', description: 'UI & components', file: '2-development/frontend.md', tier: 'Development' },
|
|
599
|
+
// Security Tier
|
|
600
|
+
{ name: 'auth', description: 'Authentication & authorization', file: '3-security/auth.md', tier: 'Security' },
|
|
601
|
+
{ name: 'security', description: 'Security audits & vulnerability fixes', file: '3-security/security.md', tier: 'Security' },
|
|
602
|
+
// DevOps Tier
|
|
603
|
+
{ name: 'devops', description: 'Deployment & infrastructure', file: '4-devops/devops.md', tier: 'DevOps' },
|
|
604
|
+
// Quality Tier
|
|
605
|
+
{ name: 'debugger', description: 'Bug fixing & troubleshooting', file: '5-quality/debugger.md', tier: 'Quality' },
|
|
606
|
+
{ name: 'documentation', description: 'Technical writing & docs maintenance', file: '5-quality/documentation.md', tier: 'Quality' },
|
|
607
|
+
{ name: 'reviewer', description: 'Code review & quality check', file: '5-quality/reviewer.md', tier: 'Quality' },
|
|
608
|
+
{ name: 'testing', description: 'QA & test automation', file: '5-quality/testing.md', tier: 'Quality' },
|
|
609
|
+
// Specialist Tier
|
|
610
|
+
{ name: 'performance', description: 'Performance optimization', file: '6-specialist/performance.md', tier: 'Specialist' },
|
|
611
|
+
{ name: 'refactoring', description: 'Code quality & design patterns', file: '6-specialist/refactoring.md', tier: 'Specialist' },
|
|
566
612
|
];
|
|
567
613
|
|
|
568
614
|
program
|
|
569
615
|
.command('agents')
|
|
570
616
|
.description('List available AI agent prompts')
|
|
571
617
|
.action(() => {
|
|
572
|
-
console.log(chalk.bold('\nš¤
|
|
573
|
-
console.log(chalk.gray('
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
618
|
+
console.log(chalk.bold('\nš¤ Ultra-Dex AI Agents (15 Total)\n'));
|
|
619
|
+
console.log(chalk.gray('Organized by tier for production pipeline\n'));
|
|
620
|
+
|
|
621
|
+
let currentTier = '';
|
|
622
|
+
AGENTS.forEach((agent) => {
|
|
623
|
+
if (agent.tier !== currentTier) {
|
|
624
|
+
currentTier = agent.tier;
|
|
625
|
+
console.log(chalk.bold(`\n ${currentTier} Tier:`));
|
|
626
|
+
}
|
|
627
|
+
console.log(chalk.cyan(` ${agent.name}`) + chalk.gray(` - ${agent.description}`));
|
|
577
628
|
});
|
|
578
629
|
|
|
579
630
|
console.log('\n' + chalk.bold('Usage:'));
|
|
580
|
-
console.log(chalk.gray(' ultra-dex agent <name> Show agent prompt
|
|
581
|
-
console.log(chalk.gray(' ultra-dex agent backend Example: show backend agent
|
|
631
|
+
console.log(chalk.gray(' ultra-dex agent <name> Show agent prompt'));
|
|
632
|
+
console.log(chalk.gray(' ultra-dex agent backend Example: show backend agent'));
|
|
582
633
|
|
|
583
|
-
console.log('\n' + chalk.gray('
|
|
634
|
+
console.log('\n' + chalk.gray('Agent Index: https://github.com/Srujan0798/Ultra-Dex/blob/main/agents/00-AGENT_INDEX.md\n'));
|
|
584
635
|
});
|
|
585
636
|
|
|
586
637
|
program
|
|
@@ -607,12 +658,634 @@ program
|
|
|
607
658
|
console.log(chalk.gray('ā'.repeat(60)));
|
|
608
659
|
console.log(chalk.bold('\nš Copy the above prompt and paste into your AI tool.\n'));
|
|
609
660
|
} catch (err) {
|
|
610
|
-
// Agent file not bundled (npm package)
|
|
661
|
+
// Agent file not bundled (npm package) - show URL instead
|
|
611
662
|
console.log(chalk.bold(`\nš¤ ${agent.name.toUpperCase()} Agent\n`));
|
|
612
|
-
console.log(chalk.
|
|
613
|
-
console.log(chalk.gray('\nDownload from GitHub:'));
|
|
663
|
+
console.log(chalk.gray('View full prompt on GitHub:'));
|
|
614
664
|
console.log(chalk.blue(` https://github.com/Srujan0798/Ultra-Dex/blob/main/agents/${agent.file}\n`));
|
|
615
665
|
}
|
|
616
666
|
});
|
|
617
667
|
|
|
668
|
+
// Pack command - assemble context for any AI tool
|
|
669
|
+
program
|
|
670
|
+
.command('pack <agent>')
|
|
671
|
+
.description('Package project context + agent prompt for any AI tool')
|
|
672
|
+
.option('-c, --clipboard', 'Copy to clipboard (requires pbcopy/xclip)')
|
|
673
|
+
.action(async (agentName, options) => {
|
|
674
|
+
// Find agent
|
|
675
|
+
const agent = AGENTS.find(a => a.name.toLowerCase() === agentName.toLowerCase());
|
|
676
|
+
if (!agent) {
|
|
677
|
+
console.log(chalk.red(`\nā Agent "${agentName}" not found.\n`));
|
|
678
|
+
console.log(chalk.gray('Available agents:'));
|
|
679
|
+
AGENTS.forEach(a => console.log(chalk.cyan(` - ${a.name}`)));
|
|
680
|
+
process.exit(1);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
let output = '';
|
|
684
|
+
|
|
685
|
+
// 1. Read Agent Prompt
|
|
686
|
+
const agentPath = path.resolve(__dirname, '../../agents', agent.file);
|
|
687
|
+
try {
|
|
688
|
+
const agentPrompt = await fs.readFile(agentPath, 'utf-8');
|
|
689
|
+
output += agentPrompt + '\n\n';
|
|
690
|
+
} catch (err) {
|
|
691
|
+
output += `# ${agent.name.toUpperCase()} Agent\n\nSee: https://github.com/Srujan0798/Ultra-Dex/blob/main/agents/${agent.file}\n\n`;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
output += '---\n\n';
|
|
695
|
+
|
|
696
|
+
// 2. Read CONTEXT.md
|
|
697
|
+
try {
|
|
698
|
+
const context = await fs.readFile('CONTEXT.md', 'utf-8');
|
|
699
|
+
output += '# PROJECT CONTEXT\n\n' + context + '\n\n';
|
|
700
|
+
} catch (err) {
|
|
701
|
+
output += '# PROJECT CONTEXT\n\n*No CONTEXT.md found. Run `ultra-dex init` first.*\n\n';
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
output += '---\n\n';
|
|
705
|
+
|
|
706
|
+
// 3. Read IMPLEMENTATION-PLAN.md
|
|
707
|
+
try {
|
|
708
|
+
const plan = await fs.readFile('IMPLEMENTATION-PLAN.md', 'utf-8');
|
|
709
|
+
output += '# IMPLEMENTATION PLAN\n\n' + plan + '\n';
|
|
710
|
+
} catch (err) {
|
|
711
|
+
output += '# IMPLEMENTATION PLAN\n\n*No IMPLEMENTATION-PLAN.md found. Run `ultra-dex init` first.*\n';
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// Output
|
|
715
|
+
console.log(chalk.bold(`\nš¦ Packed context for @${agent.name}\n`));
|
|
716
|
+
console.log(chalk.gray('ā'.repeat(60)));
|
|
717
|
+
console.log(output);
|
|
718
|
+
console.log(chalk.gray('ā'.repeat(60)));
|
|
719
|
+
|
|
720
|
+
// Try to copy to clipboard if requested
|
|
721
|
+
if (options.clipboard) {
|
|
722
|
+
try {
|
|
723
|
+
const { execSync } = require('child_process');
|
|
724
|
+
const platform = process.platform;
|
|
725
|
+
if (platform === 'darwin') {
|
|
726
|
+
execSync('pbcopy', { input: output });
|
|
727
|
+
console.log(chalk.green('\nā
Copied to clipboard!\n'));
|
|
728
|
+
} else if (platform === 'linux') {
|
|
729
|
+
execSync('xclip -selection clipboard', { input: output });
|
|
730
|
+
console.log(chalk.green('\nā
Copied to clipboard!\n'));
|
|
731
|
+
} else {
|
|
732
|
+
console.log(chalk.yellow('\nā ļø Clipboard not supported on this platform. Copy manually.\n'));
|
|
733
|
+
}
|
|
734
|
+
} catch (err) {
|
|
735
|
+
console.log(chalk.yellow('\nā ļø Could not copy to clipboard. Copy manually.\n'));
|
|
736
|
+
}
|
|
737
|
+
} else {
|
|
738
|
+
console.log(chalk.cyan('\nš” Tip: Use --clipboard flag to copy directly\n'));
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
// Workflow examples map
|
|
743
|
+
const WORKFLOWS = {
|
|
744
|
+
auth: {
|
|
745
|
+
name: 'Authentication',
|
|
746
|
+
agents: ['@Planner', '@Research', '@CTO', '@Database', '@Backend', '@Frontend', '@Security', '@DevOps'],
|
|
747
|
+
description: 'Complete authentication with email/password and OAuth',
|
|
748
|
+
example: 'supabase',
|
|
749
|
+
},
|
|
750
|
+
supabase: {
|
|
751
|
+
name: 'Supabase Authentication Setup',
|
|
752
|
+
agents: ['@Planner', '@Research', '@CTO', '@Database', '@Backend', '@Frontend', '@Security', '@DevOps'],
|
|
753
|
+
description: 'Set up Supabase auth with RLS policies',
|
|
754
|
+
steps: [
|
|
755
|
+
'1. Create Supabase project and get API keys',
|
|
756
|
+
'2. Set up database schema with RLS policies',
|
|
757
|
+
'3. Configure authentication providers (email + Google OAuth)',
|
|
758
|
+
'4. Implement backend auth middleware',
|
|
759
|
+
'5. Build frontend auth UI components',
|
|
760
|
+
'6. Test authentication flow',
|
|
761
|
+
],
|
|
762
|
+
},
|
|
763
|
+
payments: {
|
|
764
|
+
name: 'Payment Integration (Stripe)',
|
|
765
|
+
agents: ['@Planner', '@Research', '@CTO', '@Database', '@Backend', '@Frontend', '@Testing', '@Security', '@DevOps'],
|
|
766
|
+
description: 'Integrate Stripe for subscriptions and one-time payments',
|
|
767
|
+
steps: [
|
|
768
|
+
'1. Create Stripe account and get API keys',
|
|
769
|
+
'2. Design subscription/payment schema',
|
|
770
|
+
'3. Implement Stripe Checkout API',
|
|
771
|
+
'4. Handle webhooks for payment events',
|
|
772
|
+
'5. Build payment UI with checkout flow',
|
|
773
|
+
'6. Test with Stripe test cards',
|
|
774
|
+
],
|
|
775
|
+
},
|
|
776
|
+
deployment: {
|
|
777
|
+
name: 'Deployment Pipeline',
|
|
778
|
+
agents: ['@Planner', '@CTO', '@Frontend', '@DevOps'],
|
|
779
|
+
description: 'Deploy to Vercel with staging and production environments',
|
|
780
|
+
example: 'vercel',
|
|
781
|
+
},
|
|
782
|
+
vercel: {
|
|
783
|
+
name: 'Vercel Deployment Pipeline',
|
|
784
|
+
agents: ['@Planner', '@CTO', '@Frontend', '@DevOps'],
|
|
785
|
+
description: 'Deploy Next.js app to Vercel',
|
|
786
|
+
steps: [
|
|
787
|
+
'1. Set up Vercel project and link Git repository',
|
|
788
|
+
'2. Configure environment variables for staging/production',
|
|
789
|
+
'3. Set up custom domain',
|
|
790
|
+
'4. Configure preview deployments for PRs',
|
|
791
|
+
'5. Set up deployment protection rules',
|
|
792
|
+
'6. Test deployment pipeline',
|
|
793
|
+
],
|
|
794
|
+
},
|
|
795
|
+
cicd: {
|
|
796
|
+
name: 'GitHub Actions CI/CD',
|
|
797
|
+
agents: ['@Planner', '@CTO', '@Testing', '@DevOps'],
|
|
798
|
+
description: 'Automated testing and deployment with GitHub Actions',
|
|
799
|
+
steps: [
|
|
800
|
+
'1. Create workflow file for CI (tests + lint)',
|
|
801
|
+
'2. Add build verification job',
|
|
802
|
+
'3. Add deployment job for production',
|
|
803
|
+
'4. Configure secrets for deployment',
|
|
804
|
+
'5. Add status badges to README',
|
|
805
|
+
'6. Test workflow on PR',
|
|
806
|
+
],
|
|
807
|
+
},
|
|
808
|
+
database: {
|
|
809
|
+
name: 'Database Migration',
|
|
810
|
+
agents: ['@Planner', '@CTO', '@Database', '@Backend', '@Testing'],
|
|
811
|
+
description: 'Database schema migration and data sync',
|
|
812
|
+
steps: [
|
|
813
|
+
'1. Design new schema changes',
|
|
814
|
+
'2. Write migration scripts',
|
|
815
|
+
'3. Test migrations in staging',
|
|
816
|
+
'4. Back up production database',
|
|
817
|
+
'5. Run migrations in production',
|
|
818
|
+
'6. Verify data integrity',
|
|
819
|
+
],
|
|
820
|
+
},
|
|
821
|
+
email: {
|
|
822
|
+
name: 'Email Notification System',
|
|
823
|
+
agents: ['@Planner', '@Research', '@CTO', '@Backend', '@Frontend', '@Testing'],
|
|
824
|
+
description: 'Transactional emails with templates',
|
|
825
|
+
steps: [
|
|
826
|
+
'1. Choose email service (Resend, SendGrid)',
|
|
827
|
+
'2. Set up email templates',
|
|
828
|
+
'3. Implement email API endpoints',
|
|
829
|
+
'4. Add email queue for async sending',
|
|
830
|
+
'5. Test email delivery',
|
|
831
|
+
'6. Monitor deliverability',
|
|
832
|
+
],
|
|
833
|
+
},
|
|
834
|
+
realtime: {
|
|
835
|
+
name: 'Real-Time Features',
|
|
836
|
+
agents: ['@Planner', '@CTO', '@Backend', '@Frontend', '@Testing'],
|
|
837
|
+
description: 'Live notifications with WebSockets',
|
|
838
|
+
steps: [
|
|
839
|
+
'1. Choose WebSocket library (Socket.io, Pusher)',
|
|
840
|
+
'2. Set up WebSocket server',
|
|
841
|
+
'3. Implement event broadcasting',
|
|
842
|
+
'4. Build frontend listeners',
|
|
843
|
+
'5. Test real-time updates',
|
|
844
|
+
'6. Handle reconnection logic',
|
|
845
|
+
],
|
|
846
|
+
},
|
|
847
|
+
sentry: {
|
|
848
|
+
name: 'Sentry Error Tracking',
|
|
849
|
+
agents: ['@Planner', '@Research', '@CTO', '@Backend', '@Frontend', '@DevOps'],
|
|
850
|
+
description: 'Error monitoring with Sentry',
|
|
851
|
+
steps: [
|
|
852
|
+
'1. Create Sentry account and project',
|
|
853
|
+
'2. Install Sentry SDKs for frontend and backend',
|
|
854
|
+
'3. Configure error boundaries for React',
|
|
855
|
+
'4. Set up source maps for debugging',
|
|
856
|
+
'5. Configure alerts and notifications',
|
|
857
|
+
'6. Test error capture in development',
|
|
858
|
+
],
|
|
859
|
+
},
|
|
860
|
+
shopify: {
|
|
861
|
+
name: 'Shopify Product Integration',
|
|
862
|
+
agents: ['@Planner', '@Research', '@CTO', '@Database', '@Backend', '@DevOps'],
|
|
863
|
+
description: 'Sync products from Shopify store',
|
|
864
|
+
steps: [
|
|
865
|
+
'1. Create Shopify Partner account and development store',
|
|
866
|
+
'2. Set up Shopify app with Admin API access',
|
|
867
|
+
'3. Design database schema for products',
|
|
868
|
+
'4. Build product sync endpoint',
|
|
869
|
+
'5. Implement webhook handlers for product updates',
|
|
870
|
+
'6. Schedule full product sync (cron job)',
|
|
871
|
+
],
|
|
872
|
+
},
|
|
873
|
+
analytics: {
|
|
874
|
+
name: 'PostHog Analytics Integration',
|
|
875
|
+
agents: ['@Planner', '@Research', '@CTO', '@Backend', '@Frontend', '@DevOps'],
|
|
876
|
+
description: 'Track user behavior with PostHog',
|
|
877
|
+
steps: [
|
|
878
|
+
'1. Create PostHog account and project',
|
|
879
|
+
'2. Install PostHog SDKs for frontend and backend',
|
|
880
|
+
'3. Set up core event tracking (signup, login, feature usage)',
|
|
881
|
+
'4. Create conversion funnel dashboard',
|
|
882
|
+
'5. Set up feature flags (optional)',
|
|
883
|
+
'6. Configure user identification',
|
|
884
|
+
],
|
|
885
|
+
},
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
program
|
|
889
|
+
.command('workflow <feature>')
|
|
890
|
+
.description('Show workflow for common features (auth, payments, deployment, etc.)')
|
|
891
|
+
.action((feature) => {
|
|
892
|
+
const workflow = WORKFLOWS[feature.toLowerCase()];
|
|
893
|
+
|
|
894
|
+
if (!workflow) {
|
|
895
|
+
console.log(chalk.red(`\nā Workflow "${feature}" not found.\n`));
|
|
896
|
+
console.log(chalk.gray('Available workflows:'));
|
|
897
|
+
Object.keys(WORKFLOWS).forEach(key => {
|
|
898
|
+
console.log(chalk.cyan(` - ${key}`) + chalk.gray(` (${WORKFLOWS[key].name})`));
|
|
899
|
+
});
|
|
900
|
+
console.log('\n' + chalk.gray('Usage: ultra-dex workflow <feature>\n'));
|
|
901
|
+
process.exit(1);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
console.log(chalk.bold(`\nš ${workflow.name} Workflow\n`));
|
|
905
|
+
console.log(chalk.gray(workflow.description));
|
|
906
|
+
|
|
907
|
+
console.log(chalk.bold('\nš¤ Agents Involved:\n'));
|
|
908
|
+
workflow.agents.forEach((agent, i) => {
|
|
909
|
+
console.log(chalk.cyan(` ${i + 1}. ${agent}`));
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
if (workflow.steps) {
|
|
913
|
+
console.log(chalk.bold('\nš Implementation Steps:\n'));
|
|
914
|
+
workflow.steps.forEach(step => {
|
|
915
|
+
console.log(chalk.gray(` ${step}`));
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
console.log(chalk.bold('\nš Full Example:\n'));
|
|
920
|
+
console.log(chalk.blue(' https://github.com/Srujan0798/Ultra-Dex/blob/main/guides/ADVANCED-WORKFLOWS.md'));
|
|
921
|
+
console.log(chalk.gray(` (Search for "Example: ${workflow.name}")\n`));
|
|
922
|
+
});
|
|
923
|
+
|
|
924
|
+
program
|
|
925
|
+
.command('suggest')
|
|
926
|
+
.description('Get AI agent suggestions for your task')
|
|
927
|
+
.action(async () => {
|
|
928
|
+
console.log(chalk.cyan('\nš¤ Ultra-Dex Agent Suggester\n'));
|
|
929
|
+
|
|
930
|
+
const answers = await inquirer.prompt([
|
|
931
|
+
{
|
|
932
|
+
type: 'list',
|
|
933
|
+
name: 'taskType',
|
|
934
|
+
message: 'What are you trying to build?',
|
|
935
|
+
choices: [
|
|
936
|
+
'New feature from scratch',
|
|
937
|
+
'Authentication system',
|
|
938
|
+
'Payment integration',
|
|
939
|
+
'Database changes',
|
|
940
|
+
'Bug fix',
|
|
941
|
+
'Performance optimization',
|
|
942
|
+
'Deployment/DevOps',
|
|
943
|
+
'API endpoint',
|
|
944
|
+
'UI component',
|
|
945
|
+
'Testing',
|
|
946
|
+
],
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
type: 'input',
|
|
950
|
+
name: 'description',
|
|
951
|
+
message: 'Briefly describe your task:',
|
|
952
|
+
default: '',
|
|
953
|
+
},
|
|
954
|
+
]);
|
|
955
|
+
|
|
956
|
+
console.log(chalk.bold('\nš” Suggested Agent Workflow:\n'));
|
|
957
|
+
|
|
958
|
+
// Agent suggestions based on task type
|
|
959
|
+
let suggestedAgents = [];
|
|
960
|
+
let reasoning = '';
|
|
961
|
+
|
|
962
|
+
switch (answers.taskType) {
|
|
963
|
+
case 'New feature from scratch':
|
|
964
|
+
suggestedAgents = ['@Planner', '@CTO', '@Database', '@Backend', '@Frontend', '@Testing', '@Reviewer', '@DevOps'];
|
|
965
|
+
reasoning = 'Complete feature requires planning, architecture, implementation, testing, and deployment';
|
|
966
|
+
break;
|
|
967
|
+
|
|
968
|
+
case 'Authentication system':
|
|
969
|
+
suggestedAgents = ['@Planner', '@Research', '@CTO', '@Database', '@Backend', '@Frontend', '@Security', '@DevOps'];
|
|
970
|
+
reasoning = 'Auth requires research (providers), security review, and full-stack implementation';
|
|
971
|
+
break;
|
|
972
|
+
|
|
973
|
+
case 'Payment integration':
|
|
974
|
+
suggestedAgents = ['@Planner', '@Research', '@CTO', '@Database', '@Backend', '@Frontend', '@Testing', '@Security', '@DevOps'];
|
|
975
|
+
reasoning = 'Payments need provider research, webhook handling, testing, and security audit';
|
|
976
|
+
break;
|
|
977
|
+
|
|
978
|
+
case 'Database changes':
|
|
979
|
+
suggestedAgents = ['@Planner', '@CTO', '@Database', '@Backend', '@Testing'];
|
|
980
|
+
reasoning = 'Schema changes need planning, architecture review, migration, and testing';
|
|
981
|
+
break;
|
|
982
|
+
|
|
983
|
+
case 'Bug fix':
|
|
984
|
+
suggestedAgents = ['@Debugger', '@Testing', '@Reviewer'];
|
|
985
|
+
reasoning = 'Debug issue, add test to prevent regression, review fix';
|
|
986
|
+
break;
|
|
987
|
+
|
|
988
|
+
case 'Performance optimization':
|
|
989
|
+
suggestedAgents = ['@Performance', '@Backend', '@Frontend', '@Database', '@Testing'];
|
|
990
|
+
reasoning = 'Identify bottlenecks, optimize code/queries, verify improvements';
|
|
991
|
+
break;
|
|
992
|
+
|
|
993
|
+
case 'Deployment/DevOps':
|
|
994
|
+
suggestedAgents = ['@DevOps', '@CTO', '@Security'];
|
|
995
|
+
reasoning = 'Infrastructure setup with security review';
|
|
996
|
+
break;
|
|
997
|
+
|
|
998
|
+
case 'API endpoint':
|
|
999
|
+
suggestedAgents = ['@Backend', '@Database', '@Testing', '@Reviewer'];
|
|
1000
|
+
reasoning = 'Implement endpoint, add tests, review code quality';
|
|
1001
|
+
break;
|
|
1002
|
+
|
|
1003
|
+
case 'UI component':
|
|
1004
|
+
suggestedAgents = ['@Frontend', '@Reviewer'];
|
|
1005
|
+
reasoning = 'Build component, review for quality and accessibility';
|
|
1006
|
+
break;
|
|
1007
|
+
|
|
1008
|
+
case 'Testing':
|
|
1009
|
+
suggestedAgents = ['@Testing', '@Reviewer'];
|
|
1010
|
+
reasoning = 'Write tests, review coverage';
|
|
1011
|
+
break;
|
|
1012
|
+
|
|
1013
|
+
default:
|
|
1014
|
+
suggestedAgents = ['@Planner', '@CTO'];
|
|
1015
|
+
reasoning = 'Start with planning and architecture review';
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
console.log(chalk.gray(reasoning + '\n'));
|
|
1019
|
+
|
|
1020
|
+
suggestedAgents.forEach((agent, i) => {
|
|
1021
|
+
const agentName = agent.replace('@', '').toLowerCase();
|
|
1022
|
+
const agentInfo = AGENTS.find(a => a.name === agentName);
|
|
1023
|
+
const arrow = i < suggestedAgents.length - 1 ? ' ā' : '';
|
|
1024
|
+
console.log(chalk.cyan(` ${i + 1}. ${agent}`) + chalk.gray(` - ${agentInfo?.description || ''}`) + arrow);
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
console.log(chalk.bold('\nš Next Steps:\n'));
|
|
1028
|
+
console.log(chalk.gray(` 1. Start with ${suggestedAgents[0]} to plan the task`));
|
|
1029
|
+
console.log(chalk.gray(` 2. Hand off to each agent in sequence`));
|
|
1030
|
+
console.log(chalk.gray(' 3. Use "ultra-dex agent <name>" to see full prompts\n'));
|
|
1031
|
+
|
|
1032
|
+
console.log(chalk.bold('š Related Workflows:\n'));
|
|
1033
|
+
if (answers.taskType === 'Authentication system') {
|
|
1034
|
+
console.log(chalk.blue(' ultra-dex workflow auth'));
|
|
1035
|
+
console.log(chalk.blue(' ultra-dex workflow supabase\n'));
|
|
1036
|
+
} else if (answers.taskType === 'Payment integration') {
|
|
1037
|
+
console.log(chalk.blue(' ultra-dex workflow payments\n'));
|
|
1038
|
+
} else if (answers.taskType === 'Deployment/DevOps') {
|
|
1039
|
+
console.log(chalk.blue(' ultra-dex workflow vercel'));
|
|
1040
|
+
console.log(chalk.blue(' ultra-dex workflow cicd\n'));
|
|
1041
|
+
} else {
|
|
1042
|
+
console.log(chalk.gray(' Use "ultra-dex workflow <feature>" to see examples\n'));
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
|
|
1046
|
+
program
|
|
1047
|
+
.command('validate')
|
|
1048
|
+
.description('Validate project structure against Ultra-Dex standards')
|
|
1049
|
+
.option('-d, --dir <directory>', 'Project directory to validate', '.')
|
|
1050
|
+
.action(async (options) => {
|
|
1051
|
+
console.log(chalk.cyan('\nā
Ultra-Dex Structure Validator\n'));
|
|
1052
|
+
|
|
1053
|
+
const projectDir = path.resolve(options.dir);
|
|
1054
|
+
let passed = 0;
|
|
1055
|
+
let failed = 0;
|
|
1056
|
+
const warnings = [];
|
|
1057
|
+
|
|
1058
|
+
// Helper to check file/directory exists
|
|
1059
|
+
async function checkExists(itemPath, type = 'file') {
|
|
1060
|
+
try {
|
|
1061
|
+
const stats = await fs.stat(path.join(projectDir, itemPath));
|
|
1062
|
+
if (type === 'file' && stats.isFile()) return true;
|
|
1063
|
+
if (type === 'dir' && stats.isDirectory()) return true;
|
|
1064
|
+
return false;
|
|
1065
|
+
} catch {
|
|
1066
|
+
return false;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
console.log(chalk.bold('Checking required files...\n'));
|
|
1071
|
+
|
|
1072
|
+
// Check core planning files
|
|
1073
|
+
const coreFiles = [
|
|
1074
|
+
{ path: 'QUICK-START.md', required: true },
|
|
1075
|
+
{ path: 'IMPLEMENTATION-PLAN.md', required: true },
|
|
1076
|
+
{ path: 'CONTEXT.md', required: false },
|
|
1077
|
+
{ path: 'README.md', required: false },
|
|
1078
|
+
];
|
|
1079
|
+
|
|
1080
|
+
for (const file of coreFiles) {
|
|
1081
|
+
const exists = await checkExists(file.path);
|
|
1082
|
+
if (exists) {
|
|
1083
|
+
passed++;
|
|
1084
|
+
console.log(chalk.green(` ā
${file.path}`));
|
|
1085
|
+
} else if (file.required) {
|
|
1086
|
+
failed++;
|
|
1087
|
+
console.log(chalk.red(` ā ${file.path} (required)`));
|
|
1088
|
+
} else {
|
|
1089
|
+
warnings.push(file.path);
|
|
1090
|
+
console.log(chalk.yellow(` ā ļø ${file.path} (recommended)`));
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
console.log(chalk.bold('\nChecking directory structure...\n'));
|
|
1095
|
+
|
|
1096
|
+
const directories = [
|
|
1097
|
+
{ path: 'docs', required: false },
|
|
1098
|
+
{ path: '.agents', required: false },
|
|
1099
|
+
{ path: '.cursor/rules', required: false },
|
|
1100
|
+
];
|
|
1101
|
+
|
|
1102
|
+
for (const dir of directories) {
|
|
1103
|
+
const exists = await checkExists(dir.path, 'dir');
|
|
1104
|
+
if (exists) {
|
|
1105
|
+
passed++;
|
|
1106
|
+
console.log(chalk.green(` ā
${dir.path}/`));
|
|
1107
|
+
} else {
|
|
1108
|
+
warnings.push(dir.path);
|
|
1109
|
+
console.log(chalk.yellow(` ā ļø ${dir.path}/ (optional)`));
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
console.log(chalk.bold('\nValidating content quality...\n'));
|
|
1114
|
+
|
|
1115
|
+
// Check if QUICK-START has key sections
|
|
1116
|
+
try {
|
|
1117
|
+
const quickStart = await fs.readFile(path.join(projectDir, 'QUICK-START.md'), 'utf-8');
|
|
1118
|
+
|
|
1119
|
+
const sections = ['idea', 'problem', 'feature', 'tech stack', 'tasks'];
|
|
1120
|
+
let sectionsFound = 0;
|
|
1121
|
+
|
|
1122
|
+
sections.forEach(section => {
|
|
1123
|
+
if (quickStart.toLowerCase().includes(section)) {
|
|
1124
|
+
sectionsFound++;
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
if (sectionsFound >= 4) {
|
|
1129
|
+
passed++;
|
|
1130
|
+
console.log(chalk.green(` ā
QUICK-START.md has ${sectionsFound}/${sections.length} key sections`));
|
|
1131
|
+
} else {
|
|
1132
|
+
failed++;
|
|
1133
|
+
console.log(chalk.red(` ā QUICK-START.md missing key sections (${sectionsFound}/${sections.length})`));
|
|
1134
|
+
}
|
|
1135
|
+
} catch {
|
|
1136
|
+
console.log(chalk.gray(' ā Could not validate QUICK-START.md content'));
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// Check if implementation plan has content
|
|
1140
|
+
try {
|
|
1141
|
+
const implPlan = await fs.readFile(path.join(projectDir, 'IMPLEMENTATION-PLAN.md'), 'utf-8');
|
|
1142
|
+
|
|
1143
|
+
if (implPlan.length > 500) {
|
|
1144
|
+
passed++;
|
|
1145
|
+
console.log(chalk.green(` ā
IMPLEMENTATION-PLAN.md has substantial content`));
|
|
1146
|
+
} else {
|
|
1147
|
+
warnings.push('IMPLEMENTATION-PLAN.md needs more detail');
|
|
1148
|
+
console.log(chalk.yellow(` ā ļø IMPLEMENTATION-PLAN.md is sparse (${implPlan.length} chars)`));
|
|
1149
|
+
}
|
|
1150
|
+
} catch {
|
|
1151
|
+
console.log(chalk.gray(' ā Could not validate IMPLEMENTATION-PLAN.md content'));
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// Summary
|
|
1155
|
+
console.log('\n' + chalk.bold('ā'.repeat(50)));
|
|
1156
|
+
console.log(chalk.bold('\nValidation Summary:\n'));
|
|
1157
|
+
console.log(chalk.green(` ā
Passed: ${passed}`));
|
|
1158
|
+
console.log(chalk.red(` ā Failed: ${failed}`));
|
|
1159
|
+
console.log(chalk.yellow(` ā ļø Warnings: ${warnings.length}`));
|
|
1160
|
+
|
|
1161
|
+
// Overall status
|
|
1162
|
+
if (failed === 0) {
|
|
1163
|
+
console.log(chalk.bold.green('\nā
VALIDATION PASSED\n'));
|
|
1164
|
+
console.log(chalk.gray('Your project structure follows Ultra-Dex standards.'));
|
|
1165
|
+
} else {
|
|
1166
|
+
console.log(chalk.bold.yellow('\nā ļø VALIDATION INCOMPLETE\n'));
|
|
1167
|
+
console.log(chalk.gray('Fix required files to meet Ultra-Dex standards.'));
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// Recommendations
|
|
1171
|
+
if (warnings.length > 0) {
|
|
1172
|
+
console.log(chalk.bold('\nš” Recommendations:\n'));
|
|
1173
|
+
warnings.slice(0, 3).forEach(w => {
|
|
1174
|
+
console.log(chalk.cyan(` ā Consider adding ${w}`));
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
console.log('\n' + chalk.gray('Run "ultra-dex init" to set up a proper Ultra-Dex project.\n'));
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
// ========================================
|
|
1182
|
+
// HOOKS COMMAND - Automated Verification
|
|
1183
|
+
// ========================================
|
|
1184
|
+
program
|
|
1185
|
+
.command('hooks')
|
|
1186
|
+
.description('Set up git hooks for automated verification')
|
|
1187
|
+
.option('--remove', 'Remove Ultra-Dex git hooks')
|
|
1188
|
+
.action(async (options) => {
|
|
1189
|
+
console.log(chalk.cyan('\nšŖ Ultra-Dex Git Hooks Setup\n'));
|
|
1190
|
+
|
|
1191
|
+
const gitDir = path.join(process.cwd(), '.git');
|
|
1192
|
+
const hooksDir = path.join(gitDir, 'hooks');
|
|
1193
|
+
|
|
1194
|
+
// Check if git repo exists
|
|
1195
|
+
try {
|
|
1196
|
+
await fs.access(gitDir);
|
|
1197
|
+
} catch {
|
|
1198
|
+
console.log(chalk.red('ā Not a git repository. Run "git init" first.\n'));
|
|
1199
|
+
process.exit(1);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
// Create hooks directory if it doesn't exist
|
|
1203
|
+
await fs.mkdir(hooksDir, { recursive: true });
|
|
1204
|
+
|
|
1205
|
+
const preCommitPath = path.join(hooksDir, 'pre-commit');
|
|
1206
|
+
|
|
1207
|
+
if (options.remove) {
|
|
1208
|
+
// Remove hooks
|
|
1209
|
+
try {
|
|
1210
|
+
const content = await fs.readFile(preCommitPath, 'utf-8');
|
|
1211
|
+
if (content.includes('ultra-dex')) {
|
|
1212
|
+
await fs.unlink(preCommitPath);
|
|
1213
|
+
console.log(chalk.green('ā
Ultra-Dex pre-commit hook removed.\n'));
|
|
1214
|
+
} else {
|
|
1215
|
+
console.log(chalk.yellow('ā ļø Pre-commit hook exists but is not from Ultra-Dex.\n'));
|
|
1216
|
+
}
|
|
1217
|
+
} catch {
|
|
1218
|
+
console.log(chalk.gray('No Ultra-Dex hooks found.\n'));
|
|
1219
|
+
}
|
|
1220
|
+
return;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// Generate pre-commit hook
|
|
1224
|
+
const preCommitScript = `#!/bin/sh
|
|
1225
|
+
# Ultra-Dex Pre-Commit Hook
|
|
1226
|
+
# Validates project structure before allowing commits
|
|
1227
|
+
# Remove with: npx ultra-dex hooks --remove
|
|
1228
|
+
|
|
1229
|
+
echo "š Ultra-Dex: Validating project structure..."
|
|
1230
|
+
|
|
1231
|
+
# Run validation
|
|
1232
|
+
npx ultra-dex validate --dir . > /tmp/ultra-dex-validate.log 2>&1
|
|
1233
|
+
RESULT=$?
|
|
1234
|
+
|
|
1235
|
+
if [ $RESULT -ne 0 ]; then
|
|
1236
|
+
echo ""
|
|
1237
|
+
echo "ā Ultra-Dex validation failed. Commit blocked."
|
|
1238
|
+
echo ""
|
|
1239
|
+
echo "Run 'npx ultra-dex validate' to see details."
|
|
1240
|
+
echo "Fix issues or bypass with: git commit --no-verify"
|
|
1241
|
+
echo ""
|
|
1242
|
+
exit 1
|
|
1243
|
+
fi
|
|
1244
|
+
|
|
1245
|
+
# Check for required files
|
|
1246
|
+
if [ ! -f "QUICK-START.md" ]; then
|
|
1247
|
+
echo "ā ļø Warning: QUICK-START.md not found"
|
|
1248
|
+
fi
|
|
1249
|
+
|
|
1250
|
+
if [ ! -f "IMPLEMENTATION-PLAN.md" ]; then
|
|
1251
|
+
echo "ā ļø Warning: IMPLEMENTATION-PLAN.md not found"
|
|
1252
|
+
fi
|
|
1253
|
+
|
|
1254
|
+
echo "ā
Ultra-Dex validation passed."
|
|
1255
|
+
exit 0
|
|
1256
|
+
`;
|
|
1257
|
+
|
|
1258
|
+
// Check if pre-commit already exists
|
|
1259
|
+
try {
|
|
1260
|
+
const existing = await fs.readFile(preCommitPath, 'utf-8');
|
|
1261
|
+
if (existing.includes('ultra-dex')) {
|
|
1262
|
+
console.log(chalk.yellow('ā ļø Ultra-Dex pre-commit hook already exists.\n'));
|
|
1263
|
+
console.log(chalk.gray(' Use --remove to remove it first.\n'));
|
|
1264
|
+
return;
|
|
1265
|
+
} else {
|
|
1266
|
+
// Append to existing hook
|
|
1267
|
+
const combined = existing + '\n\n' + preCommitScript;
|
|
1268
|
+
await fs.writeFile(preCommitPath, combined);
|
|
1269
|
+
await fs.chmod(preCommitPath, '755');
|
|
1270
|
+
console.log(chalk.green('ā
Ultra-Dex hook appended to existing pre-commit.\n'));
|
|
1271
|
+
}
|
|
1272
|
+
} catch {
|
|
1273
|
+
// No existing hook, create new
|
|
1274
|
+
await fs.writeFile(preCommitPath, preCommitScript);
|
|
1275
|
+
await fs.chmod(preCommitPath, '755');
|
|
1276
|
+
console.log(chalk.green('ā
Pre-commit hook installed.\n'));
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
console.log(chalk.bold('What this does:\n'));
|
|
1280
|
+
console.log(chalk.gray(' ⢠Runs "ultra-dex validate" before each commit'));
|
|
1281
|
+
console.log(chalk.gray(' ⢠Blocks commits if required files are missing'));
|
|
1282
|
+
console.log(chalk.gray(' ⢠Warns about incomplete sections\n'));
|
|
1283
|
+
|
|
1284
|
+
console.log(chalk.bold('To bypass (not recommended):\n'));
|
|
1285
|
+
console.log(chalk.cyan(' git commit --no-verify\n'));
|
|
1286
|
+
|
|
1287
|
+
console.log(chalk.bold('To remove:\n'));
|
|
1288
|
+
console.log(chalk.cyan(' npx ultra-dex hooks --remove\n'));
|
|
1289
|
+
});
|
|
1290
|
+
|
|
618
1291
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra-dex",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "CLI for Ultra-Dex SaaS Implementation Framework",
|
|
3
|
+
"version": "1.7.2",
|
|
4
|
+
"description": "CLI for Ultra-Dex SaaS Implementation Framework with 16 Production Agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"saas",
|
|
7
7
|
"template",
|