ultra-dex 2.2.1 ā 3.1.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 +84 -128
- package/assets/agents/00-AGENT_INDEX.md +1 -1
- package/assets/docs/LAUNCH-POSTS.md +1 -1
- package/assets/docs/QUICK-REFERENCE.md +9 -4
- package/assets/docs/VISION-V2.md +1 -1
- package/assets/hooks/pre-commit +98 -0
- package/assets/saas-plan/04-Imp-Template.md +1 -1
- package/bin/ultra-dex.js +95 -4
- package/lib/commands/advanced.js +471 -0
- package/lib/commands/agent-builder.js +226 -0
- package/lib/commands/agents.js +99 -42
- package/lib/commands/auto-implement.js +68 -0
- package/lib/commands/build.js +73 -187
- package/lib/commands/ci-monitor.js +84 -0
- package/lib/commands/config.js +207 -0
- package/lib/commands/dashboard.js +770 -0
- package/lib/commands/diff.js +233 -0
- package/lib/commands/doctor.js +397 -0
- package/lib/commands/export.js +408 -0
- package/lib/commands/fix.js +96 -0
- package/lib/commands/generate.js +96 -72
- package/lib/commands/hooks.js +251 -76
- package/lib/commands/init.js +53 -1
- package/lib/commands/memory.js +80 -0
- package/lib/commands/plan.js +82 -0
- package/lib/commands/review.js +34 -5
- package/lib/commands/run.js +233 -0
- package/lib/commands/serve.js +177 -146
- package/lib/commands/state.js +354 -0
- package/lib/commands/swarm.js +284 -0
- package/lib/commands/sync.js +82 -23
- package/lib/commands/team.js +275 -0
- package/lib/commands/upgrade.js +190 -0
- package/lib/commands/validate.js +34 -0
- package/lib/commands/verify.js +81 -0
- package/lib/commands/watch.js +79 -0
- package/lib/mcp/graph.js +92 -0
- package/lib/mcp/memory.js +95 -0
- package/lib/mcp/resources.js +152 -0
- package/lib/mcp/server.js +34 -0
- package/lib/mcp/tools.js +481 -0
- package/lib/mcp/websocket.js +117 -0
- package/lib/providers/index.js +49 -4
- package/lib/providers/ollama.js +136 -0
- package/lib/providers/router.js +63 -0
- package/lib/quality/scanner.js +128 -0
- package/lib/swarm/coordinator.js +97 -0
- package/lib/swarm/index.js +598 -0
- package/lib/swarm/protocol.js +677 -0
- package/lib/swarm/tiers.js +485 -0
- package/lib/templates/custom-agent.md +10 -0
- package/lib/utils/files.js +14 -0
- package/lib/utils/graph.js +108 -0
- package/package.json +22 -13
package/lib/commands/serve.js
CHANGED
|
@@ -2,172 +2,203 @@ import chalk from 'chalk';
|
|
|
2
2
|
import http from 'http';
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
5
|
+
import { loadState, generateMarkdown } from './plan.js';
|
|
6
|
+
import { startMcpServer } from '../mcp/server.js';
|
|
7
|
+
import { projectGraph } from '../mcp/graph.js';
|
|
8
|
+
import { UltraDexSocket } from '../mcp/websocket.js';
|
|
9
|
+
import { swarmCommand } from './swarm.js';
|
|
10
|
+
import { glob } from 'glob';
|
|
11
|
+
import { execSync, spawn } from 'child_process';
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
export function registerServeCommand(program) {
|
|
14
|
+
program
|
|
15
|
+
.command('serve')
|
|
16
|
+
.description('Start the Ultra-Dex Active Kernel (MCP + Dashboard + API)')
|
|
17
|
+
.option('-p, --port <port>', 'Port to listen on', '3001')
|
|
18
|
+
.option('--stdio', 'Run in Stdio mode (MCP Standard Only)', false)
|
|
19
|
+
.action(async (options) => {
|
|
20
|
+
if (options.stdio) {
|
|
21
|
+
// Run only MCP Stdio server
|
|
22
|
+
try {
|
|
23
|
+
await startMcpServer();
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error("Failed to start MCP Server:", error);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
// Run full Unified Kernel (HTTP + WebSocket + Dashboard + MCP over HTTP)
|
|
30
|
+
await startUnifiedKernel(options.port);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function getGitInfo() {
|
|
9
36
|
try {
|
|
10
|
-
const
|
|
11
|
-
|
|
37
|
+
const branch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();
|
|
38
|
+
const lastCommit = execSync('git log -1 --format="%h %s" 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
39
|
+
const status = execSync('git status --porcelain 2>/dev/null', { encoding: 'utf8' });
|
|
40
|
+
const changedFiles = status.split('\n').filter(l => l.trim()).length;
|
|
41
|
+
return { branch, lastCommit, changedFiles };
|
|
12
42
|
} catch {
|
|
13
|
-
return
|
|
43
|
+
return { branch: 'unknown', lastCommit: 'N/A', changedFiles: 0 };
|
|
14
44
|
}
|
|
15
45
|
}
|
|
16
46
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
state.files[file] = { exists: true, size: stat.size };
|
|
32
|
-
} catch {
|
|
33
|
-
state.files[file] = { exists: false };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
47
|
+
// Re-using dashboard HTML generation logic (modularized)
|
|
48
|
+
async function getDashboardHTML() {
|
|
49
|
+
const { generateDashboardHTML } = await import('./dashboard.js');
|
|
50
|
+
const state = await loadState();
|
|
51
|
+
const gitInfo = await getGitInfo();
|
|
52
|
+
await projectGraph.scan();
|
|
53
|
+
const summary = projectGraph.getSummary();
|
|
54
|
+
return generateDashboardHTML(state, gitInfo, { nodes: summary.nodeCount, edges: summary.edgeCount });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function startUnifiedKernel(portStr) {
|
|
58
|
+
const port = Number.parseInt(portStr, 10);
|
|
59
|
+
|
|
60
|
+
console.log(chalk.bold.cyan('\nš Ultra-Dex Active Kernel Starting (GOD MODE)...\n'));
|
|
36
61
|
|
|
62
|
+
// Initialize Graph
|
|
63
|
+
console.log(chalk.gray('š§ Initializing Neural Link (Code Graph)...'));
|
|
37
64
|
try {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
state.sections.completed = state.sections.list.length;
|
|
45
|
-
} catch { /* no plan */ }
|
|
65
|
+
await projectGraph.scan();
|
|
66
|
+
console.log(chalk.green(`ā
Graph loaded: ${projectGraph.nodes.size} nodes`));
|
|
67
|
+
} catch (e) {
|
|
68
|
+
console.log(chalk.yellow(`ā ļø Graph init failed: ${e.message}`));
|
|
69
|
+
}
|
|
46
70
|
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
71
|
+
const server = http.createServer(async (req, res) => {
|
|
72
|
+
// CORS headers for local tools
|
|
73
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
74
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
75
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
|
|
77
|
+
if (req.method === 'OPTIONS') {
|
|
78
|
+
res.writeHead(204);
|
|
79
|
+
res.end();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
53
82
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
{ name: 'cto', tier: 'architect', task: 'Technical decisions & architecture' },
|
|
57
|
-
{ name: 'backend', tier: 'core', task: 'API, business logic, services' },
|
|
58
|
-
{ name: 'frontend', tier: 'core', task: 'UI components, pages, styling' },
|
|
59
|
-
{ name: 'database', tier: 'core', task: 'Schema design, migrations, queries' },
|
|
60
|
-
{ name: 'auth', tier: 'specialist', task: 'Authentication & authorization' },
|
|
61
|
-
{ name: 'security', tier: 'specialist', task: 'Security audit & hardening' },
|
|
62
|
-
{ name: 'testing', tier: 'specialist', task: 'Test strategy & implementation' },
|
|
63
|
-
{ name: 'reviewer', tier: 'quality', task: 'Code review & best practices' },
|
|
64
|
-
{ name: 'devops', tier: 'quality', task: 'CI/CD, deployment, infrastructure' }
|
|
65
|
-
];
|
|
83
|
+
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
84
|
+
const pathname = url.pathname;
|
|
66
85
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (Number.isNaN(port)) {
|
|
75
|
-
console.log(chalk.red('Invalid port. Use a numeric value.'));
|
|
76
|
-
process.exit(1);
|
|
86
|
+
try {
|
|
87
|
+
// Dashboard UI
|
|
88
|
+
if (pathname === '/' || pathname === '/dashboard') {
|
|
89
|
+
const html = await getDashboardHTML();
|
|
90
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
91
|
+
res.end(html);
|
|
92
|
+
return;
|
|
77
93
|
}
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
95
|
+
// Endpoint: /api/info
|
|
96
|
+
if (pathname === '/api/info') {
|
|
97
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
98
|
+
res.end(JSON.stringify({
|
|
99
|
+
name: 'Ultra-Dex Active Kernel',
|
|
100
|
+
version: '2.4.1',
|
|
101
|
+
status: 'online',
|
|
102
|
+
endpoints: ['/api/state', '/api/plan', '/api/context', '/api/graph', '/api/swarm']
|
|
103
|
+
}, null, 2));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
91
106
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
readFileSafe('CONTEXT.md', 'CONTEXT.md'),
|
|
100
|
-
readFileSafe('IMPLEMENTATION-PLAN.md', 'IMPLEMENTATION-PLAN.md'),
|
|
101
|
-
readFileSafe('QUICK-START.md', 'QUICK-START.md'),
|
|
102
|
-
]);
|
|
103
|
-
|
|
104
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
105
|
-
res.end(JSON.stringify({ meta, files: [context, plan, quickStart] }));
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
107
|
+
// Endpoint: /api/graph
|
|
108
|
+
if (pathname === '/api/graph' || pathname === '/graph') {
|
|
109
|
+
const summary = projectGraph.getSummary();
|
|
110
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
111
|
+
res.end(JSON.stringify(summary, null, 2));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
108
114
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
115
|
+
// Endpoint: /api/state
|
|
116
|
+
if (pathname === '/api/state' || pathname === '/state') {
|
|
117
|
+
const state = await loadState();
|
|
118
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
119
|
+
res.end(JSON.stringify(state, null, 2));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
117
122
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
// Endpoint: /api/swarm (Execute Swarm)
|
|
124
|
+
if ((pathname === '/api/swarm' || pathname === '/swarm') && req.method === 'POST') {
|
|
125
|
+
let body = '';
|
|
126
|
+
req.on('data', chunk => body += chunk);
|
|
127
|
+
req.on('end', async () => {
|
|
128
|
+
try {
|
|
129
|
+
const { task, feature, parallel } = JSON.parse(body);
|
|
130
|
+
const objective = task || feature;
|
|
131
|
+
if (!objective) throw new Error('Task/Feature objective is required');
|
|
132
|
+
|
|
133
|
+
// Run swarm
|
|
134
|
+
swarmCommand(objective, { parallel, dryRun: false }).catch(err => console.error(err));
|
|
135
|
+
|
|
136
|
+
res.writeHead(202, { 'Content-Type': 'application/json' });
|
|
137
|
+
res.end(JSON.stringify({ status: 'accepted', message: 'Swarm started' }));
|
|
138
|
+
} catch (e) {
|
|
139
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
140
|
+
res.end(JSON.stringify({ error: e.message }));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
125
145
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
146
|
+
// Endpoint: /api/plan
|
|
147
|
+
if (pathname === '/api/plan' || pathname === '/plan') {
|
|
148
|
+
const state = await loadState();
|
|
149
|
+
const markdown = generateMarkdown(state);
|
|
150
|
+
res.writeHead(200, { 'Content-Type': 'text/markdown' });
|
|
151
|
+
res.end(markdown);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
132
154
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
143
|
-
res.end(JSON.stringify({ error: `Agent ${agentName} not found` }));
|
|
144
|
-
}
|
|
155
|
+
// SSE Events for Dashboard
|
|
156
|
+
if (pathname === '/events') {
|
|
157
|
+
res.writeHead(200, {
|
|
158
|
+
'Content-Type': 'text/event-stream',
|
|
159
|
+
'Cache-Control': 'no-cache',
|
|
160
|
+
'Connection': 'keep-alive'
|
|
161
|
+
});
|
|
162
|
+
res.write(`data: ${JSON.stringify({ type: 'log', message: 'Connected to Active Kernel' })}\n\n`);
|
|
163
|
+
// We'd need to manage clients here if we wanted to push updates
|
|
145
164
|
return;
|
|
146
|
-
|
|
165
|
+
}
|
|
147
166
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const state = await computeState();
|
|
151
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
152
|
-
res.end(JSON.stringify({ refreshed: true, score: state.score }));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
167
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
168
|
+
res.end(JSON.stringify({ error: 'Not found' }));
|
|
155
169
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
} catch (error) {
|
|
171
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
172
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const wss = new UltraDexSocket(server);
|
|
177
|
+
|
|
178
|
+
server.listen(port, () => {
|
|
179
|
+
console.log(chalk.green(`ā
Unified Kernel active at http://localhost:${port}`));
|
|
180
|
+
console.log(chalk.gray(` ⢠Dashboard: http://localhost:${port}/`));
|
|
181
|
+
console.log(chalk.gray(` ⢠MCP API: http://localhost:${port}/api/info`));
|
|
182
|
+
|
|
183
|
+
console.log(chalk.bold.magenta('\nš AI Tool Integration:'));
|
|
184
|
+
console.log(chalk.white(' Cursor IDE: '));
|
|
185
|
+
console.log(chalk.cyan(` URL: http://localhost:${port}/api/info`));
|
|
186
|
+
console.log(chalk.white(' Claude Desktop:'));
|
|
187
|
+
console.log(chalk.cyan(` Run "ultra-dex config --mcp" to register.`));
|
|
188
|
+
|
|
189
|
+
// Auto-Pilot
|
|
190
|
+
fs.watch(process.cwd(), { recursive: true }, async (eventType, filename) => {
|
|
191
|
+
if (!filename || filename.includes('node_modules') || filename.includes('.git') || filename.includes('IMPLEMENTATION-PLAN.md')) return;
|
|
192
|
+
|
|
193
|
+
console.log(chalk.gray(`\nš Change in ${filename}. Synchronizing...`));
|
|
194
|
+
try {
|
|
195
|
+
const state = await loadState();
|
|
196
|
+
if (state) {
|
|
197
|
+
const markdown = generateMarkdown(state);
|
|
198
|
+
await fs.writeFile(path.resolve(process.cwd(), 'IMPLEMENTATION-PLAN.md'), markdown);
|
|
199
|
+
wss.sendStateUpdate(state);
|
|
200
|
+
}
|
|
201
|
+
} catch (e) {}
|
|
172
202
|
});
|
|
173
|
-
}
|
|
203
|
+
});
|
|
204
|
+
}
|