148 lines
9.7 KiB
JavaScript
148 lines
9.7 KiB
JavaScript
#!/usr/bin/env node
|
|
import { existsSync, readFileSync } from "node:fs";
|
|
|
|
const requiredFiles = [
|
|
"src/shared/lib/model.ts",
|
|
"src/shared/lib/codexHandoff.ts",
|
|
"src/shared/lib/codexSessionPack.ts",
|
|
"src/shared/lib/safeData.ts",
|
|
"src/shared/api/realClient.ts",
|
|
"src/shared/hooks/useProjectData.ts",
|
|
"src/shared/contexts/ProjectContext.tsx",
|
|
"src/app/routes.tsx",
|
|
"src/shared/lib/navigation.tsx",
|
|
"src/shared/components/ProjectFlowRail.tsx",
|
|
"src/features/handoffs/pages/CodexHandoffs.tsx",
|
|
"src/features/execution-feedback/pages/ExecutionFeedback.tsx",
|
|
"src/features/repo-builder/pages/RepoBuilder.tsx",
|
|
"src/features/execution/pages/ExecutionCenter.tsx",
|
|
"src/features/prompts/pages/PromptGenerator.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/codexHandoff.ts"] ?? "";
|
|
const sessionPackHelper = text["src/shared/lib/codexSessionPack.ts"] ?? "";
|
|
const safeData = text["src/shared/lib/safeData.ts"] ?? "";
|
|
const realClient = text["src/shared/api/realClient.ts"] ?? "";
|
|
const hooks = text["src/shared/hooks/useProjectData.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 handoffPage = text["src/features/handoffs/pages/CodexHandoffs.tsx"] ?? "";
|
|
const feedbackPage = text["src/features/execution-feedback/pages/ExecutionFeedback.tsx"] ?? "";
|
|
const repoBuilder = text["src/features/repo-builder/pages/RepoBuilder.tsx"] ?? "";
|
|
const execution = text["src/features/execution/pages/ExecutionCenter.tsx"] ?? "";
|
|
const promptBuilder = text["src/features/prompts/pages/PromptGenerator.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 CodexHandoff", "CodexHandoff model missing."],
|
|
[model, "export interface CodexHandoffValidationItem", "CodexHandoffValidationItem model missing."],
|
|
[model, "export interface CodexHandoffRisk", "CodexHandoffRisk model missing."],
|
|
[model, "export interface CodexHandoffScope", "CodexHandoffScope model missing."],
|
|
[model, "export interface CodexHandoffQualityScore", "CodexHandoffQualityScore model missing."],
|
|
[model, "codexHandoffs?: CodexHandoff[]", "Project model must persist Codex handoffs."],
|
|
[model, "codexSessionPacks?: CodexSessionPack[]", "Project model must persist Codex session packs."],
|
|
[safeData, "codexHandoffs: asArray(project.codexHandoffs)", "Runtime normalization must preserve Codex handoffs."],
|
|
[realClient, "createHandoffBundle", "Real client must expose backend handoff bundle creation."],
|
|
[realClient, "createCodexTaskFromHandoff", "Real client must expose backend Codex task creation from handoff bundles."],
|
|
[hooks, "useProjectHandoffBundlesData", "Async hooks must expose backend handoff bundles."],
|
|
[hooks, "useProjectCodexTasksData", "Async hooks must expose backend Codex tasks."],
|
|
[helper, "generateCodexHandoffFromDeliveryPackage", "Handoff helper must generate from delivery packages."],
|
|
[helper, "generateCodexHandoffFromRepoGap", "Handoff helper must generate from repository gaps."],
|
|
[helper, "generateCodexHandoffFromWorkPlan", "Handoff helper must generate from work plans."],
|
|
[helper, "generateCodexHandoffFromRepoState", "Handoff helper must generate from repo state snapshots."],
|
|
[helper, "buildAllowedFiles", "Handoff helper must build allowed files."],
|
|
[helper, "buildForbiddenChanges", "Handoff helper must build forbidden changes."],
|
|
[helper, "buildValidationMatrix", "Handoff helper must build validation matrix."],
|
|
[helper, "buildRollbackPlan", "Handoff helper must build rollback plan."],
|
|
[helper, "buildDoneCriteria", "Handoff helper must build done criteria."],
|
|
[helper, "formatCodexHandoffMarkdown", "Handoff helper must format markdown."],
|
|
[helper, "scoreCodexHandoffQuality", "Handoff helper must score quality."],
|
|
[helper, "getHandoffWarnings", "Handoff helper must produce warnings."],
|
|
[helper, "promptInstructions", "Skill prompt instructions must be included."],
|
|
[helper, "validationCommands", "Skill validation commands must be included."],
|
|
[helper, "qualityChecklist", "Skill quality checklist must be included."],
|
|
[helper, "riskNotes", "Skill risk notes must be included."],
|
|
[helper, "This is derived from imported repository evidence, not live filesystem truth", "Repo-gap handoffs must label imported evidence boundary."],
|
|
[sessionPackHelper, "generateCodexSessionPack", "Session pack helper must generate packs from handoffs."],
|
|
[routes, "/projects/:projectId/handoffs", "Codex Handoffs route missing."],
|
|
[routes, "CodexHandoffs", "Codex Handoffs page must be imported in routes."],
|
|
[navigation, "Codex Handoffs", "Navigation must expose Codex Handoffs."],
|
|
[flowRail, 'id: "handoffs"', "Project Flow Rail must include Handoffs."],
|
|
[handoffPage, "Codex Handoffs", "Handoff page must exist."],
|
|
[handoffPage, "Live backend handoff path", "Handoff page must expose the live backend handoff bridge."],
|
|
[handoffPage, "Create live handoff", "Handoff page must support creating backend-persisted handoff bundles."],
|
|
[handoffPage, "Create Codex task", "Handoff page must support creating backend-persisted Codex tasks from handoff bundles."],
|
|
[handoffPage, "useProjectHandoffBundlesData", "Handoff page must read backend handoff bundles in real mode."],
|
|
[handoffPage, "quality", "Handoff page must show quality score."],
|
|
[handoffPage, "Allowed files", "Handoff page must show allowed files."],
|
|
[handoffPage, "Forbidden changes", "Handoff page must show forbidden changes."],
|
|
[handoffPage, "Validation matrix", "Handoff page must show validation matrix."],
|
|
[handoffPage, "Rollback", "Handoff page must show rollback."],
|
|
[handoffPage, "Generated prompt", "Handoff page must show generated prompt."],
|
|
[handoffPage, "Copy next Codex prompt", "Handoff page must support copying prompts."],
|
|
[handoffPage, "Generate impact review", "Handoff page must support impact review generation."],
|
|
[handoffPage, "ProjectBrain-derived impact simulation, not a live git diff", "Handoff page must distinguish simulated review from live git diff."],
|
|
[handoffPage, "Add execution feedback", "Handoff page must link to execution feedback intake."],
|
|
[handoffPage, "Create session pack", "Handoff page must create session packs."],
|
|
[handoffPage, "Open session pack", "Handoff page must open session packs."],
|
|
[handoffPage, "Copy session pack", "Handoff page must copy session packs."],
|
|
[handoffPage, "Download session pack", "Handoff page must download session packs."],
|
|
[handoffPage, "Download ZIP", "Handoff page must download session pack ZIP."],
|
|
[handoffPage, "Export session pack files", "Handoff page must export session pack files."],
|
|
[handoffPage, "controlled input for a Codex build session", "Handoff page must explain session pack purpose."],
|
|
[handoffPage, "View in Build Loop", "Handoff page must link to Build Loop."],
|
|
[feedbackPage, "Execution Feedback", "Execution feedback page must exist for post-handoff evidence intake."],
|
|
[repoBuilder, "Create Codex handoff", "Repo Builder must generate handoffs."],
|
|
[repoBuilder, "Create handoff from work plan", "Repo Builder must generate handoffs from work plans."],
|
|
[repoBuilder, "Create handoff from repo state", "Repo Builder must generate handoffs from repo state."],
|
|
[execution, "Codex Handoff Quality Engine", "Execution Center must show handoff engine."],
|
|
[execution, "Copy next Codex prompt", "Execution Center must copy next prompt."],
|
|
[execution, "Open Codex Handoff", "Execution Center must link to Handoffs."],
|
|
[promptBuilder, "Codex Handoff source", "Prompt Builder must expose handoff source."],
|
|
[promptBuilder, "Use handoff promptText", "Prompt Builder must use handoff promptText."],
|
|
[context, "generateCodexHandoff", "ProjectContext must expose generateCodexHandoff."],
|
|
[context, "generateCodexSessionPack", "ProjectContext must expose generateCodexSessionPack."],
|
|
[context, "archiveCodexHandoff", "ProjectContext must expose archiveCodexHandoff."],
|
|
[context, "codexHandoffItems", "Project search must index Codex handoffs."],
|
|
[history, 'kind: "handoff"', "Project History must include handoff records."],
|
|
[audit, "Codex handoff quality", "Audit Center must show handoff quality."],
|
|
[workspace, "codexHandoffCount", "Workspace must count Codex handoffs."],
|
|
[workspace, "Codex Handoffs", "Workspace must expose Codex Handoffs."],
|
|
[pkg, "audit:handoffs", "package.json must expose audit:handoffs."],
|
|
[pkg, "check-codex-handoff-readiness.mjs", "package.json must wire handoff readiness script."],
|
|
];
|
|
|
|
for (const [haystack, needle, message] of mustContain) {
|
|
if (!haystack.includes(needle)) failures.push(message);
|
|
}
|
|
|
|
if (!pkg.includes("audit:handoffs") || !pkg.includes("audit:all")) {
|
|
failures.push("audit:all must include the Codex handoff readiness check.");
|
|
}
|
|
|
|
if (failures.length) {
|
|
console.error("ProjectBrain Codex handoff readiness: FAIL");
|
|
for (const failure of failures) console.error(`- ${failure}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log("ProjectBrain Codex handoff readiness: PASS");
|