Skip to content

Commit 8a1c15e

Browse files
author
ma111e
committed
docs(github-pages): document swipe page and full manifest schema
- Document the per-digest swipe/triage page that is published alongside each digest. - Add an exhaustive manifest schema (top-level Manifest + every ManifestEntry field). - Replace the non-existent 'scheduler' section with how automatic publishing actually works.
1 parent 2afbb35 commit 8a1c15e

1 file changed

Lines changed: 48 additions & 16 deletions

File tree

docs/github-pages.md

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Downlink can automatically publish each digest as a self-contained HTML page to a GitHub Pages repository. After every successful digest generation, it:
44

55
1. Clones (or pulls) your Pages repo locally.
6-
2. Writes the digest HTML file (e.g. `digests/downlink-digest-2026-04-24_1200.html`).
6+
2. Writes the digest HTML file (e.g. `digests/downlink-digest-2026-04-24_1200.html`) and a companion swipe/triage page (`digests/downlink-swipe-2026-04-24_1200.html`).
77
3. Regenerates `digests/index.html` and `digests/manifest.json` listing all digests, newest first.
88
4. Writes a root `index.html` that renders the digest archive and reads files from the configured output directory.
99
5. Commits and pushes the changed files.
@@ -15,13 +15,13 @@ Downlink can automatically publish each digest as a self-contained HTML page to
1515

1616
If you don't have one, create a repository named `<your-username>.github.io` (for a user site) or any repo with GitHub Pages enabled on a branch.
1717

18-
In the repo's **Settings Pages**, set the source to the branch you'll push to (e.g. `main`, root `/`).
18+
In the repo's **Settings -> Pages**, set the source to the branch you'll push to (e.g. `main`, root `/`).
1919

2020
---
2121

2222
## 2. Create a Personal Access Token
2323

24-
Go to **GitHub Settings Developer settings Personal access tokens Fine-grained tokens** (or classic tokens).
24+
Go to **GitHub -> Settings -> Developer settings -> Personal access tokens -> Fine-grained tokens** (or classic tokens).
2525

2626
For normal publishing, the token needs **Contents: Read and write** on the target repository.
2727

@@ -63,16 +63,16 @@ Add a `github_pages` block inside `notifications`:
6363
| Field | Required | Default | Description |
6464
|---|---|---|---|
6565
| `enabled` | yes | `false` | Enable or disable publishing. |
66-
| `repo_url` | yes | | HTTPS clone URL of the Pages repo. |
66+
| `repo_url` | yes | / | HTTPS clone URL of the Pages repo. |
6767
| `branch` | no | `main` | Branch to clone and push to. When `configure_pages` is true, this is also configured as the GitHub Pages source branch. |
6868
| `configure_pages` | no | `false` | Configure the GitHub Pages source to `branch` at `/` before publishing. Requires extra token permissions. |
69-
| `token` | no* | | GitHub PAT. Prefer `DOWNLINK_GH_PAGES_TOKEN` env var instead. |
69+
| `token` | no* | / | GitHub PAT. Prefer `DOWNLINK_GH_PAGES_TOKEN` env var instead. |
7070
| `output_dir` | no | `digests` | Safe relative subdirectory inside the repo where digest files are written. Absolute paths, `.`, `..`, and parent traversal are rejected. |
71-
| `base_url` | no | | Public URL of the site (e.g. `https://your-username.github.io`). Used to build links in Discord notifications. |
71+
| `base_url` | no | / | Public URL of the site (e.g. `https://your-username.github.io`). Used to build links in Discord notifications. |
7272
| `commit_author` | no | `downlink-bot` | Git commit author name. |
7373
| `commit_email` | no | `downlink-bot@users.noreply.github.com` | Git commit author email. |
7474
| `clone_dir` | no | `$TMPDIR/downlink-ghpages` | Local path where the repo is cloned. Persists across runs to avoid full re-clones. |
75-
| `discord_webhook_url` | no | | A **separate** Discord webhook to notify when a page is published. Distinct from the main digest webhook. |
75+
| `discord_webhook_url` | no | / | A **separate** Discord webhook to notify when a page is published. Distinct from the main digest webhook. |
7676

7777
*\* `token` must be provided via config or environment variable for publishing to work.*
7878

@@ -87,7 +87,7 @@ export DOWNLINK_GH_PAGES_TOKEN=github_pat_...
8787
./server
8888
```
8989

90-
Or put the token directly in `config.json` under `github_pages.token` but be careful not to commit it.
90+
Or put the token directly in `config.json` under `github_pages.token` - but be careful not to commit it.
9191

9292
---
9393

@@ -109,7 +109,7 @@ Every config field has a corresponding flag on the `server` command. Flags overr
109109
--gh-pages-discord-webhook <url> Discord webhook for publish notifications
110110
```
111111

112-
Example enable for one run without touching `config.json`:
112+
Example - enable for one run without touching `config.json`:
113113

114114
```sh
115115
export DOWNLINK_GH_PAGES_TOKEN=github_pat_...
@@ -126,15 +126,47 @@ export DOWNLINK_GH_PAGES_TOKEN=github_pat_...
126126

127127
On each digest generation:
128128

129-
- **`<output_dir>/downlink-digest-YYYY-MM-DD_HHMM.html`** — self-contained dark-themed HTML page for that digest (same file sent to Discord).
130-
- **`<output_dir>/manifest.json`** — machine-readable archive data for the digest index, newest first. Each digest entry includes `filename`, `started_at`, `time_window`, `article_count`, `must_count`, `should_count`, `may_count`, `opt_count`, `provider`, `model`, `headlines`, and `summary`.
131-
- **`<output_dir>/index.html`** — regenerated archive UI with latest-digest hero, search, filters, sort controls, log/grid/timeline layouts, keyboard navigation, and pinned digests in browser local storage.
132-
- **`index.html`** — root archive UI that loads `<output_dir>/manifest.json` and links digest pages under `<output_dir>`.
129+
- **`<output_dir>/downlink-digest-YYYY-MM-DD_HHMM.html`** - self-contained dark-themed HTML page for that digest (same file sent to Discord).
130+
- **`<output_dir>/downlink-swipe-YYYY-MM-DD_HHMM.html`** - self-contained mobile-friendly "swipe" triage view of the same digest, linked from the articles page. Shares its timestamp.
131+
- **`<output_dir>/manifest.json`** - machine-readable archive data for the digest index, newest first. See [Manifest schema](#manifest-schema) below for every field.
132+
- **`<output_dir>/index.html`** - regenerated archive UI with latest-digest hero, search, filters, sort controls, log/grid/timeline layouts, keyboard navigation, and pinned digests in browser local storage.
133+
- **`index.html`** - root archive UI that loads `<output_dir>/manifest.json` and links digest pages under `<output_dir>`.
133134

134135
If `output_dir` is empty, Downlink uses `digests`. Publishing directly to the repo root is not supported.
135136

136137
The browser-facing archive index uses `manifest.json` directly. The manifest follows the current archive schema only; old manifests should be regenerated by publishing a new digest or reinitializing the Pages structure.
137138

139+
### Manifest schema
140+
141+
Top-level `manifest.json` object:
142+
143+
| Field | Type | Description |
144+
|---|---|---|
145+
| `generated_at` | string | Timestamp when the manifest was last (re)generated. |
146+
| `source_repo` | string | The Pages repository URL the manifest was written to. |
147+
| `digests` | array | List of digest entries, newest first (see below). |
148+
149+
Each entry in `digests`:
150+
151+
| Field | Type | Description |
152+
|---|---|---|
153+
| `filename` | string | Digest HTML filename (e.g. `downlink-digest-2026-04-24_1200.html`). |
154+
| `started_at` | string | When digest generation started. |
155+
| `period_start` | string | Start of the time window the digest covers. Omitted when unset. |
156+
| `time_window` | string | Human-readable description of the covered time window. |
157+
| `article_count` | int | Total number of articles in the digest. |
158+
| `must_count` | int | Articles tagged "Must Read". |
159+
| `should_count` | int | Articles tagged "Should Read". |
160+
| `may_count` | int | Articles tagged "May Read". |
161+
| `opt_count` | int | Articles tagged "Optional". |
162+
| `provider` | string | Analysis provider used for the digest summary. |
163+
| `model` | string | Primary model name. |
164+
| `models` | array | All unique model names across the summary and per-article analysis. Omitted when empty. |
165+
| `title` | string | Digest title. Omitted when unset. |
166+
| `headlines` | array | Headline strings shown in the archive index. |
167+
| `headline_priorities` | array | Per-headline priority labels, aligned with `headlines`. Omitted when empty. |
168+
| `summary` | string | Digest summary (markdown). |
169+
138170
---
139171

140172
## 7. Discord publish notification
@@ -153,12 +185,12 @@ If `base_url` is not set, the message omits the URL. Failure to send this notifi
153185

154186
On the first publish, Downlink clones the repository into `clone_dir` (shallow, depth 1). On subsequent runs it pulls the latest from origin before writing and committing. This means:
155187

156-
- The clone persists between server restarts no full re-clone each time.
188+
- The clone persists between server restarts - no full re-clone each time.
157189
- If two concurrent digest generations race, the second push may be rejected as non-fast-forward; Downlink will pull and retry once automatically.
158190
- If you need to force a fresh clone, delete the `clone_dir` directory.
159191

160192
---
161193

162-
## 9. Scheduler usage
194+
## 9. Automatic publishing
163195

164-
The scheduler triggers digest generation on the server via gRPC. Because publishing is wired into the server-side pipeline, no extra scheduler configuration is needed — any digest the scheduler generates will be published automatically if `github_pages.enabled` is `true` in the server's `config.json`.
196+
Publishing is wired into the server-side digest pipeline, so no extra configuration is needed beyond `github_pages.enabled`. Any digest generated against the server - via `dlk digest generate` or the gRPC `DigestService` - is published automatically when `github_pages.enabled` is `true` in the server's `config.json`. To publish on a schedule, run `dlk digest generate` from cron (or any external scheduler) against the running server.

0 commit comments

Comments
 (0)