From aacaf57540b6a68565c96cc2bc769b14a48a53a2 Mon Sep 17 00:00:00 2001 From: OpenCode Test Date: Wed, 31 Dec 2025 22:07:51 -0800 Subject: [PATCH] Add Google Calendar integration design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Design for /gcal command following the Gmail pattern: - Subcommands: today, tomorrow, week, next, summary - Hybrid interface (subcommands + natural language) - Tiered delegation (Haiku for fetch, Sonnet for analysis) - Reuses existing OAuth credentials with added Calendar scope ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- plans/2025-01-02-gcal-design.md | 229 ++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 plans/2025-01-02-gcal-design.md diff --git a/plans/2025-01-02-gcal-design.md b/plans/2025-01-02-gcal-design.md new file mode 100644 index 0000000..5620fe7 --- /dev/null +++ b/plans/2025-01-02-gcal-design.md @@ -0,0 +1,229 @@ +# Google Calendar Integration Design + +**Date:** 2025-01-02 +**Status:** Approved +**Primary Use Case:** Agenda overview + +## Overview + +Build a `/gcal` slash command for Google Calendar access, following the same architectural pattern as `/gmail`: +- OAuth credentials (reuse existing `~/.gmail-mcp/`) +- Python API wrapper with tiered delegation +- Skill file defining usage patterns +- Read-only by default + +## Architecture + +``` +User types /gcal + โ”‚ + โ–ผ + Command (gcal.md) + โ”‚ + โ”œโ”€โ†’ invokes: skill:gcal + โ”‚ + โ–ผ + Skill determines tier + โ”‚ + โ”œโ”€โ†’ Haiku: today, tomorrow, week, next (fetch + format) + โ””โ”€โ†’ Sonnet: summary (fetch + analyze) + โ”‚ + โ–ผ + Python helper (gcal_delegate.py) + โ”‚ + โ”œโ”€โ†’ Google Calendar API via OAuth + โ””โ”€โ†’ Returns structured JSON + โ”‚ + โ–ผ + PA formats response for user +``` + +## Components + +| File | Format | Purpose | +|------|--------|---------| +| `~/.claude/commands/gcal.md` | Markdown | Slash command definition | +| `~/.claude/skills/gcal/SKILL.md` | Markdown | Usage patterns and routing | +| `~/.claude/mcp/delegation/gcal_delegate.py` | Python | API wrapper + delegation | +| `~/.gmail-mcp/credentials.json` | JSON | OAuth credentials (add Calendar scope) | + +## Command Interface + +### Subcommands + +| Subcommand | Description | Tier | +|------------|-------------|------| +| `today` | Today's agenda | Haiku | +| `tomorrow` | Tomorrow's agenda | Haiku | +| `week` | Next 7 days, grouped by day | Haiku | +| `next` | Next upcoming event | Haiku | +| `summary` | Smart analysis of your week | Sonnet | + +### Routing + +``` +/gcal โ†’ Smart default (today if before 6pm, tomorrow if after) +/gcal today โ†’ Today's agenda +/gcal tomorrow โ†’ Tomorrow's agenda +/gcal week โ†’ Next 7 days, grouped by day +/gcal next โ†’ Next upcoming event only +/gcal summary โ†’ Sonnet-powered week analysis +/gcal โ†’ PA interprets intent, routes to appropriate subcommand +``` + +### Hybrid Approach + +1. **Exact subcommand match first:** `today`, `tomorrow`, `week`, `next`, `summary` +2. **Natural language fallback:** + - "what's on today" โ†’ today + - "this week" โ†’ week + - "next meeting" โ†’ next + - "am I busy tomorrow" โ†’ tomorrow + - "give me an overview" โ†’ summary +3. **Ambiguous input:** Ask for clarification + +### Smart Default + +```python +from datetime import datetime +def default_view(): + return "today" if datetime.now().hour < 18 else "tomorrow" +``` + +## Output Format + +### Simple List (today/tomorrow/next) + +``` +๐Ÿ“… Today โ€” Thursday, Jan 2 + + 9:00 AM Team standup (30m) + ๐Ÿ“ Zoom ยท ๐Ÿ‘ฅ 5 attendees + + 10:30 AM 1:1 with Sarah (45m) + ๐Ÿ“ Conference Room B + + 2:00 PM Project review (1h) + ๐Ÿ“ Google Meet ยท ๐Ÿ‘ฅ 8 attendees + ๐Ÿ“ Q4 roadmap discussion + +No more events today. +``` + +### Grouped by Day (week) + +``` +๐Ÿ“… This Week โ€” Jan 2-8 + +โ”โ”โ” Thursday, Jan 2 โ”โ”โ” + 9:00 AM Team standup (30m) + 2:00 PM Project review (1h) + +โ”โ”โ” Friday, Jan 3 โ”โ”โ” + 11:00 AM Client call (1h) + +โ”โ”โ” Monday, Jan 6 โ”โ”โ” + (no events) + +... +``` + +### Context Fields + +- ๐Ÿ“ Location or meeting link +- ๐Ÿ‘ฅ Attendee count +- ๐Ÿ“ Description snippet (first ~50 chars) + +### Smart Summary (Sonnet) + +> "Your week is front-loaded โ€” Thursday and Friday are packed with 6 meetings totaling 5.5 hours. Monday-Wednesday are mostly clear, good for deep work. Heads up: the Client call Friday overlaps with your blocked focus time." + +## Python Helper + +### Structure + +```python +#!/usr/bin/env python3 +""" +Google Calendar Delegation Helper + +Usage: + gcal_delegate.py today + gcal_delegate.py tomorrow + gcal_delegate.py week + gcal_delegate.py next + gcal_delegate.py summary +""" + +SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'] +CREDENTIALS_PATH = "~/.gmail-mcp/credentials.json" + +# Core functions +def get_calendar_service() # OAuth flow, returns Calendar API client +def fetch_events(start, end) # Returns list of event dicts +def format_event(event) # Extracts: time, title, location, attendees, description +def delegate(model, prompt) # Calls Claude CLI for Sonnet-tier tasks + +# Subcommand handlers +def cmd_today() # fetch_events for today, format, return JSON +def cmd_tomorrow() # fetch_events for tomorrow +def cmd_week() # fetch_events for 7 days, group by date +def cmd_next() # fetch next single event +def cmd_summary() # fetch week, delegate to Sonnet for analysis +``` + +### Output Format + +```json +{ + "tier": "haiku", + "operation": "today", + "date": "2025-01-02", + "events": [...], + "count": 3 +} +``` + +## OAuth Setup + +### One-Time Setup + +1. Go to [Google Cloud Console](https://console.cloud.google.com/) โ†’ APIs & Services +2. Enable "Google Calendar API" +3. OAuth consent screen โ†’ Add scope: `calendar.readonly` +4. Delete local token: `rm ~/.gmail-mcp/token.json` +5. Run `/gcal today` โ€” triggers re-auth with new scope + +### Scope Detection + +Helper detects missing scope and prompts: +``` +Calendar scope not authorized. Run: + rm ~/.gmail-mcp/token.json + Then retry /gcal today to re-authenticate. +``` + +## Delegation Tiers + +| Tier | Operations | Reason | +|------|------------|--------| +| Haiku | today, tomorrow, week, next | Fetch + format only | +| Sonnet | summary | Requires analysis | +| Opus | (reserved) | Strategic planning if needed | + +## Policy + +- Read-only operations only +- Show context (attendees, location) by default +- Summarize results, don't dump raw data +- Start with lowest capable model tier + +## Implementation Checklist + +- [ ] Add Calendar scope to GCP OAuth app +- [ ] Create `~/.claude/skills/gcal/SKILL.md` +- [ ] Create `~/.claude/commands/gcal.md` +- [ ] Create `~/.claude/mcp/delegation/gcal_delegate.py` +- [ ] Test OAuth re-authorization +- [ ] Test all subcommands +- [ ] Test natural language fallback