mattrguerra/meridian-ops-boardmainPrivate on GitHub, published here in full

briefings-file.ts

Language TypeScript1.5 KB39 lines

apps/dashboard/src/briefings-file.ts

  1. /**
  2. * The model-written briefings, as produced by `analysis/brief.py`. Node only.
  3. *
  4. * The page's own `briefingProse()` assembles sentences deterministically in
  5. * TypeScript from the snapshot, a different artifact from what the model
  6. * writes. This file is how the model's briefing, and its per-person views,
  7. * reach the board.
  8. *
  9. * The chain is deliberately one-directional and file-mediated:
  10. *
  11. * pnpm dashboard -> briefing-payload.json (numbers)
  12. * brief.py -> briefings.json (prose, written from those numbers)
  13. * pnpm dashboard -> dashboard.html (renders both)
  14. *
  15. * which is why `pnpm morning` runs the dashboard twice. The alternative (having
  16. * the renderer call a model) would put a paid network round-trip inside a page
  17. * build and make the board unrenderable whenever the model was unavailable.
  18. */
  19. import { readFile } from 'node:fs/promises'
  20. import type { Briefings } from './briefings.js'
  21. export type { Briefings }
  22. export const BRIEFINGS_FILE = new URL('../../../briefings.json', import.meta.url)
  23. export async function readBriefings(file: URL = BRIEFINGS_FILE): Promise<Briefings | null> {
  24. try {
  25. const parsed: unknown = JSON.parse(await readFile(file, 'utf8'))
  26. if (!parsed || typeof parsed !== 'object') return null
  27. const b = parsed as Briefings
  28. return b.briefings && typeof b.briefings === 'object' ? b : null
  29. } catch {
  30. // Absent is the normal case before the first run. The page renders the
  31. // deterministic briefing and says the written one has not been generated.
  32. return null
  33. }
  34. }