icali-cli
v1.1.0
Published
Node CLI for querying iCal data from files, raw strings, and URLs
Maintainers
Readme
iCaLI
iCaLI is a Node.js CLI for querying iCalendar (.ics) data from:
- local files
- raw iCal strings
- remote URLs
It is built on top of node-ical and is designed for quick filtering by date and datetime windows, field values, cross-field search, and component type.
Install
npm install -g icali-cliOr run it without installing globally:
npx icali-cli --helpUsage
The first positional argument is auto-detected as a URL, file path, or raw iCal string.
icali <url|file|ics> [options]You can also use explicit source flags:
icali --file ./calendar.ics --date 2026-04-11
icali --file ./calendar.ics --from 2026-04-14 --to 2026-04-21
icali --file ./calendar.ics --from-datetime 2026-04-11T14:00 --to-datetime 2026-04-11T17:00
icali --file ./calendar.ics --search Stacey --limit 3
icali --url "https://example.com/feed.ics" --today
icali --string "BEGIN:VCALENDAR..." --jsonOptions
--file <path> Read iCal data from a local file
--string <ics> Read iCal data from a raw iCal string
--url <url> Read iCal data from a URL
--date <YYYY-MM-DD> Match items that overlap the given date in the active timezone
--from <YYYY-MM-DD> Match items that overlap a range starting at midnight in the active timezone
--to <YYYY-MM-DD> Exclusive range end at midnight in the active timezone
--from-datetime <d> Match items that overlap a local datetime range start in the active timezone
--to-datetime <d> Exclusive local datetime range end in the active timezone
--today Shortcut for --date using today's date in the active timezone
--tz <identifier> Use a custom IANA timezone like America/New_York
--utc Shortcut for --tz UTC
--field <k=v> Filter by metadata field; value may be a regex
--field-any <k=v> OR-match a pattern across comma-separated fields like summary,description=/stacey/i
--search <pattern> Search summary, description, and location with OR semantics
--limit <n> Return at most n sorted results
--exclude-status <s> Exclude items with a matching status like CANCELLED
--type <name> Filter by component type; defaults to event
--json Emit JSON
--help Show helpExamples
Query today's events from a remote iCal feed:
icali "https://example.com/feed.ics" --todayQuery using a custom timezone:
icali ./calendar.ics --date 2026-04-11 --tz America/New_YorkForce UTC:
icali ./calendar.ics --date 2026-04-11 --utcQuery a local file for events on a specific day:
icali ./calendar.ics --date 2026-04-11Query a half-open date window that includes 2026-04-14 and excludes 2026-04-21:
icali --file "/path/to/calendar.ics" --from 2026-04-14 --to 2026-04-21 --jsonQuery upcoming matching items from a start date onward:
icali --file "/path/to/calendar.ics" --from 2026-04-11 --field "summary=/stacey/i" --jsonQuery a local datetime window:
icali --file "/path/to/calendar.ics" --from-datetime 2026-04-11T14:00 --to-datetime 2026-04-11T17:00 --jsonSearch across summary, description, and location:
icali --file "/path/to/calendar.ics" --from 2026-04-11 --search "/stacey/i" --limit 3 --jsonSearch across explicit fields with OR semantics:
icali --file "/path/to/calendar.ics" --field-any "summary,description,location=/stacey/i" --jsonExclude cancelled items:
icali --file "/path/to/calendar.ics" --exclude-status CANCELLED --jsonFilter by substring:
icali ./calendar.ics --field summary=reviewFilter by regex:
icali ./calendar.ics --field "summary=/review/i"Return JSON:
icali ./calendar.ics --date 2026-04-11 --jsonQuery a different component type:
icali ./calendar.ics --type todo
icali ./calendar.ics --type journal
icali ./calendar.ics --type freebusyComponent Type Aliases
Human-readable type aliases are supported:
event->VEVENTtodo->VTODOjournal->VJOURNALfreebusy->VFREEBUSYtimezone->VTIMEZONEcalendar->VCALENDARalarm->VALARMstandard->STANDARDdaylight->DAYLIGHT
Date Semantics
By default, iCaLI uses the system timezone for both date filtering and rendered output. You can override that with --tz, or force UTC with --utc.
--date YYYY-MM-DD is equivalent to querying the half-open window [date, nextDate).
--from and --to use the same timezone behavior as --date. The query window is half-open: items match when they overlap [from, to). --to is exclusive, and --from can be used without --to for open-ended "upcoming" queries.
--from-datetime and --to-datetime use the same timezone behavior as --date, but they operate on local datetimes. The query window is half-open: items match when they overlap [from-datetime, to-datetime). --to-datetime is exclusive, and --from-datetime can be used without --to-datetime.
When an item has an explicit end, that end is treated as exclusive. This is important for all-day events, which commonly end at midnight on the following day. For example, an all-day event from 2026-04-11 to 2026-04-12 will match --date 2026-04-11, but will not match --date 2026-04-12.
--date cannot be combined with --from, --to, --from-datetime, or --to-datetime.
--from and --to cannot be combined with --from-datetime or --to-datetime.
Filter Semantics
Repeated --field filters are ANDed together.
--field-any OR-matches across the named fields within a single filter. Repeating --field-any applies AND semantics between those grouped OR filters.
--search is shorthand for an OR search across summary, description, and location.
--limit is applied after filtering and chronological sorting.
--exclude-status may be repeated and matches statuses case-insensitively.
Output
Plaintext output includes:
- summary
- type and type label
- start
- end
- uid
- description, when present
- status, when present
- location, when present
JSON output includes the normalized event list plus metadata about the source, date window, search filters, limit, excluded statuses, and type.
Development
Install dependencies:
npm installRun tests:
npm testThe test suite enforces 100% line, branch, and function coverage for the CLI implementation.
License
MIT
