calendar: add recurring events, event management, and safety rules

Add --rrule flag to send with DTSTART/BYDAY validation (RFC 5545).
Add event list (via khal) and event delete (safe single-event removal).
Document safety rules from 2026-03-25 incident: always dry-run recurring
events, never rm .ics files, space out SMTP sends.
This commit is contained in:
Yanxin Lu
2026-03-25 09:32:22 -07:00
parent 810a9923f9
commit 35f048dd83
6 changed files with 347 additions and 19 deletions

View File

@@ -293,9 +293,98 @@ $SKILL_DIR/scripts/calendar.sh todo check
# Should produce no output
```
## 14. Regression: Existing Invite Commands
## 14. Dry Run: Recurring Event (--rrule)
Verify the rename didn't break VEVENT flow.
Test recurring event generation. Use a date that falls on a Tuesday.
```bash
# Find next Tuesday
NEXT_TUE=$(python3 -c "from datetime import date,timedelta; d=date.today(); d+=timedelta((1-d.weekday())%7 or 7); print(d)")
$SKILL_DIR/scripts/calendar.sh send \
--to "mail@luyx.org" \
--subject "Recurring Test (Tue)" \
--summary "Recurring Test (Tue)" \
--start "${NEXT_TUE}T14:30:00" \
--end "${NEXT_TUE}T15:00:00" \
--rrule "FREQ=WEEKLY;COUNT=4;BYDAY=TU" \
--dry-run
```
**Verify:**
- [ ] ICS has `RRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=4`
- [ ] DTSTART falls on a Tuesday
- [ ] No validation errors
## 15. Validation: DTSTART/BYDAY Mismatch
Verify the tool rejects mismatched DTSTART and BYDAY.
```bash
# This should FAIL — start is on a Tuesday but BYDAY=TH
$SKILL_DIR/scripts/calendar.sh send \
--to "mail@luyx.org" \
--subject "Mismatch Test" \
--summary "Mismatch Test" \
--start "${NEXT_TUE}T09:00:00" \
--end "${NEXT_TUE}T09:30:00" \
--rrule "FREQ=WEEKLY;COUNT=4;BYDAY=TH" \
--dry-run
```
**Verify:**
- [ ] Script exits with error
- [ ] Error message says DTSTART falls on TU but RRULE says BYDAY=TH
- [ ] Suggests changing --start to a date that falls on TH
## 16. Event List
```bash
# List upcoming events
$SKILL_DIR/scripts/calendar.sh event list
# Search by text
$SKILL_DIR/scripts/calendar.sh event list --search "Calendar Skill Test"
# List with UIDs
$SKILL_DIR/scripts/calendar.sh event list --format "{uid} {title}"
```
**Verify:**
- [ ] Events from earlier tests appear
- [ ] Search narrows results correctly
- [ ] UIDs are displayed with --format
## 17. Event Delete
```bash
# Send a throwaway event first
$SKILL_DIR/scripts/calendar.sh send \
--to "mail@luyx.org" \
--subject "Delete Me Event" \
--summary "Delete Me Event" \
--start "${TEST_DATE}T20:00:00" \
--end "${TEST_DATE}T21:00:00"
# Verify it exists
$SKILL_DIR/scripts/calendar.sh event list --search "Delete Me"
# Delete it
$SKILL_DIR/scripts/calendar.sh event delete --match "Delete Me Event"
# Verify it's gone
$SKILL_DIR/scripts/calendar.sh event list --search "Delete Me"
```
**Verify:**
- [ ] Event is created and visible
- [ ] Delete removes exactly one event
- [ ] Other events are untouched
- [ ] `vdirsyncer sync` ran after delete
## 18. Regression: Existing Invite Commands
Verify new features didn't break VEVENT flow.
```bash
$SKILL_DIR/scripts/calendar.sh send \
@@ -309,7 +398,8 @@ $SKILL_DIR/scripts/calendar.sh send \
**Verify:**
- [ ] ICS has `BEGIN:VEVENT`, `METHOD:REQUEST`
- [ ] No errors from the renamed script
- [ ] No RRULE present (single event)
- [ ] No errors
---
@@ -347,3 +437,7 @@ todo list
| `todo` command not found | Install with `uv tool install todoman` |
| `todo list` errors | Check `~/.config/todoman/config.py` exists and `path` points to tasks dir |
| Todo not syncing | Check `~/.openclaw/workspace/calendars/tasks/` exists, verify vdirsyncer `cal/tasks` pair |
| DTSTART/BYDAY mismatch error | `--start` date doesn't fall on the BYDAY day. Change the start date to match |
| Recurring events on wrong day | DTSTART was not aligned with BYDAY. Delete the event and resend with correct `--start` |
| SMTP rate limit / EOF error | Too many sends too fast. Wait 10+ seconds between sends (Migadu limit) |
| Events disappeared after cleanup | **Never use `rm *.ics`** on calendar dirs. Use `event delete --match` instead |