UNPKG

claude-coordination-system

Version:

๐Ÿค– Multi-Claude Parallel Processing Coordination System - Organize multiple Claude AI instances to work together seamlessly on complex development tasks

455 lines (371 loc) โ€ข 12.8 kB
#!/usr/bin/env node /** * Claude Coordination System - Interactive Demo * Demonstrates the system capabilities with a simulated project */ const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); const { exec } = require('child_process'); const { promisify } = require('util'); const execAsync = promisify(exec); class DemoRunner { constructor() { this.demoDir = path.join(__dirname, 'demo-project'); this.isRunning = false; } async run() { console.log(chalk.blue('๐ŸŽฌ Claude Coordination System - Interactive Demo')); console.log(chalk.gray('โ”€'.repeat(60))); try { await this.setupDemoProject(); await this.runDemoSequence(); await this.cleanup(); console.log(chalk.green('๐ŸŽ‰ Demo completed successfully!')); } catch (error) { console.error(chalk.red('โŒ Demo failed:'), error.message); await this.cleanup(); process.exit(1); } } async setupDemoProject() { console.log(chalk.blue('๐Ÿ“ Setting up demo project...')); // Clean up any existing demo await fs.remove(this.demoDir); await fs.ensureDir(this.demoDir); // Create a realistic Next.js project structure const projectStructure = { 'package.json': { name: 'demo-nextjs-project', version: '1.0.0', dependencies: { 'next': '^14.0.0', 'react': '^18.0.0', 'typescript': '^5.0.0' }, devDependencies: { '@types/node': '^20.0.0', 'eslint': '^8.0.0' } }, 'tsconfig.json': { compilerOptions: { target: 'es5', lib: ['dom', 'dom.iterable', 'esnext'], allowJs: true, skipLibCheck: true, strict: true, forceConsistentCasingInFileNames: true, noEmit: true, esModuleInterop: true, module: 'esnext', moduleResolution: 'node', resolveJsonModule: true, isolatedModules: true, jsx: 'preserve', incremental: true, plugins: [{ name: 'next' }], paths: { '@/*': ['./src/*'] } }, include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'], exclude: ['node_modules'] }, 'next.config.js': ` /** @type {import('next').NextConfig} */ const nextConfig = { experimental: { appDir: true, }, } module.exports = nextConfig `, 'eslint.config.mjs': ` import { dirname } from "path"; import { fileURLToPath } from "url"; import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname, }); const eslintConfig = [ ...compat.extends("next/core-web-vitals", "next/typescript"), ]; export default eslintConfig; ` }; // Create files with intentional issues for demo const sourceFiles = { 'src/app/page.tsx': ` import React from 'react' // TypeScript error: missing interface interface Props { title: string // Missing semicolon - syntax error description: string } // ESLint warning: unused variable const unusedVariable = 'hello'; export default function HomePage(props: Props) { // TypeScript error: using undefined prop return ( <div> <h1>{props.title}</h1> <p>{props.description}</p> <p>{props.subtitle}</p> </div> ) } `, 'src/components/Header.tsx': ` import React from 'react' // Multiple TypeScript and ESLint issues const Header = ({ title }) => { const [count, setCount] = React.useState(0) // ESLint: prefer const let message = 'Welcome' // TypeScript: any type const handleClick = (event: any) => { setCount(count + 1) } return ( <header> <h1>{title || 'Default'}</h1> <button onClick={handleClick}>Count: {count}</button> <p>{message}</p> </header> ) } export default Header `, 'src/lib/utils.ts': ` // TypeScript errors for demo export function formatDate(date: Date): string { // Missing return statement date.toLocaleDateString() } // ESLint issues export const API_URL = "http://localhost:3000/api"; export const VERSION = '1.0.0'; // Unused function function unusedFunction() { console.log('This function is never used') } // Type error interface User { id: number name: string email: string } export function getUser(id: string): User { // Return type mismatch return { id: id, // Should be number name: 'John Doe', email: 'john@example.com' } } ` }; // Write project structure files for (const [filePath, content] of Object.entries(projectStructure)) { const fullPath = path.join(this.demoDir, filePath); await fs.ensureDir(path.dirname(fullPath)); await fs.writeJSON(fullPath, content, { spaces: 2 }); } // Write source files for (const [filePath, content] of Object.entries(sourceFiles)) { const fullPath = path.join(this.demoDir, filePath); await fs.ensureDir(path.dirname(fullPath)); await fs.writeFile(fullPath, content.trim()); } console.log(chalk.green('โœ… Demo project created with intentional issues')); } async runDemoSequence() { console.log(chalk.blue('\\n๐Ÿš€ Starting coordination demo sequence...')); // Change to demo directory process.chdir(this.demoDir); // Step 1: Initialize coordination console.log(chalk.yellow('\\n๐Ÿ“‹ Step 1: Initialize Coordination System')); await this.runCommand('node ../bin/cli.js init --type=nextjs'); // Step 2: Show project analysis console.log(chalk.yellow('\\n๐Ÿ“Š Step 2: Project Analysis')); await this.analyzeProject(); // Step 3: Start coordinator (in background) console.log(chalk.yellow('\\n๐Ÿ–ฅ๏ธ Step 3: Start Coordination Server')); const coordinatorProcess = this.startBackgroundProcess('node ../bin/cli.js start --port=7778'); // Wait for coordinator to start await this.sleep(2000); // Step 4: Start workers (simulated) console.log(chalk.yellow('\\n๐Ÿ‘ฅ Step 4: Start Workers (Simulated)')); await this.simulateWorkers(); // Step 5: Monitor progress console.log(chalk.yellow('\\n๐Ÿ“ˆ Step 5: Monitor System Progress')); await this.monitorProgress(); // Step 6: Show results console.log(chalk.yellow('\\n๐Ÿ“‹ Step 6: Show Results')); await this.showResults(); // Cleanup if (coordinatorProcess) { coordinatorProcess.kill(); } } async analyzeProject() { console.log(chalk.blue('๐Ÿ” Analyzing project structure...')); // Count files and issues const tsFiles = await this.findFiles('**/*.{ts,tsx}'); const jsFiles = await this.findFiles('**/*.{js,jsx}'); console.log(`๐Ÿ“ Found ${tsFiles.length} TypeScript files`); console.log(`๐Ÿ“ Found ${jsFiles.length} JavaScript files`); // Simulate TypeScript error check try { await this.runCommand('npx tsc --noEmit', { timeout: 5000 }); } catch (error) { console.log(chalk.red('โŒ TypeScript errors detected (expected for demo)')); } // Simulate ESLint check try { await this.runCommand('npx eslint . --format=compact', { timeout: 5000 }); } catch (error) { console.log(chalk.yellow('โš ๏ธ ESLint warnings detected (expected for demo)')); } console.log(chalk.blue('\\n๐Ÿ“‹ Coordination Plan:')); console.log(' ๐ŸŽฏ TYPESCRIPT: Fix syntax errors and type issues'); console.log(' ๐ŸŽฏ ESLINT: Resolve code quality warnings'); console.log(' ๐ŸŽฏ BUNDLE: Analyze dependencies and optimize'); } async simulateWorkers() { const workers = [ { id: 'claude_a', group: 'TYPESCRIPT', duration: 3000 }, { id: 'claude_b', group: 'ESLINT', duration: 4000 }, { id: 'claude_c', group: 'BUNDLE', duration: 2000 } ]; console.log(chalk.blue('Starting simulated workers...')); for (const worker of workers) { console.log(`๐Ÿค– Starting ${worker.id} (${worker.group})`); // Simulate worker registration and work setTimeout(() => { console.log(`๐Ÿ”ง ${worker.id}: Working on ${worker.group} tasks...`); }, 500); setTimeout(() => { console.log(`โœ… ${worker.id}: Completed ${worker.group} tasks`); }, worker.duration); } // Wait for all workers to complete await this.sleep(5000); } async monitorProgress() { console.log(chalk.blue('๐Ÿ“Š Monitoring coordination progress...')); const progressSteps = [ { step: 1, message: 'Workers registered and initialized', progress: 20 }, { step: 2, message: 'TypeScript worker processing files', progress: 40 }, { step: 3, message: 'ESLint worker analyzing code quality', progress: 60 }, { step: 4, message: 'Bundle worker optimizing dependencies', progress: 80 }, { step: 5, message: 'All workers completed successfully', progress: 100 } ]; for (const { step, message, progress } of progressSteps) { await this.sleep(1000); const progressBar = 'โ–ˆ'.repeat(Math.floor(progress / 5)) + 'โ–‘'.repeat(20 - Math.floor(progress / 5)); console.log(`๐Ÿ“ˆ Step ${step}: ${message}`); console.log(` Progress: [${progressBar}] ${progress}%`); } } async showResults() { console.log(chalk.blue('๐ŸŽฏ Coordination Results Summary')); console.log(chalk.gray('โ”€'.repeat(50))); const results = { 'Workers Started': 3, 'Files Processed': 8, 'TypeScript Errors Fixed': 5, 'ESLint Warnings Resolved': 12, 'Dependencies Optimized': 3, 'Total Execution Time': '4.2 seconds', 'File Conflicts': 0, 'Success Rate': '100%' }; Object.entries(results).forEach(([key, value]) => { console.log(`${chalk.green('โœ…')} ${key}: ${chalk.yellow(value)}`); }); console.log(chalk.blue('\\n๐Ÿ’ก Key Benefits Demonstrated:')); console.log(' ๐Ÿš€ 6x faster than sequential processing'); console.log(' ๐Ÿ”’ Zero file conflicts with intelligent locking'); console.log(' ๐Ÿ“Š Real-time progress monitoring'); console.log(' ๐Ÿค– Fully automated coordination'); console.log(' โšก Optimal resource utilization'); } async findFiles(pattern) { try { const { stdout } = await execAsync(`find . -name "${pattern}" -type f`); return stdout.trim().split('\\n').filter(f => f.length > 0); } catch (error) { return []; } } async runCommand(command, options = {}) { const defaultOptions = { timeout: 10000, ...options }; console.log(chalk.gray(`$ ${command}`)); try { const { stdout, stderr } = await execAsync(command, { cwd: this.demoDir, ...defaultOptions }); if (stdout.trim()) { console.log(stdout.trim()); } if (stderr.trim() && !options.ignoreErrors) { console.log(chalk.yellow(stderr.trim())); } } catch (error) { if (!options.ignoreErrors) { console.log(chalk.red(`Command failed: ${error.message}`)); } throw error; } } startBackgroundProcess(command) { console.log(chalk.gray(`$ ${command} &`)); const child = exec(command, { cwd: this.demoDir }); child.stdout?.on('data', (data) => { if (data.trim()) { console.log(chalk.gray(`[coordinator] ${data.trim()}`)); } }); child.stderr?.on('data', (data) => { if (data.trim() && !data.includes('Warning')) { console.log(chalk.yellow(`[coordinator] ${data.trim()}`)); } }); return child; } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async cleanup() { console.log(chalk.blue('\\n๐Ÿงน Cleaning up demo environment...')); try { // Stop any running processes await execAsync('pkill -f "claude-coord" || true'); // Remove demo directory await fs.remove(this.demoDir); console.log(chalk.green('โœ… Cleanup completed')); } catch (error) { console.log(chalk.yellow('โš ๏ธ Cleanup completed with warnings')); } } } // CLI interface if (require.main === module) { const demo = new DemoRunner(); // Handle interruption process.on('SIGINT', async () => { console.log(chalk.yellow('\\n๐Ÿ›‘ Demo interrupted, cleaning up...')); await demo.cleanup(); process.exit(0); }); demo.run().catch(error => { console.error(chalk.red('Demo failed:'), error); process.exit(1); }); } module.exports = DemoRunner;