
## Overview

ical provides commands for managing macOS Calendar events and calendars. Every command that displays data supports `--output` (`-o`) with `table`, `json`, or `plain` formats.

| Command                          | Description                                       |
|----------------------------------|---------------------------------------------------|
| `ical calendars`                  | List all calendars                                |
| `ical calendars create [title]`   | Create a new calendar                             |
| `ical calendars update [name]`    | Update a calendar (rename, recolor)               |
| `ical calendars delete [name]`    | Delete a calendar and all its events              |
| `ical list`                       | List events in a date range                       |
| `ical today`                      | Today's events                                    |
| `ical upcoming`                   | Events in next N days                             |
| `ical show [# or id]`            | Show event details                                |
| `ical add [title]`               | Create an event                                   |
| `ical update [# or id]`          | Update an event                                   |
| `ical delete [# or id]`          | Delete an event                                   |
| `ical search [query]`            | Search events                                     |
| `ical join [# or id]`            | Open the conference link of the current/next event |
| `ical rsvp [status] [# or id]`   | Respond to an invitation (accepted/declined/tentative) |
| `ical free [email...]`           | Free/busy availability lookup (Exchange/Workspace only) |
| `ical inbox`                      | List pending event invitations                    |
| `ical export`                     | Export events (JSON/CSV/ICS)                      |
| `ical import [file]`             | Import events (JSON/CSV)                          |
| `ical skills install`             | Install AI agent skill (Claude Code / Codex / OpenClaw / others) |
| `ical skills uninstall`           | Remove AI agent skill                             |
| `ical skills status`              | Show skill installation status                    |
| `ical version`                    | Show version info                                 |
| `ical completion`                 | Generate shell completions                        |

## Global Flags

These flags are available on all commands:

| Flag         | Short | Default | Description                                     |
|--------------|-------|---------|--------------------------------------------------|
| `--output`   | `-o`  | `table` | Output format: `table`, `json`, `plain`          |
| `--no-color` |       | `false` | Disable color output (also respects `NO_COLOR`)  |

---

## ical calendars

Manage calendars. Running without a subcommand lists all calendars.

```bash
ical calendars
ical cals
ical calendars -o json
```

Displays the calendar name, source (iCloud, Google, etc.), type, color, and read-only status. Useful for finding the exact calendar name to pass to `-c` and discovering available sources for creating new calendars.

---

### ical calendars create

Create a new calendar. Requires `--source` to specify the account.

```bash
# Create with flags
ical calendars create "Projects" --source iCloud --color "#FF6961"

# Interactive mode
ical calendars create -i
```

#### Flags

| Flag              | Short | Description                                      |
|-------------------|-------|--------------------------------------------------|
| `--title`         | `-T`  | Calendar title                                   |
| `--source`        | `-s`  | Account source — required (e.g., "iCloud")       |
| `--color`         |       | Calendar color (hex, e.g., "#FF6961")            |
| `--interactive`   | `-i`  | Interactive mode with guided prompts             |

Run `ical calendars` to see available sources from existing calendars.

---

### ical calendars update

Update an existing calendar (rename or recolor).

```bash
# Update by name
ical calendars update "Projects" --title "Archived" --color "#8295AF"

# Interactive mode (guided form)
ical calendars update "Projects" -i

# Interactive picker (no argument)
ical calendars update -i
```

#### Flags

| Flag              | Short | Description                                  |
|-------------------|-------|----------------------------------------------|
| `--title`         | `-T`  | New calendar title                           |
| `--color`         |       | New calendar color (hex, e.g., "#42D692")    |
| `--interactive`   | `-i`  | Interactive mode with guided prompts         |

Subscribed and birthday calendars cannot be updated (immutable).

---

### ical calendars delete

Permanently delete a calendar and all its events.

```bash
# Delete by name (with confirmation)
ical calendars delete "Projects"

# Skip confirmation
ical calendars delete "Projects" --force

# Interactive picker (no argument)
ical calendars delete
```

#### Flags

| Flag      | Short | Description                |
|-----------|-------|----------------------------|
| `--force` | `-f`  | Skip confirmation prompt   |

Subscribed and birthday calendars cannot be deleted (immutable).

---

## ical list

List events within a date range.

```bash
ical list -f "next monday" -t "next friday"
ical list -f today -t "in 7 days" -c Work
```

### Flags

| Flag                  | Short | Description                                    |
|-----------------------|-------|------------------------------------------------|
| `--from`              | `-f`  | Start date (natural language)                  |
| `--to`                | `-t`  | End date (natural language)                    |
| `--calendar`          | `-c`  | Filter by calendar name (repeatable)           |
| `--exclude-calendar`  |       | Exclude calendar (repeatable)                  |
| `--attendee`          | `-a`  | Filter by attendee or organizer name/email     |
| `--no-recurring`      |       | Hide recurring events                          |
| `--limit`             | `-n`  | Maximum number of results                      |
| `--sort`              |       | Sort by: `title`, `time`, `calendar`           |

Events are displayed with row numbers (`#1`, `#2`, ...) that can be used with `show`, `update`, and `delete`. The row mapping is cached to `~/.ical-last-list` so subsequent commands can reference events by number. When events span multiple years, the date column includes the year for disambiguation.

```bash
# List, then act on event #2
ical list -f today -t "next friday"
ical show 2

# Filter by multiple calendars
ical list -f today -t "in 7 days" -c Work -c Personal
```

---

## ical today

Show today's events. A convenience shortcut for `ical list -f today -t today`.

```bash
ical today
ical today -c Work
ical today -o json
```

### Flags

| Flag                  | Short | Description                                |
|-----------------------|-------|--------------------------------------------|
| `--calendar`          | `-c`  | Filter by calendar name (repeatable)       |
| `--exclude-calendar`  |       | Exclude calendar (repeatable)              |
| `--attendee`          | `-a`  | Filter by attendee or organizer name/email |
| `--no-recurring`      |       | Hide recurring events                      |

---

## ical upcoming

Show events for the next N days (default: 7).

```bash
ical upcoming
ical upcoming -d 30
ical upcoming -d 14 -c Work --exclude-calendar Birthdays
```

### Flags

| Flag                  | Short | Default | Description                                    |
|-----------------------|-------|---------|------------------------------------------------|
| `--days`              | `-d`  | `7`     | Number of days to look ahead                   |
| `--calendar`          | `-c`  |         | Filter by calendar name (repeatable)           |
| `--exclude-calendar`  |       |         | Exclude calendar (repeatable)                  |
| `--attendee`          | `-a`  |         | Filter by attendee or organizer name/email     |
| `--no-recurring`      |       |         | Hide recurring events                          |
| `--limit`             | `-n`  |         | Maximum number of results                      |
| `--sort`              |       |         | Sort by: `title`, `time`, `calendar`           |

---

## ical show

Display detailed information about a single event.

```bash
# Interactive picker (no argument)
ical show

# By row number from last listing
ical show 2

# By full or partial event ID
ical show 577B8983-DF44-4665-B0F9-ABCD1234

# By exact event ID (for scripts and agents)
ical show --id "577B8983-DF44-4665-B0F9-ABCD1234:abc"
```

### Flags

| Flag     | Short | Description                                   |
|----------|-------|-----------------------------------------------|
| `--id`   |       | Full event ID — exact match, no prefix search |
| `--from` | `-f`  | Start date for event picker                   |
| `--to`   | `-t`  | End date for event picker                     |
| `--days` | `-d`  | Days to show in picker (default: 7)           |

### Event Selection

Events can be selected four ways:

1. **Interactive picker** — Run with no argument to get a searchable list
2. **Row number** — Use `#N` from the last `list`, `today`, or `upcoming` output
3. **Event ID** — Pass a full or partial `eventIdentifier` as a positional arg
4. **`--id` flag** — Full event ID, exact match only (preferred for scripts/agents)

> `--id` and a positional argument are mutually exclusive.

The show command displays title, calendar, start/end times, location, notes, alerts, recurrence rules, URL, and attendees.

---

## ical add

Create a new calendar event.

```bash
# With flags
ical add "Team Standup" -s "tomorrow 9am" -e "tomorrow 9:30am" -c Work

# Interactive guided form
ical add -i
```

### Flags

| Flag              | Short | Description                                |
|-------------------|-------|--------------------------------------------|
| `--start`         | `-s`  | Start time (natural language)              |
| `--end`           | `-e`  | End time (natural language)                |
| `--calendar`      | `-c`  | Calendar to add to                         |
| `--location`      | `-l`  | Event location                             |
| `--all-day`       |       | Create an all-day event                    |
| `--alert`         |       | Add alert before event (repeatable)        |
| `--no-alert`      |       | Create with zero alerts (overrides calendar default alerts) |
| `--timezone`      |       | Timezone (e.g., `America/New_York`)        |
| `--invite`        |       | Invite an attendee (`email` or `"Name <email>"`) — repeatable; sends an invitation |
| `--travel`        |       | Travel time before the event (e.g., `30m`, `1h`) |
| `--repeat`        |       | Recurrence: `daily`, `weekly`, `monthly`, `yearly` |
| `--repeat-days`   |       | Days for weekly recurrence (repeatable)    |
| `--repeat-until`  |       | Recurrence end date (a bare date includes the whole day) |
| `--interactive`   | `-i`  | Use guided interactive form                |

`--invite` and `--travel` are not available in interactive (`-i`) mode. Inviting an attendee makes the calendar account send a real invitation email on save, and the organizer (you) is added automatically.

### Examples

```bash
# All-day event
ical add "Company Holiday" -s 2026-03-15 --all-day -c Work

# With location and multiple alerts
# Passing any --alert gives the event exactly those alerts — the calendar's
# default alerts are not merged in. Omit --alert to inherit the default.
ical add "Dinner" -s "friday 7pm" -e "friday 9pm" \
  -l "The Restaurant, 123 Main St" --alert 1h --alert 15m

# Suppress the calendar's default alerts (e.g. for mirrored busy blocks)
ical add "Busy block" -s "tomorrow 9am" -e "tomorrow 10am" --no-alert

# Weekly recurring event
ical add "Weekly Sync" -s "next monday 10am" -e "next monday 11am" \
  --repeat weekly --repeat-days mon -c Work

# Recurring with end date
ical add "Daily Standup" -s "tomorrow 9am" -e "tomorrow 9:15am" \
  --repeat daily --repeat-until "2026-12-31" -c Work

# With timezone
ical add "NYC Meeting" -s "tomorrow 2pm" -e "tomorrow 3pm" \
  --timezone "America/New_York" -c Work
```

### Interactive Mode

The `-i` flag launches a guided form where you fill in each field step by step. The form uses the Catppuccin theme and supports calendar selection from a dropdown.

---

## ical update

Update an existing event.

```bash
# Interactive picker + guided form
ical update -i

# Update by row number
ical update 2 --title "New Title"

# Reschedule
ical update 3 -s "tomorrow 2pm" -e "tomorrow 3pm"

# Update future occurrences of recurring event
ical update 1 --span future --title "New Series Name"

# By exact event ID (for scripts and agents)
ical update --id "577B8983-DF44:abc" --title "New Title"
```

### Flags

| Flag              | Short | Description                                |
|-------------------|-------|--------------------------------------------|
| `--id`            |       | Full event ID — exact match, no prefix search |
| `--title`         |       | New title                                  |
| `--start`         | `-s`  | New start time (natural language)          |
| `--end`           | `-e`  | New end time (natural language)            |
| `--calendar`      | `-c`  | Move to different calendar                 |
| `--location`      | `-l`  | New location                               |
| `--all-day`       |       | Toggle all-day status                      |
| `--alert`         |       | Replace alerts (repeatable)                |
| `--timezone`      |       | New timezone                               |
| `--repeat`        |       | New recurrence pattern                     |
| `--repeat-days`   |       | New recurrence days                        |
| `--repeat-until`  |       | New recurrence end date                    |
| `--span`          |       | Apply to: `this` or `future` occurrences   |
| `--interactive`   | `-i`  | Use guided interactive form                |

> `update` applies changes immediately — there is no confirmation prompt and no `--force` flag.
> `--id` and a positional argument are mutually exclusive.

---

## ical delete

Delete one or more events with a confirmation prompt.

```bash
# Interactive picker with confirmation
ical delete

# Delete by row number
ical delete 3

# Skip confirmation
ical delete 3 -f

# Batch delete multiple events at once
ical delete 1 2 3 --force

# Delete future occurrences of recurring event
ical delete 2 --span future

# By exact event ID (for scripts and agents)
ical delete --id "577B8983-DF44:abc" --force
```

### Flags

| Flag       | Short | Description                                   |
|------------|-------|-----------------------------------------------|
| `--id`     |       | Full event ID — exact match, no prefix search |
| `--force`  | `-f`  | Skip confirmation prompt                      |
| `--span`   |       | For recurring: `this`, `future`, or `all` (whole series) |

### Batch Delete

Multiple row numbers or event IDs can be passed as positional arguments to delete several events in a single operation:

```bash
ical list --from today --to "next friday"   # Shows #1, #2, #3...
ical delete 1 3 5 --force                   # Delete events #1, #3, #5
```

Batch delete uses go-eventkit's `DeleteEvents` API for efficient single-call deletion. Each event is resolved individually, and per-event errors are reported without aborting the entire batch.

> Always pass `--force` when running non-interactively (scripts, agents). There is no `--confirm` flag.
> `--id` and a positional argument are mutually exclusive. `--id` only works for single event deletion.

---

## ical search

Search events by title and description.

```bash
ical search "standup"
ical search "meeting" -c Work -f "1 month ago" -t "in 1 month"
```

### Flags

| Flag             | Short | Description                                |
|------------------|-------|--------------------------------------------|
| `--from`         | `-f`  | Start date (natural language)              |
| `--to`           | `-t`  | End date (natural language)                |
| `--calendar`     | `-c`  | Filter by calendar name (repeatable)       |
| `--attendee`     | `-a`  | Filter by attendee or organizer name/email |
| `--no-recurring` |       | Hide recurring events                      |
| `--limit`        | `-n`  | Maximum number of results                  |

---

## ical join

Open the video-conference link of the current or next meeting. With no argument, ical picks the event you most likely want to join: one happening now (most recently started wins), otherwise the soonest upcoming event with a link. With an argument, it resolves a row number or event ID like `show`.

```bash
ical join              # open the current/next meeting link in the browser
ical join --print      # print just the URL (pipe-friendly)
ical join 3            # join the event at row 3 of the last listing
```

### Flags

| Flag      | Short | Description                                      |
|-----------|-------|--------------------------------------------------|
| `--print` | `-p`  | Print the conference link instead of opening it  |
| `--days`  | `-d`  | How many days ahead to look for the next meeting |

Links are detected for Zoom, Google Meet, Teams, FaceTime, Webex, Jitsi, Whereby, Chime, and GoToMeeting, whether in the event's URL field, location, or notes.

---

## ical rsvp

Respond to an event invitation. The first argument is your response; the second optionally selects the event by row number or ID. With no event argument, an interactive picker is shown. On a server-backed calendar this sends the reply to the organizer.

```bash
ical rsvp accepted 3       # accept the event at row 3
ical rsvp declined <id>    # decline by event ID
ical rsvp tentative        # pick interactively
```

Response words: `accepted`, `declined`, `tentative` (aliases `yes`/`no`/`maybe`).

---

## ical free

Look up free/busy availability for one or more people over a time range. **Requires an Exchange or Google Workspace account — iCloud does not support availability lookups.**

```bash
ical free alice@example.com
ical free alice@example.com bob@example.com --from "monday 9am" --to "monday 6pm"
```

### Flags

| Flag     | Short | Description         |
|----------|-------|---------------------|
| `--from` | `-f`  | Start of the window (default: now) |
| `--to`   | `-t`  | End of the window (default: +24h)  |

Each person's busy blocks are printed; an address with no busy periods shows "free for the whole window".

---

## ical inbox

List event invitations awaiting your response (the Calendar notification inbox).

```bash
ical inbox
ical inbox -o json
```

Invitations carry no stable ID — respond with `ical rsvp <status>` (interactive picker) or find the event with `ical list` and use its row number.

---

## ical export

Export events to a file or stdout.

```bash
# Export to JSON
ical export -f 2026-01-01 -t 2026-12-31 --format json > events.json

# Export to CSV
ical export -c Work --format csv --output-file work-events.csv

# Export to ICS (RFC 5545)
ical export --format ics --output-file calendar.ics
```

### Flags

| Flag             | Short | Default | Description                    |
|------------------|-------|---------|--------------------------------|
| `--format`       |       | `json`  | Export format: `json`, `csv`, `ics` |
| `--from`         | `-f`  |         | Start date filter              |
| `--to`           | `-t`  |         | End date filter                |
| `--calendar`     | `-c`  |         | Filter by calendar (repeatable) |
| `--output-file`  |       |         | Save to file (default: stdout) |

### Formats

- **JSON**: Full event data including IDs, timestamps, recurrence rules
- **CSV**: Tabular format suitable for spreadsheets
- **ICS**: RFC 5545 iCalendar format, compatible with any calendar app

---

## ical import

Import events from a JSON or CSV file.

```bash
ical import events.json
ical import events.csv -c Personal
ical import events.json --dry-run
```

### Flags

| Flag          | Short | Description                            |
|---------------|-------|----------------------------------------|
| `--calendar`  | `-c`  | Target calendar for imported events    |
| `--dry-run`   |       | Preview import without creating events |

The format is auto-detected from the file extension (`.json` or `.csv`).

---

## ical skills

Manage the embedded AI agent skill. ical ships with an [agent skill](https://agentskills.io) baked into the binary that teaches AI coding agents (Claude Code, Codex CLI, OpenClaw, GitHub Copilot, Cursor, Windsurf, Augment) how to use it.

### ical skills install

Install the skill to the selected agent's skill directory. Without `--agent`, shows an interactive picker. In interactive mode, a confirmation prompt shows exactly which paths will be created before writing anything. The skill files are the same documentation published at [ical.sidv.dev/docs](https://ical.sidv.dev/docs).

```bash
# Preview what would be installed (no files written)
ical skills install --dry-run

# Interactive — pick which agents, then confirm
ical skills install

# Direct
ical skills install --agent claude    # → ~/.claude/skills/ical-cli/
ical skills install --agent codex     # → ~/.codex/skills/ical-cli/
ical skills install --agent openclaw  # → ~/.openclaw/skills/ical-cli/
ical skills install --agent others    # → ~/.agents/skills/ical-cli/
ical skills install --agent all       # All agents
```

#### Flags

| Flag        | Description                                                      |
|-------------|------------------------------------------------------------------|
| `--agent`   | Target agent: `claude`, `codex`, `openclaw`, `others`, or `all`  |
| `--dry-run` | Preview what would be installed without writing                   |

Supported targets:
- **claude** → `~/.claude/skills/ical-cli/` — works with Claude Code, GitHub Copilot, Cursor, OpenCode, Augment
- **codex** → `~/.codex/skills/ical-cli/` — works with Codex CLI
- **openclaw** → `~/.openclaw/skills/ical-cli/` — works with OpenClaw
- **others** → `~/.agents/skills/ical-cli/` — works with Copilot, Windsurf, OpenCode, Augment

---

### ical skills uninstall

Remove the skill from the selected agent's skill directory.

```bash
ical skills uninstall
ical skills uninstall --agent claude
```

#### Flags

| Flag      | Description                          |
|-----------|--------------------------------------|
| `--agent` | Target agent: `claude`, `codex`, `openclaw`, `others`, or `all` |

---

### ical skills status

Show where skills are installed and whether they match the current binary version.

```bash
ical skills status
```

If installed skills are outdated (from a previous version), ical will show a warning and prompt you to run `ical skills install` to update them.

---

## ical version

Display the installed version of ical.

```bash
ical version
```

---

## ical completion

Generate shell completion scripts.

```bash
# Bash
ical completion bash > /usr/local/etc/bash_completion.d/ical

# Zsh
ical completion zsh > "${fpath[1]}/_ical"

# Fish
ical completion fish > ~/.config/fish/completions/ical.fish
```

After generating, restart your shell or source the completion file to activate.

