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

@@ -33,12 +33,16 @@ All commands go through the wrapper script:
```bash
SKILL_DIR=~/.openclaw/workspace/skills/calendar
# Send an invite
# Send an invite (supports recurring events via --rrule)
$SKILL_DIR/scripts/calendar.sh send [options]
# Reply to an invite
$SKILL_DIR/scripts/calendar.sh reply [options]
# Manage events
$SKILL_DIR/scripts/calendar.sh event list [options]
$SKILL_DIR/scripts/calendar.sh event delete [options]
# Manage todos
$SKILL_DIR/scripts/calendar.sh todo add [options]
$SKILL_DIR/scripts/calendar.sh todo list [options]
@@ -76,6 +80,7 @@ $SKILL_DIR/scripts/calendar.sh send \
| `--location` | No | Event location |
| `--description` | No | Event description / notes |
| `--organizer` | No | Organizer display name (defaults to `--from`) |
| `--rrule` | No | Recurrence rule (e.g. `FREQ=WEEKLY;COUNT=13;BYDAY=TU`) |
| `--uid` | No | Custom event UID (auto-generated if omitted) |
| `--account` | No | Himalaya account name (if not default) |
| `--dry-run` | No | Print ICS + MIME without sending |
@@ -101,7 +106,17 @@ $SKILL_DIR/scripts/calendar.sh send \
--location "Zoom - https://zoom.us/j/123456" \
--description "Weekly check-in. Agenda: updates, blockers, action items."
# Dry run
# Recurring: every Tuesday for 13 weeks (--start MUST fall on a Tuesday)
$SKILL_DIR/scripts/calendar.sh send \
--to "alice@example.com" \
--subject "Allergy Shot (Tue)" \
--summary "Allergy Shot (Tue)" \
--start "2026-03-31T14:30:00" \
--end "2026-03-31T15:00:00" \
--location "11965 Venice Blvd. #300, LA" \
--rrule "FREQ=WEEKLY;COUNT=13;BYDAY=TU"
# Dry run (always use for recurring events to verify)
$SKILL_DIR/scripts/calendar.sh send \
--to "test@example.com" \
--subject "Test" \
@@ -111,6 +126,52 @@ $SKILL_DIR/scripts/calendar.sh send \
--dry-run
```
### Recurring Events (--rrule)
The `--rrule` flag accepts an RFC 5545 RRULE string. Common patterns:
| Pattern | RRULE |
|---------|-------|
| Weekly on Tue, 13 weeks | `FREQ=WEEKLY;COUNT=13;BYDAY=TU` |
| Weekly on Mon/Wed/Fri, until date | `FREQ=WEEKLY;UNTIL=20260630T000000Z;BYDAY=MO,WE,FR` |
| Every 2 weeks on Thu | `FREQ=WEEKLY;INTERVAL=2;BYDAY=TH` |
| Monthly on the 15th, 6 times | `FREQ=MONTHLY;COUNT=6;BYMONTHDAY=15` |
| Daily for 5 days | `FREQ=DAILY;COUNT=5` |
**Critical rule**: For `FREQ=WEEKLY` with a single `BYDAY`, the `--start` date **must fall on that day of the week**. The tool validates this and will reject mismatches. RFC 5545 says mismatched DTSTART/BYDAY produces undefined behavior.
**Best practice**: Always `--dry-run` first for recurring events to verify the generated ICS.
---
## Managing Events
```bash
# List upcoming events (next 90 days)
$SKILL_DIR/scripts/calendar.sh event list
# Search events by text
$SKILL_DIR/scripts/calendar.sh event list --search "Allergy"
# List with UIDs (for deletion)
$SKILL_DIR/scripts/calendar.sh event list --format "{uid} {title}"
# Custom date range
$SKILL_DIR/scripts/calendar.sh event list --range-start "2026-04-01" --range-end "2026-04-30"
# Delete by UID
$SKILL_DIR/scripts/calendar.sh event delete --uid "abc123@openclaw"
# Delete by summary match
$SKILL_DIR/scripts/calendar.sh event delete --match "Allergy Shot (Tue)"
```
### Event Delete Safety
- Deletes only ONE event at a time. If multiple events match, it lists them and exits.
- **NEVER use `rm` on calendar .ics files directly.** Always use `event delete`.
- After deleting, verify with `event list` or `khal list`.
---
## Replying to Invites