/process-meetings
Turn synced meetings into updated person pages, extracted tasks and organized notes. Use when the user says 'process my meetings', 'catch up my notes', or after Granola/Otter syncs. Also use proactively when unprocessed meetings exist. Not for prepping an upcoming meeting; use
$ npx -y skills add davekilleen/Dex --skill process-meetings --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/process-meetings
Context preview
The summary Claude sees to decide when to auto-load this skill.
Turn synced meetings into updated person pages, extracted tasks and organized notes. Use when the user says 'process my meetings', 'catch up my notes', or after Granola/Otter syncs. Also use proactively when unprocessed meetings exist. Not for prepping an upcoming meeting; use
SKILL.md
process-meetings.SKILL.mdname: process-meetings
description: "Turn synced meetings into updated person pages, extracted tasks and organized notes. Use when the user says 'process my meetings', 'catch up my notes', or after Granola/Otter syncs. Also use proactively when unprocessed meetings exist. Not for prepping an upcoming meeting; use `meeting-prep`."
model_hint: balanced
context: fork
hooks:
PostToolUse:
- matcher: Write
type: command
command: "node .claude/hooks/post-meeting-person-update.cjs"Process Meetings
Process meetings that have been synced from Granola by the background automation. Updates person pages, extracts tasks, and organizes meeting notes.
Background Execution
This skill supports background execution. When invoked: 1. Acknowledge: "Processing [N] meetings in the background. I'll let you know when done." 2. Process all meetings 3. On completion, provide summary: "[N] meetings processed. [X] person pages updated. [Y] action items created."
How It Works
Meetings are synced automatically every 30 minutes by a background process. This command reads those synced files and:
- Creates/updates person and company pages
- Extracts action items to 03-Tasks/Tasks.md
- Links everything together
**No terminal commands are shown** - the heavy lifting happens in the background.
Arguments
- No arguments: Process all unprocessed meetings from the last 7 days
- `today`: Only process today's meetings
- `"search term"`: Find meetings by title/attendee
- `--people-only`: Only update person/company pages (skip tasks)
- `--no-todos`: Create notes but don't extract tasks
- `--setup`: Install/check background automation
Pre-flight: Granola Check
Granola sync uses the official Granola public API. Desktop and mobile recordings both come through it once your Granola API key is connected. If `GRANOLA_API_KEY` isn't set (checked in the environment, then the `.env` file at the vault root), say: "Granola isn't connected yet — run `/granola-setup` to add your Granola API key (requires a Granola Business plan)." and continue with any meetings already synced.
---
Process
Step 1: Check Background Sync Status
First, check if background sync is set up:
# Check for state file (indicates sync has run)
ls .scripts/meeting-intel/processed-meetings.json
**If state file exists:** Background sync is working. Continue to Step 2.
**If state file doesn't exist:** > "Background meeting sync isn't set up yet. This runs automatically every 30 minutes so `/process-meetings` doesn't need terminal commands. > > **To set up (one-time, takes 30 seconds):** > ```bash > cd .scripts/meeting-intel && ./install-automation.sh > ``` > > Or run `/process-meetings --setup` and I'll do it for you. > > **Requirements:** > - A Granola Business plan, with your Granola API key connected via `/granola-setup` > - An LLM API key in `.env` (GEMINI_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY)"
If user runs `--setup`:
cd .scripts/meeting-intel && ./install-automation.sh
Step 2: Find Waiting Meetings
Read the processed meetings state:
const state = JSON.parse(fs.readFileSync('.scripts/meeting-intel/processed-meetings.json'));List meeting files in `00-Inbox/Meetings/`:
find 00-Inbox/Meetings -name "*.md" -mtime -7 | head -50
This includes Granola-synced notes in day directories and flat `*.md` notes in the `00-Inbox/Meetings/` folder root. Root-level notes are manually captured meetings with no `granola_id`; process and stamp them with the same `tasks-extracted` marker as any other meeting note. The `queue/` subfolder is handled in Step 2.5.
For each meeting file, skip notes containing `<!-- dex:skip-processing -->`: 1. Read frontmatter to get `granola_id`, `participants`, `company`, `date` 2. Check if person/company pages need updating 3. Check if tasks need extracting (look for unchecked items in "For Me" section)
Report findings: > "Found X waiting meetings from the last 7 days. Y need person page updates, Z have unextracted tasks."
Step 2.5: Consume Queued Meetings (manual mode)
If `00-Inbox/Meetings/queue/*.json` files exist, consume each queued meeting before continuing:
1. Read the complete JSON: `id`, `title`, `createdAt`, `participants`, `attendees`, `company`, `notes`, and `transcript`. 2. Check whether a meeting note with that JSON object's `id` as its `granola_id` already exists. If it does, delete the queue JSON and continue to the next one. 3. Otherwise, create the meeting note under `00-Inbox/Meetings/{date}/` (with `{date}` and `time` derived from `createdAt`) in the standard format, including frontmatter for `date`, `time`, `type: meeting-note`, `source: granola`, `title`, `participants`, `attendees`, `company`, and `granola_id` from the JSON `id`. Include the queued `notes` and `transcript` in the note body. 4. Delete the queue JSON only after its note has been written successfully.
The new note then flows through the normal processing steps. Never delete a queue file before its meeting note is written.
Step 3: Update Person Pages
For each participant in synced meetings:
1. **Load user profile** for email domain:
Read System/user-profile.yaml → get email_domain
2. **Classify as Internal/External:**
- If participant email domain matches user's domain → Internal
- Otherwise → External
3. **Look up the person with the Work MCP `lookup_person` tool.**
- If lookup returns `ambiguous: true`, do not create a page. Surface the possible matches to the user.
- If a match exists, update that existing page.
4. **If no match exists, call the Work MCP `create_person` tool:**
- Pass `name`, `role` when known, `emails` from the meeting's `attendees` block, and `location` from that attendee's `location` field.
- Pass the meeting company and a short source note when available.
<!-- What the create_person tool creates (reference only; do not hand-write this templ
Read more
name: process-meetings
description: "Turn synced meetings into updated person pages, extracted tasks and organized notes. Use when the user says 'process my meetings', 'catch up my notes', or after Granola/Otter syncs. Also use proactively when unprocessed meetings exist. Not for prepping an upcoming meeting; use `meeting-prep`."
model_hint: balanced
context: fork
hooks:
PostToolUse:
- matcher: Write
type: command
command: "node .claude/hooks/post-meeting-person-update.cjs"Process Meetings
Process meetings that have been synced from Granola by the background automation. Updates person pages, extracts tasks, and organizes meeting notes.
Background Execution
This skill supports background execution. When invoked: 1. Acknowledge: "Processing [N] meetings in the background. I'll let you know when done." 2. Process all meetings 3. On completion, provide summary: "[N] meetings processed. [X] person pages updated. [Y] action items created."
How It Works
Meetings are synced automatically every 30 minutes by a background process. This command reads those synced files and:
- Creates/updates person and company pages
- Extracts action items to 03-Tasks/Tasks.md
- Links everything together
**No terminal commands are shown** - the heavy lifting happens in the background.
Arguments
- No arguments: Process all unprocessed meetings from the last 7 days
- `today`: Only process today's meetings
- `"search term"`: Find meetings by title/attendee
- `--people-only`: Only update person/company pages (skip tasks)
- `--no-todos`: Create notes but don't extract tasks
- `--setup`: Install/check background automation
Pre-flight: Granola Check
Granola sync uses the official Granola public API. Desktop and mobile recordings both come through it once your Granola API key is connected. If `GRANOLA_API_KEY` isn't set (checked in the environment, then the `.env` file at the vault root), say: "Granola isn't connected yet — run `/granola-setup` to add your Granola API key (requires a Granola Business plan)." and continue with any meetings already synced.
---
Process
Step 1: Check Background Sync Status
First, check if background sync is set up:
# Check for state file (indicates sync has run) ls .scripts/meeting-intel/processed-meetings.json
**If state file exists:** Background sync is working. Continue to Step 2.
**If state file doesn't exist:** > "Background meeting sync isn't set up yet. This runs automatically every 30 minutes so `/process-meetings` doesn't need terminal commands. > > **To set up (one-time, takes 30 seconds):** > ```bash > cd .scripts/meeting-intel && ./install-automation.sh > ``` > > Or run `/process-meetings --setup` and I'll do it for you. > > **Requirements:** > - A Granola Business plan, with your Granola API key connected via `/granola-setup` > - An LLM API key in `.env` (GEMINI_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY)"
If user runs `--setup`:
cd .scripts/meeting-intel && ./install-automation.sh
Step 2: Find Waiting Meetings
Read the processed meetings state:
const state = JSON.parse(fs.readFileSync('.scripts/meeting-intel/processed-meetings.json'));List meeting files in `00-Inbox/Meetings/`:
find 00-Inbox/Meetings -name "*.md" -mtime -7 | head -50
This includes Granola-synced notes in day directories and flat `*.md` notes in the `00-Inbox/Meetings/` folder root. Root-level notes are manually captured meetings with no `granola_id`; process and stamp them with the same `tasks-extracted` marker as any other meeting note. The `queue/` subfolder is handled in Step 2.5.
For each meeting file, skip notes containing `<!-- dex:skip-processing -->`: 1. Read frontmatter to get `granola_id`, `participants`, `company`, `date` 2. Check if person/company pages need updating 3. Check if tasks need extracting (look for unchecked items in "For Me" section)
Report findings: > "Found X waiting meetings from the last 7 days. Y need person page updates, Z have unextracted tasks."
Step 2.5: Consume Queued Meetings (manual mode)
If `00-Inbox/Meetings/queue/*.json` files exist, consume each queued meeting before continuing:
1. Read the complete JSON: `id`, `title`, `createdAt`, `participants`, `attendees`, `company`, `notes`, and `transcript`. 2. Check whether a meeting note with that JSON object's `id` as its `granola_id` already exists. If it does, delete the queue JSON and continue to the next one. 3. Otherwise, create the meeting note under `00-Inbox/Meetings/{date}/` (with `{date}` and `time` derived from `createdAt`) in the standard format, including frontmatter for `date`, `time`, `type: meeting-note`, `source: granola`, `title`, `participants`, `attendees`, `company`, and `granola_id` from the JSON `id`. Include the queued `notes` and `transcript` in the note body. 4. Delete the queue JSON only after its note has been written successfully.
The new note then flows through the normal processing steps. Never delete a queue file before its meeting note is written.
Step 3: Update Person Pages
For each participant in synced meetings:
1. **Load user profile** for email domain:
Read System/user-profile.yaml → get email_domain
2. **Classify as Internal/External:**
- If participant email domain matches user's domain → Internal
- Otherwise → External
3. **Look up the person with the Work MCP `lookup_person` tool.**
- If lookup returns `ambiguous: true`, do not create a page. Surface the possible matches to the user.
- If a match exists, update that existing page.
4. **If no match exists, call the Work MCP `create_person` tool:**
- Pass `name`, `role` when known, `emails` from the meeting's `attendees` block, and `location` from that attendee's `location` field.
- Pass the meeting company and a short source note when available.
<!-- What the create_person tool creates (reference only; do not hand-write this templ
A personal operating system powered by Claude. Strategic work management, meeting intelligence, relationship tracking, daily planning — all configured for your specific role. No coding required.
Repo: davekilleen/Dex
Other skills on davekilleen-dex.
- /agent-browser
Browser automation using Vercel's agent-browser CLI. Use when you need to interact with web pages, fill forms, take screenshots, or scrape data. Alternative to Playwright MCP - uses Bash commands with ref-based element selection. Triggers on "browse website", "fill form", "click
Open skill - /agent-native-architecture
Build applications where agents are first-class citizens. Use this skill when designing autonomous agents, creating MCP tools, implementing self-modifying systems, or building apps where features are outcomes achieved by agents operating in a loop.
Open skill - /andrew-kane-gem-writer
This skill should be used when writing Ruby gems following Andrew Kane's proven patterns and philosophy. It applies when creating new Ruby gems, refactoring existing gems, designing gem APIs, or when clean, minimal, production-ready Ruby library code is needed. Triggers on
Open skill - /brainstorming
This skill should be used before implementing features, building components, or making changes. It guides exploring user intent, approaches, and design decisions before planning. Triggers on "let's brainstorm", "help me think through", "what should we build", "explore
Open skill - /compound-docs
Capture solved problems as categorized documentation with YAML frontmatter for fast lookup
Open skill - /create-agent-skills
Expert guidance for creating, writing, and refining Claude Code Skills. Use when working with SKILL.md files, authoring new skills, improving existing skills, or understanding skill structure and best practices.
Open skill

