#!/usr/bin/env node import { existsSync, readFileSync } from "node:fs"; const requiredFiles = [ "src/shared/lib/model.ts", "src/shared/lib/codexSessionPack.ts", "src/shared/lib/safeData.ts", "src/shared/contexts/ProjectContext.tsx", "src/app/routes.tsx", "src/shared/lib/navigation.tsx", "src/shared/components/ProjectFlowRail.tsx", "src/features/session-packs/pages/SessionPacks.tsx", "src/features/handoffs/pages/CodexHandoffs.tsx", "src/features/build-loop/pages/BuildLoopDashboard.tsx", "src/shared/lib/buildLoop.ts", "src/shared/lib/buildLoopWalkthrough.ts", "src/features/execution/pages/ExecutionCenter.tsx", "src/features/prompts/pages/PromptGenerator.tsx", "src/features/execution-feedback/pages/ExecutionFeedback.tsx", "src/features/history/pages/ProjectHistory.tsx", "src/features/audit/pages/ProjectAuditCenter.tsx", "src/features/projects/pages/Workspace.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/codexSessionPack.ts"] ?? ""; const safeData = text["src/shared/lib/safeData.ts"] ?? ""; const context = text["src/shared/contexts/ProjectContext.tsx"] ?? ""; const routes = text["src/app/routes.tsx"] ?? ""; const navigation = text["src/shared/lib/navigation.tsx"] ?? ""; const flowRail = text["src/shared/components/ProjectFlowRail.tsx"] ?? ""; const page = text["src/features/session-packs/pages/SessionPacks.tsx"] ?? ""; const handoffs = text["src/features/handoffs/pages/CodexHandoffs.tsx"] ?? ""; const buildLoopPage = text["src/features/build-loop/pages/BuildLoopDashboard.tsx"] ?? ""; const buildLoop = text["src/shared/lib/buildLoop.ts"] ?? ""; const walkthrough = text["src/shared/lib/buildLoopWalkthrough.ts"] ?? ""; const execution = text["src/features/execution/pages/ExecutionCenter.tsx"] ?? ""; const promptBuilder = text["src/features/prompts/pages/PromptGenerator.tsx"] ?? ""; const feedback = text["src/features/execution-feedback/pages/ExecutionFeedback.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 pkg = text["package.json"] ?? ""; const mustContain = [ [model, "export interface CodexSessionPack", "CodexSessionPack type missing."], [model, "export interface CodexSessionPackSection", "CodexSessionPackSection type missing."], [model, "export interface CodexSessionPackFileReference", "CodexSessionPackFileReference type missing."], [model, "export interface CodexSessionPackValidationPlan", "CodexSessionPackValidationPlan type missing."], [model, "export interface CodexSessionPackFeedbackTemplate", "CodexSessionPackFeedbackTemplate type missing."], [model, "export type CodexSessionPackExportFormat", "CodexSessionPackExportFormat type missing."], [model, "codexSessionPacks?: CodexSessionPack[]", "Project model must persist session packs."], [safeData, "codexSessionPacks: asArray(project.codexSessionPacks)", "Runtime normalization must preserve session packs."], [helper, "generateCodexSessionPack", "Session pack helper must generate packs."], [helper, "buildSessionPackContext", "Session pack helper must build context."], [helper, "buildSessionPackValidationPlan", "Session pack helper must build validation plan."], [helper, "buildSessionPackFeedbackTemplate", "Session pack helper must build feedback template."], [helper, "formatCodexSessionPackMarkdown", "Session pack helper must format markdown."], [helper, "formatCodexSessionPackJson", "Session pack helper must format JSON."], [helper, "scoreCodexSessionPackQuality", "Session pack helper must score quality."], [helper, "getCodexSessionPackWarnings", "Session pack helper must produce warnings."], [helper, "generated from context pack", "Session pack export must keep context-pack provenance language."], [context, "generateCodexSessionPack", "ProjectContext must expose session pack generation."], [context, "archiveCodexSessionPack", "ProjectContext must expose session pack archival."], [context, "sessionPackItems", "Project search must index session packs."], [routes, "/projects/:projectId/session-packs", "Session Packs route missing."], [routes, "SessionPacks", "Session Packs page must be imported in routes."], [navigation, "Session Packs", "Navigation must expose Session Packs."], [flowRail, 'id: "session-packs"', "Project Flow Rail must include Session Packs."], [page, "Session Packs", "Session Packs page must exist."], [page, "Copy markdown", "Session Packs page must copy markdown."], [page, "Download markdown", "Session Packs page must download markdown."], [page, "Copy JSON", "Session Packs page must copy JSON."], [page, "Download JSON", "Session Packs page must download JSON."], [page, "Download instructions/scripts ZIP", "Session Packs page must expose clear instructions/scripts ZIP export."], [page, "Export session pack files", "Session Packs page must expose bundle file export."], [page, "Bundle contents", "Session Packs page must show bundle contents."], [page, "Validation plan", "Session Packs page must show validation plan."], [page, "Feedback template", "Session Packs page must show feedback template."], [handoffs, "Create session pack", "Codex Handoffs must create session packs."], [handoffs, "Open session pack", "Codex Handoffs must open session packs."], [handoffs, "Copy session pack", "Codex Handoffs must copy session packs."], [handoffs, "Download session pack", "Codex Handoffs must download session packs."], [handoffs, "Download ZIP", "Codex Handoffs must download session pack ZIP."], [handoffs, "Export session pack files", "Codex Handoffs must export session pack files."], [buildLoop, "Create Codex session pack", "Build Loop must recommend creating session packs."], [buildLoop, "Run session and add feedback", "Build Loop must recommend feedback after session pack."], [buildLoop, "latestSessionPack", "Build Loop status must expose latest session pack."], [buildLoopPage, "Session pack", "Build Loop page must show session pack status."], [walkthrough, "create-session-pack", "Build Loop walkthrough must include create-session-pack step."], [walkthrough, "session-packs", "Build Loop walkthrough must explain Session Packs module."], [execution, "Codex Session Pack", "Execution Center must show recommended session pack."], [execution, "Run in Codex", "Execution Center must expose session packs as runnable Codex input."], [promptBuilder, "Codex Session Pack source", "Prompt Builder must expose session pack source."], [promptBuilder, "Use session pack prompt", "Prompt Builder must load session pack markdown."], [feedback, "Linked session pack", "Execution Feedback must link session packs."], [feedback, "Session pack feedback boundary", "Execution Feedback must show pack feedback template."], [feedback, "Paste Codex report generated from this session pack", "Execution Feedback textarea must adapt to linked pack."], [history, 'kind: "sessionPack"', "Project History must include session pack records."], [audit, "Codex session pack readiness", "Audit Center must show session pack coverage."], [audit, "Approved handoffs without pack", "Audit Center must count handoffs without session pack."], [workspace, "Session Packs", "Workspace must expose Session Packs."], [workspace, "activeSessionPacks", "Workspace must inspect active session packs."], [pkg, "audit:session-packs", "package.json must expose audit:session-packs."], [pkg, "check-session-pack-readiness.mjs", "package.json must wire session pack readiness script."], ]; for (const [haystack, needle, message] of mustContain) { if (!haystack.includes(needle)) failures.push(message); } if (page.includes("Download Bundle / ZIP")) { failures.push("Session Packs page must use no-ZIP wording for bundle file export."); } if (!pkg.includes("audit:session-packs") || !pkg.includes("audit:all")) { failures.push("audit:all must include the session pack readiness check."); } if (failures.length) { console.error("ProjectBrain session pack readiness: FAIL"); for (const failure of failures) console.error(`- ${failure}`); process.exit(1); } console.log("ProjectBrain session pack readiness: PASS");