Initial commit with translated description
This commit is contained in:
65
README.md
Normal file
65
README.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# gcalcli-calendar
|
||||||
|
|
||||||
|
An OpenClaw skill for managing Google Calendar via [gcalcli](https://github.com/insanum/gcalcli).
|
||||||
|
|
||||||
|
## What this skill does
|
||||||
|
|
||||||
|
Teaches the agent to read, search, create, and delete Google Calendar events using the `gcalcli` CLI. Optimized for low tool calls, minimal token usage, and fast conversational calendar management.
|
||||||
|
|
||||||
|
## About gcalcli
|
||||||
|
|
||||||
|
[gcalcli](https://github.com/insanum/gcalcli) is a well-established open-source CLI for Google Calendar (5k+ GitHub stars, actively maintained). It authenticates via OAuth2 and stores credentials locally. This skill does not handle authentication — gcalcli must be set up and authenticated before use.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Python 3.6+
|
||||||
|
- `gcalcli` — install via `pip install gcalcli` or `brew install gcalcli`
|
||||||
|
- Google Calendar OAuth2 credentials (set up via `gcalcli init` or `gcalcli list` on first run)
|
||||||
|
|
||||||
|
## Actions policy — design rationale
|
||||||
|
|
||||||
|
**This skill intentionally skips user confirmation for unambiguous destructive actions (delete/edit).** This is a deliberate UX decision, not an oversight. Here's why and how it's kept safe:
|
||||||
|
|
||||||
|
### Why skip confirmation?
|
||||||
|
|
||||||
|
This skill is designed for personal assistant use via messaging apps (Telegram, WhatsApp, etc.), where:
|
||||||
|
- The user has already stated their intent explicitly (e.g. "delete my dentist appointment on Thursday").
|
||||||
|
- An extra "Are you sure?" round-trip adds latency and friction with no real safety benefit when the target is unambiguous.
|
||||||
|
- The interaction model is conversational — the user's message *is* the confirmation.
|
||||||
|
|
||||||
|
### Safety guards in place
|
||||||
|
|
||||||
|
The skill does NOT blindly delete. All of these must hold before executing without confirmation:
|
||||||
|
|
||||||
|
1. **Explicit user request** — the user must have asked for the action in their message.
|
||||||
|
2. **Single unambiguous match** — exactly one event matches in a tight, bounded time window.
|
||||||
|
3. **Post-action verification** — after every delete, the agent verifies via agenda that the event is actually gone. It never claims success without verification.
|
||||||
|
4. **Disambiguation for ambiguous cases** — if multiple events match, the agent always stops and asks the user to choose before proceeding.
|
||||||
|
5. **Overlap checks for creates** — before creating events, the agent checks for scheduling conflicts across all calendars and asks for confirmation if an overlap exists.
|
||||||
|
|
||||||
|
### If you prefer confirmation for all actions
|
||||||
|
|
||||||
|
You can modify the "Actions policy" section in SKILL.md to require confirmation for all destructive actions. Change the "Unambiguous actions" rule to always ask before executing.
|
||||||
|
|
||||||
|
## Network access
|
||||||
|
|
||||||
|
This skill invokes `gcalcli`, which communicates with:
|
||||||
|
- `https://www.googleapis.com/calendar/` — Google Calendar API (authenticated via local OAuth2 tokens)
|
||||||
|
- `https://oauth2.googleapis.com/` — OAuth2 token refresh
|
||||||
|
|
||||||
|
No other network access is made. The skill itself makes no HTTP requests — all API communication is handled by gcalcli. OAuth2 credentials are stored locally by gcalcli (typically in `~/.gcalcli_oauth`).
|
||||||
|
|
||||||
|
## Commands used
|
||||||
|
|
||||||
|
All `gcalcli` commands used by this skill:
|
||||||
|
- `gcalcli agenda` — list events in a time window (read-only)
|
||||||
|
- `gcalcli search` — search events by text query (read-only)
|
||||||
|
- `gcalcli add` — create a one-off event
|
||||||
|
- `gcalcli import` — create events via ICS (for recurrence/free-busy)
|
||||||
|
- `gcalcli delete` — delete events (uses `--iamaexpert` flag for non-interactive mode, which is gcalcli's built-in flag for scripted/automated use)
|
||||||
|
|
||||||
|
No other commands or subcommands are used. No file system writes are performed (ICS content is piped via stdin, never written to disk).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This skill is MIT licensed. [gcalcli](https://github.com/insanum/gcalcli) is MIT licensed.
|
||||||
163
SKILL.md
Normal file
163
SKILL.md
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
---
|
||||||
|
name: gcalcli-calendar
|
||||||
|
description: "通过gcalcli使用Google日历。"
|
||||||
|
metadata: {"openclaw":{"emoji":"📅","requires":{"bins":["gcalcli"]}}}
|
||||||
|
---
|
||||||
|
|
||||||
|
# gcalcli-calendar
|
||||||
|
|
||||||
|
Use `gcalcli` to read/search/manage Google Calendar with minimal tool calls and minimal output.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### CLI flag placement (critical)
|
||||||
|
- Global flags (`--nocolor`, `--calendar`) go BEFORE the subcommand.
|
||||||
|
- Subcommand-specific flags go AFTER the subcommand name.
|
||||||
|
- Example: `gcalcli --nocolor delete --iamaexpert "query" start end` — NOT `gcalcli --nocolor --iamaexpert delete ...`.
|
||||||
|
- This applies to ALL subcommand flags: `--iamaexpert` (delete), `--noprompt`/`--allday` (add), `--use-legacy-import` (import), etc.
|
||||||
|
|
||||||
|
### Output & language
|
||||||
|
- Don't print CLI commands/flags/tool details unless the user explicitly asks (e.g. "show commands used", "/debug", "/commands").
|
||||||
|
- If asked for commands: print ALL executed commands in order (including retries) and nothing else.
|
||||||
|
- Don't mix languages within one reply.
|
||||||
|
- Be concise. No scope unless nothing found.
|
||||||
|
|
||||||
|
### Dates & formatting
|
||||||
|
- Human-friendly dates by default. ISO only if explicitly requested.
|
||||||
|
- Don't quote event titles unless needed to disambiguate.
|
||||||
|
|
||||||
|
### Calendar scope
|
||||||
|
- Trust gcalcli config (default/ignore calendars). Don't broaden scope unless user asks "across all calendars" or results are clearly wrong.
|
||||||
|
|
||||||
|
### Agenda (today-only by default)
|
||||||
|
- If user asks "agenda" without a period, return today only.
|
||||||
|
- Expand only if explicitly asked (tomorrow / next N days / date range).
|
||||||
|
|
||||||
|
### Weekday requests (no mental math)
|
||||||
|
If user says "on Monday/Tuesday/..." without a date:
|
||||||
|
1) fetch next 14 days agenda once,
|
||||||
|
2) pick matching day/event from tool output,
|
||||||
|
3) proceed (or disambiguate if multiple).
|
||||||
|
|
||||||
|
### Finding events: prefer deterministic agenda scan (meaning-first)
|
||||||
|
When locating events to cancel/delete/edit:
|
||||||
|
- Prefer `agenda` over `search`.
|
||||||
|
- Use a bounded window and match events by meaning (semantic match) rather than exact text.
|
||||||
|
- Default locate windows:
|
||||||
|
- If user gives an exact date: scan that day only.
|
||||||
|
- If user gives a weekday: scan next 14 days.
|
||||||
|
- If user gives only meaning words ("train", "lecture", etc.) with no date: scan next 30 days first.
|
||||||
|
- If still not found: expand to 180 days and say so only if still empty.
|
||||||
|
|
||||||
|
Use gcalcli `search` only as a fallback when:
|
||||||
|
- the time window would be too large to scan via agenda (token-heavy), or
|
||||||
|
- the user explicitly asked to "search".
|
||||||
|
|
||||||
|
### Search (bounded)
|
||||||
|
- Default search window: next ~180 days (unless user specified otherwise).
|
||||||
|
- If no matches: say "No matches in next ~6 months (<from>-><to>)" and offer to expand.
|
||||||
|
- Show scope only when nothing is found.
|
||||||
|
|
||||||
|
### Tool efficiency
|
||||||
|
- Default: use `--nocolor` to reduce formatting noise and tokens.
|
||||||
|
- Use `--tsv` only if you must parse/dedupe/sort.
|
||||||
|
|
||||||
|
## Actions policy (optimized for conversational speed)
|
||||||
|
|
||||||
|
This skill is designed for personal assistant use where the user expects fast, low-friction calendar management. The confirmation policy below is an intentional UX choice — see README.md for rationale and safety guards.
|
||||||
|
|
||||||
|
### Unambiguous actions: execute immediately
|
||||||
|
For cancel/delete/edit actions, skip confirmation when ALL of these hold:
|
||||||
|
- The user explicitly requested the action (e.g. "delete my dentist appointment").
|
||||||
|
- Exactly one event matches in a tight time window.
|
||||||
|
- The match is unambiguous (single clear result on an exact date, or user specified date+time).
|
||||||
|
|
||||||
|
### Ambiguous actions: always ask first
|
||||||
|
If multiple candidates match, or the match is uncertain:
|
||||||
|
- Ask a short disambiguation question listing the candidates (1-3 lines) and wait for the user's choice.
|
||||||
|
|
||||||
|
### Create events: overlap check MUST be cross-calendar (non-ignored scope)
|
||||||
|
When creating an event:
|
||||||
|
- Always run a best-effort overlap check across ALL non-ignored calendars by scanning agenda WITHOUT `--calendar`.
|
||||||
|
- This ensures overlaps are detected even if the new event is created into a specific calendar.
|
||||||
|
- If overlap exists with busy events:
|
||||||
|
- Ask for confirmation before creating.
|
||||||
|
- If no overlap:
|
||||||
|
- Create immediately.
|
||||||
|
|
||||||
|
### Choose the right create method
|
||||||
|
- **`add`** — default for one-off events. Supports `--allday`, `--reminder`, `--noprompt`. Does NOT support recurrence or free/busy (transparency).
|
||||||
|
- **`import` via stdin** — use ONLY when you need recurrence (RRULE) or free/busy (TRANSP:TRANSPARENT). Pipe ICS content via stdin; NEVER write temp .ics files (working directory is unreliable in exec sandbox).
|
||||||
|
- **`quick`** — avoid unless user explicitly asks for natural-language add. Less deterministic.
|
||||||
|
|
||||||
|
### Deletes must be verified
|
||||||
|
- Use non-interactive delete with `--iamaexpert` (a `delete` subcommand flag — goes AFTER `delete`). This is gcalcli's built-in flag for non-interactive/scripted deletion.
|
||||||
|
- Always verify via agenda in the same tight window after deletion.
|
||||||
|
- If verification still shows the event, do one retry with `--refresh`.
|
||||||
|
- Never claim success unless verification confirms the event is gone.
|
||||||
|
|
||||||
|
## Canonical commands
|
||||||
|
|
||||||
|
### Agenda (deterministic listing)
|
||||||
|
- Today: `gcalcli --nocolor agenda today tomorrow`
|
||||||
|
- Next 14d (weekday resolution): `gcalcli --nocolor agenda today +14d`
|
||||||
|
- Next 30d (meaning-first locate): `gcalcli --nocolor agenda today +30d`
|
||||||
|
- Custom: `gcalcli --nocolor agenda <start> <end>`
|
||||||
|
|
||||||
|
### Search (fallback / explicit request)
|
||||||
|
- Default (~6 months): `gcalcli --nocolor search "<query>" today +180d`
|
||||||
|
- Custom: `gcalcli --nocolor search "<query>" <start> <end>`
|
||||||
|
|
||||||
|
### Create — `add` (one-off events)
|
||||||
|
- Overlap preflight (tight, cross-calendar):
|
||||||
|
- `gcalcli --nocolor agenda <start> <end>`
|
||||||
|
- IMPORTANT: do NOT add `--calendar` here; overlaps must be checked across all non-ignored calendars.
|
||||||
|
- Timed event:
|
||||||
|
- `gcalcli --nocolor --calendar "<Cal>" add --noprompt --title "<Title>" --when "<Start>" --duration <minutes>`
|
||||||
|
- All-day event:
|
||||||
|
- `gcalcli --nocolor --calendar "<Cal>" add --noprompt --allday --title "<Title>" --when "<Date>"`
|
||||||
|
- With reminders (repeatable flag):
|
||||||
|
- `--reminder "20160 popup"` → 14 days before (20160 = 14×24×60)
|
||||||
|
- `--reminder "10080 popup"` → 7 days before
|
||||||
|
- `--reminder "0 popup"` → at event start
|
||||||
|
- Time unit suffixes: `w` (weeks), `d` (days), `h` (hours), `m` (minutes). No suffix = minutes.
|
||||||
|
- Method: `popup` (default), `email`, `sms`.
|
||||||
|
|
||||||
|
### Create — `import` via stdin (recurrence / free/busy)
|
||||||
|
Use ONLY when `add` can't cover the need (recurring events, TRANSP, etc.).
|
||||||
|
Pipe ICS directly via stdin — never write temp files.
|
||||||
|
```
|
||||||
|
echo 'BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
BEGIN:VEVENT
|
||||||
|
DTSTART;VALUE=DATE:20260308
|
||||||
|
SUMMARY:Event Title
|
||||||
|
RRULE:FREQ=YEARLY
|
||||||
|
TRANSP:TRANSPARENT
|
||||||
|
END:VEVENT
|
||||||
|
END:VCALENDAR' | gcalcli import --calendar "<Cal>"
|
||||||
|
```
|
||||||
|
- `DTSTART;VALUE=DATE:YYYYMMDD` for all-day; `DTSTART:YYYYMMDDTHHmmSS` for timed.
|
||||||
|
- `RRULE:FREQ=YEARLY` — yearly recurrence. Also: `DAILY`, `WEEKLY`, `MONTHLY`.
|
||||||
|
- `TRANSP:TRANSPARENT` — free; `TRANSP:OPAQUE` — busy (default).
|
||||||
|
- One import call = one event (one VEVENT block). For multiple events, run separate piped imports.
|
||||||
|
- Add `--reminder "TIME"` flag(s) to set reminders (overrides any VALARM in ICS).
|
||||||
|
- All import-specific flags (`--use-legacy-import`, `--verbose`, etc.) go AFTER `import`.
|
||||||
|
|
||||||
|
### Delete (with post-delete verification)
|
||||||
|
- Locate via agenda (preferred):
|
||||||
|
- `gcalcli --nocolor agenda <dayStart> <dayEnd>` (exact date)
|
||||||
|
- `gcalcli --nocolor agenda today +14d` (weekday)
|
||||||
|
- `gcalcli --nocolor agenda today +30d` (meaning only)
|
||||||
|
- Delete (non-interactive, bounded):
|
||||||
|
- `gcalcli --nocolor delete --iamaexpert "<query>" <start> <end>`
|
||||||
|
- Verify (same window):
|
||||||
|
- `gcalcli --nocolor agenda <dayStart> <dayEnd>`
|
||||||
|
- Optional one retry if still present:
|
||||||
|
- `gcalcli --nocolor --refresh agenda <dayStart> <dayEnd>`
|
||||||
|
|
||||||
|
### Edit / Modify existing events
|
||||||
|
- `gcalcli edit` is interactive — cannot be used in non-interactive exec.
|
||||||
|
- To change properties not editable in-place: **delete + recreate** the event.
|
||||||
|
- Locate → delete (with `--iamaexpert`) → create with updated properties → verify.
|
||||||
|
- For bulk property changes (e.g. setting all events to free): iterate delete+recreate per event.
|
||||||
6
_meta.json
Normal file
6
_meta.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"ownerId": "kn757ghzsay7zhsft6rb14jhwn80d28q",
|
||||||
|
"slug": "gcalcli-calendar",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"publishedAt": 1770939510320
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user