Install
$ agentstack add skill-jackchuka-skills-p-meeting-prep ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Meeting Prep
Setup
Locate this skill's directory (the folder containing this SKILL.md), then run the resolver script from there:
python /scripts/skillctx-resolve.py resolve p-meeting-prep
The resolver outputs each binding as key: value (one per line). Substitute each {binding_key} placeholder below with the resolved value.
If any values are missing or the user requests changes, use:
python /scripts/skillctx-resolve.py set p-meeting-prep
Generate per-meeting prep briefs for today's calendar (one markdown file per meeting + an index), writing to {output_dir}/YYYY-MM-DD/.
When to Use
- User says "meeting prep", "prep my meetings", "prep brief"
- User invokes
/p-meeting-prep - A scheduled cron / launchd job triggers
/p-meeting-prep(typically early morning)
Prerequisites
gwsCLI installed and authenticated (Google Calendar)ghCLI authenticated (gh auth status)- Slack MCP connected (optional — skip gracefully if unavailable)
- Fireflies MCP connected (optional — skip gracefully if unavailable)
- skillctx config initialized for
p-meeting-prep
Arguments
--date YYYY-MM-DD— Target date. Default: today.--lang ja|en— Output language. Default:{default_lang}.--dry-run— Print briefs to stdout instead of writing files.--no-open— Skip auto-opening the index after generation.
Workflow
Phase 1: Initialize
- Parse arguments:
--date YYYY-MM-DD(default: today, local time)--lang ja|en(default:{default_lang})--dry-run(default: false)--no-open(default: false)
- Compute:
TARGET_DATE: the date to process,YYYY-MM-DDWEEKDAY: short weekday name (e.g.Tue)OUTPUT_DAY_DIR:{output_dir}/{TARGET_DATE}(expand~and env vars)
- Confirm prerequisites:
gwsis on PATH (command -v gws); if missing, fail with a clear error.gh auth statussucceeds; if not, fail with a clear error.- Slack MCP is reachable (one cheap call, e.g.
slack_read_user_profile); if not, mark Slack asUNAVAILABLEand continue. - Fireflies MCP is reachable (one cheap call, e.g.
fireflies_get_user); if not, mark Fireflies asUNAVAILABLEand continue.
- Record availability flags as
SOURCES_AVAILABLE = {calendar: bool, github: bool, slack: bool, fireflies: bool}for use in Phase 3.
Phase 2: Calendar fetch + classify
- Fetch the day's events.
→ See references/agent-gather-calendar.md
- Filter out junk:
- Declined events (the user's response is
declined). - All-day events.
- Events with only one attendee = the user (focus blocks, holds).
- Classify everything else in a single LLM call.
→ See references/agent-classify-meetings.md
- Cluster meetings by
topic_key. A cluster is any set of 2+ meetings sharing the sametopic_key. Singletons are clusters of one and need no cross-links. - Save the classified list as
MEETINGS = [{event, category, topic_key, cluster_id, …}]for Phase 3.
Phase 3: Parallel source fetch
First, read the attendee cache once — ~/.cache/p-meeting-prep/attendees.json (see references/attendee-cache.md) — and pass relevant entries to the GitHub and Slack fetches so cached attendees skip live resolution entirely.
For each meeting, pick the source set from this table:
| Category | Fireflies | Slack DMs/mentions | GitHub (attendees) | Slack topic search | Web (candidate) | | ---------- | --------- | ------------------ | ------------------ | ------------------ | --------------- | | 1:1 | yes | yes | yes | no | no | | team-sync | yes | no | yes (self) | yes | no | | external | yes | yes | no | yes | no | | interview | yes | no | no | no | yes | | other | no | no | no | no | no |
Fan out all required fetches in parallel within a single tool-use batch where possible. Deduplicate by topic_key: a Fireflies or Slack topic search keyed off topic_key is run once per cluster, not once per meeting.
For each source, follow the corresponding reference:
- Fireflies →
references/agent-gather-fireflies-meeting-context.md - Slack →
references/agent-gather-slack-meeting-context.md - GitHub →
references/agent-gather-github-attendee-context.md - Web (candidate) →
references/agent-gather-web-candidate-context.md
If a source's SOURCES_AVAILABLE flag is false (from Phase 1), skip every call to it and mark the corresponding sections as _(unavailable)_ later in Phase 4.
Each fetch has a soft budget of 15 seconds; on timeout, treat as unavailable for that meeting.
Save results as MEETING_CONTEXT[event_id] = {fireflies, slack_attendees, slack_topic, github, web_candidate}.
Phase 4: Synthesize briefs
For each meeting in MEETINGS:
- Pick the template by
category:
1:1→references/template-1on1.mdteam-sync→references/template-team-sync.mdexternal→references/template-external.mdinterview→references/template-interview.mdother→references/template-other.md
- Render the template using
MEETING_CONTEXT[event_id], in language{lang}. - If the meeting belongs to a cluster of size ≥ 2, add the
Related today:line referencing the sibling filenames computed in Phase 5. - Empty data sections render as
_(no relevant context found)_rather than being omitted, so the user can tell the skill looked.
Store the rendered markdown per event as BRIEFS[event_id]. This completes Pass 1.
Pass 2 — cross-scan (after all briefs are drafted):
Filenames are deterministic from Phase 2 data (chronological order + start time + title slug) — compute them before Pass 2 so both cluster links and overlap links can reference sibling files.
- Detect overlaps across the day's drafts:
- (a) shared non-self attendees appearing in 2+ meetings;
- (b) shared salient topics/entities — proper nouns, repo names, project names appearing in 2+ briefs' bodies (e.g.
changelog-management).
- For each overlap, inject into the header block of every affected brief:
Related today: []() — Multiple siblings → comma-separated. Merge with any existing cluster-based Related today: line rather than duplicating it.
other-category meetings are excluded from the cross-scan (they have no body and no fetches).- Record the overlap list as
OVERLAPSfor the index (Phase 5).
Phase 5: Write files
- Compute
OUTPUT_DAY_DIR={output_dir}/(expand~). - If
OUTPUT_DAY_DIRalready exists:
- Remove any existing
.bak/. mvthe currentOUTPUT_DAY_DIRto.bak/.
- Create
OUTPUT_DAY_DIR. - Compute filenames in chronological order:
NN= zero-padded sequence starting at 01 (the index uses00).HHMM= local start time, 24-hour, no colon.- `
= ASCII-folded, lowercase, hyphenated title; collapse runs of non-[a-z0-9]to a single-; trim to 40 chars; strip leading/trailing-`. - If ASCII-folding leaves fewer than 4 useful characters (typical for Japanese titles), romanize instead: kanji/kana → romaji words, katakana loanwords → their English source word. Example:
採用:グッズブレストMTG→saiyo-goods-brainstorm-mtg. Same 40-char cap and collision rule. - Final name:
NN-HHMM-.md.
- Write
00-index.mdfirst:
# Meeting prep — ()
meetings · categories · clusters
## Today
- HH:MM **** `[category]` → [NN-HHMM-slug.md](NN-HHMM-slug.md)` if cluster size ≥ 2>
... (one bullet per meeting, chronological)
## Clusters
- `` — meetings (HH:MM, HH:MM, ...)
... (only clusters with size ≥ 2)
## Overlaps
- — meetings (HH:MM, HH:MM, ...)
... (from Pass 2 cross-scan; omit the section when `OVERLAPS` is empty)
If N == 0, the index body is No meetings today. and no per-meeting files are written.
- Write one file per meeting using
BRIEFS[event_id]. - Merge any live attendee resolutions from this run back into
~/.cache/p-meeting-prep/attendees.json(read-modify-write; seereferences/attendee-cache.md). - Print the absolute path to
00-index.mdand a one-line summary (N meetings · K categories · C clusters). - On macOS (
uname -s=Darwin), unless--no-openor--dry-run, runopen "". - If
--dry-run, do NOT touch the filesystem at all. Instead, print to stdout: the index body, then each brief separated by---.
Error Handling
| Error | Action | | ------------------------------------------- | --------------------------------------------------------------------------------------- | | gws not installed or not authenticated | Abort with clear error message. The calendar is required. | | gh not authenticated | Mark GitHub UNAVAILABLE; continue. Add a warning to the top of 00-index.md. | | Slack MCP unavailable | Mark Slack UNAVAILABLE; continue. Slack sections render as _(unavailable)_. | | Fireflies MCP unavailable | Mark Fireflies UNAVAILABLE; continue. Fireflies sections render as _(unavailable)_. | | Classification LLM call fails / bad JSON | Treat every meeting as other. Add a warning to the top of 00-index.md. | | Per-meeting source fetch timeout (15s) | Section renders as _(unavailable)_. No retry within this run. | | OUTPUT_DAY_DIR exists from a prior run | Rename to .bak/ (replacing any prior backup) before writing. | | Attendee cache missing / corrupt JSON | Treat as empty cache; resolve live; rewrite the file at end of run. | | Calendar empty for the target date | Write 00-index.md with body No meetings today. Exit 0. | | --dry-run set | Print to stdout only. Do not touch the filesystem. Do not call open. | | Filename slug collision (rare) | Append -2, -3, … to the slug until unique within the day's directory. |
Scheduling
This skill is user-triggered. Two recipes for running it automatically each morning are documented in references/cron-recipes.md. Whichever you pick, ensure the scheduled environment inherits credentials for gh, gws, the Slack MCP server, and the Fireflies MCP server.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jackchuka
- Source: jackchuka/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.