--- title: Interface Changes --- ```js import {API} from "./components/config.js"; ``` ```js const [published, draft, repos] = await Promise.all([ fetch(`${API}/interface-changes/?status=published`).then(r => r.ok ? r.json() : []), fetch(`${API}/interface-changes/?status=draft`).then(r => r.ok ? r.json() : []), fetch(`${API}/repos/`).then(r => r.ok ? r.json() : []), ]); ``` ```js const repoMap = Object.fromEntries(repos.map(r => [r.slug, r])); const CHANGE_TYPE_COLOR = { breaking: "#ef4444", removal: "#f97316", deprecation: "#f59e0b", additive: "#22c55e", }; function changeBadge(type) { const color = CHANGE_TYPE_COLOR[type] ?? "#6b7280"; return htl.html`${type}`; } function interfaceBadge(type) { return htl.html`${type}`; } ``` # Interface Changes Track breaking and additive mutations to published interfaces across repos. Publishing a change sends inbox notifications to all affected agents.
${published.filter(c => c.change_type === "breaking").length}
Breaking (live)
${published.filter(c => c.change_type === "deprecation").length}
Deprecations (live)
${published.filter(c => c.change_type === "additive").length}
Additive (live)
${draft.length}
Drafts
## Planned changes ```js const planned = [...published, ...draft].filter(c => c.planned_for); planned.sort((a, b) => a.planned_for.localeCompare(b.planned_for)); ``` ```js if (planned.length === 0) { display(htl.html`

No changes with a planned date.

`); } else { display(htl.html` ${planned.map(c => htl.html``)}
Date Change Repo Status
${c.planned_for} ${changeBadge(c.change_type)} ${c.title} ${c.origin_repo_slug ?? c.repo_slug} ${c.status}
`); } ``` ## Published changes ```js if (published.length === 0) { display(htl.html`

No published changes.

`); } else { display(htl.html`
${published.map(c => htl.html`
${changeBadge(c.change_type)} ${interfaceBadge(c.interface_type)} ${c.title}
Repo: ${c.origin_repo_slug ?? c.repo_slug} ${c.published_at ? htl.html` · Published ${c.published_at.slice(0,10)}` : ""} ${c.affected_repo_slugs?.length ? htl.html` · Affects: ${c.affected_repo_slugs.join(", ")}` : ""}
Description
${c.description}
${c.affected_paths?.length ? htl.html`
Paths: ${c.affected_paths.map(p => htl.html`${p}`)}
` : ""}
`)}
`); } ``` ## Drafts ```js if (draft.length === 0) { display(htl.html`

No draft changes.

`); } else { display(htl.html` ${draft.map(c => htl.html``)}
Title Repo Type Affected
${c.title} ${c.repo_slug} ${changeBadge(c.change_type)} ${interfaceBadge(c.interface_type)} ${(c.affected_repo_slugs ?? []).join(", ") || "—"}
`); } ```