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
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ultra-Dex Agent Tier System v3.0
|
|
3
|
+
* Defines the hierarchical structure of agents and their dependencies.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// TIER DEFINITIONS
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Tier structure for all 16 agents.
|
|
12
|
+
* Lower tier numbers indicate higher-level strategic roles.
|
|
13
|
+
*/
|
|
14
|
+
export const TIERS = {
|
|
15
|
+
META: {
|
|
16
|
+
id: 0,
|
|
17
|
+
name: 'Meta Orchestration',
|
|
18
|
+
description: 'Coordinates all other agents',
|
|
19
|
+
agents: ['orchestrator']
|
|
20
|
+
},
|
|
21
|
+
LEADERSHIP: {
|
|
22
|
+
id: 1,
|
|
23
|
+
name: 'Leadership',
|
|
24
|
+
description: 'Strategic planning and technology decisions',
|
|
25
|
+
agents: ['cto', 'planner', 'research']
|
|
26
|
+
},
|
|
27
|
+
DEVELOPMENT: {
|
|
28
|
+
id: 2,
|
|
29
|
+
name: 'Development',
|
|
30
|
+
description: 'Core implementation of features',
|
|
31
|
+
agents: ['backend', 'frontend', 'database']
|
|
32
|
+
},
|
|
33
|
+
SECURITY: {
|
|
34
|
+
id: 3,
|
|
35
|
+
name: 'Security',
|
|
36
|
+
description: 'Authentication, authorization, and security audits',
|
|
37
|
+
agents: ['auth', 'security']
|
|
38
|
+
},
|
|
39
|
+
DEVOPS: {
|
|
40
|
+
id: 4,
|
|
41
|
+
name: 'DevOps',
|
|
42
|
+
description: 'Deployment and infrastructure management',
|
|
43
|
+
agents: ['devops']
|
|
44
|
+
},
|
|
45
|
+
QUALITY: {
|
|
46
|
+
id: 5,
|
|
47
|
+
name: 'Quality',
|
|
48
|
+
description: 'Testing, debugging, and code review',
|
|
49
|
+
agents: ['testing', 'reviewer', 'debugger', 'documentation']
|
|
50
|
+
},
|
|
51
|
+
SPECIALIST: {
|
|
52
|
+
id: 6,
|
|
53
|
+
name: 'Specialist',
|
|
54
|
+
description: 'Advanced optimization and code improvement',
|
|
55
|
+
agents: ['performance', 'refactoring']
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// AGENT REGISTRY
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Complete agent registry with metadata.
|
|
65
|
+
*/
|
|
66
|
+
export const AGENTS = {
|
|
67
|
+
// Tier 0: Meta
|
|
68
|
+
orchestrator: {
|
|
69
|
+
name: 'Orchestrator',
|
|
70
|
+
tier: 0,
|
|
71
|
+
tierName: 'Meta Orchestration',
|
|
72
|
+
role: 'Coordinate all agents for complete features',
|
|
73
|
+
invocation: '@orchestrator',
|
|
74
|
+
file: '0-orchestration/orchestrator.md',
|
|
75
|
+
capabilities: ['task_decomposition', 'agent_selection', 'pipeline_execution', 'result_synthesis'],
|
|
76
|
+
canInvoke: ['all']
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
// Tier 1: Leadership
|
|
80
|
+
cto: {
|
|
81
|
+
name: 'CTO',
|
|
82
|
+
tier: 1,
|
|
83
|
+
tierName: 'Leadership',
|
|
84
|
+
role: 'Architecture & tech stack decisions',
|
|
85
|
+
invocation: '@cto',
|
|
86
|
+
file: '1-leadership/cto.md',
|
|
87
|
+
capabilities: ['architecture_design', 'tech_selection', 'system_design'],
|
|
88
|
+
canInvoke: ['research']
|
|
89
|
+
},
|
|
90
|
+
planner: {
|
|
91
|
+
name: 'Planner',
|
|
92
|
+
tier: 1,
|
|
93
|
+
tierName: 'Leadership',
|
|
94
|
+
role: 'Task breakdown & sprint planning',
|
|
95
|
+
invocation: '@planner',
|
|
96
|
+
file: '1-leadership/planner.md',
|
|
97
|
+
capabilities: ['task_breakdown', 'estimation', 'prioritization'],
|
|
98
|
+
canInvoke: []
|
|
99
|
+
},
|
|
100
|
+
research: {
|
|
101
|
+
name: 'Research',
|
|
102
|
+
tier: 1,
|
|
103
|
+
tierName: 'Leadership',
|
|
104
|
+
role: 'Technology evaluation & comparison',
|
|
105
|
+
invocation: '@research',
|
|
106
|
+
file: '1-leadership/research.md',
|
|
107
|
+
capabilities: ['technology_evaluation', 'comparison', 'recommendations'],
|
|
108
|
+
canInvoke: []
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Tier 2: Development
|
|
112
|
+
backend: {
|
|
113
|
+
name: 'Backend',
|
|
114
|
+
tier: 2,
|
|
115
|
+
tierName: 'Development',
|
|
116
|
+
role: 'API & server implementation',
|
|
117
|
+
invocation: '@backend',
|
|
118
|
+
file: '2-development/backend.md',
|
|
119
|
+
capabilities: ['api_development', 'business_logic', 'integrations'],
|
|
120
|
+
canInvoke: ['database']
|
|
121
|
+
},
|
|
122
|
+
frontend: {
|
|
123
|
+
name: 'Frontend',
|
|
124
|
+
tier: 2,
|
|
125
|
+
tierName: 'Development',
|
|
126
|
+
role: 'UI & component implementation',
|
|
127
|
+
invocation: '@frontend',
|
|
128
|
+
file: '2-development/frontend.md',
|
|
129
|
+
capabilities: ['ui_development', 'components', 'state_management'],
|
|
130
|
+
canInvoke: []
|
|
131
|
+
},
|
|
132
|
+
database: {
|
|
133
|
+
name: 'Database',
|
|
134
|
+
tier: 2,
|
|
135
|
+
tierName: 'Development',
|
|
136
|
+
role: 'Schema design & query optimization',
|
|
137
|
+
invocation: '@database',
|
|
138
|
+
file: '2-development/database.md',
|
|
139
|
+
capabilities: ['schema_design', 'migrations', 'query_optimization'],
|
|
140
|
+
canInvoke: []
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
// Tier 3: Security
|
|
144
|
+
auth: {
|
|
145
|
+
name: 'Auth',
|
|
146
|
+
tier: 3,
|
|
147
|
+
tierName: 'Security',
|
|
148
|
+
role: 'Authentication & authorization',
|
|
149
|
+
invocation: '@auth',
|
|
150
|
+
file: '3-security/auth.md',
|
|
151
|
+
capabilities: ['authentication', 'authorization', 'session_management'],
|
|
152
|
+
canInvoke: ['backend', 'database']
|
|
153
|
+
},
|
|
154
|
+
security: {
|
|
155
|
+
name: 'Security',
|
|
156
|
+
tier: 3,
|
|
157
|
+
tierName: 'Security',
|
|
158
|
+
role: 'Security audits & vulnerability fixes',
|
|
159
|
+
invocation: '@security',
|
|
160
|
+
file: '3-security/security.md',
|
|
161
|
+
capabilities: ['security_audit', 'vulnerability_detection', 'hardening'],
|
|
162
|
+
canInvoke: []
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
// Tier 4: DevOps
|
|
166
|
+
devops: {
|
|
167
|
+
name: 'DevOps',
|
|
168
|
+
tier: 4,
|
|
169
|
+
tierName: 'DevOps',
|
|
170
|
+
role: 'Deployment & infrastructure',
|
|
171
|
+
invocation: '@devops',
|
|
172
|
+
file: '4-devops/devops.md',
|
|
173
|
+
capabilities: ['deployment', 'ci_cd', 'infrastructure', 'monitoring'],
|
|
174
|
+
canInvoke: []
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
// Tier 5: Quality
|
|
178
|
+
testing: {
|
|
179
|
+
name: 'Testing',
|
|
180
|
+
tier: 5,
|
|
181
|
+
tierName: 'Quality',
|
|
182
|
+
role: 'QA & test automation',
|
|
183
|
+
invocation: '@testing',
|
|
184
|
+
file: '5-quality/testing.md',
|
|
185
|
+
capabilities: ['unit_testing', 'integration_testing', 'e2e_testing'],
|
|
186
|
+
canInvoke: []
|
|
187
|
+
},
|
|
188
|
+
reviewer: {
|
|
189
|
+
name: 'Reviewer',
|
|
190
|
+
tier: 5,
|
|
191
|
+
tierName: 'Quality',
|
|
192
|
+
role: 'Code review & quality checks',
|
|
193
|
+
invocation: '@reviewer',
|
|
194
|
+
file: '5-quality/reviewer.md',
|
|
195
|
+
capabilities: ['code_review', 'best_practices', 'quality_gates'],
|
|
196
|
+
canInvoke: []
|
|
197
|
+
},
|
|
198
|
+
debugger: {
|
|
199
|
+
name: 'Debugger',
|
|
200
|
+
tier: 5,
|
|
201
|
+
tierName: 'Quality',
|
|
202
|
+
role: 'Bug investigation & fixes',
|
|
203
|
+
invocation: '@debugger',
|
|
204
|
+
file: '5-quality/debugger.md',
|
|
205
|
+
capabilities: ['debugging', 'root_cause_analysis', 'bug_fixing'],
|
|
206
|
+
canInvoke: ['backend', 'frontend', 'database']
|
|
207
|
+
},
|
|
208
|
+
documentation: {
|
|
209
|
+
name: 'Documentation',
|
|
210
|
+
tier: 5,
|
|
211
|
+
tierName: 'Quality',
|
|
212
|
+
role: 'Technical writing & docs maintenance',
|
|
213
|
+
invocation: '@documentation',
|
|
214
|
+
file: '5-quality/documentation.md',
|
|
215
|
+
capabilities: ['technical_writing', 'api_docs', 'user_guides'],
|
|
216
|
+
canInvoke: []
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
// Tier 6: Specialist
|
|
220
|
+
performance: {
|
|
221
|
+
name: 'Performance',
|
|
222
|
+
tier: 6,
|
|
223
|
+
tierName: 'Specialist',
|
|
224
|
+
role: 'Performance optimization',
|
|
225
|
+
invocation: '@performance',
|
|
226
|
+
file: '6-specialist/performance.md',
|
|
227
|
+
capabilities: ['profiling', 'optimization', 'caching', 'load_testing'],
|
|
228
|
+
canInvoke: ['backend', 'frontend', 'database']
|
|
229
|
+
},
|
|
230
|
+
refactoring: {
|
|
231
|
+
name: 'Refactoring',
|
|
232
|
+
tier: 6,
|
|
233
|
+
tierName: 'Specialist',
|
|
234
|
+
role: 'Code quality & design patterns',
|
|
235
|
+
invocation: '@refactoring',
|
|
236
|
+
file: '6-specialist/refactoring.md',
|
|
237
|
+
capabilities: ['code_cleanup', 'design_patterns', 'architecture_improvement'],
|
|
238
|
+
canInvoke: ['backend', 'frontend']
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// ============================================================================
|
|
243
|
+
// TIER DEPENDENCY GRAPH
|
|
244
|
+
// ============================================================================
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Defines standard execution flow between tiers.
|
|
248
|
+
* This represents the typical order of operations for a full feature.
|
|
249
|
+
*/
|
|
250
|
+
export const TIER_FLOW = {
|
|
251
|
+
standard: [
|
|
252
|
+
{ tier: 1, phase: 'Planning', required: true },
|
|
253
|
+
{ tier: 2, phase: 'Implementation', required: true },
|
|
254
|
+
{ tier: 3, phase: 'Security', required: false },
|
|
255
|
+
{ tier: 5, phase: 'Quality', required: true },
|
|
256
|
+
{ tier: 4, phase: 'Deployment', required: false },
|
|
257
|
+
{ tier: 6, phase: 'Optimization', required: false }
|
|
258
|
+
],
|
|
259
|
+
hotfix: [
|
|
260
|
+
{ tier: 5, phase: 'Debug', agents: ['debugger'], required: true },
|
|
261
|
+
{ tier: 5, phase: 'Test', agents: ['testing'], required: true },
|
|
262
|
+
{ tier: 4, phase: 'Deploy', agents: ['devops'], required: true }
|
|
263
|
+
],
|
|
264
|
+
optimization: [
|
|
265
|
+
{ tier: 6, phase: 'Optimize', required: true },
|
|
266
|
+
{ tier: 5, phase: 'Test', agents: ['testing'], required: true },
|
|
267
|
+
{ tier: 5, phase: 'Review', agents: ['reviewer'], required: true }
|
|
268
|
+
]
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Agent dependency graph - which agents depend on outputs from others.
|
|
273
|
+
*/
|
|
274
|
+
export const AGENT_DEPENDENCIES = {
|
|
275
|
+
// Leadership tier has no dependencies (entry points)
|
|
276
|
+
planner: [],
|
|
277
|
+
cto: ['planner'],
|
|
278
|
+
research: ['planner'],
|
|
279
|
+
|
|
280
|
+
// Development depends on leadership decisions
|
|
281
|
+
database: ['cto'],
|
|
282
|
+
backend: ['cto', 'database'],
|
|
283
|
+
frontend: ['cto', 'backend'],
|
|
284
|
+
|
|
285
|
+
// Security depends on implementation
|
|
286
|
+
auth: ['backend', 'database'],
|
|
287
|
+
security: ['backend', 'frontend', 'auth'],
|
|
288
|
+
|
|
289
|
+
// Quality depends on implementation
|
|
290
|
+
testing: ['backend', 'frontend'],
|
|
291
|
+
reviewer: ['backend', 'frontend', 'testing'],
|
|
292
|
+
debugger: [], // Can be invoked anytime
|
|
293
|
+
documentation: ['backend', 'frontend'],
|
|
294
|
+
|
|
295
|
+
// DevOps depends on quality approval
|
|
296
|
+
devops: ['testing', 'reviewer'],
|
|
297
|
+
|
|
298
|
+
// Specialist can run after implementation
|
|
299
|
+
performance: ['backend', 'frontend'],
|
|
300
|
+
refactoring: ['backend', 'frontend']
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
// ============================================================================
|
|
304
|
+
// UTILITY FUNCTIONS
|
|
305
|
+
// ============================================================================
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Get agent by name.
|
|
309
|
+
*/
|
|
310
|
+
export function getAgent(name) {
|
|
311
|
+
const normalized = name.toLowerCase().replace('@', '');
|
|
312
|
+
return AGENTS[normalized] || null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Get all agents in a tier.
|
|
317
|
+
*/
|
|
318
|
+
export function getAgentsByTier(tierId) {
|
|
319
|
+
return Object.values(AGENTS).filter(agent => agent.tier === tierId);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get tier by ID.
|
|
324
|
+
*/
|
|
325
|
+
export function getTier(tierId) {
|
|
326
|
+
return Object.values(TIERS).find(tier => tier.id === tierId) || null;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Get tier by agent name.
|
|
331
|
+
*/
|
|
332
|
+
export function getTierForAgent(agentName) {
|
|
333
|
+
const agent = getAgent(agentName);
|
|
334
|
+
return agent ? getTier(agent.tier) : null;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Get dependencies for an agent.
|
|
339
|
+
*/
|
|
340
|
+
export function getAgentDependencies(agentName) {
|
|
341
|
+
const normalized = agentName.toLowerCase().replace('@', '');
|
|
342
|
+
return AGENT_DEPENDENCIES[normalized] || [];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Check if agent A can invoke agent B.
|
|
347
|
+
*/
|
|
348
|
+
export function canInvoke(agentA, agentB) {
|
|
349
|
+
const a = getAgent(agentA);
|
|
350
|
+
if (!a) return false;
|
|
351
|
+
if (a.canInvoke.includes('all')) return true;
|
|
352
|
+
return a.canInvoke.includes(agentB.toLowerCase().replace('@', ''));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Get execution order for a set of agents based on dependencies.
|
|
357
|
+
*/
|
|
358
|
+
export function getExecutionOrder(agentNames) {
|
|
359
|
+
const normalized = agentNames.map(n => n.toLowerCase().replace('@', ''));
|
|
360
|
+
const visited = new Set();
|
|
361
|
+
const order = [];
|
|
362
|
+
|
|
363
|
+
function visit(agent) {
|
|
364
|
+
if (visited.has(agent)) return;
|
|
365
|
+
visited.add(agent);
|
|
366
|
+
|
|
367
|
+
const deps = AGENT_DEPENDENCIES[agent] || [];
|
|
368
|
+
for (const dep of deps) {
|
|
369
|
+
if (normalized.includes(dep)) {
|
|
370
|
+
visit(dep);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
order.push(agent);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
for (const agent of normalized) {
|
|
377
|
+
visit(agent);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return order;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Identify parallel execution opportunities.
|
|
385
|
+
*/
|
|
386
|
+
export function findParallelGroups(agentNames) {
|
|
387
|
+
const order = getExecutionOrder(agentNames);
|
|
388
|
+
const groups = [];
|
|
389
|
+
const scheduled = new Set();
|
|
390
|
+
|
|
391
|
+
while (scheduled.size < order.length) {
|
|
392
|
+
const group = [];
|
|
393
|
+
|
|
394
|
+
for (const agent of order) {
|
|
395
|
+
if (scheduled.has(agent)) continue;
|
|
396
|
+
|
|
397
|
+
const deps = AGENT_DEPENDENCIES[agent] || [];
|
|
398
|
+
const depsInList = deps.filter(d => order.includes(d));
|
|
399
|
+
const depsMet = depsInList.every(d => scheduled.has(d));
|
|
400
|
+
|
|
401
|
+
if (depsMet) {
|
|
402
|
+
group.push(agent);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (group.length === 0) break; // Prevent infinite loop
|
|
407
|
+
|
|
408
|
+
for (const agent of group) {
|
|
409
|
+
scheduled.add(agent);
|
|
410
|
+
}
|
|
411
|
+
groups.push(group);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return groups;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Generate a tier summary for display.
|
|
419
|
+
*/
|
|
420
|
+
export function getTierSummary() {
|
|
421
|
+
return Object.values(TIERS).map(tier => ({
|
|
422
|
+
id: tier.id,
|
|
423
|
+
name: tier.name,
|
|
424
|
+
description: tier.description,
|
|
425
|
+
agentCount: tier.agents.length,
|
|
426
|
+
agents: tier.agents.map(a => AGENTS[a]?.name || a)
|
|
427
|
+
}));
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Validate a pipeline for dependency violations.
|
|
432
|
+
*/
|
|
433
|
+
export function validatePipeline(pipeline) {
|
|
434
|
+
const errors = [];
|
|
435
|
+
const completed = new Set();
|
|
436
|
+
|
|
437
|
+
for (let i = 0; i < pipeline.length; i++) {
|
|
438
|
+
const step = pipeline[i];
|
|
439
|
+
const agent = step.agent?.toLowerCase().replace('@', '');
|
|
440
|
+
const deps = AGENT_DEPENDENCIES[agent] || [];
|
|
441
|
+
|
|
442
|
+
for (const dep of deps) {
|
|
443
|
+
// Check if dependency is in pipeline and comes before
|
|
444
|
+
const depIndex = pipeline.findIndex(s =>
|
|
445
|
+
s.agent?.toLowerCase().replace('@', '') === dep
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
if (depIndex > i) {
|
|
449
|
+
errors.push({
|
|
450
|
+
step: i + 1,
|
|
451
|
+
agent,
|
|
452
|
+
error: `Depends on ${dep} which is scheduled after (step ${depIndex + 1})`
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
completed.add(agent);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return {
|
|
461
|
+
valid: errors.length === 0,
|
|
462
|
+
errors
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// ============================================================================
|
|
467
|
+
// EXPORTS
|
|
468
|
+
// ============================================================================
|
|
469
|
+
|
|
470
|
+
export default {
|
|
471
|
+
TIERS,
|
|
472
|
+
AGENTS,
|
|
473
|
+
TIER_FLOW,
|
|
474
|
+
AGENT_DEPENDENCIES,
|
|
475
|
+
getAgent,
|
|
476
|
+
getAgentsByTier,
|
|
477
|
+
getTier,
|
|
478
|
+
getTierForAgent,
|
|
479
|
+
getAgentDependencies,
|
|
480
|
+
canInvoke,
|
|
481
|
+
getExecutionOrder,
|
|
482
|
+
findParallelGroups,
|
|
483
|
+
getTierSummary,
|
|
484
|
+
validatePipeline
|
|
485
|
+
};
|
package/lib/utils/files.js
CHANGED
|
@@ -24,3 +24,17 @@ export async function pathExists(targetPath, type = 'file') {
|
|
|
24
24
|
export function resolveAssetPath(basePath, relativePath) {
|
|
25
25
|
return path.join(basePath, relativePath);
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
export async function copyDirectory(sourceDir, targetDir) {
|
|
29
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
30
|
+
const entries = await fs.readdir(sourceDir, { withFileTypes: true });
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
33
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
34
|
+
if (entry.isDirectory()) {
|
|
35
|
+
await copyDirectory(sourcePath, targetPath);
|
|
36
|
+
} else if (entry.isFile()) {
|
|
37
|
+
await fs.copyFile(sourcePath, targetPath);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Utility (CPG Implementation)
|
|
3
|
+
* Manages the Code Property Graph (CPG) for architectural memory
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from 'fs/promises';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { glob } from 'glob';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build a simple Code Property Graph (CPG)
|
|
12
|
+
* Maps files, functions, and dependencies
|
|
13
|
+
*/
|
|
14
|
+
export async function buildGraph() {
|
|
15
|
+
const files = await glob('**/*.{js,ts,jsx,tsx}', {
|
|
16
|
+
ignore: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
|
|
17
|
+
nodir: true
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const graph = {
|
|
21
|
+
nodes: [],
|
|
22
|
+
edges: [],
|
|
23
|
+
lastUpdated: new Date().toISOString()
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
try {
|
|
28
|
+
const content = await fs.readFile(file, 'utf8');
|
|
29
|
+
const fileNode = {
|
|
30
|
+
id: file,
|
|
31
|
+
type: 'file',
|
|
32
|
+
path: file,
|
|
33
|
+
exports: [],
|
|
34
|
+
imports: []
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Naive parsing using Regex (Phase 2.1)
|
|
38
|
+
// In Phase 2.2+ this would use tree-sitter
|
|
39
|
+
|
|
40
|
+
// Extract imports
|
|
41
|
+
const importRegex = /import\s+.*?\s+from\s+['"](.+?)['"]/g;
|
|
42
|
+
let match;
|
|
43
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
44
|
+
fileNode.imports.push(match[1]);
|
|
45
|
+
graph.edges.push({
|
|
46
|
+
source: file,
|
|
47
|
+
target: match[1],
|
|
48
|
+
type: 'depends_on'
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Extract function declarations
|
|
53
|
+
const funcRegex = /(?:export\s+)?(?:async\s+)?function\s+([a-zA-Z0-9_]+)/g;
|
|
54
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
55
|
+
const funcName = match[1];
|
|
56
|
+
const funcId = `${file}:${funcName}`;
|
|
57
|
+
graph.nodes.push({
|
|
58
|
+
id: funcId,
|
|
59
|
+
type: 'function',
|
|
60
|
+
name: funcName,
|
|
61
|
+
parent: file
|
|
62
|
+
});
|
|
63
|
+
graph.edges.push({
|
|
64
|
+
source: funcId,
|
|
65
|
+
target: file,
|
|
66
|
+
type: 'contained_in'
|
|
67
|
+
});
|
|
68
|
+
fileNode.exports.push(funcName);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
graph.nodes.push(fileNode);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
// Skip files that can't be read
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return graph;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Find the impact of changing a file
|
|
82
|
+
* @param {Object} graph - The CPG
|
|
83
|
+
* @param {string} filePath - The file being changed
|
|
84
|
+
*/
|
|
85
|
+
export function getImpactAnalysis(graph, filePath) {
|
|
86
|
+
const impactedBy = graph.edges
|
|
87
|
+
.filter(edge => edge.target === filePath || filePath.endsWith(edge.target))
|
|
88
|
+
.map(edge => edge.source);
|
|
89
|
+
|
|
90
|
+
return [...new Set(impactedBy)];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Find structural truth (exact subgraph)
|
|
95
|
+
* @param {Object} graph - The CPG
|
|
96
|
+
* @param {string} query - Symbol name
|
|
97
|
+
*/
|
|
98
|
+
export function queryGraph(graph, query) {
|
|
99
|
+
return graph.nodes.filter(node =>
|
|
100
|
+
node.id.includes(query) || (node.name && node.name === query)
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export default {
|
|
105
|
+
buildGraph,
|
|
106
|
+
getImpactAnalysis,
|
|
107
|
+
queryGraph
|
|
108
|
+
};
|
package/package.json
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra-dex",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "AI Orchestration Meta-Layer for SaaS Development",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"saas",
|
|
7
|
-
"template",
|
|
8
|
-
"implementation",
|
|
9
|
-
"planning",
|
|
10
|
-
"startup",
|
|
11
|
-
"framework",
|
|
12
6
|
"ai",
|
|
7
|
+
"orchestration",
|
|
8
|
+
"saas",
|
|
9
|
+
"mcp",
|
|
10
|
+
"langchain",
|
|
13
11
|
"claude",
|
|
14
12
|
"openai",
|
|
15
13
|
"gemini",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
14
|
+
"agents",
|
|
15
|
+
"swarm"
|
|
18
16
|
],
|
|
19
17
|
"author": "Srujan Sai Karna",
|
|
20
18
|
"license": "MIT",
|
|
@@ -36,15 +34,26 @@
|
|
|
36
34
|
"node": ">=18"
|
|
37
35
|
},
|
|
38
36
|
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
39
38
|
"chalk": "^5.3.0",
|
|
40
39
|
"commander": "^11.1.0",
|
|
40
|
+
"glob": "^10.5.0",
|
|
41
41
|
"inquirer": "^9.2.12",
|
|
42
|
-
"ora": "^8.0.1"
|
|
42
|
+
"ora": "^8.0.1",
|
|
43
|
+
"ws": "^8.19.0",
|
|
44
|
+
"zod": "^3.25.76"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"test": "node --test test/*.test.js",
|
|
48
|
+
"lint": "eslint lib bin --fix"
|
|
43
49
|
},
|
|
44
50
|
"optionalDependencies": {
|
|
45
51
|
"@anthropic-ai/sdk": "^0.30.0",
|
|
46
|
-
"openai": "^4.70.0",
|
|
47
52
|
"@google/generative-ai": "^0.21.0",
|
|
48
|
-
"dotenv": "^16.4.5"
|
|
53
|
+
"dotenv": "^16.4.5",
|
|
54
|
+
"openai": "^4.70.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"eslint": "^8.57.0"
|
|
49
58
|
}
|
|
50
59
|
}
|