mira-consciousness
Version:
Memory & Intelligence Retention Archive - Preserving The Spark
107 lines • 4.38 kB
JavaScript
import * as path from 'path';
import fs from 'fs-extra';
import * as glob from 'glob';
export class ProjectDetector {
projectRoot;
constructor(projectRoot) {
this.projectRoot = projectRoot;
}
async detectProject() {
const info = {
name: path.basename(this.projectRoot),
type: 'unknown',
techStack: [],
frameworks: [],
hasTests: false,
hasCI: false,
hasDocs: false
};
// Detect Node.js project
if (await fs.pathExists(path.join(this.projectRoot, 'package.json'))) {
const packageJson = await fs.readJson(path.join(this.projectRoot, 'package.json'));
info.name = packageJson.name || info.name;
info.type = 'node';
info.techStack.push('JavaScript', 'Node.js');
// Detect package manager
if (await fs.pathExists(path.join(this.projectRoot, 'yarn.lock'))) {
info.packageManager = 'yarn';
}
else if (await fs.pathExists(path.join(this.projectRoot, 'pnpm-lock.yaml'))) {
info.packageManager = 'pnpm';
}
else {
info.packageManager = 'npm';
}
// Detect frameworks
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
if (deps.react)
info.frameworks.push('React');
if (deps.vue)
info.frameworks.push('Vue');
if (deps.angular)
info.frameworks.push('Angular');
if (deps.express)
info.frameworks.push('Express');
if (deps.fastify)
info.frameworks.push('Fastify');
if (deps.next)
info.frameworks.push('Next.js');
if (deps.nuxt)
info.frameworks.push('Nuxt');
// Detect TypeScript
if (deps.typescript || await fs.pathExists(path.join(this.projectRoot, 'tsconfig.json'))) {
info.techStack.push('TypeScript');
}
}
// Detect Python project
if (await fs.pathExists(path.join(this.projectRoot, 'requirements.txt')) ||
await fs.pathExists(path.join(this.projectRoot, 'setup.py')) ||
await fs.pathExists(path.join(this.projectRoot, 'pyproject.toml'))) {
info.type = info.type === 'unknown' ? 'python' : 'mixed';
info.techStack.push('Python');
// Check for common Python frameworks
try {
const requirementsPath = path.join(this.projectRoot, 'requirements.txt');
if (await fs.pathExists(requirementsPath)) {
const requirements = await fs.readFile(requirementsPath, 'utf-8');
if (requirements.includes('django'))
info.frameworks.push('Django');
if (requirements.includes('flask'))
info.frameworks.push('Flask');
if (requirements.includes('fastapi'))
info.frameworks.push('FastAPI');
}
}
catch (error) {
// Ignore errors reading requirements
}
}
// Detect tests
const testPatterns = ['**/test/**', '**/tests/**', '**/*.test.*', '**/*.spec.*'];
for (const pattern of testPatterns) {
const matches = glob.sync(pattern, { cwd: this.projectRoot, ignore: ['node_modules/**'] });
if (matches.length > 0) {
info.hasTests = true;
break;
}
}
// Detect CI
const ciFiles = ['.github/workflows', '.gitlab-ci.yml', '.circleci', 'Jenkinsfile'];
for (const ciFile of ciFiles) {
if (await fs.pathExists(path.join(this.projectRoot, ciFile))) {
info.hasCI = true;
break;
}
}
// Detect documentation
const docFiles = ['README.md', 'README.rst', 'docs', 'documentation'];
for (const docFile of docFiles) {
if (await fs.pathExists(path.join(this.projectRoot, docFile))) {
info.hasDocs = true;
break;
}
}
return info;
}
}
//# sourceMappingURL=ProjectDetector.js.map