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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +612 -0
  3. package/bin/claude-flow +0 -0
  4. package/bin/claude-flow-simple +0 -0
  5. package/bin/claude-flow-typecheck +0 -0
  6. package/deno.json +84 -0
  7. package/package.json +45 -0
  8. package/scripts/check-links.ts +274 -0
  9. package/scripts/check-performance-regression.ts +168 -0
  10. package/scripts/claude-sparc.sh +562 -0
  11. package/scripts/coverage-report.ts +692 -0
  12. package/scripts/demo-task-system.ts +224 -0
  13. package/scripts/install.js +72 -0
  14. package/scripts/test-batch-tasks.ts +29 -0
  15. package/scripts/test-coordination-features.ts +238 -0
  16. package/scripts/test-mcp.ts +251 -0
  17. package/scripts/test-runner.ts +571 -0
  18. package/scripts/validate-examples.ts +288 -0
  19. package/src/cli/cli-core.ts +273 -0
  20. package/src/cli/commands/agent.ts +83 -0
  21. package/src/cli/commands/config.ts +442 -0
  22. package/src/cli/commands/help.ts +765 -0
  23. package/src/cli/commands/index.ts +963 -0
  24. package/src/cli/commands/mcp.ts +191 -0
  25. package/src/cli/commands/memory.ts +74 -0
  26. package/src/cli/commands/monitor.ts +403 -0
  27. package/src/cli/commands/session.ts +595 -0
  28. package/src/cli/commands/start.ts +156 -0
  29. package/src/cli/commands/status.ts +345 -0
  30. package/src/cli/commands/task.ts +79 -0
  31. package/src/cli/commands/workflow.ts +763 -0
  32. package/src/cli/completion.ts +553 -0
  33. package/src/cli/formatter.ts +310 -0
  34. package/src/cli/index.ts +211 -0
  35. package/src/cli/main.ts +23 -0
  36. package/src/cli/repl.ts +1050 -0
  37. package/src/cli/simple-cli.js +211 -0
  38. package/src/cli/simple-cli.ts +211 -0
  39. package/src/coordination/README.md +400 -0
  40. package/src/coordination/advanced-scheduler.ts +487 -0
  41. package/src/coordination/circuit-breaker.ts +366 -0
  42. package/src/coordination/conflict-resolution.ts +490 -0
  43. package/src/coordination/dependency-graph.ts +475 -0
  44. package/src/coordination/index.ts +63 -0
  45. package/src/coordination/manager.ts +460 -0
  46. package/src/coordination/messaging.ts +290 -0
  47. package/src/coordination/metrics.ts +585 -0
  48. package/src/coordination/resources.ts +322 -0
  49. package/src/coordination/scheduler.ts +390 -0
  50. package/src/coordination/work-stealing.ts +224 -0
  51. package/src/core/config.ts +627 -0
  52. package/src/core/event-bus.ts +186 -0
  53. package/src/core/json-persistence.ts +183 -0
  54. package/src/core/logger.ts +262 -0
  55. package/src/core/orchestrator-fixed.ts +312 -0
  56. package/src/core/orchestrator.ts +1234 -0
  57. package/src/core/persistence.ts +276 -0
  58. package/src/mcp/auth.ts +438 -0
  59. package/src/mcp/claude-flow-tools.ts +1280 -0
  60. package/src/mcp/load-balancer.ts +510 -0
  61. package/src/mcp/router.ts +240 -0
  62. package/src/mcp/server.ts +548 -0
  63. package/src/mcp/session-manager.ts +418 -0
  64. package/src/mcp/tools.ts +180 -0
  65. package/src/mcp/transports/base.ts +21 -0
  66. package/src/mcp/transports/http.ts +457 -0
  67. package/src/mcp/transports/stdio.ts +254 -0
  68. package/src/memory/backends/base.ts +22 -0
  69. package/src/memory/backends/markdown.ts +283 -0
  70. package/src/memory/backends/sqlite.ts +329 -0
  71. package/src/memory/cache.ts +238 -0
  72. package/src/memory/indexer.ts +238 -0
  73. package/src/memory/manager.ts +572 -0
  74. package/src/terminal/adapters/base.ts +29 -0
  75. package/src/terminal/adapters/native.ts +504 -0
  76. package/src/terminal/adapters/vscode.ts +340 -0
  77. package/src/terminal/manager.ts +308 -0
  78. package/src/terminal/pool.ts +271 -0
  79. package/src/terminal/session.ts +250 -0
  80. package/src/terminal/vscode-bridge.ts +242 -0
  81. package/src/utils/errors.ts +231 -0
  82. package/src/utils/helpers.ts +476 -0
  83. package/src/utils/types.ts +493 -0
@@ -0,0 +1,487 @@
1
+ /**
2
+ * Advanced task scheduler with intelligent agent selection and priority handling
3
+ */
4
+
5
+ import { Task, TaskStatus, CoordinationConfig, SystemEvents, AgentProfile } from '../utils/types.ts';
6
+ import { IEventBus } from '../core/event-bus.ts';
7
+ import { ILogger } from '../core/logger.ts';
8
+ import { TaskScheduler } from './scheduler.ts';
9
+ import { WorkStealingCoordinator } from './work-stealing.ts';
10
+ import { DependencyGraph } from './dependency-graph.ts';
11
+ import { CircuitBreakerManager, CircuitBreakerConfig } from './circuit-breaker.ts';
12
+
13
+ export interface SchedulingStrategy {
14
+ name: string;
15
+ selectAgent(task: Task, agents: AgentProfile[], context: SchedulingContext): string | null;
16
+ }
17
+
18
+ export interface SchedulingContext {
19
+ taskLoads: Map<string, number>;
20
+ agentCapabilities: Map<string, string[]>;
21
+ agentPriorities: Map<string, number>;
22
+ taskHistory: Map<string, TaskStats>;
23
+ currentTime: Date;
24
+ }
25
+
26
+ export interface TaskStats {
27
+ totalExecutions: number;
28
+ avgDuration: number;
29
+ successRate: number;
30
+ lastAgent?: string;
31
+ }
32
+
33
+ /**
34
+ * Capability-based scheduling strategy
35
+ */
36
+ export class CapabilitySchedulingStrategy implements SchedulingStrategy {
37
+ name = 'capability';
38
+
39
+ selectAgent(task: Task, agents: AgentProfile[], context: SchedulingContext): string | null {
40
+ // Filter agents by capability match
41
+ const capableAgents = agents.filter(agent => {
42
+ const capabilities = context.agentCapabilities.get(agent.id) || agent.capabilities;
43
+ return task.type === 'any' ||
44
+ capabilities.includes(task.type) ||
45
+ capabilities.includes('*');
46
+ });
47
+
48
+ if (capableAgents.length === 0) {
49
+ return null;
50
+ }
51
+
52
+ // Sort by load (ascending) and priority (descending)
53
+ capableAgents.sort((a, b) => {
54
+ const loadA = context.taskLoads.get(a.id) || 0;
55
+ const loadB = context.taskLoads.get(b.id) || 0;
56
+
57
+ if (loadA !== loadB) {
58
+ return loadA - loadB;
59
+ }
60
+
61
+ const priorityA = context.agentPriorities.get(a.id) || a.priority;
62
+ const priorityB = context.agentPriorities.get(b.id) || b.priority;
63
+
64
+ return priorityB - priorityA;
65
+ });
66
+
67
+ return capableAgents[0].id;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Round-robin scheduling strategy
73
+ */
74
+ export class RoundRobinSchedulingStrategy implements SchedulingStrategy {
75
+ name = 'round-robin';
76
+ private lastIndex = 0;
77
+
78
+ selectAgent(task: Task, agents: AgentProfile[], context: SchedulingContext): string | null {
79
+ if (agents.length === 0) {
80
+ return null;
81
+ }
82
+
83
+ this.lastIndex = (this.lastIndex + 1) % agents.length;
84
+ return agents[this.lastIndex].id;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Least-loaded scheduling strategy
90
+ */
91
+ export class LeastLoadedSchedulingStrategy implements SchedulingStrategy {
92
+ name = 'least-loaded';
93
+
94
+ selectAgent(task: Task, agents: AgentProfile[], context: SchedulingContext): string | null {
95
+ if (agents.length === 0) {
96
+ return null;
97
+ }
98
+
99
+ let minLoad = Infinity;
100
+ let selectedAgent: string | null = null;
101
+
102
+ for (const agent of agents) {
103
+ const load = context.taskLoads.get(agent.id) || 0;
104
+ if (load < minLoad) {
105
+ minLoad = load;
106
+ selectedAgent = agent.id;
107
+ }
108
+ }
109
+
110
+ return selectedAgent;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Affinity-based scheduling strategy (prefers agents that previously executed similar tasks)
116
+ */
117
+ export class AffinitySchedulingStrategy implements SchedulingStrategy {
118
+ name = 'affinity';
119
+
120
+ selectAgent(task: Task, agents: AgentProfile[], context: SchedulingContext): string | null {
121
+ const taskStats = context.taskHistory.get(task.type);
122
+
123
+ if (taskStats?.lastAgent) {
124
+ // Check if the last agent is available
125
+ const lastAgent = agents.find(a => a.id === taskStats.lastAgent);
126
+ if (lastAgent) {
127
+ const load = context.taskLoads.get(lastAgent.id) || 0;
128
+ // Use last agent if not overloaded
129
+ if (load < lastAgent.maxConcurrentTasks * 0.8) {
130
+ return lastAgent.id;
131
+ }
132
+ }
133
+ }
134
+
135
+ // Fall back to capability-based selection
136
+ return new CapabilitySchedulingStrategy().selectAgent(task, agents, context);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Advanced task scheduler with multiple strategies
142
+ */
143
+ export class AdvancedTaskScheduler extends TaskScheduler {
144
+ private strategies = new Map<string, SchedulingStrategy>();
145
+ private activeAgents = new Map<string, AgentProfile>();
146
+ private taskStats = new Map<string, TaskStats>();
147
+ private workStealing: WorkStealingCoordinator;
148
+ private dependencyGraph: DependencyGraph;
149
+ private circuitBreakers: CircuitBreakerManager;
150
+ private defaultStrategy = 'capability';
151
+
152
+ constructor(
153
+ config: CoordinationConfig,
154
+ eventBus: IEventBus,
155
+ logger: ILogger,
156
+ ) {
157
+ super(config, eventBus, logger);
158
+
159
+ // Initialize components
160
+ this.workStealing = new WorkStealingCoordinator(
161
+ {
162
+ enabled: true,
163
+ stealThreshold: 3,
164
+ maxStealBatch: 2,
165
+ stealInterval: 5000,
166
+ },
167
+ eventBus,
168
+ logger,
169
+ );
170
+
171
+ this.dependencyGraph = new DependencyGraph(logger);
172
+
173
+ const cbConfig: CircuitBreakerConfig = {
174
+ failureThreshold: 3,
175
+ successThreshold: 2,
176
+ timeout: 30000,
177
+ halfOpenLimit: 1,
178
+ };
179
+ this.circuitBreakers = new CircuitBreakerManager(cbConfig, logger, eventBus);
180
+
181
+ // Register default strategies
182
+ this.registerStrategy(new CapabilitySchedulingStrategy());
183
+ this.registerStrategy(new RoundRobinSchedulingStrategy());
184
+ this.registerStrategy(new LeastLoadedSchedulingStrategy());
185
+ this.registerStrategy(new AffinitySchedulingStrategy());
186
+
187
+ // Set up event handlers
188
+ this.setupAdvancedEventHandlers();
189
+ }
190
+
191
+ override async initialize(): Promise<void> {
192
+ await super.initialize();
193
+ await this.workStealing.initialize();
194
+
195
+ this.logger.info('Advanced task scheduler initialized');
196
+ }
197
+
198
+ override async shutdown(): Promise<void> {
199
+ await this.workStealing.shutdown();
200
+ await super.shutdown();
201
+ }
202
+
203
+ /**
204
+ * Register a scheduling strategy
205
+ */
206
+ registerStrategy(strategy: SchedulingStrategy): void {
207
+ this.strategies.set(strategy.name, strategy);
208
+ this.logger.info('Registered scheduling strategy', { name: strategy.name });
209
+ }
210
+
211
+ /**
212
+ * Set the default scheduling strategy
213
+ */
214
+ setDefaultStrategy(name: string): void {
215
+ if (!this.strategies.has(name)) {
216
+ throw new Error(`Strategy not found: ${name}`);
217
+ }
218
+ this.defaultStrategy = name;
219
+ }
220
+
221
+ /**
222
+ * Register an agent
223
+ */
224
+ registerAgent(profile: AgentProfile): void {
225
+ this.activeAgents.set(profile.id, profile);
226
+ this.workStealing.updateAgentWorkload(profile.id, {
227
+ agentId: profile.id,
228
+ taskCount: 0,
229
+ avgTaskDuration: 0,
230
+ cpuUsage: 0,
231
+ memoryUsage: 0,
232
+ priority: profile.priority,
233
+ capabilities: profile.capabilities,
234
+ });
235
+ }
236
+
237
+ /**
238
+ * Unregister an agent
239
+ */
240
+ unregisterAgent(agentId: string): void {
241
+ this.activeAgents.delete(agentId);
242
+ }
243
+
244
+ /**
245
+ * Override assignTask to use advanced scheduling
246
+ */
247
+ override async assignTask(task: Task, agentId?: string): Promise<void> {
248
+ // Add to dependency graph
249
+ this.dependencyGraph.addTask(task);
250
+
251
+ // If no agent specified, select one
252
+ if (!agentId) {
253
+ const selectedAgent = await this.selectAgentForTask(task);
254
+ if (!selectedAgent) {
255
+ throw new Error('No suitable agent found for task');
256
+ }
257
+ agentId = selectedAgent;
258
+ }
259
+
260
+ // Use circuit breaker for assignment
261
+ await this.circuitBreakers.execute(`assign-${agentId}`, async () => {
262
+ await super.assignTask(task, agentId!);
263
+ });
264
+
265
+ // Update work stealing metrics
266
+ const taskCount = await this.getAgentTaskCount(agentId);
267
+ this.workStealing.updateAgentWorkload(agentId, { taskCount });
268
+ }
269
+
270
+ /**
271
+ * Select the best agent for a task
272
+ */
273
+ private async selectAgentForTask(task: Task): Promise<string | null> {
274
+ const availableAgents = Array.from(this.activeAgents.values());
275
+ if (availableAgents.length === 0) {
276
+ return null;
277
+ }
278
+
279
+ // Build scheduling context
280
+ const context: SchedulingContext = {
281
+ taskLoads: new Map(),
282
+ agentCapabilities: new Map(),
283
+ agentPriorities: new Map(),
284
+ taskHistory: this.taskStats,
285
+ currentTime: new Date(),
286
+ };
287
+
288
+ // Populate context
289
+ for (const agent of availableAgents) {
290
+ const taskCount = await this.getAgentTaskCount(agent.id);
291
+ context.taskLoads.set(agent.id, taskCount);
292
+ context.agentCapabilities.set(agent.id, agent.capabilities);
293
+ context.agentPriorities.set(agent.id, agent.priority);
294
+ }
295
+
296
+ // Try work stealing first
297
+ const workStealingAgent = this.workStealing.findBestAgent(task, availableAgents);
298
+ if (workStealingAgent) {
299
+ return workStealingAgent;
300
+ }
301
+
302
+ // Use configured strategy
303
+ const strategy = this.strategies.get(this.defaultStrategy);
304
+ if (!strategy) {
305
+ throw new Error(`Strategy not found: ${this.defaultStrategy}`);
306
+ }
307
+
308
+ return strategy.selectAgent(task, availableAgents, context);
309
+ }
310
+
311
+ /**
312
+ * Override completeTask to update stats and dependency graph
313
+ */
314
+ override async completeTask(taskId: string, result: unknown): Promise<void> {
315
+ const task = await this.getTask(taskId);
316
+ if (!task) {
317
+ throw new Error(`Task not found: ${taskId}`);
318
+ }
319
+
320
+ // Calculate duration
321
+ const duration = task.startedAt
322
+ ? new Date().getTime() - task.startedAt.getTime()
323
+ : 0;
324
+
325
+ // Update task stats
326
+ this.updateTaskStats(task.type, true, duration);
327
+
328
+ // Update work stealing metrics
329
+ if (task.assignedAgent) {
330
+ this.workStealing.recordTaskDuration(task.assignedAgent, duration);
331
+ }
332
+
333
+ // Mark as completed in dependency graph
334
+ const readyTasks = this.dependencyGraph.markCompleted(taskId);
335
+
336
+ // Complete the task
337
+ await super.completeTask(taskId, result);
338
+
339
+ // Start ready tasks
340
+ for (const readyTaskId of readyTasks) {
341
+ const readyTask = await this.getTask(readyTaskId);
342
+ if (readyTask) {
343
+ this.eventBus.emit(SystemEvents.TASK_CREATED, { task: readyTask });
344
+ }
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Override failTask to update stats and dependency graph
350
+ */
351
+ override async failTask(taskId: string, error: Error): Promise<void> {
352
+ const task = await this.getTask(taskId);
353
+ if (!task) {
354
+ throw new Error(`Task not found: ${taskId}`);
355
+ }
356
+
357
+ // Update task stats
358
+ this.updateTaskStats(task.type, false, 0);
359
+
360
+ // Mark as failed in dependency graph
361
+ const toCancelIds = this.dependencyGraph.markFailed(taskId);
362
+
363
+ // Fail the task
364
+ await super.failTask(taskId, error);
365
+
366
+ // Cancel dependent tasks
367
+ for (const cancelId of toCancelIds) {
368
+ await this.cancelTask(cancelId, 'Parent task failed');
369
+ }
370
+ }
371
+
372
+ /**
373
+ * Get a task by ID (helper method)
374
+ */
375
+ private async getTask(taskId: string): Promise<Task | null> {
376
+ // This would need to be implemented based on how tasks are stored
377
+ // For now, return null
378
+ return null;
379
+ }
380
+
381
+ /**
382
+ * Update task statistics
383
+ */
384
+ private updateTaskStats(taskType: string, success: boolean, duration: number): void {
385
+ const stats = this.taskStats.get(taskType) || {
386
+ totalExecutions: 0,
387
+ avgDuration: 0,
388
+ successRate: 0,
389
+ };
390
+
391
+ stats.totalExecutions++;
392
+
393
+ if (success) {
394
+ const successCount = Math.round(stats.successRate * (stats.totalExecutions - 1));
395
+ stats.successRate = (successCount + 1) / stats.totalExecutions;
396
+
397
+ if (duration > 0) {
398
+ const totalDuration = stats.avgDuration * (stats.totalExecutions - 1);
399
+ stats.avgDuration = (totalDuration + duration) / stats.totalExecutions;
400
+ }
401
+ } else {
402
+ const successCount = Math.round(stats.successRate * (stats.totalExecutions - 1));
403
+ stats.successRate = successCount / stats.totalExecutions;
404
+ }
405
+
406
+ this.taskStats.set(taskType, stats);
407
+ }
408
+
409
+ /**
410
+ * Set up advanced event handlers
411
+ */
412
+ private setupAdvancedEventHandlers(): void {
413
+ // Handle work stealing requests
414
+ this.eventBus.on('workstealing:request', async (data: any) => {
415
+ const { sourceAgent, targetAgent, taskCount } = data;
416
+
417
+ try {
418
+ const tasks = await this.getAgentTasks(sourceAgent);
419
+ const tasksToSteal = tasks
420
+ .filter(t => t.status === 'queued' || t.status === 'assigned')
421
+ .slice(0, taskCount);
422
+
423
+ for (const task of tasksToSteal) {
424
+ await this.reassignTask(task.id, targetAgent);
425
+ }
426
+
427
+ this.logger.info('Work stealing completed', {
428
+ from: sourceAgent,
429
+ to: targetAgent,
430
+ stolenCount: tasksToSteal.length,
431
+ });
432
+ } catch (error) {
433
+ this.logger.error('Work stealing failed', { error });
434
+ }
435
+ });
436
+
437
+ // Update workload on task events
438
+ this.eventBus.on(SystemEvents.TASK_ASSIGNED, async (data: any) => {
439
+ const { agentId } = data;
440
+ const taskCount = await this.getAgentTaskCount(agentId);
441
+ this.workStealing.updateAgentWorkload(agentId, { taskCount });
442
+ });
443
+
444
+ this.eventBus.on(SystemEvents.TASK_COMPLETED, async (data: any) => {
445
+ const { taskId } = data;
446
+ // Update workload after task completion
447
+ // This would need the agent ID from the task
448
+ });
449
+ }
450
+
451
+ /**
452
+ * Reassign a task to a different agent
453
+ */
454
+ private async reassignTask(taskId: string, newAgentId: string): Promise<void> {
455
+ // Cancel the current assignment
456
+ await this.cancelTask(taskId, 'Reassigning to different agent');
457
+
458
+ // Get the task
459
+ const task = await this.getTask(taskId);
460
+ if (!task) {
461
+ throw new Error(`Task not found: ${taskId}`);
462
+ }
463
+
464
+ // Assign to new agent
465
+ await this.assignTask(task, newAgentId);
466
+ }
467
+
468
+ /**
469
+ * Get advanced scheduling metrics
470
+ */
471
+ async getSchedulingMetrics(): Promise<Record<string, unknown>> {
472
+ const baseMetrics = await this.getHealthStatus();
473
+ const workloadStats = this.workStealing.getWorkloadStats();
474
+ const depGraphStats = this.dependencyGraph.getStats();
475
+ const cbMetrics = this.circuitBreakers.getAllMetrics();
476
+
477
+ return {
478
+ ...baseMetrics.metrics,
479
+ workStealing: workloadStats,
480
+ dependencies: depGraphStats,
481
+ circuitBreakers: cbMetrics,
482
+ taskStats: Object.fromEntries(this.taskStats),
483
+ activeStrategies: Array.from(this.strategies.keys()),
484
+ defaultStrategy: this.defaultStrategy,
485
+ };
486
+ }
487
+ }