#!/usr/bin/env node /** * cli:derive-form-sections — entry point. * * BACKFILL: promote the uiDesign overlay's per-field `section` judgment * (Phase 3.1 ui-design pre-pass) into the first-order `sections[]` of * form/detail pagespecs. Never invents a grouping (≥ 8 ungrouped fields → * reported `needs-judgment`), never touches an existing `sections[]`, leaves * `tabs[]` forms alone. Idempotent. * * Invocation: * npx --prefer-offline tsx skills/business-analyse/create-prd/cli/derive-form-sections/index.ts \ * --spec '{"mode":"derive","pagespecDir":".smartstack/ba/CRM/CLIENTS/pagespecs"}' \ * [--workdir ] * * `mode:"check"` reports the same outcomes without writing anything. * Runbook: ss upgrade → scaffold-ui-primitives → THIS → /ba-translate-prd * (en/it/de section labels) → /ba-audit-prd (PRD-111/112) → frontend regen via * the spec-drift the write itself triggers (compute-page-diff). */ import { parseArgs } from 'node:util' import { generateEnvelope, failGenerate, printEnvelope } from '../../../../lib/output.js' import { validate } from './validate.js' import { execute } from './execute.js' import type { DeriveFormSectionsSpec } from './types.js' const COMMAND = 'derive-form-sections' function main(): void { const { values } = parseArgs({ options: { spec: { type: 'string' }, workdir: { type: 'string' }, }, strict: true, }) if (!values.spec) { printEnvelope(failGenerate(COMMAND, ['--spec is required'])) process.exit(1) } let raw: unknown try { raw = JSON.parse(values.spec) } catch { printEnvelope(failGenerate(COMMAND, ['Invalid JSON'])) process.exit(1) } const validation = validate(raw) if (!validation.valid) { printEnvelope(failGenerate(COMMAND, validation.errors)) process.exit(1) } try { const spec = raw as DeriveFormSectionsSpec const report = execute(spec, values.workdir ?? process.cwd()) printEnvelope(generateEnvelope(COMMAND, { data: report, filesModified: report.outcomes.filter((o) => o.status === 'promoted' && spec.mode === 'derive').map((o) => o.path), nextSteps: [ 'Run /ba-translate-prd to author the en/it/de form.section.* labels (fr is seeded)', 'Run /ba-audit-prd (PRD-111/112) on the module', 'Regenerate the frontend — the pagespec write is a legitimate spec-drift (compute-page-diff)', ...(report.outcomes.some((o) => o.status === 'needs-judgment') ? ['Run /ui-design on the needs-judgment pagespecs — no grouping is invented mechanically'] : []), ], })) } catch (e) { printEnvelope(failGenerate(COMMAND, [e instanceof Error ? e.message : String(e)])) process.exit(1) } } main()