UNPKG

@every-env/cli

Version:

Multi-agent orchestrator for AI-powered development workflows

136 lines 4.09 kB
import { promises as fs } from 'fs'; import { join } from 'path'; /** * Detect project type based on repository heuristics */ export async function detectProjectType(cwd = process.cwd()) { const signals = []; const projectTypes = []; // Check for Node.js if (await fileExists(join(cwd, 'package.json'))) { signals.push('package.json'); projectTypes.push('node'); } // Check for Rails (Gemfile + Rails-specific files) const hasGemfile = await fileExists(join(cwd, 'Gemfile')); if (hasGemfile) { signals.push('Gemfile'); // Check for Rails-specific fingerprints const railsFingerprints = [ 'bin/rails', 'config/application.rb', 'app/controllers', 'app/models', 'app/views' ]; let railsSignalCount = 0; for (const fingerprint of railsFingerprints) { if (await fileExists(join(cwd, fingerprint))) { signals.push(fingerprint); railsSignalCount++; } } if (railsSignalCount >= 2) { projectTypes.push('rails'); } else { // Ruby project but not Rails projectTypes.push('ruby'); } } // Check for Python const pythonFiles = ['pyproject.toml', 'requirements.txt', 'Pipfile', 'setup.py']; for (const file of pythonFiles) { if (await fileExists(join(cwd, file))) { signals.push(file); if (!projectTypes.includes('python')) { projectTypes.push('python'); } } } // Check for Go if (await fileExists(join(cwd, 'go.mod'))) { signals.push('go.mod'); projectTypes.push('go'); } // Check for additional Go files if (await fileExists(join(cwd, 'go.sum'))) { signals.push('go.sum'); } // Determine final project type let finalProjectType; if (projectTypes.length === 0) { finalProjectType = 'basic'; } else if (projectTypes.length === 1) { finalProjectType = projectTypes[0]; } else { // Multiple strong signals - this is ambiguous, caller should prompt user finalProjectType = 'monorepo'; signals.push(`multiple-types:${projectTypes.join(',')}`); } return { projectType: finalProjectType, signals }; } /** * Check if a file or directory exists */ async function fileExists(path) { try { await fs.access(path); return true; } catch { return false; } } /** * Get project type display name for UI */ export function getProjectTypeDisplayName(projectType) { const displayNames = { node: 'Node.js', rails: 'Ruby on Rails', python: 'Python', go: 'Go', ruby: 'Ruby', basic: 'Basic/Other', monorepo: 'Monorepo/Multi-language' }; return displayNames[projectType]; } /** * Get available project types for selection */ export function getAvailableProjectTypes() { return [ { value: 'node', label: 'Node.js' }, { value: 'rails', label: 'Ruby on Rails' }, { value: 'python', label: 'Python' }, { value: 'go', label: 'Go' }, { value: 'ruby', label: 'Ruby' }, { value: 'monorepo', label: 'Monorepo/Multi-language' }, { value: 'basic', label: 'Basic/Other' } ]; } /** * Check if detection result indicates ambiguous project type */ export function isAmbiguousDetection(result) { return result.projectType === 'monorepo' && result.signals.some(signal => signal.startsWith('multiple-types:')); } /** * Get detected project types from ambiguous detection */ export function getDetectedTypesFromAmbiguous(result) { const multipleTypesSignal = result.signals.find(signal => signal.startsWith('multiple-types:')); if (!multipleTypesSignal) return []; const typesString = multipleTypesSignal.replace('multiple-types:', ''); return typesString.split(','); } //# sourceMappingURL=project-detect.js.map