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,504 @@
1
+ /**
2
+ * Native terminal adapter implementation
3
+ */
4
+
5
+ import { ITerminalAdapter, Terminal } from './base.ts';
6
+ import { ILogger } from '../../core/logger.ts';
7
+ import { TerminalError, TerminalCommandError } from '../../utils/errors.ts';
8
+ import { generateId, delay, timeout, createDeferred } from '../../utils/helpers.ts';
9
+
10
+ /**
11
+ * Platform-specific shell configuration
12
+ */
13
+ interface ShellConfig {
14
+ path: string;
15
+ args: string[];
16
+ env?: Record<string, string>;
17
+ }
18
+
19
+ /**
20
+ * Native terminal implementation using Deno subprocess
21
+ */
22
+ class NativeTerminal implements Terminal {
23
+ id: string;
24
+ pid?: number;
25
+ private process?: Deno.ChildProcess | undefined;
26
+ private encoder = new TextEncoder();
27
+ private decoder = new TextDecoder();
28
+ private shell: string;
29
+ private outputBuffer = '';
30
+ private errorBuffer = '';
31
+ private commandMarker: string;
32
+ private commandDeferred?: ReturnType<typeof createDeferred<string>> | undefined;
33
+ private outputListeners = new Set<(data: string) => void>();
34
+ private alive = true;
35
+ private stdoutReader?: ReadableStreamDefaultReader<Uint8Array> | undefined;
36
+ private stderrReader?: ReadableStreamDefaultReader<Uint8Array> | undefined;
37
+
38
+ constructor(shell: string, private logger: ILogger) {
39
+ this.id = generateId('native-term');
40
+ this.shell = shell;
41
+ this.commandMarker = `__CLAUDE_FLOW_${this.id}__`;
42
+ }
43
+
44
+ async initialize(): Promise<void> {
45
+ try {
46
+ const shellConfig = this.getShellConfig();
47
+
48
+ // Start shell process
49
+ const command = new Deno.Command(shellConfig.path, {
50
+ args: shellConfig.args,
51
+ stdin: 'piped',
52
+ stdout: 'piped',
53
+ stderr: 'piped',
54
+ env: {
55
+ ...Deno.env.toObject(),
56
+ ...shellConfig.env,
57
+ CLAUDE_FLOW_TERMINAL: 'true',
58
+ CLAUDE_FLOW_TERMINAL_ID: this.id,
59
+ },
60
+ });
61
+
62
+ this.process = command.spawn();
63
+
64
+ // Get PID if available
65
+ if ('pid' in this.process) {
66
+ this.pid = (this.process as any).pid;
67
+ }
68
+
69
+ // Start output readers
70
+ this.startOutputReader();
71
+ this.startErrorReader();
72
+
73
+ // Monitor process status
74
+ this.monitorProcess();
75
+
76
+ // Wait for shell to be ready
77
+ await this.waitForReady();
78
+
79
+ this.logger.debug('Native terminal initialized', {
80
+ id: this.id,
81
+ pid: this.pid,
82
+ shell: this.shell,
83
+ });
84
+ } catch (error) {
85
+ this.alive = false;
86
+ throw new TerminalError('Failed to create native terminal', { error });
87
+ }
88
+ }
89
+
90
+ async executeCommand(command: string): Promise<string> {
91
+ if (!this.process || !this.isAlive()) {
92
+ throw new TerminalError('Terminal is not alive');
93
+ }
94
+
95
+ try {
96
+ // Create deferred for this command
97
+ this.commandDeferred = createDeferred<string>();
98
+
99
+ // Clear output buffer
100
+ this.outputBuffer = '';
101
+
102
+ // Send command with marker
103
+ const markedCommand = this.wrapCommand(command);
104
+ await this.write(markedCommand + '\n');
105
+
106
+ // Wait for command to complete
107
+ const output = await timeout(
108
+ this.commandDeferred.promise,
109
+ 30000,
110
+ 'Command execution timeout',
111
+ );
112
+
113
+ return output;
114
+ } catch (error) {
115
+ throw new TerminalCommandError('Failed to execute command', { command, error });
116
+ }
117
+ }
118
+
119
+ async write(data: string): Promise<void> {
120
+ if (!this.process || !this.isAlive()) {
121
+ throw new TerminalError('Terminal is not alive');
122
+ }
123
+
124
+ const writer = this.process.stdin.getWriter();
125
+ try {
126
+ await writer.write(this.encoder.encode(data));
127
+ } finally {
128
+ writer.releaseLock();
129
+ }
130
+ }
131
+
132
+ async read(): Promise<string> {
133
+ if (!this.process || !this.isAlive()) {
134
+ throw new TerminalError('Terminal is not alive');
135
+ }
136
+
137
+ // Return buffered output
138
+ const output = this.outputBuffer;
139
+ this.outputBuffer = '';
140
+ return output;
141
+ }
142
+
143
+ isAlive(): boolean {
144
+ return this.alive && this.process !== undefined;
145
+ }
146
+
147
+ async kill(): Promise<void> {
148
+ if (!this.process) return;
149
+
150
+ try {
151
+ this.alive = false;
152
+
153
+ // Cancel readers
154
+ if (this.stdoutReader) {
155
+ await this.stdoutReader.cancel();
156
+ }
157
+ if (this.stderrReader) {
158
+ await this.stderrReader.cancel();
159
+ }
160
+
161
+ // Try graceful shutdown first
162
+ try {
163
+ await this.write('exit\n');
164
+ await delay(500);
165
+ } catch {
166
+ // Ignore write errors during shutdown
167
+ }
168
+
169
+ // Force kill if still alive
170
+ try {
171
+ this.process.kill('SIGTERM');
172
+ await delay(500);
173
+
174
+ // Use SIGKILL if SIGTERM didn't work
175
+ this.process.kill('SIGKILL');
176
+ } catch {
177
+ // Process might already be dead
178
+ }
179
+
180
+ // Wait for process to exit
181
+ try {
182
+ await this.process.status;
183
+ } catch {
184
+ // Ignore status errors
185
+ }
186
+ } catch (error) {
187
+ this.logger.warn('Error killing native terminal', { id: this.id, error });
188
+ } finally {
189
+ this.process = undefined;
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Add output listener
195
+ */
196
+ addOutputListener(listener: (data: string) => void): void {
197
+ this.outputListeners.add(listener);
198
+ }
199
+
200
+ /**
201
+ * Remove output listener
202
+ */
203
+ removeOutputListener(listener: (data: string) => void): void {
204
+ this.outputListeners.delete(listener);
205
+ }
206
+
207
+ private getShellConfig(): ShellConfig {
208
+ const platform = Deno.build.os;
209
+
210
+ switch (this.shell) {
211
+ case 'bash':
212
+ return {
213
+ path: platform === 'windows' ? 'C:\\Program Files\\Git\\bin\\bash.exe' : '/bin/bash',
214
+ args: ['--norc', '--noprofile'],
215
+ env: { PS1: '$ ' },
216
+ };
217
+
218
+ case 'zsh':
219
+ return {
220
+ path: '/bin/zsh',
221
+ args: ['--no-rcs'],
222
+ env: { PS1: '$ ' },
223
+ };
224
+
225
+ case 'powershell':
226
+ return {
227
+ path: platform === 'windows' ? 'powershell.exe' : 'pwsh',
228
+ args: ['-NoProfile', '-NonInteractive', '-NoLogo'],
229
+ };
230
+
231
+ case 'cmd':
232
+ return {
233
+ path: 'cmd.exe',
234
+ args: ['/Q', '/K', 'prompt $G'],
235
+ };
236
+
237
+ case 'sh':
238
+ default:
239
+ return {
240
+ path: '/bin/sh',
241
+ args: [],
242
+ env: { PS1: '$ ' },
243
+ };
244
+ }
245
+ }
246
+
247
+ private wrapCommand(command: string): string {
248
+ const platform = Deno.build.os;
249
+
250
+ if (this.shell === 'powershell') {
251
+ // PowerShell command wrapping
252
+ return `${command}; Write-Host "${this.commandMarker}"`;
253
+ } else if (this.shell === 'cmd' && platform === 'windows') {
254
+ // Windows CMD command wrapping
255
+ return `${command} & echo ${this.commandMarker}`;
256
+ } else {
257
+ // Unix-like shell command wrapping
258
+ return `${command} && echo "${this.commandMarker}" || (echo "${this.commandMarker}"; false)`;
259
+ }
260
+ }
261
+
262
+ private async startOutputReader(): Promise<void> {
263
+ if (!this.process) return;
264
+
265
+ this.stdoutReader = this.process.stdout.getReader();
266
+
267
+ try {
268
+ while (this.alive) {
269
+ const { done, value } = await this.stdoutReader.read();
270
+ if (done) break;
271
+
272
+ const text = this.decoder.decode(value);
273
+ this.processOutput(text);
274
+ }
275
+ } catch (error) {
276
+ if (this.alive) {
277
+ this.logger.error('Error reading stdout', { id: this.id, error });
278
+ }
279
+ }
280
+ }
281
+
282
+ private async startErrorReader(): Promise<void> {
283
+ if (!this.process) return;
284
+
285
+ this.stderrReader = this.process.stderr.getReader();
286
+
287
+ try {
288
+ while (this.alive) {
289
+ const { done, value } = await this.stderrReader.read();
290
+ if (done) break;
291
+
292
+ const text = this.decoder.decode(value);
293
+ this.errorBuffer += text;
294
+
295
+ // Also send stderr to output listeners
296
+ this.notifyListeners(text);
297
+ }
298
+ } catch (error) {
299
+ if (this.alive) {
300
+ this.logger.error('Error reading stderr', { id: this.id, error });
301
+ }
302
+ }
303
+ }
304
+
305
+ private processOutput(text: string): void {
306
+ this.outputBuffer += text;
307
+
308
+ // Notify listeners
309
+ this.notifyListeners(text);
310
+
311
+ // Check for command completion marker
312
+ const markerIndex = this.outputBuffer.indexOf(this.commandMarker);
313
+ if (markerIndex !== -1 && this.commandDeferred) {
314
+ // Extract output before marker
315
+ const output = this.outputBuffer.substring(0, markerIndex).trim();
316
+
317
+ // Include any stderr output
318
+ const fullOutput = this.errorBuffer ? `${output}\n${this.errorBuffer}` : output;
319
+ this.errorBuffer = '';
320
+
321
+ // Clear buffer up to after marker
322
+ this.outputBuffer = this.outputBuffer.substring(
323
+ markerIndex + this.commandMarker.length,
324
+ ).trim();
325
+
326
+ // Resolve pending command
327
+ this.commandDeferred.resolve(fullOutput);
328
+ this.commandDeferred = undefined;
329
+ }
330
+ }
331
+
332
+ private notifyListeners(data: string): void {
333
+ this.outputListeners.forEach(listener => {
334
+ try {
335
+ listener(data);
336
+ } catch (error) {
337
+ this.logger.error('Error in output listener', { id: this.id, error });
338
+ }
339
+ });
340
+ }
341
+
342
+ private async monitorProcess(): Promise<void> {
343
+ if (!this.process) return;
344
+
345
+ try {
346
+ const status = await this.process.status;
347
+ this.logger.info('Terminal process exited', {
348
+ id: this.id,
349
+ code: status.code,
350
+ signal: status.signal,
351
+ });
352
+ } catch (error) {
353
+ this.logger.error('Error monitoring process', { id: this.id, error });
354
+ } finally {
355
+ this.alive = false;
356
+
357
+ // Reject any pending command
358
+ if (this.commandDeferred) {
359
+ this.commandDeferred.reject(new Error('Terminal process exited'));
360
+ }
361
+ }
362
+ }
363
+
364
+ private async waitForReady(): Promise<void> {
365
+ // Send a test command to ensure shell is ready
366
+ const testCommand = this.shell === 'powershell'
367
+ ? 'Write-Host "READY"'
368
+ : 'echo "READY"';
369
+
370
+ await this.write(testCommand + '\n');
371
+
372
+ const startTime = Date.now();
373
+ while (Date.now() - startTime < 5000) {
374
+ if (this.outputBuffer.includes('READY')) {
375
+ this.outputBuffer = '';
376
+ return;
377
+ }
378
+ await delay(100);
379
+ }
380
+
381
+ throw new TerminalError('Terminal failed to become ready');
382
+ }
383
+ }
384
+
385
+ /**
386
+ * Native terminal adapter
387
+ */
388
+ export class NativeAdapter implements ITerminalAdapter {
389
+ private terminals = new Map<string, NativeTerminal>();
390
+ private shell: string;
391
+
392
+ constructor(private logger: ILogger) {
393
+ // Detect available shell
394
+ this.shell = this.detectShell();
395
+ }
396
+
397
+ async initialize(): Promise<void> {
398
+ this.logger.info('Initializing native terminal adapter', { shell: this.shell });
399
+
400
+ // Verify shell is available
401
+ try {
402
+ const testConfig = this.getTestCommand();
403
+ const command = new Deno.Command(testConfig.cmd, { args: testConfig.args });
404
+ const { success } = await command.output();
405
+
406
+ if (!success) {
407
+ throw new Error('Shell test failed');
408
+ }
409
+ } catch (error) {
410
+ this.logger.warn(`Shell ${this.shell} not available, falling back to sh`, { error });
411
+ this.shell = 'sh';
412
+ }
413
+ }
414
+
415
+ async shutdown(): Promise<void> {
416
+ this.logger.info('Shutting down native terminal adapter');
417
+
418
+ // Kill all terminals
419
+ const terminals = Array.from(this.terminals.values());
420
+ await Promise.all(terminals.map(term => term.kill()));
421
+
422
+ this.terminals.clear();
423
+ }
424
+
425
+ async createTerminal(): Promise<Terminal> {
426
+ const terminal = new NativeTerminal(this.shell, this.logger);
427
+
428
+ await terminal.initialize();
429
+ this.terminals.set(terminal.id, terminal);
430
+
431
+ return terminal;
432
+ }
433
+
434
+ async destroyTerminal(terminal: Terminal): Promise<void> {
435
+ await terminal.kill();
436
+ this.terminals.delete(terminal.id);
437
+ }
438
+
439
+ private detectShell(): string {
440
+ const platform = Deno.build.os;
441
+
442
+ if (platform === 'windows') {
443
+ // Windows shell detection
444
+ const comspec = Deno.env.get('COMSPEC');
445
+ if (comspec?.toLowerCase().includes('powershell')) {
446
+ return 'powershell';
447
+ }
448
+
449
+ // Check if PowerShell is available
450
+ try {
451
+ const command = new Deno.Command('powershell', { args: ['-Version'] });
452
+ const { success } = command.outputSync();
453
+ if (success) {
454
+ return 'powershell';
455
+ }
456
+ } catch {
457
+ // PowerShell not available
458
+ }
459
+
460
+ return 'cmd';
461
+ } else {
462
+ // Unix-like shell detection
463
+ const shell = Deno.env.get('SHELL');
464
+ if (shell) {
465
+ const shellName = shell.split('/').pop();
466
+ if (shellName && this.isShellSupported(shellName)) {
467
+ return shellName;
468
+ }
469
+ }
470
+
471
+ // Try common shells in order of preference
472
+ const shells = ['bash', 'zsh', 'sh'];
473
+ for (const shell of shells) {
474
+ try {
475
+ const command = new Deno.Command('which', { args: [shell] });
476
+ const { success } = command.outputSync();
477
+ if (success) {
478
+ return shell;
479
+ }
480
+ } catch {
481
+ // Continue to next shell
482
+ }
483
+ }
484
+
485
+ // Default to sh
486
+ return 'sh';
487
+ }
488
+ }
489
+
490
+ private isShellSupported(shell: string): boolean {
491
+ return ['bash', 'zsh', 'sh', 'fish', 'dash', 'powershell', 'cmd'].includes(shell);
492
+ }
493
+
494
+ private getTestCommand(): { cmd: string; args: string[] } {
495
+ switch (this.shell) {
496
+ case 'powershell':
497
+ return { cmd: 'powershell', args: ['-Version'] };
498
+ case 'cmd':
499
+ return { cmd: 'cmd', args: ['/C', 'echo test'] };
500
+ default:
501
+ return { cmd: this.shell, args: ['--version'] };
502
+ }
503
+ }
504
+ }