diff options
Diffstat (limited to 'AGENTS.md')
| -rw-r--r-- | AGENTS.md | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..4a13a10 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,88 @@ +# slackware-changelog + +A widget for a [Homepage](https://gethomepage.dev) dashboard, one of the +modules under `homepage-modules/`. Siblings share the shape described below. + +## Shape of a module + +Homepage's `customapi` widget fetches JSON and maps fields to labels. It +cannot parse text, cannot do arithmetic, and refetches on every refresh +interval. So each module is a small stdlib Python HTTP service on localhost +that does the parsing and caching, plus: + +- `<name>.py` - the service, single file, stdlib only, executable +- `test_<name>.py` - self-check, fakes the upstream, prints `ok` +- `<name>.service` - systemd unit, `DynamicUser=yes`, config via `Environment=` +- `homepage-services.yaml` / `homepage-settings.yaml` - snippets to merge + +No dependencies. No framework. `ThreadingHTTPServer` and `urllib`. + +## This module + +Serves the latest Slackware -current ChangeLog entry on `127.0.0.1:8098`. + +Endpoints: `/latest` (counts and summary), `/top` (the first `TOP_N` packages +as flat fields), `/packages` (every package with its action), `/entry` (HTML +page of the entry), `/refresh` (bypass the cache). + +### Why /top exists + +`customapi` maps a fixed list of field names to labels. It cannot iterate an +array and cannot scroll, so a JSON list of packages renders as nothing. `/top` +flattens the first `TOP_N` into `pkg1`, `pkg2`, ... which the widget can map +one per row, and appends a `... and N more` row in the next slot when the entry +is longer. The card links to the ChangeLog for the rest. + +Mapping more `pkgN` fields than the entry has packages is harmless: Homepage +skips a field that is absent. So the snippet maps a fixed 9 rows regardless of +how many that day's entry holds. + +### ChangeLog format + +The file is reverse-chronological. Entries are separated by a `+--------+` +line, so the latest entry is everything before the first separator. + +Inside an entry: + +``` +Mon Sep 7 22:56:39 UTC 2026 +a/util-linux-2.42.3-x86_64-1.txz: Upgraded. + This update fixes bugs and security issues. + (* Security fix *) +l/cryptopp-8.9.0-x86_64-3.txz: Rebuilt. + Fixed library location. Thanks to Petri Kaukasoina. +``` + +Gotcha: a package line is identified by **starting at column 0**, not by +ending in a period. Note lines are indented and frequently end in a period +too ("Thanks to Petri Kaukasoina."), so a period-based regex counts prose as +packages. The test asserts this specific case. + +Actions seen: `Upgraded`, `Rebuilt`, `Added`, `Removed`. The parser counts +whatever word it finds rather than matching a fixed list, so a new action +verb shows up in `summary` instead of vanishing. + +Security fixes are marked by the literal `(* Security fix *)` on its own +indented line. CVE ids appear in the notes as cve.org URLs. + +### Caching + +`CACHE_TTL` (default 1800s) governs upstream fetches; the widget's +`refreshInterval` only redraws. A failed refresh keeps the previous entry and +adds a `stale` field with the error, so an unreachable mirror degrades to an +old entry rather than a blank card. `/refresh` forces a fetch but obeys the +same fallback. + +### Rendering + +`/entry` escapes everything from the ChangeLog with `html.escape` before it +reaches the page. Upstream text is not trusted markup; the test asserts no +`<script` survives. + +## Conventions + +- GPLv2 only. Header notice in every source file. +- Snippet YAML files are merged into Homepage's config by hand, never copied + over it; the comments at the top of each say so. +- Layout groups: any group omitted from `layout:` falls to the bottom of the + page, so the snippet reminds the reader to list their existing groups too. |
