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,1050 @@
1
+ /**
2
+ * Enhanced Interactive REPL for Claude-Flow
3
+ */
4
+
5
+ import { Input, Confirm, Select } from '@cliffy/prompt';
6
+ import { colors } from '@cliffy/ansi/colors';
7
+ import { Table } from '@cliffy/table';
8
+ import { AgentProfile, Task } from '../utils/types.ts';
9
+ import { generateId } from '../utils/helpers.ts';
10
+ import { formatStatusIndicator, formatDuration, formatProgressBar } from './formatter.ts';
11
+
12
+ interface REPLCommand {
13
+ name: string;
14
+ aliases?: string[];
15
+ description: string;
16
+ usage?: string;
17
+ examples?: string[];
18
+ handler: (args: string[], context: REPLContext) => Promise<void>;
19
+ }
20
+
21
+ interface REPLContext {
22
+ options: any;
23
+ history: string[];
24
+ workingDirectory: string;
25
+ currentSession?: string;
26
+ connectionStatus: 'connected' | 'disconnected' | 'connecting';
27
+ lastActivity: Date;
28
+ }
29
+
30
+ class CommandHistory {
31
+ private history: string[] = [];
32
+ private maxSize = 1000;
33
+ private historyFile: string;
34
+
35
+ constructor(historyFile?: string) {
36
+ this.historyFile = historyFile || '.claude-flow-history';
37
+ this.loadHistory();
38
+ }
39
+
40
+ add(command: string): void {
41
+ if (command.trim() && command !== this.history[this.history.length - 1]) {
42
+ this.history.push(command);
43
+ if (this.history.length > this.maxSize) {
44
+ this.history = this.history.slice(-this.maxSize);
45
+ }
46
+ this.saveHistory();
47
+ }
48
+ }
49
+
50
+ get(): string[] {
51
+ return [...this.history];
52
+ }
53
+
54
+ search(query: string): string[] {
55
+ return this.history.filter(cmd => cmd.includes(query));
56
+ }
57
+
58
+ private async loadHistory(): Promise<void> {
59
+ try {
60
+ const content = await Deno.readTextFile(this.historyFile);
61
+ this.history = content.split('\n').filter(line => line.trim());
62
+ } catch {
63
+ // History file doesn't exist yet
64
+ }
65
+ }
66
+
67
+ private async saveHistory(): Promise<void> {
68
+ try {
69
+ await Deno.writeTextFile(this.historyFile, this.history.join('\n'));
70
+ } catch {
71
+ // Ignore save errors
72
+ }
73
+ }
74
+ }
75
+
76
+ class CommandCompleter {
77
+ private commands: Map<string, REPLCommand> = new Map();
78
+
79
+ setCommands(commands: REPLCommand[]): void {
80
+ this.commands.clear();
81
+ for (const cmd of commands) {
82
+ this.commands.set(cmd.name, cmd);
83
+ if (cmd.aliases) {
84
+ for (const alias of cmd.aliases) {
85
+ this.commands.set(alias, cmd);
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ complete(input: string): string[] {
92
+ const parts = input.trim().split(/\s+/);
93
+
94
+ if (parts.length === 1) {
95
+ // Complete command names
96
+ const prefix = parts[0];
97
+ return Array.from(this.commands.keys())
98
+ .filter(name => name.startsWith(prefix))
99
+ .sort();
100
+ }
101
+
102
+ // Complete subcommands and arguments
103
+ const commandName = parts[0];
104
+ const command = this.commands.get(commandName);
105
+
106
+ if (command) {
107
+ return this.completeForCommand(command, parts.slice(1));
108
+ }
109
+
110
+ return [];
111
+ }
112
+
113
+ private completeForCommand(command: REPLCommand, args: string[]): string[] {
114
+ // Basic completion for known commands
115
+ switch (command.name) {
116
+ case 'agent':
117
+ if (args.length === 1) {
118
+ return ['spawn', 'list', 'terminate', 'info'].filter(sub =>
119
+ sub.startsWith(args[0])
120
+ );
121
+ }
122
+ if (args[0] === 'spawn' && args.length === 2) {
123
+ return ['coordinator', 'researcher', 'implementer', 'analyst', 'custom']
124
+ .filter(type => type.startsWith(args[1]));
125
+ }
126
+ break;
127
+
128
+ case 'task':
129
+ if (args.length === 1) {
130
+ return ['create', 'list', 'status', 'cancel', 'workflow'].filter(sub =>
131
+ sub.startsWith(args[0])
132
+ );
133
+ }
134
+ if (args[0] === 'create' && args.length === 2) {
135
+ return ['research', 'implementation', 'analysis', 'coordination']
136
+ .filter(type => type.startsWith(args[1]));
137
+ }
138
+ break;
139
+
140
+ case 'session':
141
+ if (args.length === 1) {
142
+ return ['list', 'save', 'restore', 'delete', 'export', 'import']
143
+ .filter(sub => sub.startsWith(args[0]));
144
+ }
145
+ break;
146
+
147
+ case 'workflow':
148
+ if (args.length === 1) {
149
+ return ['run', 'validate', 'list', 'status', 'stop', 'template']
150
+ .filter(sub => sub.startsWith(args[0]));
151
+ }
152
+ break;
153
+ }
154
+
155
+ return [];
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Start the enhanced interactive REPL
161
+ */
162
+ export async function startREPL(options: any = {}): Promise<void> {
163
+ const context: REPLContext = {
164
+ options,
165
+ history: [],
166
+ workingDirectory: Deno.cwd(),
167
+ connectionStatus: 'disconnected',
168
+ lastActivity: new Date(),
169
+ };
170
+
171
+ const history = new CommandHistory(options.historyFile);
172
+ const completer = new CommandCompleter();
173
+
174
+ const commands: REPLCommand[] = [
175
+ {
176
+ name: 'help',
177
+ aliases: ['h', '?'],
178
+ description: 'Show available commands or help for a specific command',
179
+ usage: 'help [command]',
180
+ examples: ['help', 'help agent', 'help task create'],
181
+ handler: async (args) => {
182
+ if (args.length === 0) {
183
+ showHelp(commands);
184
+ } else {
185
+ showCommandHelp(commands, args[0]);
186
+ }
187
+ },
188
+ },
189
+ {
190
+ name: 'status',
191
+ aliases: ['st'],
192
+ description: 'Show system status and connection info',
193
+ usage: 'status [component]',
194
+ examples: ['status', 'status orchestrator'],
195
+ handler: async (args, ctx) => {
196
+ await showSystemStatus(ctx, args[0]);
197
+ },
198
+ },
199
+ {
200
+ name: 'connect',
201
+ aliases: ['conn'],
202
+ description: 'Connect to Claude-Flow orchestrator',
203
+ usage: 'connect [host:port]',
204
+ examples: ['connect', 'connect localhost:3000'],
205
+ handler: async (args, ctx) => {
206
+ await connectToOrchestrator(ctx, args[0]);
207
+ },
208
+ },
209
+ {
210
+ name: 'agent',
211
+ description: 'Agent management (spawn, list, terminate, info)',
212
+ usage: 'agent <subcommand> [options]',
213
+ examples: [
214
+ 'agent list',
215
+ 'agent spawn researcher --name "Research Agent"',
216
+ 'agent info agent-001',
217
+ 'agent terminate agent-001'
218
+ ],
219
+ handler: async (args, ctx) => {
220
+ await handleAgentCommand(args, ctx);
221
+ },
222
+ },
223
+ {
224
+ name: 'task',
225
+ description: 'Task management (create, list, status, cancel)',
226
+ usage: 'task <subcommand> [options]',
227
+ examples: [
228
+ 'task list',
229
+ 'task create research "Find quantum computing papers"',
230
+ 'task status task-001',
231
+ 'task cancel task-001'
232
+ ],
233
+ handler: async (args, ctx) => {
234
+ await handleTaskCommand(args, ctx);
235
+ },
236
+ },
237
+ {
238
+ name: 'memory',
239
+ description: 'Memory operations (query, stats, export)',
240
+ usage: 'memory <subcommand> [options]',
241
+ examples: [
242
+ 'memory stats',
243
+ 'memory query --agent agent-001',
244
+ 'memory export memory.json'
245
+ ],
246
+ handler: async (args, ctx) => {
247
+ await handleMemoryCommand(args, ctx);
248
+ },
249
+ },
250
+ {
251
+ name: 'session',
252
+ description: 'Session management (save, restore, list)',
253
+ usage: 'session <subcommand> [options]',
254
+ examples: [
255
+ 'session list',
256
+ 'session save "Development Session"',
257
+ 'session restore session-001'
258
+ ],
259
+ handler: async (args, ctx) => {
260
+ await handleSessionCommand(args, ctx);
261
+ },
262
+ },
263
+ {
264
+ name: 'workflow',
265
+ description: 'Workflow operations (run, list, status)',
266
+ usage: 'workflow <subcommand> [options]',
267
+ examples: [
268
+ 'workflow list',
269
+ 'workflow run workflow.json',
270
+ 'workflow status workflow-001'
271
+ ],
272
+ handler: async (args, ctx) => {
273
+ await handleWorkflowCommand(args, ctx);
274
+ },
275
+ },
276
+ {
277
+ name: 'monitor',
278
+ aliases: ['mon'],
279
+ description: 'Start monitoring mode',
280
+ usage: 'monitor [--interval seconds]',
281
+ examples: ['monitor', 'monitor --interval 5'],
282
+ handler: async (args) => {
283
+ console.log(colors.cyan('Starting monitor mode...'));
284
+ console.log(colors.gray('(This would start the live dashboard)'));
285
+ },
286
+ },
287
+ {
288
+ name: 'history',
289
+ aliases: ['hist'],
290
+ description: 'Show command history',
291
+ usage: 'history [--search query]',
292
+ examples: ['history', 'history --search agent'],
293
+ handler: async (args) => {
294
+ const searchQuery = args.indexOf('--search') >= 0 ? args[args.indexOf('--search') + 1] : null;
295
+ const historyItems = searchQuery ? history.search(searchQuery) : history.get();
296
+
297
+ console.log(colors.cyan.bold(`Command History${searchQuery ? ` (search: ${searchQuery})` : ''}`));
298
+ console.log('─'.repeat(50));
299
+
300
+ if (historyItems.length === 0) {
301
+ console.log(colors.gray('No commands in history'));
302
+ return;
303
+ }
304
+
305
+ const recent = historyItems.slice(-20); // Show last 20
306
+ recent.forEach((cmd, i) => {
307
+ const lineNumber = historyItems.length - recent.length + i + 1;
308
+ console.log(`${colors.gray(lineNumber.toString().padStart(3))} ${cmd}`);
309
+ });
310
+ },
311
+ },
312
+ {
313
+ name: 'clear',
314
+ aliases: ['cls'],
315
+ description: 'Clear the screen',
316
+ handler: async () => {
317
+ console.clear();
318
+ },
319
+ },
320
+ {
321
+ name: 'cd',
322
+ description: 'Change working directory',
323
+ usage: 'cd <directory>',
324
+ examples: ['cd /path/to/project', 'cd ..'],
325
+ handler: async (args, ctx) => {
326
+ if (args.length === 0) {
327
+ console.log(ctx.workingDirectory);
328
+ return;
329
+ }
330
+
331
+ try {
332
+ const newDir = args[0] === '~' ? Deno.env.get('HOME') || '/' : args[0];
333
+ Deno.chdir(newDir);
334
+ ctx.workingDirectory = Deno.cwd();
335
+ console.log(colors.gray(`Changed to: ${ctx.workingDirectory}`));
336
+ } catch (error) {
337
+ console.error(colors.red('Error:'), error instanceof Error ? error.message : String(error));
338
+ }
339
+ },
340
+ },
341
+ {
342
+ name: 'pwd',
343
+ description: 'Print working directory',
344
+ handler: async (_, ctx) => {
345
+ console.log(ctx.workingDirectory);
346
+ },
347
+ },
348
+ {
349
+ name: 'echo',
350
+ description: 'Echo arguments',
351
+ usage: 'echo <text>',
352
+ examples: ['echo "Hello, world!"'],
353
+ handler: async (args) => {
354
+ console.log(args.join(' '));
355
+ },
356
+ },
357
+ {
358
+ name: 'exit',
359
+ aliases: ['quit', 'q'],
360
+ description: 'Exit the REPL',
361
+ handler: async () => {
362
+ console.log(colors.gray('Goodbye!'));
363
+ Deno.exit(0);
364
+ },
365
+ },
366
+ ];
367
+
368
+ // Set up command completion
369
+ completer.setCommands(commands);
370
+
371
+ // Show initial status
372
+ if (!options.quiet) {
373
+ await showSystemStatus(context);
374
+ console.log(colors.gray('Type "help" for available commands or "exit" to quit.\n'));
375
+ }
376
+
377
+ // Main REPL loop
378
+ while (true) {
379
+ try {
380
+ const prompt = createPrompt(context);
381
+ const input = await Input.prompt({
382
+ message: prompt,
383
+ suggestions: (input: string) => completer.complete(input),
384
+ });
385
+
386
+ if (!input.trim()) {
387
+ continue;
388
+ }
389
+
390
+ // Add to history
391
+ history.add(input);
392
+ context.history.push(input);
393
+ context.lastActivity = new Date();
394
+
395
+ // Parse command
396
+ const args = parseCommand(input);
397
+ const [commandName, ...commandArgs] = args;
398
+
399
+ // Find and execute command
400
+ const command = commands.find(c =>
401
+ c.name === commandName ||
402
+ (c.aliases && c.aliases.includes(commandName))
403
+ );
404
+
405
+ if (command) {
406
+ try {
407
+ await command.handler(commandArgs, context);
408
+ } catch (error) {
409
+ console.error(colors.red('Command failed:'), error instanceof Error ? error.message : String(error));
410
+ }
411
+ } else {
412
+ console.log(colors.red(`Unknown command: ${commandName}`));
413
+ console.log(colors.gray('Type "help" for available commands'));
414
+
415
+ // Suggest similar commands
416
+ const suggestions = findSimilarCommands(commandName, commands);
417
+ if (suggestions.length > 0) {
418
+ console.log(colors.gray('Did you mean:'), suggestions.map(s => colors.cyan(s)).join(', '));
419
+ }
420
+ }
421
+ } catch (error) {
422
+ const errorMessage = error instanceof Error ? error.message : String(error);
423
+ if (errorMessage.includes('EOF') || errorMessage.includes('interrupted')) {
424
+ // Ctrl+D or Ctrl+C pressed
425
+ console.log('\n' + colors.gray('Goodbye!'));
426
+ break;
427
+ }
428
+ console.error(colors.red('REPL Error:'), errorMessage);
429
+ }
430
+ }
431
+ }
432
+
433
+ function createPrompt(context: REPLContext): string {
434
+ const statusIcon = getConnectionStatusIcon(context.connectionStatus);
435
+ const dir = context.workingDirectory.split('/').pop() || '/';
436
+
437
+ return `${statusIcon} ${colors.cyan('claude-flow')}:${colors.yellow(dir)}${colors.white('>')} `;
438
+ }
439
+
440
+ function getConnectionStatusIcon(status: string): string {
441
+ switch (status) {
442
+ case 'connected': return colors.green('●');
443
+ case 'connecting': return colors.yellow('◐');
444
+ case 'disconnected': return colors.red('○');
445
+ default: return colors.gray('?');
446
+ }
447
+ }
448
+
449
+ function parseCommand(input: string): string[] {
450
+ // Simple command parsing - handle quoted strings
451
+ const args: string[] = [];
452
+ let current = '';
453
+ let inQuotes = false;
454
+ let quoteChar = '';
455
+
456
+ for (let i = 0; i < input.length; i++) {
457
+ const char = input[i];
458
+
459
+ if (inQuotes) {
460
+ if (char === quoteChar) {
461
+ inQuotes = false;
462
+ quoteChar = '';
463
+ } else {
464
+ current += char;
465
+ }
466
+ } else {
467
+ if (char === '"' || char === "'") {
468
+ inQuotes = true;
469
+ quoteChar = char;
470
+ } else if (char === ' ' || char === '\t') {
471
+ if (current.trim()) {
472
+ args.push(current.trim());
473
+ current = '';
474
+ }
475
+ } else {
476
+ current += char;
477
+ }
478
+ }
479
+ }
480
+
481
+ if (current.trim()) {
482
+ args.push(current.trim());
483
+ }
484
+
485
+ return args;
486
+ }
487
+
488
+ function showHelp(commands: REPLCommand[]): void {
489
+ console.log(colors.cyan.bold('Claude-Flow Interactive REPL'));
490
+ console.log('─'.repeat(50));
491
+ console.log();
492
+
493
+ console.log(colors.white.bold('Available Commands:'));
494
+ console.log();
495
+
496
+ const table = new Table()
497
+ .header(['Command', 'Aliases', 'Description'])
498
+ .border(false);
499
+
500
+ for (const cmd of commands) {
501
+ table.push([
502
+ colors.cyan(cmd.name),
503
+ cmd.aliases ? colors.gray(cmd.aliases.join(', ')) : '',
504
+ cmd.description
505
+ ]);
506
+ }
507
+
508
+ table.render();
509
+ console.log();
510
+
511
+ console.log(colors.gray('Tips:'));
512
+ console.log(colors.gray('• Use TAB for command completion'));
513
+ console.log(colors.gray('• Use "help <command>" for detailed help'));
514
+ console.log(colors.gray('• Use UP/DOWN arrows for command history'));
515
+ console.log(colors.gray('• Use Ctrl+C or "exit" to quit'));
516
+ }
517
+
518
+ function showCommandHelp(commands: REPLCommand[], commandName: string): void {
519
+ const command = commands.find(c =>
520
+ c.name === commandName ||
521
+ (c.aliases && c.aliases.includes(commandName))
522
+ );
523
+
524
+ if (!command) {
525
+ console.log(colors.red(`Unknown command: ${commandName}`));
526
+ return;
527
+ }
528
+
529
+ console.log(colors.cyan.bold(`Command: ${command.name}`));
530
+ console.log('─'.repeat(30));
531
+ console.log(`${colors.white('Description:')} ${command.description}`);
532
+
533
+ if (command.aliases) {
534
+ console.log(`${colors.white('Aliases:')} ${command.aliases.join(', ')}`);
535
+ }
536
+
537
+ if (command.usage) {
538
+ console.log(`${colors.white('Usage:')} ${command.usage}`);
539
+ }
540
+
541
+ if (command.examples) {
542
+ console.log();
543
+ console.log(colors.white.bold('Examples:'));
544
+ for (const example of command.examples) {
545
+ console.log(` ${colors.gray('$')} ${colors.cyan(example)}`);
546
+ }
547
+ }
548
+ }
549
+
550
+ async function showSystemStatus(context: REPLContext, component?: string): Promise<void> {
551
+ console.log(colors.cyan.bold('System Status'));
552
+ console.log('─'.repeat(30));
553
+
554
+ const statusIcon = formatStatusIndicator(context.connectionStatus === 'connected' ? 'success' : 'error');
555
+ console.log(`${statusIcon} Connection: ${context.connectionStatus}`);
556
+ console.log(`${colors.white('Working Directory:')} ${context.workingDirectory}`);
557
+ console.log(`${colors.white('Last Activity:')} ${context.lastActivity.toLocaleTimeString()}`);
558
+
559
+ if (context.currentSession) {
560
+ console.log(`${colors.white('Current Session:')} ${context.currentSession}`);
561
+ }
562
+
563
+ console.log(`${colors.white('Commands in History:')} ${context.history.length}`);
564
+
565
+ if (context.connectionStatus === 'disconnected') {
566
+ console.log();
567
+ console.log(colors.yellow('⚠ Not connected to orchestrator'));
568
+ console.log(colors.gray('Use "connect" command to establish connection'));
569
+ }
570
+ }
571
+
572
+ async function connectToOrchestrator(context: REPLContext, target?: string): Promise<void> {
573
+ const host = target || 'localhost:3000';
574
+
575
+ console.log(colors.yellow(`Connecting to ${host}...`));
576
+ context.connectionStatus = 'connecting';
577
+
578
+ // Mock connection attempt
579
+ await new Promise(resolve => setTimeout(resolve, 1000));
580
+
581
+ // Simulate connection result
582
+ const success = Math.random() > 0.3; // 70% success rate
583
+
584
+ if (success) {
585
+ context.connectionStatus = 'connected';
586
+ console.log(colors.green('✓ Connected successfully'));
587
+ } else {
588
+ context.connectionStatus = 'disconnected';
589
+ console.log(colors.red('✗ Connection failed'));
590
+ console.log(colors.gray('Make sure Claude-Flow is running with: claude-flow start'));
591
+ }
592
+ }
593
+
594
+ async function handleAgentCommand(args: string[], context: REPLContext): Promise<void> {
595
+ if (context.connectionStatus !== 'connected') {
596
+ console.log(colors.yellow('⚠ Not connected to orchestrator'));
597
+ console.log(colors.gray('Use "connect" to establish connection first'));
598
+ return;
599
+ }
600
+
601
+ if (args.length === 0) {
602
+ console.log(colors.gray('Usage: agent <spawn|list|terminate|info> [options]'));
603
+ return;
604
+ }
605
+
606
+ const subcommand = args[0];
607
+ switch (subcommand) {
608
+ case 'list':
609
+ await showAgentList();
610
+ break;
611
+ case 'spawn':
612
+ await handleAgentSpawn(args.slice(1));
613
+ break;
614
+ case 'terminate':
615
+ if (args.length < 2) {
616
+ console.log(colors.red('Please specify agent ID'));
617
+ } else {
618
+ await handleAgentTerminate(args[1]);
619
+ }
620
+ break;
621
+ case 'info':
622
+ if (args.length < 2) {
623
+ console.log(colors.red('Please specify agent ID'));
624
+ } else {
625
+ await showAgentInfo(args[1]);
626
+ }
627
+ break;
628
+ default:
629
+ console.log(colors.red(`Unknown agent subcommand: ${subcommand}`));
630
+ }
631
+ }
632
+
633
+ async function showAgentList(): Promise<void> {
634
+ // Mock agent data
635
+ const agents = [
636
+ { id: 'agent-001', name: 'Coordinator', type: 'coordinator', status: 'active', tasks: 2 },
637
+ { id: 'agent-002', name: 'Researcher', type: 'researcher', status: 'active', tasks: 5 },
638
+ { id: 'agent-003', name: 'Implementer', type: 'implementer', status: 'idle', tasks: 0 },
639
+ ];
640
+
641
+ console.log(colors.cyan.bold(`Active Agents (${agents.length})`));
642
+ console.log('─'.repeat(50));
643
+
644
+ const table = new Table()
645
+ .header(['ID', 'Name', 'Type', 'Status', 'Tasks'])
646
+ .border(true);
647
+
648
+ for (const agent of agents) {
649
+ const statusIcon = formatStatusIndicator(agent.status);
650
+
651
+ table.push([
652
+ colors.gray(agent.id),
653
+ colors.white(agent.name),
654
+ colors.cyan(agent.type),
655
+ `${statusIcon} ${agent.status}`,
656
+ agent.tasks.toString()
657
+ ]);
658
+ }
659
+
660
+ table.render();
661
+ }
662
+
663
+ async function handleAgentSpawn(args: string[]): Promise<void> {
664
+ if (args.length === 0) {
665
+ console.log(colors.gray('Usage: agent spawn <type> [name]'));
666
+ console.log(colors.gray('Types: coordinator, researcher, implementer, analyst, custom'));
667
+ return;
668
+ }
669
+
670
+ const type = args[0];
671
+ const name = args[1] || await Input.prompt({
672
+ message: 'Agent name:',
673
+ default: `${type}-agent`,
674
+ });
675
+
676
+ console.log(colors.yellow('Spawning agent...'));
677
+
678
+ // Mock spawning
679
+ await new Promise(resolve => setTimeout(resolve, 1000));
680
+
681
+ const agentId = generateId('agent');
682
+ console.log(colors.green('✓ Agent spawned successfully'));
683
+ console.log(`${colors.white('ID:')} ${agentId}`);
684
+ console.log(`${colors.white('Name:')} ${name}`);
685
+ console.log(`${colors.white('Type:')} ${type}`);
686
+ }
687
+
688
+ async function handleAgentTerminate(agentId: string): Promise<void> {
689
+ const confirmed = await Confirm.prompt({
690
+ message: `Terminate agent ${agentId}?`,
691
+ default: false,
692
+ });
693
+
694
+ if (!confirmed) {
695
+ console.log(colors.gray('Termination cancelled'));
696
+ return;
697
+ }
698
+
699
+ console.log(colors.yellow('Terminating agent...'));
700
+ await new Promise(resolve => setTimeout(resolve, 500));
701
+ console.log(colors.green('✓ Agent terminated'));
702
+ }
703
+
704
+ async function showAgentInfo(agentId: string): Promise<void> {
705
+ // Mock agent info
706
+ console.log(colors.cyan.bold('Agent Information'));
707
+ console.log('─'.repeat(30));
708
+ console.log(`${colors.white('ID:')} ${agentId}`);
709
+ console.log(`${colors.white('Name:')} Research Agent`);
710
+ console.log(`${colors.white('Type:')} researcher`);
711
+ console.log(`${colors.white('Status:')} ${formatStatusIndicator('success')} active`);
712
+ console.log(`${colors.white('Uptime:')} ${formatDuration(3600000)}`);
713
+ console.log(`${colors.white('Active Tasks:')} 3`);
714
+ console.log(`${colors.white('Completed Tasks:')} 12`);
715
+ }
716
+
717
+ async function handleTaskCommand(args: string[], context: REPLContext): Promise<void> {
718
+ if (context.connectionStatus !== 'connected') {
719
+ console.log(colors.yellow('⚠ Not connected to orchestrator'));
720
+ return;
721
+ }
722
+
723
+ if (args.length === 0) {
724
+ console.log(colors.gray('Usage: task <create|list|status|cancel> [options]'));
725
+ return;
726
+ }
727
+
728
+ const subcommand = args[0];
729
+ switch (subcommand) {
730
+ case 'list':
731
+ await showTaskList();
732
+ break;
733
+ case 'create':
734
+ await handleTaskCreate(args.slice(1));
735
+ break;
736
+ case 'status':
737
+ if (args.length < 2) {
738
+ console.log(colors.red('Please specify task ID'));
739
+ } else {
740
+ await showTaskStatus(args[1]);
741
+ }
742
+ break;
743
+ case 'cancel':
744
+ if (args.length < 2) {
745
+ console.log(colors.red('Please specify task ID'));
746
+ } else {
747
+ await handleTaskCancel(args[1]);
748
+ }
749
+ break;
750
+ default:
751
+ console.log(colors.red(`Unknown task subcommand: ${subcommand}`));
752
+ }
753
+ }
754
+
755
+ async function showTaskList(): Promise<void> {
756
+ // Mock task data
757
+ const tasks = [
758
+ { id: 'task-001', type: 'research', description: 'Research quantum computing', status: 'running', agent: 'agent-002' },
759
+ { id: 'task-002', type: 'analysis', description: 'Analyze research results', status: 'pending', agent: null },
760
+ { id: 'task-003', type: 'implementation', description: 'Implement solution', status: 'completed', agent: 'agent-003' },
761
+ ];
762
+
763
+ console.log(colors.cyan.bold(`Tasks (${tasks.length})`));
764
+ console.log('─'.repeat(60));
765
+
766
+ const table = new Table()
767
+ .header(['ID', 'Type', 'Description', 'Status', 'Agent'])
768
+ .border(true);
769
+
770
+ for (const task of tasks) {
771
+ const statusIcon = formatStatusIndicator(task.status);
772
+
773
+ table.push([
774
+ colors.gray(task.id),
775
+ colors.white(task.type),
776
+ task.description.substring(0, 30) + (task.description.length > 30 ? '...' : ''),
777
+ `${statusIcon} ${task.status}`,
778
+ task.agent ? colors.cyan(task.agent) : '-'
779
+ ]);
780
+ }
781
+
782
+ table.render();
783
+ }
784
+
785
+ async function handleTaskCreate(args: string[]): Promise<void> {
786
+ if (args.length < 2) {
787
+ console.log(colors.gray('Usage: task create <type> <description>'));
788
+ return;
789
+ }
790
+
791
+ const type = args[0];
792
+ const description = args.slice(1).join(' ');
793
+
794
+ console.log(colors.yellow('Creating task...'));
795
+ await new Promise(resolve => setTimeout(resolve, 500));
796
+
797
+ const taskId = generateId('task');
798
+ console.log(colors.green('✓ Task created successfully'));
799
+ console.log(`${colors.white('ID:')} ${taskId}`);
800
+ console.log(`${colors.white('Type:')} ${type}`);
801
+ console.log(`${colors.white('Description:')} ${description}`);
802
+ }
803
+
804
+ async function showTaskStatus(taskId: string): Promise<void> {
805
+ console.log(colors.cyan.bold('Task Status'));
806
+ console.log('─'.repeat(30));
807
+ console.log(`${colors.white('ID:')} ${taskId}`);
808
+ console.log(`${colors.white('Type:')} research`);
809
+ console.log(`${colors.white('Status:')} ${formatStatusIndicator('running')} running`);
810
+ console.log(`${colors.white('Progress:')} ${formatProgressBar(65, 100, 20)} 65%`);
811
+ console.log(`${colors.white('Agent:')} agent-002`);
812
+ console.log(`${colors.white('Started:')} ${new Date().toLocaleTimeString()}`);
813
+ }
814
+
815
+ async function handleTaskCancel(taskId: string): Promise<void> {
816
+ const confirmed = await Confirm.prompt({
817
+ message: `Cancel task ${taskId}?`,
818
+ default: false,
819
+ });
820
+
821
+ if (!confirmed) {
822
+ console.log(colors.gray('Cancellation cancelled'));
823
+ return;
824
+ }
825
+
826
+ console.log(colors.yellow('Cancelling task...'));
827
+ await new Promise(resolve => setTimeout(resolve, 500));
828
+ console.log(colors.green('✓ Task cancelled'));
829
+ }
830
+
831
+ async function handleMemoryCommand(args: string[], context: REPLContext): Promise<void> {
832
+ if (context.connectionStatus !== 'connected') {
833
+ console.log(colors.yellow('⚠ Not connected to orchestrator'));
834
+ return;
835
+ }
836
+
837
+ if (args.length === 0) {
838
+ console.log(colors.gray('Usage: memory <query|stats|export> [options]'));
839
+ return;
840
+ }
841
+
842
+ const subcommand = args[0];
843
+ switch (subcommand) {
844
+ case 'stats':
845
+ await showMemoryStats();
846
+ break;
847
+ case 'query':
848
+ console.log(colors.yellow('Memory query functionality not yet implemented in REPL'));
849
+ break;
850
+ case 'export':
851
+ console.log(colors.yellow('Memory export functionality not yet implemented in REPL'));
852
+ break;
853
+ default:
854
+ console.log(colors.red(`Unknown memory subcommand: ${subcommand}`));
855
+ }
856
+ }
857
+
858
+ async function showMemoryStats(): Promise<void> {
859
+ console.log(colors.cyan.bold('Memory Statistics'));
860
+ console.log('─'.repeat(30));
861
+ console.log(`${colors.white('Total Entries:')} 1,247`);
862
+ console.log(`${colors.white('Cache Size:')} 95 MB`);
863
+ console.log(`${colors.white('Hit Rate:')} 94.2%`);
864
+ console.log(`${colors.white('Backend:')} SQLite + Markdown`);
865
+ }
866
+
867
+ async function handleSessionCommand(args: string[], context: REPLContext): Promise<void> {
868
+ if (args.length === 0) {
869
+ console.log(colors.gray('Usage: session <list|save|restore> [options]'));
870
+ return;
871
+ }
872
+
873
+ const subcommand = args[0];
874
+ switch (subcommand) {
875
+ case 'list':
876
+ await showSessionList();
877
+ break;
878
+ case 'save':
879
+ await handleSessionSave(args.slice(1));
880
+ break;
881
+ case 'restore':
882
+ if (args.length < 2) {
883
+ console.log(colors.red('Please specify session ID'));
884
+ } else {
885
+ await handleSessionRestore(args[1]);
886
+ }
887
+ break;
888
+ default:
889
+ console.log(colors.red(`Unknown session subcommand: ${subcommand}`));
890
+ }
891
+ }
892
+
893
+ async function showSessionList(): Promise<void> {
894
+ // Mock session data
895
+ const sessions = [
896
+ { id: 'session-001', name: 'Research Project', date: '2024-01-15', agents: 3, tasks: 8 },
897
+ { id: 'session-002', name: 'Development', date: '2024-01-14', agents: 2, tasks: 5 },
898
+ ];
899
+
900
+ console.log(colors.cyan.bold(`Saved Sessions (${sessions.length})`));
901
+ console.log('─'.repeat(50));
902
+
903
+ const table = new Table()
904
+ .header(['ID', 'Name', 'Date', 'Agents', 'Tasks'])
905
+ .border(true);
906
+
907
+ for (const session of sessions) {
908
+ table.push([
909
+ colors.gray(session.id),
910
+ colors.white(session.name),
911
+ session.date,
912
+ session.agents.toString(),
913
+ session.tasks.toString()
914
+ ]);
915
+ }
916
+
917
+ table.render();
918
+ }
919
+
920
+ async function handleSessionSave(args: string[]): Promise<void> {
921
+ const name = args.length > 0 ? args.join(' ') : await Input.prompt({
922
+ message: 'Session name:',
923
+ default: `session-${new Date().toISOString().split('T')[0]}`,
924
+ });
925
+
926
+ console.log(colors.yellow('Saving session...'));
927
+ await new Promise(resolve => setTimeout(resolve, 1000));
928
+
929
+ const sessionId = generateId('session');
930
+ console.log(colors.green('✓ Session saved successfully'));
931
+ console.log(`${colors.white('ID:')} ${sessionId}`);
932
+ console.log(`${colors.white('Name:')} ${name}`);
933
+ }
934
+
935
+ async function handleSessionRestore(sessionId: string): Promise<void> {
936
+ const confirmed = await Confirm.prompt({
937
+ message: `Restore session ${sessionId}?`,
938
+ default: false,
939
+ });
940
+
941
+ if (!confirmed) {
942
+ console.log(colors.gray('Restore cancelled'));
943
+ return;
944
+ }
945
+
946
+ console.log(colors.yellow('Restoring session...'));
947
+ await new Promise(resolve => setTimeout(resolve, 1500));
948
+ console.log(colors.green('✓ Session restored successfully'));
949
+ }
950
+
951
+ async function handleWorkflowCommand(args: string[], context: REPLContext): Promise<void> {
952
+ if (context.connectionStatus !== 'connected') {
953
+ console.log(colors.yellow('⚠ Not connected to orchestrator'));
954
+ return;
955
+ }
956
+
957
+ if (args.length === 0) {
958
+ console.log(colors.gray('Usage: workflow <list|run|status> [options]'));
959
+ return;
960
+ }
961
+
962
+ const subcommand = args[0];
963
+ switch (subcommand) {
964
+ case 'list':
965
+ await showWorkflowList();
966
+ break;
967
+ case 'run':
968
+ if (args.length < 2) {
969
+ console.log(colors.red('Please specify workflow file'));
970
+ } else {
971
+ await handleWorkflowRun(args[1]);
972
+ }
973
+ break;
974
+ case 'status':
975
+ if (args.length < 2) {
976
+ console.log(colors.red('Please specify workflow ID'));
977
+ } else {
978
+ await showWorkflowStatus(args[1]);
979
+ }
980
+ break;
981
+ default:
982
+ console.log(colors.red(`Unknown workflow subcommand: ${subcommand}`));
983
+ }
984
+ }
985
+
986
+ async function showWorkflowList(): Promise<void> {
987
+ // Mock workflow data
988
+ const workflows = [
989
+ { id: 'workflow-001', name: 'Research Pipeline', status: 'running', progress: 60 },
990
+ { id: 'workflow-002', name: 'Data Analysis', status: 'completed', progress: 100 },
991
+ ];
992
+
993
+ console.log(colors.cyan.bold(`Workflows (${workflows.length})`));
994
+ console.log('─'.repeat(50));
995
+
996
+ const table = new Table()
997
+ .header(['ID', 'Name', 'Status', 'Progress'])
998
+ .border(true);
999
+
1000
+ for (const workflow of workflows) {
1001
+ const statusIcon = formatStatusIndicator(workflow.status);
1002
+ const progressBar = formatProgressBar(workflow.progress, 100, 15);
1003
+
1004
+ table.push([
1005
+ colors.gray(workflow.id),
1006
+ colors.white(workflow.name),
1007
+ `${statusIcon} ${workflow.status}`,
1008
+ `${progressBar} ${workflow.progress}%`
1009
+ ]);
1010
+ }
1011
+
1012
+ table.render();
1013
+ }
1014
+
1015
+ async function handleWorkflowRun(filename: string): Promise<void> {
1016
+ try {
1017
+ await Deno.stat(filename);
1018
+ console.log(colors.yellow(`Running workflow: ${filename}`));
1019
+ await new Promise(resolve => setTimeout(resolve, 1000));
1020
+
1021
+ const workflowId = generateId('workflow');
1022
+ console.log(colors.green('✓ Workflow started successfully'));
1023
+ console.log(`${colors.white('ID:')} ${workflowId}`);
1024
+ } catch {
1025
+ console.log(colors.red(`Workflow file not found: ${filename}`));
1026
+ }
1027
+ }
1028
+
1029
+ async function showWorkflowStatus(workflowId: string): Promise<void> {
1030
+ console.log(colors.cyan.bold('Workflow Status'));
1031
+ console.log('─'.repeat(30));
1032
+ console.log(`${colors.white('ID:')} ${workflowId}`);
1033
+ console.log(`${colors.white('Name:')} Research Pipeline`);
1034
+ console.log(`${colors.white('Status:')} ${formatStatusIndicator('running')} running`);
1035
+ console.log(`${colors.white('Progress:')} ${formatProgressBar(75, 100, 20)} 75%`);
1036
+ console.log(`${colors.white('Tasks:')} 6/8 completed`);
1037
+ console.log(`${colors.white('Started:')} ${new Date().toLocaleTimeString()}`);
1038
+ }
1039
+
1040
+ function findSimilarCommands(input: string, commands: REPLCommand[]): string[] {
1041
+ const allNames = commands.flatMap(c => [c.name, ...(c.aliases || [])]);
1042
+
1043
+ return allNames
1044
+ .filter(name => {
1045
+ // Simple similarity check - could use Levenshtein distance
1046
+ const commonChars = input.split('').filter(char => name.includes(char)).length;
1047
+ return commonChars >= Math.min(2, input.length / 2);
1048
+ })
1049
+ .slice(0, 3); // Top 3 suggestions
1050
+ }