1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import { z } from "zod";
// Screamer news briefs (screamer.humdrum.one). Each category is an AI-written
// digest published as JSON at `${baseUrl}/data/${date}-${category}.json`.
export const BriefCategory = z.object({
key: z.string(), // "politics" | "tech" | "sports" | "culture" | …
name: z.string(), // display name
});
export const BriefsConfig = z.object({
baseUrl: z.string().url().default("https://screamer.humdrum.one"),
categories: z.array(BriefCategory).default([
{ key: "politics", name: "Politics" },
{ key: "tech", name: "Technology" },
{ key: "sports", name: "Sports" },
{ key: "culture", name: "Culture" },
]),
// How many past dates to walk back when today's brief isn't published yet.
lookbackDays: z.number().int().min(1).max(14).default(7),
});
export type BriefsConfig = z.infer<typeof BriefsConfig>;
export const BriefStory = z.object({
title: z.string(),
summary: z.string(),
sources: z.array(z.string()).default([]),
link: z.string().optional(), // first source article URL
});
export const BriefSection = z.object({
key: z.string(),
name: z.string(),
date: z.string().nullable(), // the date actually resolved for this category
stories: z.array(BriefStory),
});
export const BriefsPayload = z.object({
categories: z.array(BriefSection),
});
export type BriefsPayload = z.infer<typeof BriefsPayload>;
|