aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md55
-rw-r--r--docs/superpowers/specs/2026-09-24-calendar-design.md20
2 files changed, 67 insertions, 8 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
index 8334ddf..84df4e6 100644
--- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
+++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
@@ -142,10 +142,12 @@ taking that too literally.
| 71 | A toolbar action does not sync, so the edit sits until the next cron run | workflow | S | **done** 2026-08-11; 2s default, `auto_sync_delay_ms` |
| 72 | No khard/khal integration | workflow | ? | **split 2026-09-18** into 204 (recipient completion), 205 (contact editing), 206 (calendar window) and 207 (invitations), after the user named what they want. Nothing is planned under this number any more; it stays as the index entry the notes' single line maps to. The edge-tts reminder half is out of scope: its own project |
| 204 | No recipient completion, in the composer or the query bar | workflow | S | **done** 2026-09-24, shipped, built via subagent-driven-development, `3303c78..7454096`. `ContactStore` over the vdirsyncer vCard 3.0 directory feeds one shared `QCompleter` for the composer's To/Cc/Bcc and the query bar's `from:`/`to:`. Hand-tested and confirmed. One review fix (control-character/RFC 5322 sanitisation of `FN`) landed and was re-reviewed clean. Section in the closed file |
-| 205 | Contacts can be read but not edited from the app | workflow | M | open, 2026-09-18, from 72's split, **asked for by the user** while settling 204. Writing a vdir, so it shares the write-during-sync question with 206 and the fold/escape rules with 204's parser. Needs a brainstorm of its own |
-| 206 | No calendar: events cannot be viewed, added or edited | workflow | L | open, 2026-09-18, from 72's split, **asked for by the user** in place of khal. Its own TOP-LEVEL WINDOW and **libical**, both settled by the user. Spec-and-branch scale, not a Tuesday pickup. Blocks 207 |
+| 205 | Contacts can be read but not edited from the app | workflow | M | open, 2026-09-18, from 72's split, **asked for by the user** while settling 204. Writing a vdir, so it shares the write-during-sync question with 206 and the fold/escape rules with 204's parser. Its write-during-sync question is answered by 206's spec, § Writing: the same writer and stale check serve a vCard. Needs a brainstorm of its own |
+| 206 | No calendar: events cannot be viewed, added or edited | workflow | L | open, **built on branch calendar** 2026-09-24, awaiting hand test; spec specs/2026-09-24-calendar-design.md, plan plans/2026-09-24-calendar.md |
| 207 | An invitation cannot be accepted, refused or sent | workflow | M | open, 2026-09-18, from 72's split, **asked for by the user**: "as it is today I don't have a way of accepting an invitation." `text/calendar` in the pane, an iMIP reply through the existing `send_command`. **Blocked on 206**, which owns the calendar it writes to |
| 208 | No way to add a new correspondent to the contacts | workflow | ? | open, 2026-09-18, **asked for by the user** while settling 204: an "add to contacts" button on mail from someone not in the store. Writes a vcard, so it lands on 205's writer rather than 204's reader. **Needs a brainstorm when picked up** |
+| 209 | The calendar has no Week view | presentation | M | open, from 206's brainstorm. The occurrence list is the seam: a new painter over CalendarItem, no store change |
+| 210 | A repeating event cannot be edited "this and following" | workflow | S-M | open, from 206's brainstorm. Splits a series into two files, divides EXDATEs and overrides, shifts moved RECURRENCE-IDs, converts COUNT; see the spec's Out of scope |
| 73 | This backlog is past four thousand lines | maintenance | S | **done** 2026-08-13; 5056 lines to 578, closed sections moved to `2026-08-03-post-0.1.0-usability-closed.md` |
| 74 | "Searching..." keeps claiming a query is running while rows are already arriving | feedback | XS | **done** 2026-08-15, unreleased. The status-bar half only: the bar now counts threads per batch. The cold-cache delay itself was measured in 2026-08-11 and is not fixable here |
| 75 | The tagging rules window forgets its size and its column widths | persistence | S | **done** 2026-08-13, shipped in 0.17.0. The window-kind question is left open, see the closed-items file |
@@ -1729,3 +1731,52 @@ senders or a `Reply-To` that disagrees with `From`.
anything, and it is being written to a file that syncs to a DAV server and to
every other device. Escaping is the vCard writer's job (205's), but the
DECISION to write unvalidated header text into a synced store is this item's.
+
+## 209. The calendar has no Week view
+
+**Observed.** Not a user symptom: a decision taken while settling 206. The spec
+(`specs/2026-09-24-calendar-design.md`, Decisions 2 and Out of scope) ships
+**Month** (the default) and **Agenda** and defers **Week** rather than dropping
+it. The user asked for a calendar and named the views in that order.
+
+**Cause.** Not a defect. A view is real UI with no counterpart elsewhere in this
+tree, so the two that were built were the two that were specified; Week was
+deferred to keep the branch to one spec.
+
+**Approach.** The seam is already in place. `CalendarStore::occurrences()`
+returns one `QList<Occurrence>` and every view paints `CalendarItem` over it, so
+a Week view is a new painter and a seven-column geometry unit beside
+`MonthLayout`, with no change to the store, the parser or the writer. The
+existing MonthView/AgendaView toggle becomes a three-way one, and the same
+`‹ Today ›` and month/year controls drive it.
+
+**Constraints.** It must read the same occurrence list, so the DST rule holds
+for free only if it, too, expands in the event's own zone (AGENTS.md's Calendar
+section). Nothing about a Week view justifies a second expansion path or a
+store change; if it seems to need one, the approximation is wrong, not the
+seam.
+
+## 210. A repeating event cannot be edited "this and following"
+
+**Observed.** Not a user symptom: a decision taken while settling 206. The
+spec's Decisions 5 and Out of scope record that an edit offers **This
+occurrence** and **All** only, and that "this and following" is deferred. It is
+the scope every other calendar client offers, so a user will reach for it.
+
+**Cause.** Not a defect. The control and `CalendarStore::applyEdit` implement
+two scopes; the third is a different and larger edit than either.
+
+**Approach.** Splitting a series into two files, as the spec's Out of scope
+describes: divide the `EXDATE`s and the `RECURRENCE-ID` overrides between the
+earlier and later halves, shift any moved `RECURRENCE-ID` when the time changes,
+and convert a `COUNT` into an `UNTIL` on the first half and a fresh `DTSTART` on
+the second. `applyEdit`'s discipline still applies: the properties the form
+does not own survive on both halves.
+
+**Constraints.** The undo stack holds one command per file, so an edit that
+produces two files is two commands or one command holding two paths; either way
+both halves must move together on undo or a half-split series is left behind.
+The split runs through `CalendarWriter`, so it inherits the stale check: a
+server-normalised source must refuse rather than divide a file it does not
+recognise. See the spec's Out of scope for the full list of what the split has
+to divide.
diff --git a/docs/superpowers/specs/2026-09-24-calendar-design.md b/docs/superpowers/specs/2026-09-24-calendar-design.md
index e33767e..72358b2 100644
--- a/docs/superpowers/specs/2026-09-24-calendar-design.md
+++ b/docs/superpowers/specs/2026-09-24-calendar-design.md
@@ -1,7 +1,7 @@
# A calendar window: view, add, edit and delete events
Date: 2026-09-24
-Status: approved, not yet implemented
+Status: approved, implemented on branch calendar
Backlog: item 206 (blocks 207; answers 205's write-during-sync question)
## Problem
@@ -201,9 +201,9 @@ fourth Thursday"), as Thunderbird does.
event is reloaded, the form stays open holding the user's values, and the
status bar says the event changed on disk and needs checking before saving
again. Nothing is overwritten blind.
-2. **Atomic write.** Write `.<name>.tmp` in the same directory and `rename()`
- it into place. vdirsyncer lists only `*.ics`, so it never sees the
- temporary.
+2. **Atomic write.** `QSaveFile` writes a temporary in the same directory and
+ `rename()`s it into place on `commit()`, so vdirsyncer, which lists only
+ `*.ics`, never sees a partial file.
3. Every edit sets `DTSTAMP` and `LAST-MODIFIED` and increments `SEQUENCE`.
A **new** event is `<uuid>.ics` in `default_calendar` or the collection chosen
@@ -307,6 +307,14 @@ Edit and View holding every action; `Ctrl+N` New, `Ctrl+E` Edit, `Delete`,
`Ctrl+Z` / `Ctrl+Shift+Z`, `PgUp` / `PgDn` for the month, `Home` for today,
`Esc` to cancel an edit. Window shortcuts, not `KeyMap` entries.
+**Those that are not safe as window shortcuts are scoped to the views with
+`Qt::WidgetWithChildrenShortcut`.** A bare `Delete`, `Ctrl+Z`, `PgUp`/`PgDn` or
+`Home` would otherwise fire while the cursor is in the edit form's Title field,
+deleting the event or moving the month instead of editing text. `Delete`,
+`PgUp`/`PgDn` and `Home` sit on the stacked views; Undo and Redo sit there too;
+Escape is scoped to `EventPane`. `Ctrl+N`, `Ctrl+E` and `Ctrl+W` stay window
+shortcuts, since no text field wants them.
+
**i18n.** Every string in `tr()`; the Italian `.ts` refreshed, `lrelease`
reporting 0 unfinished.
@@ -316,7 +324,7 @@ All in `[general]`, read without the `general/` prefix per AGENTS.md:
| Key | Default | Meaning |
|---|---|---|
-| `calendars_dir` | `~/.local/share/calendars/` | The vdir root, tilde-expanded like `contacts_dir`. Empty turns the feature off: no action, no error. |
+| `calendars_dir` | unset (off) | The vdir root, tilde-expanded like `contacts_dir`. Empty turns the feature off: no action, no error. |
| `default_calendar` | first collection by name | Directory name of the collection new events go to. |
| `calendar_sync_command` | `flock -w 60 /tmp/vdirsyncer.lock vdirsyncer sync calendars` | Run after writes. Empty disables. |
| `calendar_sync_delay_ms` | `2000` | Debounce before the sync runs. |
@@ -336,7 +344,7 @@ addresses, never copied from the live vdir.
yields only the window; `COUNT` and `UNTIL`; monthly `BYDAY=-1FR`; yearly
`BYMONTH`+`BYDAY`. `RepeatRule` round-trips every row of the table, detects
a custom rule, keeps `WKST`. `applyEdit` keeps `VALARM`, `ATTENDEE` and
- `X-*` byte for byte, increments `SEQUENCE`, creates an override, adds an
+ `X-*` value for value, increments `SEQUENCE`, creates an override, adds an
`EXDATE`. `newEvent` embeds its `VTIMEZONE`. `isEditable` for an organiser
who is the user, someone else, nobody, and for a read-only collection.
- **`test_calendarwriter`**, in a temporary directory: the atomic write; the