event delete on a recurring event previously deleted the entire .ics file,
killing the whole series. Now requires --date (adds EXDATE) or --all (deletes
series) for recurring events, refusing to act without either flag.
- Replace _find_todo_id and inline UID lookups with _find_todo in
complete/delete/edit (removes ~40 lines of duplicated logic)
- Handle khal search returning exit code 1 for no results
- Sync calendar before event list for fresh data
- Use shutil.rmtree for temp dir cleanup
- Use datetime.fromisoformat instead of manual format strings
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.
- Remove duplicate email rule in TOOLS.md
- Add todo mutations to sync description in TOOLS.md
- Remove METHOD:REQUEST from todo add ICS (no longer emailed)
- Update todo check description in SKILL.md
Remove three redundant email flows since all devices sync via CalDAV:
- Auto-adding mail@luyx.org as attendee on outgoing invites
- Forwarding invites to mail@luyx.org on accept/tentative
- Emailing todos to mail@luyx.org on todo add
- Add fcntl file locking around read-modify-write cycles on both
decision_history.json and pending_emails.json to prevent data
corruption from parallel processes
- Pass --page-size 500 to himalaya envelope list to avoid silently
missing emails beyond the default first page
- Use ollama.Client(host=...) so the config.json host setting is
actually respected
- Fall back to sender-only matching in compute_confidence when LLM
returns no valid taxonomy tags, instead of always returning 50%
- Fix _format_address to return empty string instead of literal
"None" or "[]" for missing address fields
CalDAV servers (Migadu) reject ICS files with METHOD:REQUEST/REPLY
as it's an iTIP email concept, not a storage property. Strip it
when saving to local calendar, for both send and reply flows.
scan_index created confusion for the OpenClaw agent which would
sometimes reference emails by scan_index and sometimes by envelope_id.
Since himalaya's envelope ID is an IMAP UID (stable, never recycled),
it works as the sole identifier for review commands.