import { existsSync, readdirSync, statSync } from "node:fs"; import { join } from "node:path"; const IGNORED_DIRS = new Set([ "node_modules", ".git", "dist", "out", ".next", "__pycache__", ".cache", ".turbo", "coverage", ".vscode", ".idea", "target", "build", ".gradle", "vendor", ]); export async function collectProjectContext(repoRoot: string): Promise<{ readme: string | null; packageDescription: string | null; structure: string | null; }> { let readme: string | null = null; let packageDescription: string | null = null; let structure: string | null = null; for (const name of ["README.md", "README.txt", "README.rst", "README"]) { const filePath = join(repoRoot, name); if (existsSync(filePath)) { try { const content = await Bun.file(filePath).text(); readme = content.length > 1500 ? content.substring(0, 1500) + "\n... (truncated)" : content; } catch {} break; } } const pkgPath = join(repoRoot, "package.json"); if (existsSync(pkgPath)) { try { const pkg = (await Bun.file(pkgPath).json()) as { description?: string }; if (pkg.description) { packageDescription = pkg.description; } } catch {} } try { const entries = readdirSync(repoRoot) .filter((name) => !IGNORED_DIRS.has(name) && !name.startsWith(".")) .map((name) => { try { return statSync(join(repoRoot, name)).isDirectory() ? `${name}/` : name; } catch { return name; } }); if (entries.length > 0) { structure = entries.join(", "); } } catch {} return { readme, packageDescription, structure }; }