@every-env/cli
Version:
Multi-agent orchestrator for AI-powered development workflows
136 lines • 4.09 kB
JavaScript
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