import { existsSync, readFileSync } from 'node:fs'; import path from 'node:path'; import type { InspectAllProjectsInput, InspectProjectInput } from '../types.js'; import { projectAliases } from '../core/constants.js'; import { tryExecFile } from '../core/exec.js'; import { detectPackageManager, detectRepoType } from '../core/project.js'; import { listImmediateChildren, resolveProject, workspaceRoot } from '../core/workspace.js'; export async function inspectProject(input: InspectProjectInput): Promise> { const project = resolveProject(input.project); const repoType = detectRepoType(project.path); const packageInfo = detectPackageManager(project.path); const nodeVersionFile = ['.node-version', '.nvmrc'].find((file) => existsSync(path.join(project.path, file)), ); const nodeVersion = nodeVersionFile ? readFileSync(path.join(project.path, nodeVersionFile), 'utf8').trim() : null; const envFiles = ['.env.development', '.env.production', '.env.example'].map( (file) => ({ exists: existsSync(path.join(project.path, file)), file, }), ); const childSummary = listImmediateChildren(project.path).slice(0, 60); const git = repoType === 'git' && input.includeGit !== false ? { branch: await tryExecFile('git', ['branch', '--show-current'], project.path), remote: await tryExecFile('git', ['remote', '-v'], project.path), status: await tryExecFile('git', ['status', '--short'], project.path), } : null; return { childSummary, envFiles, git, nodeVersion, nodeVersionFile: nodeVersionFile || null, packageInfo, project, repoType, }; } export async function inspectAllProjects(input: InspectAllProjectsInput = {}): Promise> { const aliases = input.includeRoot === false ? Object.keys(projectAliases).filter((key) => key !== 'root') : Object.keys(projectAliases); const inspections = await Promise.all( aliases.map((alias) => inspectProject({ includeGit: input.includeGit !== false, project: alias, }), ), ); return { inspections, workspaceRoot, }; }