claude-flow-depth
Version:
DEPTH Methodology Installer - Ousterhout-First Development for Claude Code
579 lines (505 loc) • 19.3 kB
text/typescript
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();