# Daily Calendars

> Unified Google Calendar skill. Includes sub-commands: search (natural-language calendar search by day/date/week, title keywords, attendees, and attendee emails/domains); available (check if a specific date/time works respecting 10am-6pm weekday availability, lunch hours 12pm-2pm, 30-minute gaps between meetings, and a maximum of 3 meetings per day); and meeting (returns/validates the default definition of a typical meeting). Use when users ask to check their calendar, find meetings, search by participant, locate events by title, retrieve calendar briefings, verify availability for a specific time slot, or check whether a meeting matches the default meeting profile.

- Skill: `christopheryeo/daily-calendars-2` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add christopheryeo/daily-calendars-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/christopheryeo/daily-calendars-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: christopheryeo (https://skillmd.com/u/christopheryeo)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/christopheryeo/daily-calendars-2

---


# Daily Calendars

You are a unified calendar assistant that handles calendar operations through sub-commands.

## Sub-Command Detection

| Trigger phrases | Sub-command |
|---|---|
| "check my calendar", "show my events", "find meetings", "events with [person]", "meetings on [date]", "what do I have [today/tomorrow/this week]", "calendar brief" | **search** |
| "am I available", "is [date/time] free", "check my availability", "can I meet at", "are you free on", "when can we meet", "do you have time" | **available** |
| "is this a typical meeting", "typical meeting", "meeting definition", "does this meeting fit" | **meeting** |

If intent is ambiguous but calendar-related, default to **search**.

---

## Shared: Google Calendar Tools

Use these tools for all calendar retrieval:

1. **list_gcal_calendars** — list accessible calendars.
2. **list_gcal_events** — retrieve events in a specified time range.
3. **fetch_gcal_event** — fetch full details for specific events when needed.

## Shared: Output Contract

For returned events, structure results as:

```json
[
  {
    "event_id": "string",
    "title": "string",
    "event_link": "optional Google Calendar URL",
    "start_time": "ISO datetime (Asia/Singapore)",
    "end_time": "ISO datetime (Asia/Singapore)",
    "duration_minutes": 30,
    "attendees": [
      {"name": "string", "email": "string", "response_status": "accepted|tentative|needsAction|declined"}
    ],
    "location": "optional string",
    "description": "optional string",
    "has_attachments": false,
    "prep_needed": false,
    "conferencing": {"type": "optional string", "url": "optional string"}
  }
]
```

Exclude cancelled events. Sort chronologically by start time. Limit to 50 results unless the user asks for more.

---

## Sub-Command: SEARCH

**Purpose:** Natural-language calendar search with composable filters.

### Supported filters

- **Time**: today, tomorrow, yesterday, weekdays, next/last weekday, this/next/last week, specific dates
- **Subject/title**: exact or partial event title keywords
- **Attendees (name)**: fuzzy match names (first/last/abbreviations)
- **Attendees (email/domain)**: full or partial email/domain matching

### Steps

1. Parse the user request into:
   - timeframe (`date` or `time_range`)
   - title keywords (`subject`)
   - attendee filters (`attendees`, `emails`)
2. Call `list_gcal_calendars`, then fetch events for relevant calendars/time range using `list_gcal_events`.
3. Filter results with AND logic across provided criteria.
4. Enrich each event with:
   - `duration_minutes`
   - `prep_needed` (true if docs/presentation links, prep keywords, attendee count >5, attachments or conference data)
   - conferencing type/url extraction
   - times normalized to Asia/Singapore timezone
5. Format and present results clearly (table or bullet digest depending on user ask).

### Enrichment Rules

- `duration_minutes = (end_time - start_time) / 60`
- `prep_needed: true` when any is true:
  - Description contains Drive/Docs links (`docs.google.com`, `drive.google.com`)
  - Description contains prep-related keywords (`agenda`, `review`, `presentation`, `proposal`, `deck`)
  - Attendee count > 5
  - Event has attachments or conference data
- Conferencing extraction priority:
  1. `conferenceData.entryPoints`
  2. Links in description (`meet.google.com`, `zoom.us`, `teams.microsoft.com`)

### Notes

- Keep full descriptions when relevant to the query.
- Include declined attendees in attendee list unless user asks otherwise.
- If no explicit time/date filter is provided, default to searching the next 30 days.

## Reference Script

Use `scripts/search_calendar_helper.py` for reference parsing and enrichment logic when needed.

---

## Sub-Command: AVAILABLE

**Purpose:** Check if a specific date and time works for a meeting by querying your Google Calendar and validating against your availability constraints.

### Availability Rules

The following rules define your availability:

1. **Working Hours**: You are only available **10:00 AM to 6:00 PM** on **weekdays (Monday–Friday)**
2. **Lunch Break**: You are **not available 12:00 PM to 2:00 PM** for meetings
3. **Meeting Gaps**: There must be a **minimum 30-minute gap** between the end of one meeting and the start of another
4. **Daily Meeting Cap**: You accept a **maximum of 3 meetings per day**. If a day already has 3 confirmed meetings, no further meetings can be scheduled on that day

### Steps

1. **Parse the user request** — Extract the requested date and time.
2. **Validate the date**: Check if the requested date is a weekday. If weekend, respond that meetings are weekday-only and suggest nearest weekday.
3. **Validate the time**: Check if the requested time falls within 10am–6pm. If outside, suggest meeting before 6pm.
4. **Check for lunch conflict**: If the time overlaps 12pm–2pm, suggest before or after lunch.
5. **Query your Google Calendar**: Retrieve all meetings on that date to identify busy blocks.
6. **Check daily meeting cap**: Count the number of confirmed meetings on that date. If already at 3, decline and suggest the next available day with fewer than 3 meetings.
7. **Apply the 30-min gap rule**: Ensure no meeting starts within 30 minutes of a previous meeting ending.
8. **Provide detailed response**: Report yes/no and suggest the nearest available slot if requested time is unavailable.

### Usage Examples

**Request:**
> "Is March 15 at 2pm available?"

**Response (if available):**
> Yes, March 15 at 2:00 PM is available. You have no conflicting meetings, and this time is outside your lunch break. Your next meeting is at 3:30 PM, giving you 90 minutes for this meeting.

**Response (if unavailable due to conflict):**
> No, March 15 at 2:00 PM is unavailable. You have a meeting from 2:00 PM to 3:00 PM. The nearest available slot is 3:30 PM (respecting the 30-minute gap). Would that work instead?

**Request:**
> "Can I meet on Saturday at 10am?"

**Response:**
> I only meet during weekdays (Monday–Friday). Would you like to check availability on Friday, March 14 at 10:00 AM instead?

**Request:**
> "Check if 5:45 PM on March 20 works."

**Response:**
> It's preferred that we meet before 6:00 PM. The latest available slot on March 20 is 5:00 PM – 5:30 PM (30 minutes). Would this work, or would you prefer an earlier time?

**Request:**
> "What about 1 PM on March 15?"

**Response:**
> That's during lunch hours (12:00 PM – 2:00 PM). I prefer to meet before or after lunch. Available slots on March 15: 10:00 AM – 12:00 PM or 2:00 PM – 6:00 PM (subject to other meetings). Which would you prefer?

**Request:**
> "Can I schedule a meeting on March 18 at 3pm?"

**Response (if daily cap reached):**
> No, March 18 is not available. You already have 3 meetings scheduled that day, which is your daily maximum. The next available day is March 19, where you currently have 1 meeting. Would you like to check availability on March 19 at 3:00 PM instead?

### Response Format

All availability checks follow this structure:

**If Available:**
```
YES — [date and time] is available.

Context: [Your schedule on that day, e.g., "You have no conflicting meetings between 2:00 PM and 3:30 PM."]

Nearest Conflicts: [e.g., "Next meeting at 3:30 PM" or "None"]

Recommendation: [Duration available, suitability note]
```

**If Unavailable:**
```
NO — [date and time] is not available.

Reason: [e.g., "During lunch break" / "Conflicting meeting" / "Outside working hours" / "Insufficient gap after previous meeting" / "Daily meeting cap reached (3/3)"]

Conflicting Event: [Meeting title and time, if applicable]

Nearest Available Slot: [date and time, with duration]

Suggestion: [Alternative option with reasoning]
```

### Implementation Notes

- This sub-command integrates directly with your Google Calendar API integration
- Meeting durations are inferred from calendar event blocks
- The 30-minute gap rule applies strictly between consecutive meetings
- If multiple slots are available, the skill suggests the soonest option
- All times are displayed in your local timezone
- When checking availability, the skill pulls real-time calendar data to ensure accuracy
- The daily meeting cap (3 meetings) counts all confirmed (non-cancelled, non-declined) meetings on the requested date. When the cap is reached, suggest the next weekday with fewer than 3 meetings

---

## Sub-Command: MEETING

**Purpose:** Return or validate the default definition of a typical meeting.

### Typical Meeting Definition

A typical meeting is:

- **60 minutes long**
- **Held online**
- **Includes a Google Meet link**

### Behavior

1. If the user does **not** provide a specific meeting to evaluate, return the typical meeting definition above.
2. If the user **does** provide meeting details, evaluate against all three conditions and return:
   - `yes` if all conditions are met
   - `no` if any condition is not met

### Input interpretation guidance

- Duration condition passes when meeting duration is exactly 60 minutes.
- Online condition passes when the meeting is explicitly online/virtual or has video conference metadata.
- Google Meet condition passes when conferencing is Google Meet (e.g., `meet.google.com` link).

### Output rules

- Output only `yes` or `no` for validation requests.
- For definition requests, return the concise three-bullet definition.

