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>
71 lines
3.1 KiB
Markdown
71 lines
3.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
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
|
|
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). See `config.sample.json` for the config format.
|
|
|
|
## Architecture
|
|
|
|
### Plugin system
|
|
|
|
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()`.
|
|
|
|
Available plugins:
|
|
|
|
- **`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`.
|
|
|
|
### Data sources (`src/sources/`)
|
|
|
|
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
|
|
|
|
Deployed as a NixOS module via `flake.nix` / `default.nix`. The `default.nix` defines a systemd service with `DynamicUser=true`. The Nix derivation copies source directly (no build step — runs with `bun run` at runtime).
|
|
|
|
## Formatting
|
|
|
|
Uses Prettier: single quotes, trailing commas (es5), 2-space indent, bracket same line.
|