Refactors the contacts system from being embedded in cal_tool.py into a
standalone contacts skill that serves as the single source of truth for
recipient validation across all outbound email paths.
- New skills/contacts/ skill: list, add, delete, resolve commands
- New skills/himalaya/scripts/himalaya.sh wrapper: validates To/Cc/Bcc
recipients against contacts for message send, template send, and
message write commands; passes everything else through unchanged
- cal_tool.py now delegates to contacts.py resolve instead of inline logic
- TOOLS.md updated: agent should use himalaya wrapper, not raw himalaya
Agent hallucinated "xiaojuzi@meta.com" instead of looking up the correct
address from USER.md. Prompting rules can't reliably prevent this, so
recipient validation is now enforced at the tool level.
- Add contact list/add/delete subcommands (vCard .vcf files synced via CardDAV)
- send --to now resolves through contacts: accepts names, name:type, or
known emails; rejects unknown addresses with available contacts shown
- Multi-email contacts supported with type qualifier (e.g. "小橘子:work")
- Adding contacts and sending are separate operations (no chaining)
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.