calctl 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
calctl-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,370 @@
1
+ Metadata-Version: 2.4
2
+ Name: calctl
3
+ Version: 0.1.0
4
+ Summary: macOS Calendar CLI using EventKit
5
+ Author: Durmus Karatay
6
+ Author-email: Durmus Karatay <durmus@karatay.me>
7
+ License-Expression: MIT
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: MacOS
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Office/Business :: Scheduling
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: pyobjc-framework-eventkit>=12.1
20
+ Requires-Dist: pyobjc-framework-corelocation>=12.1
21
+ Requires-Dist: python-dateutil>=2.9.0.post0
22
+ Requires-Dist: typer>=0.24.1
23
+ Requires-Python: >=3.10
24
+ Project-URL: Homepage, https://github.com/ukaratay/calctl
25
+ Project-URL: Repository, https://github.com/ukaratay/calctl
26
+ Project-URL: Issues, https://github.com/ukaratay/calctl/issues
27
+ Description-Content-Type: text/markdown
28
+
29
+ # calctl
30
+
31
+ **macOS Calendar CLI using EventKit**
32
+
33
+ [![PyPI version](https://img.shields.io/pypi/v/calctl.svg)](https://pypi.org/project/calctl/)
34
+ [![Python version](https://img.shields.io/pypi/pyversions/calctl.svg)](https://pypi.org/project/calctl/)
35
+ [![License](https://img.shields.io/pypi/l/calctl.svg)](https://github.com/ukaratay/calctl/blob/main/LICENSE)
36
+
37
+ `calctl` is a command-line interface for Apple Calendar on macOS. It uses the native EventKit framework via PyObjC — the same API the Calendar app uses — so it reads and writes all your calendars directly, with no sync or bridge required.
38
+
39
+ ## Features
40
+
41
+ - **List calendars** — see all calendars with their source and type
42
+ - **List events** — browse events in any date range, optionally filtered by calendar
43
+ - **Search events** — full-text search across titles, notes, and locations
44
+ - **Create events** — all-day or timed events with full metadata
45
+ - **Edit events** — update any field; control whether edits apply to this occurrence or all future occurrences
46
+ - **Delete events** — single occurrence or this-and-future for recurring events
47
+ - **Full EventKit support** — recurrence rules (RRULE), alarms, attendees, availability, geo coordinates, timezones
48
+ - **JSON and human-readable text output** — choose your format explicitly or let calctl detect it
49
+ - **Auto-detects output format** — JSON when piped, text when run in a terminal
50
+
51
+ ## Requirements
52
+
53
+ - macOS (EventKit is macOS-only)
54
+ - Python ≥ 3.10
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ # Using pipx (recommended for CLI tools)
60
+ pipx install calctl
61
+
62
+ # Using uv
63
+ uv tool install calctl
64
+ ```
65
+
66
+ ## Permissions
67
+
68
+ calctl needs access to your calendars. On first run, macOS will show a permission dialog. If you previously denied access, go to:
69
+
70
+ **System Settings → Privacy & Security → Calendars → calctl** → enable access
71
+
72
+ ## Quick Start
73
+
74
+ ```bash
75
+ # List all calendars
76
+ calctl calendars
77
+
78
+ # List events for the next 7 days
79
+ calctl list
80
+
81
+ # List events in a specific date range
82
+ calctl list --from 2026-03-19 --to 2026-03-26
83
+
84
+ # List events from a specific calendar
85
+ calctl list --calendar Work
86
+
87
+ # Search events by keyword
88
+ calctl search "meeting"
89
+
90
+ # Search within a date range and calendar
91
+ calctl search "standup" --from 2026-03-01 --to 2026-03-31 --calendar Work
92
+
93
+ # Show full details for an event
94
+ calctl show EVENT_ID
95
+
96
+ # Create a timed event
97
+ calctl create --title "Team Standup" --start 2026-03-20T09:00:00 --end 2026-03-20T09:30:00 --calendar Work
98
+
99
+ # Create an all-day event
100
+ calctl create --title "Company Holiday" --start 2026-03-20 --all-day
101
+
102
+ # Create a recurring event with an alarm
103
+ calctl create \
104
+ --title "Weekly Review" \
105
+ --start 2026-03-20T14:00:00 \
106
+ --rrule "FREQ=WEEKLY;BYDAY=FR" \
107
+ --alarm -15m
108
+
109
+ # Create an event with location and geo coordinates
110
+ calctl create \
111
+ --title "Lunch" \
112
+ --start 2026-03-20T12:00:00 \
113
+ --end 2026-03-20T13:00:00 \
114
+ --location "Blue Bottle Coffee" \
115
+ --geo "37.7749,-122.4194"
116
+
117
+ # Edit an event's title and location
118
+ calctl edit EVENT_ID --title "Updated Title" --location "Room 42"
119
+
120
+ # Edit a recurring event — this and all future occurrences
121
+ calctl edit EVENT_ID --title "Renamed Series" --span future
122
+
123
+ # Delete an event
124
+ calctl delete EVENT_ID
125
+
126
+ # Delete a recurring event — this occurrence only
127
+ calctl delete EVENT_ID --span this
128
+ ```
129
+
130
+ ## CLI Reference
131
+
132
+ ### Global Options
133
+
134
+ These options apply to all commands and must come before the command name:
135
+
136
+ ```
137
+ calctl [OPTIONS] COMMAND [ARGS]...
138
+ ```
139
+
140
+ | Option | Short | Type | Default | Description |
141
+ |--------|-------|------|---------|-------------|
142
+ | `--format` | `-f` | `json\|text` | auto | Output format. Defaults to `text` on TTY, `json` when piped. |
143
+ | `--verbose` | `-v` | flag | false | Enable debug logging to stderr. |
144
+ | `--help` | | flag | | Show help and exit. |
145
+
146
+ ---
147
+
148
+ ### `calctl calendars`
149
+
150
+ List all calendars.
151
+
152
+ ```bash
153
+ calctl calendars
154
+ calctl calendars --format json
155
+ ```
156
+
157
+ ---
158
+
159
+ ### `calctl list`
160
+
161
+ List events in a date range.
162
+
163
+ ```bash
164
+ calctl list [OPTIONS]
165
+ ```
166
+
167
+ | Option | Type | Default | Description |
168
+ |--------|------|---------|-------------|
169
+ | `--from` | `YYYY-MM-DD` | today | Start date (inclusive). |
170
+ | `--to` | `YYYY-MM-DD` | today + 7 days | End date (inclusive). |
171
+ | `--calendar` | string | (all calendars) | Filter by calendar name. |
172
+
173
+ **Examples:**
174
+
175
+ ```bash
176
+ calctl list
177
+ calctl list --from 2026-03-01 --to 2026-03-31
178
+ calctl list --calendar Personal
179
+ ```
180
+
181
+ ---
182
+
183
+ ### `calctl search`
184
+
185
+ Search events by keyword. Matches against title, notes, and location.
186
+
187
+ ```bash
188
+ calctl search QUERY [OPTIONS]
189
+ ```
190
+
191
+ | Argument/Option | Type | Default | Description |
192
+ |-----------------|------|---------|-------------|
193
+ | `QUERY` | string | required | Search keyword(s). |
194
+ | `--from` | `YYYY-MM-DD` | (no limit) | Restrict search start date. |
195
+ | `--to` | `YYYY-MM-DD` | (no limit) | Restrict search end date. |
196
+ | `--calendar` | string | (all calendars) | Filter by calendar name. |
197
+
198
+ **Examples:**
199
+
200
+ ```bash
201
+ calctl search "team meeting"
202
+ calctl search "invoice" --from 2026-01-01 --to 2026-03-31
203
+ calctl search "standup" --calendar Work
204
+ ```
205
+
206
+ ---
207
+
208
+ ### `calctl show`
209
+
210
+ Show full details for a single event, including recurrence, alarms, and attendees.
211
+
212
+ ```bash
213
+ calctl show EVENT_ID
214
+ ```
215
+
216
+ | Argument | Type | Description |
217
+ |----------|------|-------------|
218
+ | `EVENT_ID` | string | Event identifier (from `list` or `search` output). |
219
+
220
+ ---
221
+
222
+ ### `calctl create`
223
+
224
+ Create a new event.
225
+
226
+ ```bash
227
+ calctl create --title TITLE --start DATETIME [OPTIONS]
228
+ ```
229
+
230
+ | Option | Type | Default | Description |
231
+ |--------|------|---------|-------------|
232
+ | `--title` | string | **required** | Event title. |
233
+ | `--start` | `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS` | **required** | Start date or datetime. |
234
+ | `--end` | `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS` | start + 1h (or same day if `--all-day`) | End date or datetime. |
235
+ | `--calendar` | string | default calendar | Calendar to add the event to. |
236
+ | `--location` | string | | Location string. |
237
+ | `--geo` | `lat,lng` | | Geographic coordinates (e.g. `37.7749,-122.4194`). |
238
+ | `--notes` | string | | Event notes / description. |
239
+ | `--url` | string | | URL associated with the event. |
240
+ | `--all-day` / `--no-all-day` | flag | false | Create as an all-day event. |
241
+ | `--availability` | `busy\|free\|tentative\|unavailable` | | Availability status. |
242
+ | `--timezone` | string | | Timezone identifier (e.g. `America/New_York`). |
243
+ | `--rrule` | RRULE string | | Recurrence rule (e.g. `FREQ=WEEKLY;BYDAY=MO,WE,FR`). |
244
+ | `--alarm` | duration | | Alarm offset before event (e.g. `-15m`, `-1h`). Repeatable for multiple alarms. Use `--alarm ""` to explicitly clear alarms. |
245
+
246
+ **Examples:**
247
+
248
+ ```bash
249
+ # Simple 30-minute event
250
+ calctl create --title "Coffee" --start 2026-03-20T10:00:00 --end 2026-03-20T10:30:00
251
+
252
+ # All-day event
253
+ calctl create --title "PTO" --start 2026-03-20 --all-day --calendar Personal
254
+
255
+ # Recurring weekly event with two alarms
256
+ calctl create \
257
+ --title "Weekly Sync" \
258
+ --start 2026-03-20T10:00:00 \
259
+ --rrule "FREQ=WEEKLY;BYDAY=FR" \
260
+ --alarm -10m \
261
+ --alarm -1h
262
+
263
+ # Event with location details
264
+ calctl create \
265
+ --title "Conference" \
266
+ --start 2026-03-20T09:00:00 \
267
+ --end 2026-03-20T17:00:00 \
268
+ --location "Moscone Center, San Francisco" \
269
+ --geo "37.7842,-122.4016" \
270
+ --timezone "America/Los_Angeles"
271
+ ```
272
+
273
+ ---
274
+
275
+ ### `calctl edit`
276
+
277
+ Edit an existing event. Only the fields you specify are changed.
278
+
279
+ ```bash
280
+ calctl edit EVENT_ID [OPTIONS]
281
+ ```
282
+
283
+ | Argument/Option | Type | Default | Description |
284
+ |-----------------|------|---------|-------------|
285
+ | `EVENT_ID` | string | **required** | Event to edit. |
286
+ | `--title` | string | | New title. |
287
+ | `--start` | datetime | | New start datetime. |
288
+ | `--end` | datetime | | New end datetime. |
289
+ | `--calendar` | string | | Move to this calendar. |
290
+ | `--location` | string | | New location string. |
291
+ | `--geo` | `lat,lng` | | New geo coordinates. |
292
+ | `--notes` | string | | New notes. |
293
+ | `--url` | string | | New URL. |
294
+ | `--all-day` / `--no-all-day` | flag | | Set or clear all-day flag. |
295
+ | `--availability` | `busy\|free\|tentative\|unavailable` | | New availability. |
296
+ | `--timezone` | string | | New timezone. |
297
+ | `--rrule` | RRULE string | | New recurrence rule. |
298
+ | `--alarm` | duration | | New alarm(s). Repeatable. Use `--alarm ""` to clear all alarms. |
299
+ | `--span` | `this\|future` | `this` | For recurring events: edit only this occurrence (`this`) or this and all future occurrences (`future`). |
300
+
301
+ **Examples:**
302
+
303
+ ```bash
304
+ # Rename an event
305
+ calctl edit EVENT_ID --title "New Name"
306
+
307
+ # Reschedule
308
+ calctl edit EVENT_ID --start 2026-03-21T10:00:00 --end 2026-03-21T11:00:00
309
+
310
+ # Edit all future occurrences of a recurring event
311
+ calctl edit EVENT_ID --title "Renamed Series" --span future
312
+
313
+ # Move event to a different calendar
314
+ calctl edit EVENT_ID --calendar Personal
315
+ ```
316
+
317
+ ---
318
+
319
+ ### `calctl delete`
320
+
321
+ Delete an event.
322
+
323
+ ```bash
324
+ calctl delete EVENT_ID [OPTIONS]
325
+ ```
326
+
327
+ | Argument/Option | Type | Default | Description |
328
+ |-----------------|------|---------|-------------|
329
+ | `EVENT_ID` | string | **required** | Event to delete. |
330
+ | `--span` | `this\|future` | `this` | For recurring events: delete only this occurrence (`this`) or this and all future occurrences (`future`). |
331
+
332
+ **Examples:**
333
+
334
+ ```bash
335
+ # Delete a single event
336
+ calctl delete EVENT_ID
337
+
338
+ # Delete this and all future occurrences
339
+ calctl delete EVENT_ID --span future
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Output Formats
345
+
346
+ calctl supports two output formats, controlled by `--format` / `-f`:
347
+
348
+ | Format | Flag | Description |
349
+ |--------|------|-------------|
350
+ | `text` | `--format text` | Human-readable, table-style output for the terminal. |
351
+ | `json` | `--format json` | Machine-readable JSON. Arrays for list commands, objects for single-item commands. |
352
+
353
+ **Auto-detection:** When `--format` is not specified, calctl detects whether stdout is a terminal (TTY):
354
+ - **Terminal** → `text` format
355
+ - **Pipe or redirect** → `json` format
356
+
357
+ This means you can pipe calctl output to `jq` without specifying `--format json`:
358
+
359
+ ```bash
360
+ # Pipe output — JSON is selected automatically
361
+ calctl list | jq '.[] | .title'
362
+ calctl search "meeting" | jq '.[0].id'
363
+
364
+ # Force text format in a script
365
+ calctl list --format text > events.txt
366
+ ```
367
+
368
+ ## License
369
+
370
+ MIT — see [LICENSE](LICENSE) for details.
calctl-0.1.0/README.md ADDED
@@ -0,0 +1,342 @@
1
+ # calctl
2
+
3
+ **macOS Calendar CLI using EventKit**
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/calctl.svg)](https://pypi.org/project/calctl/)
6
+ [![Python version](https://img.shields.io/pypi/pyversions/calctl.svg)](https://pypi.org/project/calctl/)
7
+ [![License](https://img.shields.io/pypi/l/calctl.svg)](https://github.com/ukaratay/calctl/blob/main/LICENSE)
8
+
9
+ `calctl` is a command-line interface for Apple Calendar on macOS. It uses the native EventKit framework via PyObjC — the same API the Calendar app uses — so it reads and writes all your calendars directly, with no sync or bridge required.
10
+
11
+ ## Features
12
+
13
+ - **List calendars** — see all calendars with their source and type
14
+ - **List events** — browse events in any date range, optionally filtered by calendar
15
+ - **Search events** — full-text search across titles, notes, and locations
16
+ - **Create events** — all-day or timed events with full metadata
17
+ - **Edit events** — update any field; control whether edits apply to this occurrence or all future occurrences
18
+ - **Delete events** — single occurrence or this-and-future for recurring events
19
+ - **Full EventKit support** — recurrence rules (RRULE), alarms, attendees, availability, geo coordinates, timezones
20
+ - **JSON and human-readable text output** — choose your format explicitly or let calctl detect it
21
+ - **Auto-detects output format** — JSON when piped, text when run in a terminal
22
+
23
+ ## Requirements
24
+
25
+ - macOS (EventKit is macOS-only)
26
+ - Python ≥ 3.10
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ # Using pipx (recommended for CLI tools)
32
+ pipx install calctl
33
+
34
+ # Using uv
35
+ uv tool install calctl
36
+ ```
37
+
38
+ ## Permissions
39
+
40
+ calctl needs access to your calendars. On first run, macOS will show a permission dialog. If you previously denied access, go to:
41
+
42
+ **System Settings → Privacy & Security → Calendars → calctl** → enable access
43
+
44
+ ## Quick Start
45
+
46
+ ```bash
47
+ # List all calendars
48
+ calctl calendars
49
+
50
+ # List events for the next 7 days
51
+ calctl list
52
+
53
+ # List events in a specific date range
54
+ calctl list --from 2026-03-19 --to 2026-03-26
55
+
56
+ # List events from a specific calendar
57
+ calctl list --calendar Work
58
+
59
+ # Search events by keyword
60
+ calctl search "meeting"
61
+
62
+ # Search within a date range and calendar
63
+ calctl search "standup" --from 2026-03-01 --to 2026-03-31 --calendar Work
64
+
65
+ # Show full details for an event
66
+ calctl show EVENT_ID
67
+
68
+ # Create a timed event
69
+ calctl create --title "Team Standup" --start 2026-03-20T09:00:00 --end 2026-03-20T09:30:00 --calendar Work
70
+
71
+ # Create an all-day event
72
+ calctl create --title "Company Holiday" --start 2026-03-20 --all-day
73
+
74
+ # Create a recurring event with an alarm
75
+ calctl create \
76
+ --title "Weekly Review" \
77
+ --start 2026-03-20T14:00:00 \
78
+ --rrule "FREQ=WEEKLY;BYDAY=FR" \
79
+ --alarm -15m
80
+
81
+ # Create an event with location and geo coordinates
82
+ calctl create \
83
+ --title "Lunch" \
84
+ --start 2026-03-20T12:00:00 \
85
+ --end 2026-03-20T13:00:00 \
86
+ --location "Blue Bottle Coffee" \
87
+ --geo "37.7749,-122.4194"
88
+
89
+ # Edit an event's title and location
90
+ calctl edit EVENT_ID --title "Updated Title" --location "Room 42"
91
+
92
+ # Edit a recurring event — this and all future occurrences
93
+ calctl edit EVENT_ID --title "Renamed Series" --span future
94
+
95
+ # Delete an event
96
+ calctl delete EVENT_ID
97
+
98
+ # Delete a recurring event — this occurrence only
99
+ calctl delete EVENT_ID --span this
100
+ ```
101
+
102
+ ## CLI Reference
103
+
104
+ ### Global Options
105
+
106
+ These options apply to all commands and must come before the command name:
107
+
108
+ ```
109
+ calctl [OPTIONS] COMMAND [ARGS]...
110
+ ```
111
+
112
+ | Option | Short | Type | Default | Description |
113
+ |--------|-------|------|---------|-------------|
114
+ | `--format` | `-f` | `json\|text` | auto | Output format. Defaults to `text` on TTY, `json` when piped. |
115
+ | `--verbose` | `-v` | flag | false | Enable debug logging to stderr. |
116
+ | `--help` | | flag | | Show help and exit. |
117
+
118
+ ---
119
+
120
+ ### `calctl calendars`
121
+
122
+ List all calendars.
123
+
124
+ ```bash
125
+ calctl calendars
126
+ calctl calendars --format json
127
+ ```
128
+
129
+ ---
130
+
131
+ ### `calctl list`
132
+
133
+ List events in a date range.
134
+
135
+ ```bash
136
+ calctl list [OPTIONS]
137
+ ```
138
+
139
+ | Option | Type | Default | Description |
140
+ |--------|------|---------|-------------|
141
+ | `--from` | `YYYY-MM-DD` | today | Start date (inclusive). |
142
+ | `--to` | `YYYY-MM-DD` | today + 7 days | End date (inclusive). |
143
+ | `--calendar` | string | (all calendars) | Filter by calendar name. |
144
+
145
+ **Examples:**
146
+
147
+ ```bash
148
+ calctl list
149
+ calctl list --from 2026-03-01 --to 2026-03-31
150
+ calctl list --calendar Personal
151
+ ```
152
+
153
+ ---
154
+
155
+ ### `calctl search`
156
+
157
+ Search events by keyword. Matches against title, notes, and location.
158
+
159
+ ```bash
160
+ calctl search QUERY [OPTIONS]
161
+ ```
162
+
163
+ | Argument/Option | Type | Default | Description |
164
+ |-----------------|------|---------|-------------|
165
+ | `QUERY` | string | required | Search keyword(s). |
166
+ | `--from` | `YYYY-MM-DD` | (no limit) | Restrict search start date. |
167
+ | `--to` | `YYYY-MM-DD` | (no limit) | Restrict search end date. |
168
+ | `--calendar` | string | (all calendars) | Filter by calendar name. |
169
+
170
+ **Examples:**
171
+
172
+ ```bash
173
+ calctl search "team meeting"
174
+ calctl search "invoice" --from 2026-01-01 --to 2026-03-31
175
+ calctl search "standup" --calendar Work
176
+ ```
177
+
178
+ ---
179
+
180
+ ### `calctl show`
181
+
182
+ Show full details for a single event, including recurrence, alarms, and attendees.
183
+
184
+ ```bash
185
+ calctl show EVENT_ID
186
+ ```
187
+
188
+ | Argument | Type | Description |
189
+ |----------|------|-------------|
190
+ | `EVENT_ID` | string | Event identifier (from `list` or `search` output). |
191
+
192
+ ---
193
+
194
+ ### `calctl create`
195
+
196
+ Create a new event.
197
+
198
+ ```bash
199
+ calctl create --title TITLE --start DATETIME [OPTIONS]
200
+ ```
201
+
202
+ | Option | Type | Default | Description |
203
+ |--------|------|---------|-------------|
204
+ | `--title` | string | **required** | Event title. |
205
+ | `--start` | `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS` | **required** | Start date or datetime. |
206
+ | `--end` | `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS` | start + 1h (or same day if `--all-day`) | End date or datetime. |
207
+ | `--calendar` | string | default calendar | Calendar to add the event to. |
208
+ | `--location` | string | | Location string. |
209
+ | `--geo` | `lat,lng` | | Geographic coordinates (e.g. `37.7749,-122.4194`). |
210
+ | `--notes` | string | | Event notes / description. |
211
+ | `--url` | string | | URL associated with the event. |
212
+ | `--all-day` / `--no-all-day` | flag | false | Create as an all-day event. |
213
+ | `--availability` | `busy\|free\|tentative\|unavailable` | | Availability status. |
214
+ | `--timezone` | string | | Timezone identifier (e.g. `America/New_York`). |
215
+ | `--rrule` | RRULE string | | Recurrence rule (e.g. `FREQ=WEEKLY;BYDAY=MO,WE,FR`). |
216
+ | `--alarm` | duration | | Alarm offset before event (e.g. `-15m`, `-1h`). Repeatable for multiple alarms. Use `--alarm ""` to explicitly clear alarms. |
217
+
218
+ **Examples:**
219
+
220
+ ```bash
221
+ # Simple 30-minute event
222
+ calctl create --title "Coffee" --start 2026-03-20T10:00:00 --end 2026-03-20T10:30:00
223
+
224
+ # All-day event
225
+ calctl create --title "PTO" --start 2026-03-20 --all-day --calendar Personal
226
+
227
+ # Recurring weekly event with two alarms
228
+ calctl create \
229
+ --title "Weekly Sync" \
230
+ --start 2026-03-20T10:00:00 \
231
+ --rrule "FREQ=WEEKLY;BYDAY=FR" \
232
+ --alarm -10m \
233
+ --alarm -1h
234
+
235
+ # Event with location details
236
+ calctl create \
237
+ --title "Conference" \
238
+ --start 2026-03-20T09:00:00 \
239
+ --end 2026-03-20T17:00:00 \
240
+ --location "Moscone Center, San Francisco" \
241
+ --geo "37.7842,-122.4016" \
242
+ --timezone "America/Los_Angeles"
243
+ ```
244
+
245
+ ---
246
+
247
+ ### `calctl edit`
248
+
249
+ Edit an existing event. Only the fields you specify are changed.
250
+
251
+ ```bash
252
+ calctl edit EVENT_ID [OPTIONS]
253
+ ```
254
+
255
+ | Argument/Option | Type | Default | Description |
256
+ |-----------------|------|---------|-------------|
257
+ | `EVENT_ID` | string | **required** | Event to edit. |
258
+ | `--title` | string | | New title. |
259
+ | `--start` | datetime | | New start datetime. |
260
+ | `--end` | datetime | | New end datetime. |
261
+ | `--calendar` | string | | Move to this calendar. |
262
+ | `--location` | string | | New location string. |
263
+ | `--geo` | `lat,lng` | | New geo coordinates. |
264
+ | `--notes` | string | | New notes. |
265
+ | `--url` | string | | New URL. |
266
+ | `--all-day` / `--no-all-day` | flag | | Set or clear all-day flag. |
267
+ | `--availability` | `busy\|free\|tentative\|unavailable` | | New availability. |
268
+ | `--timezone` | string | | New timezone. |
269
+ | `--rrule` | RRULE string | | New recurrence rule. |
270
+ | `--alarm` | duration | | New alarm(s). Repeatable. Use `--alarm ""` to clear all alarms. |
271
+ | `--span` | `this\|future` | `this` | For recurring events: edit only this occurrence (`this`) or this and all future occurrences (`future`). |
272
+
273
+ **Examples:**
274
+
275
+ ```bash
276
+ # Rename an event
277
+ calctl edit EVENT_ID --title "New Name"
278
+
279
+ # Reschedule
280
+ calctl edit EVENT_ID --start 2026-03-21T10:00:00 --end 2026-03-21T11:00:00
281
+
282
+ # Edit all future occurrences of a recurring event
283
+ calctl edit EVENT_ID --title "Renamed Series" --span future
284
+
285
+ # Move event to a different calendar
286
+ calctl edit EVENT_ID --calendar Personal
287
+ ```
288
+
289
+ ---
290
+
291
+ ### `calctl delete`
292
+
293
+ Delete an event.
294
+
295
+ ```bash
296
+ calctl delete EVENT_ID [OPTIONS]
297
+ ```
298
+
299
+ | Argument/Option | Type | Default | Description |
300
+ |-----------------|------|---------|-------------|
301
+ | `EVENT_ID` | string | **required** | Event to delete. |
302
+ | `--span` | `this\|future` | `this` | For recurring events: delete only this occurrence (`this`) or this and all future occurrences (`future`). |
303
+
304
+ **Examples:**
305
+
306
+ ```bash
307
+ # Delete a single event
308
+ calctl delete EVENT_ID
309
+
310
+ # Delete this and all future occurrences
311
+ calctl delete EVENT_ID --span future
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Output Formats
317
+
318
+ calctl supports two output formats, controlled by `--format` / `-f`:
319
+
320
+ | Format | Flag | Description |
321
+ |--------|------|-------------|
322
+ | `text` | `--format text` | Human-readable, table-style output for the terminal. |
323
+ | `json` | `--format json` | Machine-readable JSON. Arrays for list commands, objects for single-item commands. |
324
+
325
+ **Auto-detection:** When `--format` is not specified, calctl detects whether stdout is a terminal (TTY):
326
+ - **Terminal** → `text` format
327
+ - **Pipe or redirect** → `json` format
328
+
329
+ This means you can pipe calctl output to `jq` without specifying `--format json`:
330
+
331
+ ```bash
332
+ # Pipe output — JSON is selected automatically
333
+ calctl list | jq '.[] | .title'
334
+ calctl search "meeting" | jq '.[0].id'
335
+
336
+ # Force text format in a script
337
+ calctl list --format text > events.txt
338
+ ```
339
+
340
+ ## License
341
+
342
+ MIT — see [LICENSE](LICENSE) for details.