Conversation
`cal ls` for today, the week or a range, `cal show <uid>`, `cal add`, `cal rm`, and `cal calendars`, against any CalDAV host that still takes a password. No library: PROPFIND finds the principal and the calendars, REPORT reads a window with the server expanding recurrences, PUT and DELETE write. Nine providers are built in (Forward Email, iCloud, Fastmail, Zoho, Yahoo, AOL, GMX, mailbox.org, Posteo) plus `custom` by URL for Nextcloud, Radicale, Baïkal and the like; Google, Outlook and Proton are listed as unreachable with the reason, since Google's CalDAV takes only OAuth2 and the other two have none. `cal login` mirrors `mail login`: it says which kind of password the host wants before asking, discovers the calendars, and stores nothing on a refusal. `--like <mail-account>` borrows the address and password of a mail account, because iCloud, Fastmail and Forward Email use one password for both. Accounts live in ~/.config/cli-tools/cal.json (0600) or the cli-tools-cal vault as CAL_<NAME>_EMAIL / _PROVIDER / _PASSWORD. Times as people type them: 2026-09-06 14:00, tomorrow 9:30, friday 2pm, or a bare day for all-day. Zoned iCalendar times are converted with Intl, so a TZID needs no tz database. Plugin `cal` (/cal:login, /cal:agenda, /cal:add). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013h8jopY81BGQ4Pn22NfZTu
ThreatCrush Security Scan10 finding(s) HIGH/CRITICAL: 2 | MEDIUM: 4 | LOW: 4
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A
calcommand: the calendar from the terminal, over CalDAV. Followsmail(#48, #49) and shares its shape.cal ls [--today|--tomorrow|--week|--days N|--from W --to W] [-c CALENDAR]— the agenda, grouped by local day, all-day events first;cal show <uid>;cal calendars.cal add <title> --at W [--end W | --for D] [--all-day] [-c C] [--where P] [--notes T] [--link U]—--attakes2026-09-06 14:00,tomorrow 9:30,friday 2pm,14:00, or a bare day (all-day).cal rm <uid>shows the event and asks first;--yesskips it.cal login <provider|address> [address] [--as NAME] [--like MAIL-ACCOUNT]— says which kind of password the host wants before asking, discovers the calendars, stores nothing on a refusal.--likeborrows amailaccount's address and password, since iCloud, Fastmail and Forward Email use one for both.cal providers— nine built in (Forward Email, iCloud, Fastmail, Zoho, Yahoo, AOL, GMX, mailbox.org, Posteo) pluscustom --urlfor Nextcloud, Radicale, Baïkal, Stalwart; and the unreachable ones with the reason: Google Calendar (CalDAV takes only OAuth2; a Gmail app password opens the mailbox, not the calendar), Outlook.com / Microsoft 365 (no CalDAV), Proton (no CalDAV on any plan).~/.config/cli-tools/cal.json(0600) or the newcli-tools-cal--prodvault asCAL_<NAME>_EMAIL/_PROVIDER/_PASSWORD(optional_USER,_URL),CAL_DEFAULT;cal accounts pullimports them.cal(/cal:login,/cal:agenda,/cal:add) in the marketplace; README section; registry summary.Decisions worth a look
<C:expand start end/>, so a weekly standup lists on every day it happens and this code implements no RRULE.cal rmon a recurring event removes the series and says so before asking.DTSTART;TZID=America/New_York:…is converted withIntl.DateTimeFormat, DST resolved by two-step offset lookup. Output is in the machine's zone; what goes out is UTC.http://URL (other than localhost) is refused before any request; a 401 becomes the provider's fix (app password, per-alias password) rather than "Unauthorized".redirect: 'manual'), so a discovery root that 301s to the real DAV path works and the Authorization header is re-sent only to where we chose to go.maillists Outlook: the endpoint takes only OAuth2, and a login attempt would fail in a way that reads like a typo.Verified
test/cal.test.ts: providers, config and vault round-trips, XML extraction, iCalendar parse/build/fold, zoned-time conversion, typed times and windows, the CalDAV client against an in-memory server, output); typecheck clean apart from the two pre-existingfree-nameserrors. (test/torrent.test.tstalks to a live tracker and timed out once, unrelated.)cal login forwardemail --like workdiscovered the account's calendar;cal addcreated an event (PUT 201),cal ls --days 3listed it grouped by day,cal show <uid>printed it with location and notes,cal rm <uid> --yesdeleted it,cal lsthen showed nothing.CAL_WORK_*pushed to the newcli-tools-cal--prodvault andcal accounts pullreports it matching.cal login google, a Gmail address, a Proton address, an unknown domain, a bad--at, and a missing title each produce the intended message.🤖 Generated with Claude Code
https://claude.ai/code/session_013h8jopY81BGQ4Pn22NfZTu