#!/usr/bin/env node import { existsSync, readFileSync } from "node:fs"; const requiredFiles = [ "src/shared/lib/codexSessionPackExport.ts", "src/shared/lib/downloads.ts", "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/features/execution-feedback/pages/ExecutionFeedback.tsx", "src/shared/lib/codexExecutionFeedback.ts", "src/features/prompts/pages/PromptGenerator.tsx", "src/features/audit/pages/ProjectAuditCenter.tsx", "src/shared/contexts/ProjectContext.tsx", "pnpm-lock.yaml", "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 exportHelper = text["src/shared/lib/codexSessionPackExport.ts"] ?? ""; const downloads = text["src/shared/lib/downloads.ts"] ?? ""; const sessionPacks = 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 feedback = text["src/features/execution-feedback/pages/ExecutionFeedback.tsx"] ?? ""; const feedbackHelper = text["src/shared/lib/codexExecutionFeedback.ts"] ?? ""; const promptBuilder = text["src/features/prompts/pages/PromptGenerator.tsx"] ?? ""; const audit = text["src/features/audit/pages/ProjectAuditCenter.tsx"] ?? ""; const context = text["src/shared/contexts/ProjectContext.tsx"] ?? ""; const lockfile = text["pnpm-lock.yaml"] ?? ""; const pkg = text["package.json"] ?? ""; const mustContain = [ [exportHelper, "buildCodexSessionPackFiles", "Export helper must build bundle files."], [exportHelper, "formatAllowedFilesManifest", "Export helper must format allowed files manifest."], [exportHelper, "formatForbiddenChangesManifest", "Export helper must format forbidden changes manifest."], [exportHelper, "formatValidationPlanMarkdown", "Export helper must format validation plan."], [exportHelper, "formatRollbackPlanMarkdown", "Export helper must format rollback plan."], [exportHelper, "formatFeedbackTemplateMarkdown", "Export helper must format feedback template."], [exportHelper, "formatSessionPackReadme", "Export helper must format quick-start README."], [exportHelper, "formatImportableFeedbackTemplate", "Export helper must format importable feedback template."], [exportHelper, "downloadCodexSessionPackBundle", "Export helper must expose bundle download."], [exportHelper, "buildZipEntriesFromSessionPack", "Export helper must expose ZIP entries helper."], [exportHelper, "buildCodexSessionPackZipBlob", "Export helper must expose ZIP Blob builder."], [exportHelper, "downloadCodexSessionPackZip", "Export helper must expose ZIP download."], [exportHelper, "getCodexSessionPackZipFilename", "Export helper must expose ZIP filename helper."], [exportHelper, "zipExport: true", "Bundle manifest must state ZIP export is available."], [exportHelper, "fflate", "Export helper must use the selected browser-safe ZIP dependency."], [exportHelper, "codex-session-pack.md", "Bundle must include markdown handoff file."], [exportHelper, "codex-session-pack.json", "Bundle must include JSON file."], [exportHelper, "allowed-files.txt", "Bundle must include allowed files manifest."], [exportHelper, "forbidden-changes.md", "Bundle must include forbidden changes manifest."], [exportHelper, "validation-plan.md", "Bundle must include validation plan."], [exportHelper, "rollback-plan.md", "Bundle must include rollback plan."], [exportHelper, "feedback-template.md", "Bundle must include feedback template."], [exportHelper, "README_RUN_THIS_CODEX_SESSION.md", "Bundle must include quick-start README."], [downloads, "downloadTextFile", "Shared download helper must expose downloadTextFile."], [downloads, "downloadJsonFile", "Shared download helper must expose downloadJsonFile."], [downloads, "downloadBlobFile", "Shared download helper must expose downloadBlobFile."], [sessionPacks, "Bundle contents", "Session Packs page must show bundle contents."], [sessionPacks, "Download instructions/scripts ZIP", "Session Packs page must expose clear instructions/scripts ZIP download action."], [sessionPacks, "Export session pack files", "Session Packs page must expose honest session pack file export action."], [sessionPacks, "Copy feedback template", "Session Packs page must copy feedback template."], [sessionPacks, "Download feedback template", "Session Packs page must download feedback template."], [sessionPacks, "Copy quick-start README", "Session Packs page must copy quick-start README."], [sessionPacks, "ZIP export contains only", "Session Packs page must document ZIP contents."], [sessionPacks, "Export session pack files", "Session Packs page must keep individual-file fallback."], [handoffs, "Download ZIP", "Handoffs page must expose ZIP export when session pack exists."], [handoffs, "Export session pack files", "Handoffs page must export session pack files."], [handoffs, "controlled input for a Codex build session", "Handoffs page must explain session pack purpose."], [buildLoopPage, "Download ZIP", "Build Loop page must expose latest session pack ZIP."], [buildLoopPage, "Bundle readiness", "Build Loop page must show bundle readiness."], [buildLoopPage, "Feedback template readiness", "Build Loop page must show feedback template readiness."], [buildLoop, "Bundle readiness", "Build Loop markdown must include bundle readiness."], [buildLoop, "Feedback template readiness", "Build Loop markdown must include feedback template readiness."], [feedback, "Use this feedback template", "Execution Feedback must use session pack template."], [feedback, "Download template", "Execution Feedback must download template."], [feedback, "Insert template into report field", "Execution Feedback must insert template into report field."], [feedbackHelper, "Validation output", "Feedback parser/formatter must recognize validation output heading."], [feedbackHelper, "Final status", "Feedback parser/formatter must recognize final status heading."], [promptBuilder, "Use session pack prompt", "Prompt Builder must use session pack prompt."], [promptBuilder, "Copy feedback template", "Prompt Builder must copy feedback template."], [audit, "Missing allowed/rollback", "Audit Center must show allowed/rollback bundle readiness."], [context, "validation-plan.md", "Search index must include bundle files."], [pkg, '"fflate"', "package.json must include selected ZIP dependency."], [pkg, "audit:session-pack-export", "package.json must expose audit:session-pack-export."], [pkg, "check-session-pack-export-readiness.mjs", "package.json must wire session pack export readiness script."], [lockfile, "fflate", "pnpm lockfile must include selected ZIP dependency."], ]; for (const [haystack, needle, message] of mustContain) { if (!haystack.includes(needle)) failures.push(message); } if (sessionPacks.includes("Download Bundle / ZIP")) { failures.push("Session Packs page must not imply a real ZIP is downloaded."); } if (exportHelper.includes("zipExport: false") || exportHelper.includes("reasonZipIsNotIncluded")) { failures.push("Bundle manifest must no longer document ZIP export as unavailable."); } if (!pkg.includes("audit:session-pack-export") || !pkg.includes("audit:all")) { failures.push("audit:all must include session pack export readiness."); } if (failures.length) { console.error("ProjectBrain session pack export readiness: FAIL"); for (const failure of failures) console.error(`- ${failure}`); process.exit(1); } console.log("ProjectBrain session pack export readiness: PASS");