claude-flow 1.0.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/LICENSE +21 -0
- package/README.md +612 -0
- package/bin/claude-flow +0 -0
- package/bin/claude-flow-simple +0 -0
- package/bin/claude-flow-typecheck +0 -0
- package/deno.json +84 -0
- package/package.json +45 -0
- package/scripts/check-links.ts +274 -0
- package/scripts/check-performance-regression.ts +168 -0
- package/scripts/claude-sparc.sh +562 -0
- package/scripts/coverage-report.ts +692 -0
- package/scripts/demo-task-system.ts +224 -0
- package/scripts/install.js +72 -0
- package/scripts/test-batch-tasks.ts +29 -0
- package/scripts/test-coordination-features.ts +238 -0
- package/scripts/test-mcp.ts +251 -0
- package/scripts/test-runner.ts +571 -0
- package/scripts/validate-examples.ts +288 -0
- package/src/cli/cli-core.ts +273 -0
- package/src/cli/commands/agent.ts +83 -0
- package/src/cli/commands/config.ts +442 -0
- package/src/cli/commands/help.ts +765 -0
- package/src/cli/commands/index.ts +963 -0
- package/src/cli/commands/mcp.ts +191 -0
- package/src/cli/commands/memory.ts +74 -0
- package/src/cli/commands/monitor.ts +403 -0
- package/src/cli/commands/session.ts +595 -0
- package/src/cli/commands/start.ts +156 -0
- package/src/cli/commands/status.ts +345 -0
- package/src/cli/commands/task.ts +79 -0
- package/src/cli/commands/workflow.ts +763 -0
- package/src/cli/completion.ts +553 -0
- package/src/cli/formatter.ts +310 -0
- package/src/cli/index.ts +211 -0
- package/src/cli/main.ts +23 -0
- package/src/cli/repl.ts +1050 -0
- package/src/cli/simple-cli.js +211 -0
- package/src/cli/simple-cli.ts +211 -0
- package/src/coordination/README.md +400 -0
- package/src/coordination/advanced-scheduler.ts +487 -0
- package/src/coordination/circuit-breaker.ts +366 -0
- package/src/coordination/conflict-resolution.ts +490 -0
- package/src/coordination/dependency-graph.ts +475 -0
- package/src/coordination/index.ts +63 -0
- package/src/coordination/manager.ts +460 -0
- package/src/coordination/messaging.ts +290 -0
- package/src/coordination/metrics.ts +585 -0
- package/src/coordination/resources.ts +322 -0
- package/src/coordination/scheduler.ts +390 -0
- package/src/coordination/work-stealing.ts +224 -0
- package/src/core/config.ts +627 -0
- package/src/core/event-bus.ts +186 -0
- package/src/core/json-persistence.ts +183 -0
- package/src/core/logger.ts +262 -0
- package/src/core/orchestrator-fixed.ts +312 -0
- package/src/core/orchestrator.ts +1234 -0
- package/src/core/persistence.ts +276 -0
- package/src/mcp/auth.ts +438 -0
- package/src/mcp/claude-flow-tools.ts +1280 -0
- package/src/mcp/load-balancer.ts +510 -0
- package/src/mcp/router.ts +240 -0
- package/src/mcp/server.ts +548 -0
- package/src/mcp/session-manager.ts +418 -0
- package/src/mcp/tools.ts +180 -0
- package/src/mcp/transports/base.ts +21 -0
- package/src/mcp/transports/http.ts +457 -0
- package/src/mcp/transports/stdio.ts +254 -0
- package/src/memory/backends/base.ts +22 -0
- package/src/memory/backends/markdown.ts +283 -0
- package/src/memory/backends/sqlite.ts +329 -0
- package/src/memory/cache.ts +238 -0
- package/src/memory/indexer.ts +238 -0
- package/src/memory/manager.ts +572 -0
- package/src/terminal/adapters/base.ts +29 -0
- package/src/terminal/adapters/native.ts +504 -0
- package/src/terminal/adapters/vscode.ts +340 -0
- package/src/terminal/manager.ts +308 -0
- package/src/terminal/pool.ts +271 -0
- package/src/terminal/session.ts +250 -0
- package/src/terminal/vscode-bridge.ts +242 -0
- package/src/utils/errors.ts +231 -0
- package/src/utils/helpers.ts +476 -0
- package/src/utils/types.ts +493 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency graph management for task scheduling
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Task } from '../utils/types.ts';
|
|
6
|
+
import { TaskDependencyError } from '../utils/errors.ts';
|
|
7
|
+
import { ILogger } from '../core/logger.ts';
|
|
8
|
+
|
|
9
|
+
export interface DependencyNode {
|
|
10
|
+
taskId: string;
|
|
11
|
+
dependencies: Set<string>;
|
|
12
|
+
dependents: Set<string>;
|
|
13
|
+
status: 'pending' | 'ready' | 'running' | 'completed' | 'failed';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface DependencyPath {
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
path: string[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Manages task dependencies and determines execution order
|
|
24
|
+
*/
|
|
25
|
+
export class DependencyGraph {
|
|
26
|
+
private nodes = new Map<string, DependencyNode>();
|
|
27
|
+
private completedTasks = new Set<string>();
|
|
28
|
+
|
|
29
|
+
constructor(private logger: ILogger) {}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Add a task to the dependency graph
|
|
33
|
+
*/
|
|
34
|
+
addTask(task: Task): void {
|
|
35
|
+
if (this.nodes.has(task.id)) {
|
|
36
|
+
this.logger.warn('Task already exists in dependency graph', { taskId: task.id });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const node: DependencyNode = {
|
|
41
|
+
taskId: task.id,
|
|
42
|
+
dependencies: new Set(task.dependencies),
|
|
43
|
+
dependents: new Set(),
|
|
44
|
+
status: 'pending',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Validate dependencies exist
|
|
48
|
+
for (const depId of task.dependencies) {
|
|
49
|
+
if (!this.nodes.has(depId) && !this.completedTasks.has(depId)) {
|
|
50
|
+
throw new TaskDependencyError(task.id, [depId]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Add node
|
|
55
|
+
this.nodes.set(task.id, node);
|
|
56
|
+
|
|
57
|
+
// Update dependents for dependencies
|
|
58
|
+
for (const depId of task.dependencies) {
|
|
59
|
+
const depNode = this.nodes.get(depId);
|
|
60
|
+
if (depNode) {
|
|
61
|
+
depNode.dependents.add(task.id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Check if task is ready
|
|
66
|
+
if (this.isTaskReady(task.id)) {
|
|
67
|
+
node.status = 'ready';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Remove a task from the dependency graph
|
|
73
|
+
*/
|
|
74
|
+
removeTask(taskId: string): void {
|
|
75
|
+
const node = this.nodes.get(taskId);
|
|
76
|
+
if (!node) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Remove from dependents of dependencies
|
|
81
|
+
for (const depId of node.dependencies) {
|
|
82
|
+
const depNode = this.nodes.get(depId);
|
|
83
|
+
if (depNode) {
|
|
84
|
+
depNode.dependents.delete(taskId);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Remove from dependencies of dependents
|
|
89
|
+
for (const depId of node.dependents) {
|
|
90
|
+
const depNode = this.nodes.get(depId);
|
|
91
|
+
if (depNode) {
|
|
92
|
+
depNode.dependencies.delete(taskId);
|
|
93
|
+
// Check if dependent is now ready
|
|
94
|
+
if (this.isTaskReady(depId)) {
|
|
95
|
+
depNode.status = 'ready';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.nodes.delete(taskId);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Mark a task as completed
|
|
105
|
+
*/
|
|
106
|
+
markCompleted(taskId: string): string[] {
|
|
107
|
+
const node = this.nodes.get(taskId);
|
|
108
|
+
if (!node) {
|
|
109
|
+
this.logger.warn('Task not found in dependency graph', { taskId });
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
node.status = 'completed';
|
|
114
|
+
this.completedTasks.add(taskId);
|
|
115
|
+
|
|
116
|
+
// Find newly ready tasks
|
|
117
|
+
const readyTasks: string[] = [];
|
|
118
|
+
|
|
119
|
+
for (const dependentId of node.dependents) {
|
|
120
|
+
const dependent = this.nodes.get(dependentId);
|
|
121
|
+
if (dependent && dependent.status === 'pending' && this.isTaskReady(dependentId)) {
|
|
122
|
+
dependent.status = 'ready';
|
|
123
|
+
readyTasks.push(dependentId);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Remove from active graph
|
|
128
|
+
this.removeTask(taskId);
|
|
129
|
+
|
|
130
|
+
return readyTasks;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Mark a task as failed
|
|
135
|
+
*/
|
|
136
|
+
markFailed(taskId: string): string[] {
|
|
137
|
+
const node = this.nodes.get(taskId);
|
|
138
|
+
if (!node) {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
node.status = 'failed';
|
|
143
|
+
|
|
144
|
+
// Get all dependent tasks that need to be cancelled
|
|
145
|
+
const toCancelIds = this.getAllDependents(taskId);
|
|
146
|
+
|
|
147
|
+
// Mark all dependents as failed
|
|
148
|
+
for (const depId of toCancelIds) {
|
|
149
|
+
const depNode = this.nodes.get(depId);
|
|
150
|
+
if (depNode) {
|
|
151
|
+
depNode.status = 'failed';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return toCancelIds;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if a task is ready to run
|
|
160
|
+
*/
|
|
161
|
+
isTaskReady(taskId: string): boolean {
|
|
162
|
+
const node = this.nodes.get(taskId);
|
|
163
|
+
if (!node) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// All dependencies must be completed
|
|
168
|
+
for (const depId of node.dependencies) {
|
|
169
|
+
if (!this.completedTasks.has(depId)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get all ready tasks
|
|
179
|
+
*/
|
|
180
|
+
getReadyTasks(): string[] {
|
|
181
|
+
const ready: string[] = [];
|
|
182
|
+
|
|
183
|
+
for (const [taskId, node] of this.nodes) {
|
|
184
|
+
if (node.status === 'ready' || (node.status === 'pending' && this.isTaskReady(taskId))) {
|
|
185
|
+
ready.push(taskId);
|
|
186
|
+
node.status = 'ready';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return ready;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get all dependents of a task (recursive)
|
|
195
|
+
*/
|
|
196
|
+
getAllDependents(taskId: string): string[] {
|
|
197
|
+
const visited = new Set<string>();
|
|
198
|
+
const dependents: string[] = [];
|
|
199
|
+
|
|
200
|
+
const visit = (id: string) => {
|
|
201
|
+
if (visited.has(id)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
visited.add(id);
|
|
205
|
+
|
|
206
|
+
const node = this.nodes.get(id);
|
|
207
|
+
if (!node) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const depId of node.dependents) {
|
|
212
|
+
if (!visited.has(depId)) {
|
|
213
|
+
dependents.push(depId);
|
|
214
|
+
visit(depId);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
visit(taskId);
|
|
220
|
+
return dependents;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Detect circular dependencies
|
|
225
|
+
*/
|
|
226
|
+
detectCycles(): string[][] {
|
|
227
|
+
const cycles: string[][] = [];
|
|
228
|
+
const visited = new Set<string>();
|
|
229
|
+
const recursionStack = new Set<string>();
|
|
230
|
+
const currentPath: string[] = [];
|
|
231
|
+
|
|
232
|
+
const hasCycle = (taskId: string): boolean => {
|
|
233
|
+
visited.add(taskId);
|
|
234
|
+
recursionStack.add(taskId);
|
|
235
|
+
currentPath.push(taskId);
|
|
236
|
+
|
|
237
|
+
const node = this.nodes.get(taskId);
|
|
238
|
+
if (!node) {
|
|
239
|
+
currentPath.pop();
|
|
240
|
+
recursionStack.delete(taskId);
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
for (const depId of node.dependencies) {
|
|
245
|
+
if (!visited.has(depId)) {
|
|
246
|
+
if (hasCycle(depId)) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
} else if (recursionStack.has(depId)) {
|
|
250
|
+
// Found cycle
|
|
251
|
+
const cycleStart = currentPath.indexOf(depId);
|
|
252
|
+
const cycle = currentPath.slice(cycleStart);
|
|
253
|
+
cycle.push(depId); // Complete the cycle
|
|
254
|
+
cycles.push(cycle);
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
currentPath.pop();
|
|
260
|
+
recursionStack.delete(taskId);
|
|
261
|
+
return false;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// Check all nodes
|
|
265
|
+
for (const taskId of this.nodes.keys()) {
|
|
266
|
+
if (!visited.has(taskId)) {
|
|
267
|
+
hasCycle(taskId);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return cycles;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Get topological sort of tasks
|
|
276
|
+
*/
|
|
277
|
+
topologicalSort(): string[] | null {
|
|
278
|
+
// Check for cycles first
|
|
279
|
+
const cycles = this.detectCycles();
|
|
280
|
+
if (cycles.length > 0) {
|
|
281
|
+
this.logger.error('Cannot perform topological sort due to cycles', { cycles });
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const sorted: string[] = [];
|
|
286
|
+
const visited = new Set<string>();
|
|
287
|
+
|
|
288
|
+
const visit = (taskId: string) => {
|
|
289
|
+
if (visited.has(taskId)) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
visited.add(taskId);
|
|
293
|
+
|
|
294
|
+
const node = this.nodes.get(taskId);
|
|
295
|
+
if (!node) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Visit dependencies first
|
|
300
|
+
for (const depId of node.dependencies) {
|
|
301
|
+
if (!visited.has(depId)) {
|
|
302
|
+
visit(depId);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
sorted.push(taskId);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// Visit all nodes
|
|
310
|
+
for (const taskId of this.nodes.keys()) {
|
|
311
|
+
if (!visited.has(taskId)) {
|
|
312
|
+
visit(taskId);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return sorted;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Find critical path (longest path through the graph)
|
|
321
|
+
*/
|
|
322
|
+
findCriticalPath(): DependencyPath | null {
|
|
323
|
+
const paths: DependencyPath[] = [];
|
|
324
|
+
|
|
325
|
+
// Find all paths from tasks with no dependencies to tasks with no dependents
|
|
326
|
+
const sources = Array.from(this.nodes.entries())
|
|
327
|
+
.filter(([_, node]) => node.dependencies.size === 0)
|
|
328
|
+
.map(([id]) => id);
|
|
329
|
+
|
|
330
|
+
const sinks = Array.from(this.nodes.entries())
|
|
331
|
+
.filter(([_, node]) => node.dependents.size === 0)
|
|
332
|
+
.map(([id]) => id);
|
|
333
|
+
|
|
334
|
+
for (const source of sources) {
|
|
335
|
+
for (const sink of sinks) {
|
|
336
|
+
const path = this.findPath(source, sink);
|
|
337
|
+
if (path) {
|
|
338
|
+
paths.push({ from: source, to: sink, path });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Return longest path
|
|
344
|
+
if (paths.length === 0) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return paths.reduce((longest, current) =>
|
|
349
|
+
current.path.length > longest.path.length ? current : longest
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Find path between two tasks
|
|
355
|
+
*/
|
|
356
|
+
private findPath(from: string, to: string): string[] | null {
|
|
357
|
+
if (from === to) {
|
|
358
|
+
return [from];
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const visited = new Set<string>();
|
|
362
|
+
const queue: Array<{ taskId: string; path: string[] }> = [
|
|
363
|
+
{ taskId: from, path: [from] }
|
|
364
|
+
];
|
|
365
|
+
|
|
366
|
+
while (queue.length > 0) {
|
|
367
|
+
const { taskId, path } = queue.shift()!;
|
|
368
|
+
|
|
369
|
+
if (visited.has(taskId)) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
visited.add(taskId);
|
|
373
|
+
|
|
374
|
+
const node = this.nodes.get(taskId);
|
|
375
|
+
if (!node) {
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
for (const depId of node.dependents) {
|
|
380
|
+
if (depId === to) {
|
|
381
|
+
return [...path, to];
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (!visited.has(depId)) {
|
|
385
|
+
queue.push({ taskId: depId, path: [...path, depId] });
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Get graph statistics
|
|
395
|
+
*/
|
|
396
|
+
getStats(): Record<string, unknown> {
|
|
397
|
+
const stats = {
|
|
398
|
+
totalTasks: this.nodes.size,
|
|
399
|
+
completedTasks: this.completedTasks.size,
|
|
400
|
+
readyTasks: 0,
|
|
401
|
+
pendingTasks: 0,
|
|
402
|
+
runningTasks: 0,
|
|
403
|
+
failedTasks: 0,
|
|
404
|
+
avgDependencies: 0,
|
|
405
|
+
maxDependencies: 0,
|
|
406
|
+
cycles: this.detectCycles(),
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
let totalDeps = 0;
|
|
410
|
+
for (const node of this.nodes.values()) {
|
|
411
|
+
totalDeps += node.dependencies.size;
|
|
412
|
+
stats.maxDependencies = Math.max(stats.maxDependencies, node.dependencies.size);
|
|
413
|
+
|
|
414
|
+
switch (node.status) {
|
|
415
|
+
case 'ready':
|
|
416
|
+
stats.readyTasks++;
|
|
417
|
+
break;
|
|
418
|
+
case 'pending':
|
|
419
|
+
stats.pendingTasks++;
|
|
420
|
+
break;
|
|
421
|
+
case 'running':
|
|
422
|
+
stats.runningTasks++;
|
|
423
|
+
break;
|
|
424
|
+
case 'failed':
|
|
425
|
+
stats.failedTasks++;
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
stats.avgDependencies = this.nodes.size > 0 ? totalDeps / this.nodes.size : 0;
|
|
431
|
+
|
|
432
|
+
return stats;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Export graph to DOT format for visualization
|
|
437
|
+
*/
|
|
438
|
+
toDot(): string {
|
|
439
|
+
let dot = 'digraph TaskDependencies {\n';
|
|
440
|
+
dot += ' rankdir=LR;\n';
|
|
441
|
+
dot += ' node [shape=box];\n\n';
|
|
442
|
+
|
|
443
|
+
// Add nodes with status colors
|
|
444
|
+
for (const [taskId, node] of this.nodes) {
|
|
445
|
+
let color = 'white';
|
|
446
|
+
switch (node.status) {
|
|
447
|
+
case 'ready':
|
|
448
|
+
color = 'lightgreen';
|
|
449
|
+
break;
|
|
450
|
+
case 'running':
|
|
451
|
+
color = 'yellow';
|
|
452
|
+
break;
|
|
453
|
+
case 'completed':
|
|
454
|
+
color = 'green';
|
|
455
|
+
break;
|
|
456
|
+
case 'failed':
|
|
457
|
+
color = 'red';
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
dot += ` "${taskId}" [style=filled, fillcolor=${color}];\n`;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
dot += '\n';
|
|
464
|
+
|
|
465
|
+
// Add edges
|
|
466
|
+
for (const [taskId, node] of this.nodes) {
|
|
467
|
+
for (const depId of node.dependencies) {
|
|
468
|
+
dot += ` "${depId}" -> "${taskId}";\n`;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
dot += '}\n';
|
|
473
|
+
return dot;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordination system exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Core coordination components
|
|
6
|
+
export { CoordinationManager, type ICoordinationManager } from './manager.ts';
|
|
7
|
+
export { TaskScheduler } from './scheduler.ts';
|
|
8
|
+
export { ResourceManager } from './resources.ts';
|
|
9
|
+
export { MessageRouter } from './messaging.ts';
|
|
10
|
+
|
|
11
|
+
// Advanced scheduling
|
|
12
|
+
export {
|
|
13
|
+
AdvancedTaskScheduler,
|
|
14
|
+
type SchedulingStrategy,
|
|
15
|
+
type SchedulingContext,
|
|
16
|
+
CapabilitySchedulingStrategy,
|
|
17
|
+
RoundRobinSchedulingStrategy,
|
|
18
|
+
LeastLoadedSchedulingStrategy,
|
|
19
|
+
AffinitySchedulingStrategy,
|
|
20
|
+
} from './advanced-scheduler.ts';
|
|
21
|
+
|
|
22
|
+
// Work stealing
|
|
23
|
+
export {
|
|
24
|
+
WorkStealingCoordinator,
|
|
25
|
+
type WorkStealingConfig,
|
|
26
|
+
type AgentWorkload,
|
|
27
|
+
} from './work-stealing.ts';
|
|
28
|
+
|
|
29
|
+
// Dependency management
|
|
30
|
+
export {
|
|
31
|
+
DependencyGraph,
|
|
32
|
+
type DependencyNode,
|
|
33
|
+
type DependencyPath,
|
|
34
|
+
} from './dependency-graph.ts';
|
|
35
|
+
|
|
36
|
+
// Circuit breakers
|
|
37
|
+
export {
|
|
38
|
+
CircuitBreaker,
|
|
39
|
+
CircuitBreakerManager,
|
|
40
|
+
CircuitState,
|
|
41
|
+
type CircuitBreakerConfig,
|
|
42
|
+
type CircuitBreakerMetrics,
|
|
43
|
+
} from './circuit-breaker.ts';
|
|
44
|
+
|
|
45
|
+
// Conflict resolution
|
|
46
|
+
export {
|
|
47
|
+
ConflictResolver,
|
|
48
|
+
PriorityResolutionStrategy,
|
|
49
|
+
TimestampResolutionStrategy,
|
|
50
|
+
VotingResolutionStrategy,
|
|
51
|
+
OptimisticLockManager,
|
|
52
|
+
type ResourceConflict,
|
|
53
|
+
type TaskConflict,
|
|
54
|
+
type ConflictResolution,
|
|
55
|
+
type ConflictResolutionStrategy,
|
|
56
|
+
} from './conflict-resolution.ts';
|
|
57
|
+
|
|
58
|
+
// Metrics and monitoring
|
|
59
|
+
export {
|
|
60
|
+
CoordinationMetricsCollector,
|
|
61
|
+
type CoordinationMetrics,
|
|
62
|
+
type MetricsSample,
|
|
63
|
+
} from './metrics.ts';
|