From 35bce0a57b6839471e6d8a31f1af4870af0ab94d Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 13 Oct 2026 10:24:15 +0200 Subject: docs(spec): calendar protocol settled while planning One JSON envelope on stdout for every calctl command, the event as an argument rather than stdin, a get command because the editor edits the series rather than the occurrence clicked, and a pure Cal.js for the date logic so it is tested under node like the island's other helpers. Co-Authored-By: Claude Opus 5.5 --- .../specs/2026-10-13-calendar-design.md | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'docs/superpowers/specs') diff --git a/docs/superpowers/specs/2026-10-13-calendar-design.md b/docs/superpowers/specs/2026-10-13-calendar-design.md index 792e951..4afd354 100644 --- a/docs/superpowers/specs/2026-10-13-calendar-design.md +++ b/docs/superpowers/specs/2026-10-13-calendar-design.md @@ -32,6 +32,8 @@ clock pill. Measured on the live calendars: no event uses `RECURRENCE-ID` or desktop/island/calendar/ calctl Python: list, new, edit, delete; JSON in and out test_calctl.py plain asserts against temporary vdirs + Cal.js pure date logic for the QML, node-tested + test_cal.js node test for Cal.js Calendar.qml singleton: calctl list, the file watch, writes CalendarPanel.qml month grid left, agenda or editor right EventEditor.qml the form @@ -51,11 +53,12 @@ output, and its sqlite cache is a second view of the same files. Commands: - calctl calendars [{name, color}] + calctl calendars {default, calendars: [{name, color, path}]} calctl list occurrences in [from, to), local time - calctl new < event.json prints the new event's uid - calctl edit < event.json - calctl delete + calctl get the series itself, for the editor + calctl new {uid} + calctl edit {uid} + calctl delete {} `list` expands recurrence with `dateutil.rrule` and returns one object per occurrence: uid, calendar, title, start, end, allDay, location, notes, repeat, @@ -80,7 +83,22 @@ Writes: the existing sync log. A failed sync is not an error for calctl: the cron run every 30 minutes retries. -Errors go to stderr with exit 1; stdout is JSON only on success. +Every command prints one JSON object on stdout: `{"ok": true, "data": ...}` +or `{"ok": false, "error": "..."}` with exit 1, the error also on stderr. +The shell reads stdout only, so it never has to order an exit code against +a stream. The event JSON is an argument rather than stdin, which keeps the +QML side to a plain `Process` command. `get` exists because the editor edits +the series: an occurrence's start is not the series' DTSTART. + +Event JSON, in and out: `calendar`, `title`, `allDay`, `start`, `end` +(`YYYY-MM-DDTHH:MM` local, or `YYYY-MM-DD` all day with an inclusive last +day), `repeat`, `until` (`YYYY-MM-DD` or ""), `alarm`, `location`, `notes`; +out also `uid`, `color` and `override`. + +Recurrence is expanded in naive local time, which keeps the wall-clock time +of a TZID event across DST, as RFC 5545 asks. ponytail: a `Z` UNTIL is read +as local time, so an until-date can be off by the UTC offset at its very +end. ## Shell side -- cgit v1.2.3