#!/usr/bin/env node import { existsSync, readFileSync } from "node:fs"; const requiredFiles = [ "src/shared/lib/model.ts", "src/shared/lib/repositoryIntake.ts", "src/shared/lib/safeData.ts", "src/shared/lib/projectStartFlow.ts", "src/shared/lib/projectWizard.ts", "src/shared/contexts/ProjectContext.tsx", "src/features/repo-builder/pages/RepoBuilder.tsx", "src/features/history/pages/ProjectHistory.tsx", "src/features/audit/pages/ProjectAuditCenter.tsx", "src/features/projects/pages/Workspace.tsx", "src/shared/components/ProjectFlowRail.tsx", "package.json", ]; const failures = []; for (const file of requiredFiles) { if (!existsSync(file)) failures.push(`Missing required file: ${file}`); } const read = (file) => readFileSync(file, "utf8"); const text = Object.fromEntries(requiredFiles.filter(existsSync).map((file) => [file, read(file)])); const model = text["src/shared/lib/model.ts"] ?? ""; const helper = text["src/shared/lib/repositoryIntake.ts"] ?? ""; const safeData = text["src/shared/lib/safeData.ts"] ?? ""; const startFlow = text["src/shared/lib/projectStartFlow.ts"] ?? ""; const wizard = text["src/shared/lib/projectWizard.ts"] ?? ""; const context = text["src/shared/contexts/ProjectContext.tsx"] ?? ""; const repoBuilder = text["src/features/repo-builder/pages/RepoBuilder.tsx"] ?? ""; const history = text["src/features/history/pages/ProjectHistory.tsx"] ?? ""; const audit = text["src/features/audit/pages/ProjectAuditCenter.tsx"] ?? ""; const workspace = text["src/features/projects/pages/Workspace.tsx"] ?? ""; const flowRail = text["src/shared/components/ProjectFlowRail.tsx"] ?? ""; const pkg = text["package.json"] ?? ""; const mustContain = [ [model, "export interface RepositoryIntake", "RepositoryIntake model missing."], [model, "export interface RepositoryTreeEntry", "RepositoryTreeEntry model missing."], [model, "export interface RepositoryGap", "RepositoryGap model missing."], [model, "RepositorySkillMapping", "RepositorySkillMapping model missing."], [model, "RepositoryImportMode", "RepositoryImportMode model missing."], [model, "repositoryIntakes?: RepositoryIntake[]", "Project model must persist repository intakes."], [model, "linkedRepositoryIntakeIds?: ID[]", "Repo artifacts must preserve linked repository intake ids."], [safeData, "repositoryIntakes: asArray(project.repositoryIntakes)", "Runtime normalization must preserve repository intakes."], [helper, "parseRepositoryTreeInput", "Repository intake parser helper missing."], [helper, "classifyRepositoryEntry", "Repository entry classifier missing."], [helper, "detectRepositoryStack", "Repository stack detector missing."], [helper, "detectPackageManagers", "Package manager detector missing."], [helper, "detectFrameworks", "Framework detector missing."], [helper, "mapRepositoryEntriesToSkills", "Repository-to-skill mapping helper missing."], [helper, "deriveRepositoryGaps", "Repository gap derivation helper missing."], [helper, "formatRepositoryIntakeMarkdown", "Repository intake export formatter missing."], [helper, "recommendRepoBuilderActionsFromIntake", "Repository intake recommendation helper missing."], [helper, "frontend-react-vite-build", "Skill mapping must cover React/Vite evidence."], [helper, "docker-runtime-hardening", "Skill mapping must cover Docker evidence."], [helper, "database-migration", "Skill mapping must cover database evidence."], [helper, "documentation-system-build", "Skill mapping must cover documentation evidence."], [helper, "qa-qc-review", "Skill mapping must cover test evidence."], [helper, "Imported repository evidence is not live filesystem truth", "Intake export must label imported evidence as non-live truth."], [repoBuilder, "Existing repository intake", "Repo Builder must expose Existing repository intake section."], [repoBuilder, "Paste a file tree, package manifest, repo summary or current-state notes", "Repo Builder must explain repository intake source types."], [repoBuilder, "will not treat it as live disk truth", "Repo Builder must communicate the intake trust boundary."], [repoBuilder, "saveRepositoryIntake", "Repo Builder must save repository intakes."], [repoBuilder, "archiveRepositoryIntake", "Repo Builder must archive repository intakes."], [repoBuilder, "formatRepositoryIntakeMarkdown", "Repo Builder must copy/download intake markdown."], [repoBuilder, "Create expansion brief", "Repository gaps must create expansion briefs."], [repoBuilder, "Create delivery package", "Repository gaps must create delivery packages."], [repoBuilder, "Create Codex handoff", "Repository gaps must create Codex handoffs."], [context, "generateCodexHandoff", "ProjectContext must generate Codex handoffs from repository evidence."], [context, "generateHandoffReview", "ProjectContext must generate impact reviews for handoffs from repository evidence."], [context, "repositoryIntakeItems", "Project search index must include repository intakes."], [context, "saveRepositoryIntake", "ProjectContext must expose saveRepositoryIntake."], [context, "archiveRepositoryIntake", "ProjectContext must expose archiveRepositoryIntake."], [context, "createRepoExpansionFromGap", "ProjectContext must create expansion briefs from repository gaps."], [context, "createRepoDeliveryPackageFromGap", "ProjectContext must create delivery packages from repository gaps."], [context, "deriveRepositoryGaps", "Repo state snapshots must derive repository gaps from intakes."], [context, "imported files", "Repo state snapshots must include imported file evidence."], [context, "not live disk truth", "Generated handoffs must keep imported evidence separate from live truth."], [history, "repoIntakeEntries", "Project History must include repository intake records."], [history, "Repo Builder / repository intake", "History entries must label repository intake source."], [audit, "Repository intake coverage", "Audit Center must show repository intake coverage."], [workspace, "repositoryIntakeCount", "Workspace must count repository intakes."], [workspace, "repositoryGapCount", "Workspace must count repository gaps."], [startFlow, "import-repository-state", "Unified start next-actions must include repository intake for existing repo projects."], [startFlow, "Generate repo state snapshot", "Unified start next-actions must lead from intake to repo state snapshot."], [wizard, "Import repository state in Repo Builder", "First-run wizard recommendations must mention repository intake for existing repos."], [flowRail, "Import repo evidence, derive repo state, resolve gaps", "Flow rail must describe repository intake/state/gap/delivery flow."], [pkg, "audit:repository-intake", "package.json must expose audit:repository-intake."], [pkg, "check-repository-intake-readiness.mjs", "package.json must wire repository intake readiness script."], ]; for (const [haystack, needle, message] of mustContain) { if (!haystack.includes(needle)) failures.push(message); } if (!pkg.includes("audit:repository-intake") || !pkg.includes("audit:all")) { failures.push("audit:all must include the repository intake readiness check."); } if (failures.length) { console.error("ProjectBrain repository intake readiness: FAIL"); for (const failure of failures) console.error(`- ${failure}`); process.exit(1); } console.log("ProjectBrain repository intake readiness: PASS");