Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 1 | /** |
| 2 | * The postmortem editor's sections, and its preview's reading of plain | |
| 3 | * text, the same way the status page reads it (apps/status render.ts | |
| 4 | * `prose`). No Workers or React imports, so it is tested under Node. | |
| 5 | */ | |
| 6 | import type { PostmortemFields } from "@g1t/contracts/status"; | |
| 7 | ||
| 8 | export const POSTMORTEM_SECTIONS: { key: keyof PostmortemFields; title: string; hint: string; rows: number }[] = [ | |
| 9 | { key: "summary", title: "Summary", hint: "Two or three sentences: what happened, to whom, for how long. Required to publish.", rows: 4 }, | |
| 10 | { key: "impact", title: "Impact", hint: "Who noticed, and what they could not do.", rows: 3 }, | |
| 11 | { key: "timeline", title: "Timeline", hint: "Filled in from the incident's timeline. Times are UTC.", rows: 8 }, | |
| 12 | { key: "root_cause", title: "Root cause", hint: "Why it happened, not who. Required to publish.", rows: 4 }, | |
| 13 | { key: "went_well", title: "What went well", hint: "", rows: 3 }, | |
| 14 | { key: "went_badly", title: "What went badly", hint: "", rows: 3 }, | |
| 15 | { key: "action_items", title: "Action items", hint: "Filled in from the follow-ups. One per line, starting “- ”.", rows: 4 }, | |
| 16 | ]; | |
| 17 | ||
| 18 | export type Block = { kind: "paragraph"; text: string } | { kind: "list"; items: string[] }; | |
| 19 | ||
| 20 | /** Blank lines between paragraphs; a block whose lines all start with "- " is a list. */ | |
| 21 | export function proseBlocks(text: string): Block[] { | |
| 22 | return text | |
| 23 | .split(/\n{2,}/) | |
| 24 | .map((block) => block.replace(/^\n+|\n+$/g, "")) | |
| 25 | .filter(Boolean) | |
| 26 | .map((block): Block => { | |
| 27 | const lines = block.split("\n").filter((l) => l.trim() !== ""); | |
| 28 | if (lines.every((l) => /^\s*[-*] /.test(l))) return { kind: "list", items: lines.map((l) => l.replace(/^\s*[-*] /, "")) }; | |
| 29 | return { kind: "paragraph", text: block }; | |
| 30 | }); | |
| 31 | } |