Add today-view plugin with Tana, ICS, and Donetick data sources
Implements an e-ink daily dashboard plugin ("today") with four sections:
date/focus/success header, agenda timeline, chores checklist, and
due/overdue task lists.
Data sources:
- Focus & success text: Tana daily note (src/sources/tana.ts)
- Due/overdue tasks: Tana task search (src/sources/tana.ts)
- Agenda events: ICS calendar feeds (src/sources/ics.ts)
- Chores: Donetick API (src/sources/donetick.ts)
All sources fetch in parallel and fall back gracefully on error.
Tests use mock HTTP servers with synthetic data — no real services needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ddcb03d3dd
commit
2e34246d14
12 changed files with 1665 additions and 11 deletions
50
CLAUDE.md
50
CLAUDE.md
|
|
@ -4,35 +4,63 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## Project Overview
|
||||
|
||||
TRMNLc is a self-hosted server that serves rendered calendar displays to [TRMNL](https://usetrmnl.com/) e-ink devices. It fetches ICS calendar feeds, renders them as HTML using React SSR, screenshots the HTML with Puppeteer (Firefox), dithers the image with ImageMagick for e-ink display, and serves it via the TRMNL device API.
|
||||
|
||||
The UI is in Dutch (e.g., "VRIJ" = free, "BEZET" = busy, "VOLGENDE" = next, "DAARNA" = after that).
|
||||
TRMNLc is a self-hosted server that serves rendered displays to [TRMNL](https://usetrmnl.com/) e-ink devices. It renders plugin UIs as HTML using React SSR, screenshots with Puppeteer (Firefox), dithers with ImageMagick for e-ink, and serves via the TRMNL device API.
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
# Run the server (requires Firefox and ImageMagick in PATH)
|
||||
FIREFOX=/path/to/firefox CONFIG_FILE=config.json COLORMAP=./colormap.png bun run src/web.ts
|
||||
|
||||
# Run tests
|
||||
bun test
|
||||
```
|
||||
|
||||
The server runs on port 2300 by default (`BUN_PORT` env var). No test suite exists.
|
||||
The server runs on port 2300 by default (`BUN_PORT` env var). See `config.sample.json` for the config format.
|
||||
|
||||
## Architecture
|
||||
|
||||
The request flow for `/api/display`:
|
||||
### Plugin system
|
||||
|
||||
1. **`src/web.ts`** — Bun HTTP server. Reads `CONFIG_FILE` JSON mapping device MAC addresses to ICS URLs + device model. Handles `/api/setup`, `/api/display` (returns rendered PNG), `/api/display/html` (returns raw HTML), and `/api/render/:id/:ignore` (serves cached PNGs).
|
||||
Each device is configured with a `plugin` name and `settings` object. The plugin registry (`src/plugins.ts`) maps names to factory functions that return a `Renderable`. The `Renderable` interface (`src/template.ts`) requires `hash`, `nextEvent?`, and `async render()`.
|
||||
|
||||
2. **`src/xlcalendar.tsx`** — `ICSRenderable` class. Fetches ICS feeds via `node-ical`, expands recurring events, processes them into current/next/secondary slots, and renders a React component to HTML via `renderToString`. Computes a content hash and calculates the next refresh time based on upcoming events.
|
||||
Available plugins:
|
||||
|
||||
3. **`src/template.ts`** — Wraps plugin HTML output in a full HTML page with TRMNL's CSS/JS framework. Defines the `Renderable` interface and `RenderMode` type (`full`, `half_horizontal`, `half_vertical`, `quadrant`).
|
||||
- **`calendar`** — Full-screen ICS calendar view with current/next/later event slots. UI is in Dutch ("VRIJ", "BEZET", "VOLGENDE"). Implementation: `src/xlcalendar.tsx`.
|
||||
- **`today`** — Daily dashboard with date header, focus/success lines, agenda timeline, chores checklist, and due/overdue tasks. Implementation: `src/todayview.tsx`.
|
||||
|
||||
4. **`src/render.ts`** — Uses Puppeteer (Firefox) to screenshot the rendered HTML, then pipes through ImageMagick (`magick`) to dither to a 2-bit grayscale PNG using the colormap.
|
||||
### Data sources (`src/sources/`)
|
||||
|
||||
5. **`src/devices.ts`** — Fetches device model definitions (screen dimensions, CSS classes) from `trmnl.com/api/models` at startup.
|
||||
The today plugin fetches from external services during `render()`, all in parallel:
|
||||
|
||||
- **`tana.ts`** — Fetches daily focus/success text and due/overdue tasks from a Tana server. Focus: calendar node → markdown field parsing. Tasks: single search query (`lt` tomorrow), split client-side by due date.
|
||||
- **`ics.ts`** — Fetches today's non-full-day events from ICS feeds, returns `AgendaEvent[]`. Note: `location` lives on `instance.event.location`, not on the expanded instance directly.
|
||||
- **`donetick.ts`** — Fetches chores from a Donetick instance (defaults to `app.donetick.com`). Filters by `user_id` and `isActive`. Done status: `nextDueDate > today` means completed.
|
||||
|
||||
### Config structure
|
||||
|
||||
```json
|
||||
{
|
||||
"base_url": "http://host:2300",
|
||||
"devices": {
|
||||
"DEVICE_MAC": {
|
||||
"plugin": "today",
|
||||
"settings": { ... },
|
||||
"refresh": 300,
|
||||
"model": "inkplate_10"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Render pipeline
|
||||
|
||||
1. **`src/web.ts`** — Bun HTTP server. Routes: `/api/setup`, `/api/display` (PNG), `/api/display/html` (raw HTML), `/api/render/:id/:ignore` (cached PNGs).
|
||||
2. **`src/template.ts`** — Wraps plugin HTML in a full page with TRMNL's CSS/JS framework.
|
||||
3. **`src/render.ts`** — Puppeteer (Firefox) screenshots the HTML, then ImageMagick dithers to 2-bit grayscale PNG.
|
||||
4. **`src/devices.ts`** — Fetches device model definitions (screen dimensions, CSS classes) from `trmnl.com/api/models` at startup.
|
||||
|
||||
## Deployment
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue