feat: add bounded agenda view

Add a read-only 42-day occurrence agenda with keyboard navigation, six-week paging, exact return-to-grid focus, search and calendar overlays, and bounded recurrence expansion.

Keep agenda state outside persistence, document month-only mutations, and cover empty windows, filtering, overlays, navigation, rendering, and terminal restoration.
This commit is contained in:
2026-07-18 09:19:01 +01:00
parent 590db2f488
commit 8b6cf2e877
11 changed files with 609 additions and 16 deletions

View File

@@ -42,10 +42,18 @@ rule cannot turn an interactive query into unbounded work.
Calendar visibility is session presentation state. The controller derives its
calendar list from event calendar identifiers and applies the same domain
predicate to month rendering, focus traversal, and search. Hidden events remain
in the canonical collection passed to persistence, and focus identities are
always derived from that complete collection so filtering cannot renumber
events with duplicate or missing UIDs.
predicate to month rendering, agenda queries, focus traversal, and search.
Hidden events remain in the canonical collection passed to persistence, and
focus identities are always derived from that complete collection so filtering
cannot renumber events with duplicate or missing UIDs.
The agenda is a TUI projection over domain occurrence queries, not a second
calendar model. It requests exactly one 42-day window at a time so recurrence
expansion remains finite, preserves occurrence identity when returning to the
month grid, and keeps its window and selection as non-persistent controller
state. Calendar and search overlays may be opened above it, but mutations stay
in the month workflow and continue to operate on the canonical event
collection.
Timed events retain their source basis: UTC, floating process-local time, or an
IANA `TZID`. C++20 time-zone conversion keeps zoned recurrences at their civil

View File

@@ -63,6 +63,9 @@ The full terminal is treated as a responsive canvas:
| Next/previous appointment | `Tab` / `Shift-Tab` |
| Read focused appointment | `Enter` |
| Browse inside reader | arrows, `h j k l`, `Tab` / `Shift-Tab` |
| Open/close 42-day agenda | `g`; `Esc` also closes |
| Choose agenda occurrence | arrows, `j` / `k`, `Tab` / `Shift-Tab`, then `Enter` |
| Shift agenda by 42 days | `PageUp` / `PageDown`, `p` / `n` |
| Add appointment | `a` |
| Edit focused appointment | `e` |
| Delete focused appointment | `d`, then `y` to confirm |
@@ -77,7 +80,8 @@ The full terminal is treated as a responsive canvas:
| Quit | `q` |
The first usable foundation supports day and appointment navigation, a
full-frame reader, validated add/edit/delete forms, and atomic `.ics` writes.
full-frame reader, a read-only 42-day agenda, validated add/edit/delete forms,
and atomic `.ics` writes.
Dense days keep every appointment keyboard-reachable even when all lines do
not fit in the cell. Unknown or unsupported iCalendar content makes a source
read-only instead of being discarded. Saves reject external changes, retain a
@@ -88,8 +92,14 @@ semantics in the reader. `/` searches occurrence-aware title, description,
location, and calendar-ID matches in a finite ten-year window centered on the
selected date. `c` toggles session-only calendar visibility consistently across
the grid, appointment focus, and search without filtering the model supplied to
persistence. The next local-data work adds an agenda view, then advanced
recurrence overrides and rule editing.
persistence. `g` opens an occurrence-aware agenda at the selected month date;
navigation is bounded to consecutive 42-day windows and `Enter` returns to the
exact occurrence in the month grid. `Esc` or `g` closes the agenda without
changing the month selection unless an occurrence was chosen. Hidden calendars
remain filtered there, while calendar selection and search can overlay the
agenda. Agenda navigation never persists state, and add/edit/delete remain in
the month workflow. The next local-data work adds advanced recurrence overrides
and rule editing.
## Accessibility

View File

@@ -11,13 +11,14 @@
- Windowed recurrence expansion, EXDATE, IANA TZID, and multi-day segment cues
- Occurrence-aware appointment search with exact result-to-grid navigation
- Session calendar toggles shared by month rendering, focus, and search
- Read-only 42-day agenda with bounded recurrence and exact return navigation
- Meson build, Nix development shell, desktop entry, and Hyprland launcher
- Seeded sample data when explicitly requested, never silent data mutation
## 0.1 — complete local calendar
- Advanced recurrence editing, RDATE/overrides, and embedded VTIMEZONE support
- Agenda view, import/export, configurable week start
- Import/export and configurable week start
- Screen-reader-friendly linear view and full Unicode display-width handling
## 0.2 — durable cache and provider boundary