Skip to main content
ClaudeWave
Skill1.3k estrellas del repoactualizado today

minutes-graph

minutes-graph enables cross-meeting entity queries on people and topics extracted from your meeting history, answering relationship questions that full-text search cannot. Use it when asking about co-occurrences between entities, first mentions of terms, frequency trends over time, or any query requiring structured data across all meetings rather than simple text matching.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/silverstein/minutes /tmp/minutes-graph && cp -r /tmp/minutes-graph/tooling/skills/sources/minutes-graph ~/.claude/skills/minutes-graph
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

skill.md

# /minutes-graph

Cross-meeting entity graph that lets you query your meeting history as structured data — **people and topics** out of the box, with companies and products as an opt-in deep-extraction path.

Minutes already exposes `minutes people`, `minutes person`, and `minutes insights` for first-class entity queries. **Graph layers on top of those** to answer questions the CLI can't:

- "What's the co-occurrence between Sarah and pricing?"
- "First time the term 'X' appears in my history"
- "Frequency trend for topic Y over the last 6 months"
- "Who's been mentioned in the same meetings as Sarah?"
- "What topics came up when we talked about hiring?"

Defer to the existing CLI when it suffices. Use graph for the queries the CLI can't answer. Anything about companies or products requires opt-in deep extraction (see Phase 1).

## How it works

Graph has two modes: **build** (creates the index) and **query** (uses it).

### Phase 0: Determine the user's intent

If the user explicitly says "build" / "rebuild" / "refresh the graph" → Phase 1 (build mode).

Otherwise → Phase 2 (query mode). Query mode auto-builds the index if it doesn't exist, and incrementally refreshes it if new meetings exist since the last build.

**Detect company/product queries upfront.** If the user's question mentions a specific company name, product, brand, or anything that wouldn't be in standard meeting frontmatter (e.g., "Stripe", "Notion", "the deal with Acme"), tell them upfront — before any building happens — that this needs deep extraction:

> "That query is about a company/product, which isn't in standard meeting frontmatter. I'd need to deep-scan transcripts (~<estimate> seconds for <N> meetings) to answer. Continue, or rephrase to use topics/people that are already indexed?"

This avoids the worst flow: build → discover the data isn't there → ask user → rebuild.

### Phase 1: Build the index via the bundled helper script

The index lives at `~/.minutes/graph/index.json`. **Use the bundled `graph_build.py` script — do not try to walk meeting files or parse YAML frontmatter in-context.** The script is deterministic, fast, atomic, and handles all the edge cases (incremental rebuilds, garbage filtering, name disambiguation, augmentation from `minutes people --json`).

**Always warn before building**, even on the auto-trigger path. Users hate commands that hang silently more than they hate one-line confirmations:

> "Building entity graph from <N> meetings. The frontmatter-only path is fast (a few seconds for hundreds of meetings). Continue? (Ctrl+C to abort)"

To get the meeting count for the warning, use Glob on the meetings dir from `minutes paths`.

**Run the script:**

```bash
python3 "${CLAUDE_PLUGIN_ROOT}/skills/minutes-graph/scripts/graph_build.py" --incremental
```

Defaults:
- `--meetings-dir` defaults to `output_dir` from `minutes paths`
- `--output` defaults to `~/.minutes/graph/index.json`
- `--incremental` skips the rebuild entirely if no meeting files have been modified since the last build (the common case after the first build)

The script prints a one-line summary JSON to stdout:

```json
{"status": "ok", "meeting_count": 142, "person_count": 12, "topic_count": 38, "output": "/Users/.../index.json"}
```

Or `{"status": "fresh", ...}` if `--incremental` found nothing to rebuild.

**What the script does, in order:**

1. Walks every meeting file in the meetings directory
2. Parses the YAML frontmatter using a small line-based extractor (no PyYAML dep)
3. Extracts: `date`, `attendees` (display names), `people` (wikilink slugs), `tags`, and `decisions[].topic` — all the entity-relevant fields the real meeting schema actually has
4. Filters out `none`/`null`/`~` topic values that show up in some malformed meetings
5. When `attendees` and `people` have the same length, zips them positionally to map each slug to its display name (gives `mat` → `Mat S.`, etc.)
6. Builds people-people, people-topic, and topic-topic co-occurrence within each meeting
7. Runs `minutes people --json` and merges its `top_topics`, `open_commitments`, `score`, `losing_touch` fields into the people entries it already built
8. Filters diarization noise (`unknown-speaker`, `speaker-3`, etc.) out of the final people index
9. Picks a canonical display name for each person using a "looks human" heuristic (capital letter + space wins; lowercase slug-style loses)
10. Atomically writes the index to JSON (temp file + rename)

**What's NOT in the default build**: companies and products. Some real meetings **do** have an `entities:` block in their frontmatter — the current schema looks like:

```yaml
entities:
  people:
    - slug: speaker-0
      label: Speaker 0
      aliases: [speaker 0]
  projects:
    - slug: codex-native-call-attribution
      label: Codex Native Call Attribution
```

But the schema is **inconsistent across the corpus** — many meetings have no `entities:` block, and when it's present its structure varies (some meetings have `people`, some add `projects`, there's no guarantee of `companies` or `products`). `graph_build.py` intentionally uses a narrower set of fields (`attendees`, `people` slugs, `tags`, `decisions[].topic`) that are more consistently populated across the full meeting corpus, so the default build is predictable.

If you want the entities block data in the graph, modify `graph_build.py` to also parse it — but be ready to handle variant schemas across meetings. For on-demand company/product queries that go beyond what frontmatter has, use the opt-in deep extraction path below.

Two paths from here:

1. **Default path (the script above)**: people, topics, dates. Fast, deterministic, runs on every install with zero deps.

2. **Opt-in deep extraction**: only if Phase 0 detected a company/product query and the user confirmed, run a one-time LLM pass over each meeting's transcript section to extract company and product names. Cache results in the index keyed by meeting filename. Every subsequent query reu
minutes-briefSkill

Fast non-interactive briefing before any meeting — auto-detects your next calendar event, pulls relationship history, surfaces open commitments, and produces a one-page brief in under 30 seconds. Use this whenever the user says "brief me", "give me a quick brief", "what's coming up", "background on my next call", "who am I meeting next", "brief me on Sarah", "I have a call in 10 min", "quick rundown", or right before walking into a meeting. Different from /minutes-prep — brief is the fast hook-fireable version that doesn't ask questions and doesn't set goals. Use brief when speed matters; use prep when the user wants to think hard about goals first.

minutes-cleanupSkill

Manage old recordings — find large files, archive old meetings, delete processed originals. Use when the user says "clean up recordings", "how much space are meetings using", "delete old recordings", "archive meetings", "manage meeting storage", or asks about disk space from minutes.

minutes-debriefSkill

Post-meeting debrief — analyzes what happened, compares outcomes to your prep intentions, tracks decision evolution. Use when the user says "debrief", "what just happened in that meeting", "what did we decide", "debrief that call", "post-meeting", "what changed", or right after stopping a recording.

minutes-ideasSkill

Surface recent voice memos and ideas captured from any device. Use when the user asks "what ideas did I have?", "what were my recent memos?", "what did I record while walking?", or wants to recall a captured thought.

minutes-ingestSkill

Extract facts from meetings and update your knowledge base — person profiles, chronological log, and index. Use when the user asks "ingest my meetings", "update my knowledge base", "extract facts from meetings", "sync meetings to wiki", "backfill knowledge", or wants their PARA/Obsidian/wiki profiles updated from conversation data.

minutes-lintSkill

Health-check your meeting knowledge for contradictions, stale commitments, and decision conflicts. Use when the user asks "any conflicts in my meetings", "check for stale action items", "lint my meetings", "consistency check", "are there contradictions", or wants to audit their decision history.

minutes-listSkill

List recent meetings and voice memos. Use when the user asks "what meetings did I have", "show my recent recordings", "any meetings today", "list my voice memos", or wants an overview of their meeting history. Also use when they need to find a specific meeting by browsing rather than searching.

minutes-mirrorSkill

Self-coaching analysis of your own behavior across meetings — talk-time ratio, filler words, hedging language, monologue length, energy patterns, and (when meetings are tagged via /minutes-tag) what your behavior in winning meetings looks like vs losing ones. Use this whenever the user says "how did I do", "review my last meeting", "mirror", "self-review", "show my patterns", "coach me", "where am I weak", "talk time", "am I improving", "what do I do in meetings I win", "feedback on me", or asks for any kind of personal feedback on their own meeting behavior. This is the rare skill that gives the user a mirror to their own habits — surface it whenever they show curiosity about their own performance, even if they don't use the word "mirror".