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,490 @@
1
+ /**
2
+ * Conflict resolution mechanisms for multi-agent coordination
3
+ */
4
+
5
+ import { ILogger } from '../core/logger.ts';
6
+ import { IEventBus } from '../core/event-bus.ts';
7
+ import { Task, Resource } from '../utils/types.ts';
8
+
9
+ export interface ResourceConflict {
10
+ id: string;
11
+ resourceId: string;
12
+ agents: string[];
13
+ timestamp: Date;
14
+ resolved: boolean;
15
+ resolution?: ConflictResolution;
16
+ }
17
+
18
+ export interface TaskConflict {
19
+ id: string;
20
+ taskId: string;
21
+ agents: string[];
22
+ type: 'assignment' | 'dependency' | 'output';
23
+ timestamp: Date;
24
+ resolved: boolean;
25
+ resolution?: ConflictResolution;
26
+ }
27
+
28
+ export interface ConflictResolution {
29
+ type: 'priority' | 'timestamp' | 'vote' | 'manual' | 'retry';
30
+ winner?: string;
31
+ losers?: string[];
32
+ reason: string;
33
+ timestamp: Date;
34
+ }
35
+
36
+ export interface ConflictResolutionStrategy {
37
+ name: string;
38
+ resolve(conflict: ResourceConflict | TaskConflict, context: any): Promise<ConflictResolution>;
39
+ }
40
+
41
+ /**
42
+ * Priority-based resolution strategy
43
+ */
44
+ export class PriorityResolutionStrategy implements ConflictResolutionStrategy {
45
+ name = 'priority';
46
+
47
+ async resolve(
48
+ conflict: ResourceConflict | TaskConflict,
49
+ context: { agentPriorities: Map<string, number> },
50
+ ): Promise<ConflictResolution> {
51
+ const priorities = conflict.agents.map(agentId => ({
52
+ agentId,
53
+ priority: context.agentPriorities.get(agentId) || 0,
54
+ }));
55
+
56
+ // Sort by priority (descending)
57
+ priorities.sort((a, b) => b.priority - a.priority);
58
+
59
+ const winner = priorities[0].agentId;
60
+ const losers = priorities.slice(1).map(p => p.agentId);
61
+
62
+ return {
63
+ type: 'priority',
64
+ winner,
65
+ losers,
66
+ reason: `Agent ${winner} has highest priority (${priorities[0].priority})`,
67
+ timestamp: new Date(),
68
+ };
69
+ }
70
+ }
71
+
72
+ /**
73
+ * First-come-first-served resolution strategy
74
+ */
75
+ export class TimestampResolutionStrategy implements ConflictResolutionStrategy {
76
+ name = 'timestamp';
77
+
78
+ async resolve(
79
+ conflict: ResourceConflict | TaskConflict,
80
+ context: { requestTimestamps: Map<string, Date> },
81
+ ): Promise<ConflictResolution> {
82
+ const timestamps = conflict.agents.map(agentId => ({
83
+ agentId,
84
+ timestamp: context.requestTimestamps.get(agentId) || new Date(),
85
+ }));
86
+
87
+ // Sort by timestamp (ascending - earliest first)
88
+ timestamps.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
89
+
90
+ const winner = timestamps[0].agentId;
91
+ const losers = timestamps.slice(1).map(t => t.agentId);
92
+
93
+ return {
94
+ type: 'timestamp',
95
+ winner,
96
+ losers,
97
+ reason: `Agent ${winner} made the earliest request`,
98
+ timestamp: new Date(),
99
+ };
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Voting-based resolution strategy (for multi-agent consensus)
105
+ */
106
+ export class VotingResolutionStrategy implements ConflictResolutionStrategy {
107
+ name = 'vote';
108
+
109
+ async resolve(
110
+ conflict: ResourceConflict | TaskConflict,
111
+ context: { votes: Map<string, string[]> }, // agentId -> votes for that agent
112
+ ): Promise<ConflictResolution> {
113
+ const voteCounts = new Map<string, number>();
114
+
115
+ // Count votes
116
+ for (const [agentId, voters] of context.votes) {
117
+ voteCounts.set(agentId, voters.length);
118
+ }
119
+
120
+ // Find winner
121
+ let maxVotes = 0;
122
+ let winner = '';
123
+ const losers: string[] = [];
124
+
125
+ for (const [agentId, votes] of voteCounts) {
126
+ if (votes > maxVotes) {
127
+ if (winner) {
128
+ losers.push(winner);
129
+ }
130
+ maxVotes = votes;
131
+ winner = agentId;
132
+ } else {
133
+ losers.push(agentId);
134
+ }
135
+ }
136
+
137
+ return {
138
+ type: 'vote',
139
+ winner,
140
+ losers,
141
+ reason: `Agent ${winner} received the most votes (${maxVotes})`,
142
+ timestamp: new Date(),
143
+ };
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Conflict resolution manager
149
+ */
150
+ export class ConflictResolver {
151
+ private strategies = new Map<string, ConflictResolutionStrategy>();
152
+ private conflicts = new Map<string, ResourceConflict | TaskConflict>();
153
+ private resolutionHistory: ConflictResolution[] = [];
154
+
155
+ constructor(
156
+ private logger: ILogger,
157
+ private eventBus: IEventBus,
158
+ ) {
159
+ // Register default strategies
160
+ this.registerStrategy(new PriorityResolutionStrategy());
161
+ this.registerStrategy(new TimestampResolutionStrategy());
162
+ this.registerStrategy(new VotingResolutionStrategy());
163
+ }
164
+
165
+ /**
166
+ * Register a conflict resolution strategy
167
+ */
168
+ registerStrategy(strategy: ConflictResolutionStrategy): void {
169
+ this.strategies.set(strategy.name, strategy);
170
+ this.logger.info('Registered conflict resolution strategy', { name: strategy.name });
171
+ }
172
+
173
+ /**
174
+ * Report a resource conflict
175
+ */
176
+ async reportResourceConflict(
177
+ resourceId: string,
178
+ agents: string[],
179
+ ): Promise<ResourceConflict> {
180
+ const conflict: ResourceConflict = {
181
+ id: `conflict-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
182
+ resourceId,
183
+ agents,
184
+ timestamp: new Date(),
185
+ resolved: false,
186
+ };
187
+
188
+ this.conflicts.set(conflict.id, conflict);
189
+ this.logger.warn('Resource conflict reported', conflict);
190
+
191
+ // Emit conflict event
192
+ this.eventBus.emit('conflict:resource', conflict);
193
+
194
+ return conflict;
195
+ }
196
+
197
+ /**
198
+ * Report a task conflict
199
+ */
200
+ async reportTaskConflict(
201
+ taskId: string,
202
+ agents: string[],
203
+ type: TaskConflict['type'],
204
+ ): Promise<TaskConflict> {
205
+ const conflict: TaskConflict = {
206
+ id: `conflict-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
207
+ taskId,
208
+ agents,
209
+ type,
210
+ timestamp: new Date(),
211
+ resolved: false,
212
+ };
213
+
214
+ this.conflicts.set(conflict.id, conflict);
215
+ this.logger.warn('Task conflict reported', conflict);
216
+
217
+ // Emit conflict event
218
+ this.eventBus.emit('conflict:task', conflict);
219
+
220
+ return conflict;
221
+ }
222
+
223
+ /**
224
+ * Resolve a conflict using a specific strategy
225
+ */
226
+ async resolveConflict(
227
+ conflictId: string,
228
+ strategyName: string,
229
+ context: any,
230
+ ): Promise<ConflictResolution> {
231
+ const conflict = this.conflicts.get(conflictId);
232
+ if (!conflict) {
233
+ throw new Error(`Conflict not found: ${conflictId}`);
234
+ }
235
+
236
+ if (conflict.resolved) {
237
+ throw new Error(`Conflict already resolved: ${conflictId}`);
238
+ }
239
+
240
+ const strategy = this.strategies.get(strategyName);
241
+ if (!strategy) {
242
+ throw new Error(`Strategy not found: ${strategyName}`);
243
+ }
244
+
245
+ // Resolve the conflict
246
+ const resolution = await strategy.resolve(conflict, context);
247
+
248
+ // Update conflict
249
+ conflict.resolved = true;
250
+ conflict.resolution = resolution;
251
+
252
+ // Store in history
253
+ this.resolutionHistory.push(resolution);
254
+
255
+ // Emit resolution event
256
+ this.eventBus.emit('conflict:resolved', {
257
+ conflict,
258
+ resolution,
259
+ });
260
+
261
+ this.logger.info('Conflict resolved', {
262
+ conflictId,
263
+ strategy: strategyName,
264
+ resolution,
265
+ });
266
+
267
+ return resolution;
268
+ }
269
+
270
+ /**
271
+ * Auto-resolve conflicts based on configuration
272
+ */
273
+ async autoResolve(
274
+ conflictId: string,
275
+ preferredStrategy: string = 'priority',
276
+ ): Promise<ConflictResolution> {
277
+ const conflict = this.conflicts.get(conflictId);
278
+ if (!conflict) {
279
+ throw new Error(`Conflict not found: ${conflictId}`);
280
+ }
281
+
282
+ // Build context based on conflict type
283
+ let context: any = {};
284
+
285
+ if (preferredStrategy === 'priority') {
286
+ // In a real implementation, fetch agent priorities from configuration
287
+ context.agentPriorities = new Map(
288
+ conflict.agents.map((id, index) => [id, conflict.agents.length - index])
289
+ );
290
+ } else if (preferredStrategy === 'timestamp') {
291
+ // In a real implementation, fetch request timestamps
292
+ context.requestTimestamps = new Map(
293
+ conflict.agents.map((id, index) => [id, new Date(Date.now() - index * 1000)])
294
+ );
295
+ }
296
+
297
+ return this.resolveConflict(conflictId, preferredStrategy, context);
298
+ }
299
+
300
+ /**
301
+ * Get active conflicts
302
+ */
303
+ getActiveConflicts(): Array<ResourceConflict | TaskConflict> {
304
+ return Array.from(this.conflicts.values()).filter(c => !c.resolved);
305
+ }
306
+
307
+ /**
308
+ * Get conflict history
309
+ */
310
+ getConflictHistory(limit?: number): ConflictResolution[] {
311
+ if (limit) {
312
+ return this.resolutionHistory.slice(-limit);
313
+ }
314
+ return [...this.resolutionHistory];
315
+ }
316
+
317
+ /**
318
+ * Clear resolved conflicts older than a certain age
319
+ */
320
+ cleanupOldConflicts(maxAgeMs: number): number {
321
+ const now = Date.now();
322
+ let removed = 0;
323
+
324
+ for (const [id, conflict] of this.conflicts) {
325
+ if (conflict.resolved && now - conflict.timestamp.getTime() > maxAgeMs) {
326
+ this.conflicts.delete(id);
327
+ removed++;
328
+ }
329
+ }
330
+
331
+ // Also cleanup old history
332
+ const cutoffTime = now - maxAgeMs;
333
+ this.resolutionHistory = this.resolutionHistory.filter(
334
+ r => r.timestamp.getTime() > cutoffTime
335
+ );
336
+
337
+ return removed;
338
+ }
339
+
340
+ /**
341
+ * Get conflict statistics
342
+ */
343
+ getStats(): Record<string, unknown> {
344
+ const stats = {
345
+ totalConflicts: this.conflicts.size,
346
+ activeConflicts: 0,
347
+ resolvedConflicts: 0,
348
+ resolutionsByStrategy: {} as Record<string, number>,
349
+ conflictsByType: {
350
+ resource: 0,
351
+ task: 0,
352
+ },
353
+ };
354
+
355
+ for (const conflict of this.conflicts.values()) {
356
+ if (conflict.resolved) {
357
+ stats.resolvedConflicts++;
358
+
359
+ if (conflict.resolution) {
360
+ const strategy = conflict.resolution.type;
361
+ stats.resolutionsByStrategy[strategy] =
362
+ (stats.resolutionsByStrategy[strategy] || 0) + 1;
363
+ }
364
+ } else {
365
+ stats.activeConflicts++;
366
+ }
367
+
368
+ if ('resourceId' in conflict) {
369
+ stats.conflictsByType.resource++;
370
+ } else {
371
+ stats.conflictsByType.task++;
372
+ }
373
+ }
374
+
375
+ return stats;
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Optimistic concurrency control for resource updates
381
+ */
382
+ export class OptimisticLockManager {
383
+ private versions = new Map<string, number>();
384
+ private locks = new Map<string, { version: number; holder: string; timestamp: Date }>();
385
+
386
+ constructor(private logger: ILogger) {}
387
+
388
+ /**
389
+ * Acquire an optimistic lock
390
+ */
391
+ acquireLock(resourceId: string, agentId: string): number {
392
+ const currentVersion = this.versions.get(resourceId) || 0;
393
+
394
+ this.locks.set(resourceId, {
395
+ version: currentVersion,
396
+ holder: agentId,
397
+ timestamp: new Date(),
398
+ });
399
+
400
+ this.logger.debug('Optimistic lock acquired', {
401
+ resourceId,
402
+ agentId,
403
+ version: currentVersion,
404
+ });
405
+
406
+ return currentVersion;
407
+ }
408
+
409
+ /**
410
+ * Validate and update with optimistic lock
411
+ */
412
+ validateAndUpdate(
413
+ resourceId: string,
414
+ agentId: string,
415
+ expectedVersion: number,
416
+ ): boolean {
417
+ const currentVersion = this.versions.get(resourceId) || 0;
418
+ const lock = this.locks.get(resourceId);
419
+
420
+ // Check if versions match
421
+ if (currentVersion !== expectedVersion) {
422
+ this.logger.warn('Optimistic lock conflict', {
423
+ resourceId,
424
+ agentId,
425
+ expectedVersion,
426
+ currentVersion,
427
+ });
428
+ return false;
429
+ }
430
+
431
+ // Check if this agent holds the lock
432
+ if (!lock || lock.holder !== agentId) {
433
+ this.logger.warn('Agent does not hold lock', {
434
+ resourceId,
435
+ agentId,
436
+ });
437
+ return false;
438
+ }
439
+
440
+ // Update version
441
+ this.versions.set(resourceId, currentVersion + 1);
442
+ this.locks.delete(resourceId);
443
+
444
+ this.logger.debug('Optimistic update successful', {
445
+ resourceId,
446
+ agentId,
447
+ newVersion: currentVersion + 1,
448
+ });
449
+
450
+ return true;
451
+ }
452
+
453
+ /**
454
+ * Release a lock without updating
455
+ */
456
+ releaseLock(resourceId: string, agentId: string): void {
457
+ const lock = this.locks.get(resourceId);
458
+
459
+ if (lock && lock.holder === agentId) {
460
+ this.locks.delete(resourceId);
461
+ this.logger.debug('Optimistic lock released', {
462
+ resourceId,
463
+ agentId,
464
+ });
465
+ }
466
+ }
467
+
468
+ /**
469
+ * Clean up stale locks
470
+ */
471
+ cleanupStaleLocks(maxAgeMs: number): number {
472
+ const now = Date.now();
473
+ let removed = 0;
474
+
475
+ for (const [resourceId, lock] of this.locks) {
476
+ if (now - lock.timestamp.getTime() > maxAgeMs) {
477
+ this.locks.delete(resourceId);
478
+ removed++;
479
+
480
+ this.logger.warn('Removed stale lock', {
481
+ resourceId,
482
+ holder: lock.holder,
483
+ age: now - lock.timestamp.getTime(),
484
+ });
485
+ }
486
+ }
487
+
488
+ return removed;
489
+ }
490
+ }