#!/usr/bin/env node /** * cli:derive-detail-summary — entry point. * * BACKFILL: derive the `summary` block of DETAIL pagespecs (the header band — * big title value, status badge, ≤ 4 meta pairs, rendered above the tabs) from * anchors ALREADY authored: the entité.md `**Affichage**` line * (lib/display-field), the entity's state enum (derive-lifecycle parsers) and * the attribute table. Never invents (`needs-judgment` when no title anchor), * never touches an existing `summary`/`uiDesign.detail.summary`. Idempotent. * * Invocation: * npx --prefer-offline tsx skills/business-analyse/create-prd/cli/derive-detail-summary/index.ts \ * --spec '{"mode":"derive","pagespecDir":".smartstack/ba///pagespecs","moduleRoot":".smartstack/ba//"}' \ * [--workdir ] * * `mode:"check"` is the deterministic engine of PRD-134 — a detail pagespec * whose rendered strip carries ≥ 4 triggers (lib/detail-tab-strip) and no * summary band is one finding; writes nothing. */ 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 { DeriveDetailSummarySpec } from './types.js' const COMMAND = 'derive-detail-summary' 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 DeriveDetailSummarySpec const report = execute(spec, values.workdir ?? process.cwd()) printEnvelope(generateEnvelope(COMMAND, { data: report, filesModified: report.outcomes.filter((o) => o.status === 'derived' && spec.mode === 'derive').map((o) => o.path), nextSteps: spec.mode === 'check' ? [ ...(report.findings.length > 0 ? ['Fix the PRD-134 findings — run --mode derive (backfill) or author the - **Résumé** : bullet'] : ['Every crowded fiche carries its summary band — nothing to fix']), ] : [ 'Run /ba-audit-prd (PRD-119/134) on the module', 'Regenerate the entity detail pages — the pagespec write is a legitimate spec-drift (compute-page-diff)', ...(report.outcomes.some((o) => o.status === 'needs-judgment') ? ['Resolve the needs-judgment pagespecs — author the - **Résumé** : bullet (/ba-create-screen) or the **Affichage** line (/ba-create-data-model); nothing is invented mechanically'] : []), ], })) } catch (e) { printEnvelope(failGenerate(COMMAND, [e instanceof Error ? e.message : String(e)])) process.exit(1) } } main()