UNPKG

claude-flow-depth

Version:

DEPTH Methodology Installer - Ousterhout-First Development for Claude Code

579 lines (505 loc) 19.3 kB
#!/usr/bin/env node import { Command } from 'commander'; import chalk from 'chalk'; import inquirer from 'inquirer'; import fs from 'fs-extra'; import path from 'path'; import ora from 'ora'; import axios from 'axios'; const program = new Command(); interface DepthConfig { projectName: string; frontendMcpUrl?: string; backendMcpUrl?: string; supabaseApiKey?: string; includeExamples: boolean; methodology: 'depth-only' | 'depth-with-sparc' | 'full-suite'; } class DepthInstaller { private config: DepthConfig; private templatePath: string; constructor(config: DepthConfig) { this.config = config; this.templatePath = path.join(__dirname, '../templates'); } async init(targetDir: string, force: boolean = false) { const spinner = ora('Initializing DEPTH methodology...').start(); try { // Create project directory await this.createProjectStructure(targetDir, force); // Copy templates await this.copyTemplates(targetDir); // Configure DEPTH files await this.configureDepthFiles(targetDir); // Setup Claude Code configuration await this.setupClaudeCodeConfig(targetDir); // Create example project if requested if (this.config.includeExamples) { await this.createExampleProject(targetDir); } // Install dependencies await this.installDependencies(targetDir); spinner.succeed(chalk.green('DEPTH methodology initialized successfully!')); this.printSuccessMessage(targetDir); } catch (error) { spinner.fail(chalk.red('Failed to initialize DEPTH methodology')); console.error(error); process.exit(1); } } private async createProjectStructure(targetDir: string, force: boolean) { if (await fs.pathExists(targetDir)) { if (!force) { const { overwrite } = await inquirer.prompt([{ type: 'confirm', name: 'overwrite', message: `Directory ${targetDir} already exists. Overwrite?`, default: false }]); if (!overwrite) { console.log(chalk.yellow('Installation cancelled.')); process.exit(0); } } await fs.remove(targetDir); } await fs.ensureDir(targetDir); // Create DEPTH directory structure const dirs = [ '.claude/commands/depth', '.claude/helpers', 'depth-sessions', 'depth-reports', 'depth-memory', 'examples', 'docs' ]; for (const dir of dirs) { await fs.ensureDir(path.join(targetDir, dir)); } } private async copyTemplates(targetDir: string) { const templates = [ { src: 'depth-commands', dest: '.claude/commands/depth' }, { src: 'claude-settings.json', dest: '.claude/settings.json' }, { src: 'gitignore', dest: '.gitignore' }, { src: 'README.md', dest: 'README.md' }, { src: 'package.json', dest: 'package.json' } ]; for (const template of templates) { const srcPath = path.join(this.templatePath, template.src); const destPath = path.join(targetDir, template.dest); if (await fs.pathExists(srcPath)) { await fs.copy(srcPath, destPath); } } } private async configureDepthFiles(targetDir: string) { // Create .depth configuration const depthConfig = { version: '1.0.0', approach: 'ousterhout-first', implementation: 'design-b-separate-structure', principles: [ 'design-twice', 'deep-modules', 'information-hiding', 'strategic-investment', 'interface-simplicity' ], quality_gates: { module_depth_ratio: { min: 0.6, target: 0.8 }, interface_complexity_score: { max: 0.4, target: 0.2 }, strategic_investment_percentage: { min: 0.1, target: 0.15, max: 0.2 }, information_hiding_score: { min: 0.8, target: 0.9 } }, integration: { frontend_mcp: { enabled: !!this.config.frontendMcpUrl, url: this.config.frontendMcpUrl || '', api_key: this.config.supabaseApiKey || '', pattern_extraction: true }, backend_mcp: { enabled: !!this.config.backendMcpUrl, url: this.config.backendMcpUrl || '', api_key: this.config.supabaseApiKey || '', pattern_extraction: true }, swarm_coordination: { enabled: false, future_enhancement: true, adapter_planned: true }, memory_persistence: { enabled: true, storage_path: 'depth-memory/' } }, session_config: { auto_save: true, generate_reports: true, track_metrics: true, enforce_quality_gates: true, session_persistence: true }, workflow: { phases: ['Design-Twice', 'Interface-Simplification', 'Complexity-Allocation', 'Strategic-Investment', 'Implementation-Hiding'], phase_transitions: 'quality-gate-controlled', rollback_enabled: true } }; await fs.writeJson(path.join(targetDir, '.depth'), depthConfig, { spaces: 2 }); // Create .depthmodes configuration const depthModes = { 'Strategic Designer': { description: 'Apply design-twice principle and strategic thinking', cognitive_pattern: 'ousterhout-strategic', capabilities: ['design-twice', 'strategic-planning', 'complexity-analysis'], phase: 'Design-Twice', priority: 'high', quality_gates: ['design-alternatives-created', 'strategic-investment-documented'], metrics: { strategic_investment_target: 0.15, design_alternatives_minimum: 2 } }, 'Interface Optimizer': { description: 'Simplify interfaces and measure complexity', cognitive_pattern: 'complexity-reduction', capabilities: ['interface-simplification', 'complexity-measurement', 'user-experience'], phase: 'Interface-Simplification', priority: 'high', quality_gates: ['interface-complexity-measured', 'simplification-strategy-documented'], metrics: { interface_complexity_maximum: 0.4, method_parameter_limit: 4 } }, 'Complexity Allocator': { description: 'Push complexity downward and hide implementation details', cognitive_pattern: 'information-hiding', capabilities: ['architecture-design', 'information-hiding', 'module-design'], phase: 'Complexity-Allocation', priority: 'high', quality_gates: ['complexity-allocation-plan', 'information-hiding-strategy'], metrics: { module_depth_minimum: 0.6, information_hiding_score_minimum: 0.8 } }, 'Investment Planner': { description: 'Enforce 10-20% strategic investment rule', cognitive_pattern: 'strategic-investment', capabilities: ['strategic-investment', 'tactical-balance', 'long-term-thinking'], phase: 'Strategic-Investment', priority: 'medium', quality_gates: ['investment-ratio-calculated', 'strategic-plan-documented'], metrics: { strategic_investment_minimum: 0.1, strategic_investment_maximum: 0.2 } }, 'Implementation Hider': { description: 'Generate code with maximum information hiding', cognitive_pattern: 'implementation-hiding', capabilities: ['code-generation', 'comment-driven-development', 'documentation'], phase: 'Implementation-Hiding', priority: 'high', quality_gates: ['implementation-hidden', 'comments-document-decisions'], metrics: { public_interface_ratio_maximum: 0.2, comment_coverage_minimum: 0.8 } } }; await fs.writeJson(path.join(targetDir, '.depthmodes'), depthModes, { spaces: 2 }); } private async setupClaudeCodeConfig(targetDir: string) { const claudeSettings = { mcp: { mcpServers: { 'depth-frontend': { command: 'curl', args: [ '-X', 'POST', this.config.frontendMcpUrl || 'https://your-project.supabase.co/functions/v1/frontend-mcp', '-H', 'Content-Type: application/json', '-H', `Authorization: Bearer ${this.config.supabaseApiKey || 'your-api-key'}`, '-d', '@-' ], env: { SUPABASE_URL: this.config.frontendMcpUrl || '', SUPABASE_KEY: this.config.supabaseApiKey || '' } }, 'depth-backend': { command: 'curl', args: [ '-X', 'POST', this.config.backendMcpUrl || 'https://your-project.supabase.co/functions/v1/backend-mcp', '-H', 'Content-Type: application/json', '-H', `Authorization: Bearer ${this.config.supabaseApiKey || 'your-api-key'}`, '-d', '@-' ], env: { SUPABASE_URL: this.config.backendMcpUrl || '', SUPABASE_KEY: this.config.supabaseApiKey || '' } } } }, depth: { enabled: true, methodology: this.config.methodology, quality_gates_enforced: true, auto_mcp_integration: true } }; await fs.writeJson(path.join(targetDir, '.claude/settings.json'), claudeSettings, { spaces: 2 }); // Create CLAUDE.md with DEPTH documentation const claudeMd = `# DEPTH Methodology Project This project uses the DEPTH (Design-Twice, Eliminate complexity, Pull complexity down, Trade-off documentation, Hide implementation) methodology for Ousterhout-first development. ## Quick Start ### Run DEPTH Methodology \`\`\`bash # Execute complete DEPTH methodology /depth orchestrator "Build your feature" # Run specific phase /depth design-twice "Create API design" /depth interface-simplify "Optimize endpoints" \`\`\` ### MCP Integration ${this.config.frontendMcpUrl ? `- **Frontend MCP**: ${this.config.frontendMcpUrl}` : '- **Frontend MCP**: Not configured'} ${this.config.backendMcpUrl ? `- **Backend MCP**: ${this.config.backendMcpUrl}` : '- **Backend MCP**: Not configured'} ### Configuration Files - \`.depth\` - Global DEPTH methodology settings - \`.depthmodes\` - Phase-specific configurations - \`.claude/commands/depth/\` - DEPTH command implementations ### Quality Gates - Module depth ratio > 0.6 (deep modules) - Interface complexity < 0.4 (simple interfaces) - Strategic investment 10-20% (Ousterhout's rule) - Information hiding > 80% (encapsulation) ## Methodology Phases 1. **Design-Twice (D)** - Create two design alternatives 2. **Interface-Simplification (E)** - Simplify interfaces 3. **Complexity-Allocation (P)** - Push complexity downward 4. **Strategic-Investment (T)** - Enforce strategic thinking 5. **Implementation-Hiding (H)** - Generate clean code ## Examples See \`examples/\` directory for sample DEPTH workflows. ## Documentation See \`docs/\` directory for comprehensive DEPTH methodology guides. `; await fs.writeFile(path.join(targetDir, 'CLAUDE.md'), claudeMd); } private async createExampleProject(targetDir: string) { const exampleProject = { name: 'todo-app-depth-example', description: 'Example project demonstrating DEPTH methodology', phases: [ { name: 'Design-Twice', files: ['design-a-traditional.md', 'design-b-ousterhout.md', 'comparison.md'] }, { name: 'Interface-Simplification', files: ['api-interface.md', 'complexity-analysis.md'] }, { name: 'Implementation', files: ['todo-api.js', 'todo-service.js', 'tests.js'] } ] }; const exampleDir = path.join(targetDir, 'examples', 'todo-app'); await fs.ensureDir(exampleDir); await fs.writeJson(path.join(exampleDir, 'project.json'), exampleProject, { spaces: 2 }); // Create example files const exampleReadme = `# Todo App - DEPTH Methodology Example This example demonstrates how to build a Todo application using the DEPTH methodology. ## Phase 1: Design-Twice - Traditional approach vs Ousterhout approach - Deep module design - Interface simplification strategies ## Phase 2: Implementation - Clean, commented code following DEPTH principles - Maximum information hiding - Strategic investment in quality ## Running the Example \`\`\`bash /depth orchestrator "Build todo application with CRUD operations" \`\`\` `; await fs.writeFile(path.join(exampleDir, 'README.md'), exampleReadme); } private async installDependencies(targetDir: string) { // Create a basic package.json for the project const projectPackageJson = { name: this.config.projectName, version: '1.0.0', description: 'DEPTH methodology project', scripts: { 'depth': 'echo "Use /depth commands in Claude Code"', 'depth:report': 'echo "Check depth-reports/ directory"' }, devDependencies: { 'claude-flow-depth': '^1.0.0-alpha' } }; await fs.writeJson(path.join(targetDir, 'package.json'), projectPackageJson, { spaces: 2 }); } private printSuccessMessage(targetDir: string) { console.log('\n' + chalk.green('🎉 DEPTH Methodology Initialized Successfully!')); console.log('\n' + chalk.bold('📁 Project Structure:')); console.log(` ${targetDir}/`); console.log(' ├── .depth # Global configuration'); console.log(' ├── .depthmodes # Phase configurations'); console.log(' ├── .claude/commands/depth/ # DEPTH commands'); console.log(' ├── depth-sessions/ # Session history'); console.log(' ├── depth-reports/ # Generated reports'); console.log(' └── examples/ # Example projects'); console.log('\n' + chalk.bold('🚀 Next Steps:')); console.log('1. ' + chalk.cyan(`cd ${targetDir}`)); console.log('2. ' + chalk.cyan('Open in Claude Code')); console.log('3. ' + chalk.cyan('/depth orchestrator "Your first project"')); if (this.config.frontendMcpUrl && this.config.backendMcpUrl) { console.log('\n' + chalk.bold('✅ MCP Integration Configured:')); console.log(` Frontend: ${this.config.frontendMcpUrl}`); console.log(` Backend: ${this.config.backendMcpUrl}`); } else { console.log('\n' + chalk.yellow('⚠️ MCP Integration:')); console.log(' Configure Frontend/Backend MCP URLs in .depth file'); } console.log('\n' + chalk.bold('📚 Documentation:')); console.log(' • CLAUDE.md - Project overview'); console.log(' • docs/ - Comprehensive guides'); console.log(' • examples/ - Sample workflows'); } } async function promptForConfig(): Promise<DepthConfig> { const answers = await inquirer.prompt([ { type: 'input', name: 'projectName', message: 'Project name:', default: 'my-depth-project', validate: (input) => input.length > 0 || 'Project name is required' }, { type: 'list', name: 'methodology', message: 'Choose methodology setup:', choices: [ { name: 'DEPTH only (Ousterhout-first)', value: 'depth-only' }, { name: 'DEPTH + SPARC (Hybrid approach)', value: 'depth-with-sparc' }, { name: 'Full suite (All methodologies)', value: 'full-suite' } ], default: 'depth-only' }, { type: 'confirm', name: 'configureMcp', message: 'Configure Frontend/Backend MCP integration?', default: true } ]); let mcpConfig = {}; if (answers.configureMcp) { mcpConfig = await inquirer.prompt([ { type: 'input', name: 'frontendMcpUrl', message: 'Frontend MCP URL (optional):', default: 'https://plwgqygbzreiogubsaui.supabase.co/functions/v1/frontend-mcp' }, { type: 'input', name: 'backendMcpUrl', message: 'Backend MCP URL (optional):', default: 'https://plwgqygbzreiogubsaui.supabase.co/functions/v1/backend-mcp' }, { type: 'password', name: 'supabaseApiKey', message: 'Supabase API Key (optional):', mask: '*' } ]); } const includeExamples = await inquirer.prompt([{ type: 'confirm', name: 'includeExamples', message: 'Include example projects?', default: true }]); return { ...answers, ...mcpConfig, ...includeExamples }; } // CLI Commands program .name('claude-flow-depth') .description('DEPTH Methodology Installer for Claude Code') .version('1.0.0-alpha.1'); program .command('init [directory]') .description('Initialize DEPTH methodology in a new project') .option('-f, --force', 'Force overwrite existing directory') .option('-y, --yes', 'Skip prompts and use defaults') .option('--frontend-mcp <url>', 'Frontend MCP URL') .option('--backend-mcp <url>', 'Backend MCP URL') .option('--api-key <key>', 'Supabase API Key') .action(async (directory, options) => { const targetDir = directory || process.cwd(); let config: DepthConfig; if (options.yes) { config = { projectName: path.basename(targetDir), frontendMcpUrl: options.frontendMcp, backendMcpUrl: options.backendMcp, supabaseApiKey: options.apiKey, includeExamples: true, methodology: 'depth-only' }; } else { config = await promptForConfig(); } const installer = new DepthInstaller(config); await installer.init(targetDir, options.force); }); program .command('test-mcp') .description('Test MCP connections') .option('--frontend <url>', 'Frontend MCP URL to test') .option('--backend <url>', 'Backend MCP URL to test') .option('--api-key <key>', 'API key for authentication') .action(async (options) => { const spinner = ora('Testing MCP connections...').start(); try { if (options.frontend) { const response = await axios.post(options.frontend, { tool: 'get_frontend_recommendation', params: { query: 'test', maxRecommendations: 1 } }, { headers: { 'Authorization': `Bearer ${options.apiKey}`, 'Content-Type': 'application/json' } }); if (response.data.success) { spinner.succeed(chalk.green('Frontend MCP: ✅ Connected')); } else { spinner.fail(chalk.red('Frontend MCP: ❌ Failed')); } } if (options.backend) { const response = await axios.post(options.backend, { tool: 'suggest_architecture', params: { query: 'test', system_type: 'web-application' } }, { headers: { 'Authorization': `Bearer ${options.apiKey}`, 'Content-Type': 'application/json' } }); if (response.data.success) { console.log(chalk.green('Backend MCP: ✅ Connected')); } else { console.log(chalk.red('Backend MCP: ❌ Failed')); } } } catch (error) { spinner.fail(chalk.red('MCP connection test failed')); console.error(error instanceof Error ? error.message : 'Unknown error occurred'); } }); program.parse();