#!/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()