#!/usr/bin/env node /** * cli:validate-page — Entry point. * * Read-only deterministic validator for a single generated page .tsx file. * Used by the per-page audit-or-regenerate loop in ba-develop * Phase 3a as the gate between scaffold-component invocations. * * Invocation: * npx --prefer-offline tsx skills/development/frontend/component/cli/validate-page/index.ts \ * --project-path "" \ * --page-file "src/pages/myapp/crm/contacts/ContactListPage.tsx" * * Exit code: 0 if no err violations; 1 otherwise. The orchestrator reads the * report.violations array to drive the retry-once-then-halt policy. */ import { parseArgs } from 'node:util' import { validate } from './validate.js' import { execute } from './execute.js' import { executeEnvelope, failExecute, printEnvelope, } from '../../../../../lib/output.js' import type { ValidatePageReport } from './types.js' const COMMAND = 'validate-page' function main(): void { const { values } = parseArgs({ options: { 'project-path': { type: 'string' }, 'page-file': { type: 'string' }, }, strict: true, }) if (!values['project-path']) { printEnvelope(failExecute(COMMAND, ['--project-path is required'])) process.exit(1) } if (!values['page-file']) { printEnvelope(failExecute(COMMAND, ['--page-file is required'])) process.exit(1) } const spec = { projectPath: values['project-path'], pageFile: values['page-file'], } const validation = validate(spec) if (!validation.valid || !validation.spec) { printEnvelope(failExecute(COMMAND, validation.errors)) process.exit(1) } const report = execute(validation.spec) const errCount = report.violations.filter((v) => v.severity === 'err').length const warnCount = report.violations.filter((v) => v.severity === 'warn').length const success = errCount === 0 const nextSteps: string[] = [] if (!success) { nextSteps.push( `${errCount} err / ${warnCount} warn. The orchestrator should re-invoke scaffold-component with priorErrors[] populated from these violations and retry once. If retry still fails, halt the Phase 3a loop.`, ) } printEnvelope( executeEnvelope(COMMAND, { success, data: { module: report.module, entity: report.entity, view: report.view, errors: errCount, warnings: warnCount, }, report, nextSteps, }), ) process.exit(success ? 0 : 1) } main()