[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-74686":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":15,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":39,"readmeContent":40,"aiSummary":41,"trendingCount":16,"starSnapshotCount":16,"syncStatus":42,"lastSyncTime":43,"discoverSource":44},74686,"minutes","silverstein\u002Fminutes","silverstein","Every meeting, every idea, every voice note — searchable by your AI. Open-source, privacy-first conversation memory layer.","https:\u002F\u002Fuseminutes.app",null,"Rust",1265,132,3,25,0,9,80,27,19.37,"MIT License",false,"main",true,[26,27,28,29,30,31,32,33,34,35,36,37,38],"agent-skills","ai","claude","mcp","meeting-notes","meetings","parakeet","privacy","rust","speech-to-text","transcription","voice-memo","whisper","2026-06-12 02:03:26","# minutes\n\n[![GitHub stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Fsilverstein\u002Fminutes?style=social)](https:\u002F\u002Fgithub.com\u002Fsilverstein\u002Fminutes)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-blue.svg)](LICENSE)\n\n**Open-source conversation memory.** &nbsp; [useminutes.app](https:\u002F\u002Fuseminutes.app)\n\nAgents have run logs. Humans have conversations. **minutes** captures the human side — the decisions, the intent, the context that agents need but can't observe — and makes it queryable.\n\nRecord a meeting. Capture a voice memo on a walk. Ask Claude *\"what did I promise Sarah?\"* — and get an answer. Your AI remembers every conversation you've had.\n\nMinutes is not just a meeting-notes app. It is local conversation infrastructure for agents: audio capture, transcripts, decisions, commitments, people, and provenance exposed through plain files, CLI commands, MCP tools, and live transcript streams.\n\n> **Own every conversation you've ever had.** Cloud meeting tools rent your own conversations back to you. Minutes writes every meeting to `~\u002Fmeetings\u002F` as plain markdown, which every AI you use (Claude Code, Codex, Gemini CLI, Cursor, OpenCode, Pi) reads directly. No SDK. No API key. No vendor to outlive. Ten years from now, `grep` still works on your corpus. &nbsp;[**For agents →**](https:\u002F\u002Fuseminutes.app\u002Ffor-agents) &nbsp;·&nbsp; [**Frontmatter schema →**](docs\u002Ffrontmatter-schema.md)\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fdemo.gif\" alt=\"minutes demo — record, dictate, phone sync, AI recall\" width=\"750\">\n\u003C\u002Fp>\n\n### Works with\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"#claude-code-plugin\">Claude Code\u003C\u002Fa> &bull;\n  \u003Ca href=\"#any-mcp-client-claude-code-codex-gemini-cli-claude-desktop-or-your-own-agent\">Codex\u003C\u002Fa> &bull;\n  \u003Ca href=\"#opencode-cli\">OpenCode\u003C\u002Fa> &bull;\n  \u003Ca href=\"#pi-coding-agent\">Pi\u003C\u002Fa> &bull;\n  \u003Ca href=\"#any-mcp-client-claude-code-codex-gemini-cli-claude-desktop-or-your-own-agent\">Gemini CLI\u003C\u002Fa> &bull;\n  \u003Ca href=\"#any-mcp-client-claude-code-codex-gemini-cli-claude-desktop-or-your-own-agent\">Claude Desktop\u003C\u002Fa> &bull;\n  \u003Ca href=\"#mistral-vibe\">Mistral Vibe\u003C\u002Fa> &bull;\n  \u003Ca href=\"#vault-sync-obsidian--logseq\">Obsidian\u003C\u002Fa> &bull;\n  \u003Ca href=\"#vault-sync-obsidian--logseq\">Logseq\u003C\u002Fa> &bull;\n  \u003Ca href=\"#phone--desktop-voice-memo-pipeline\">Phone Voice Memos\u003C\u002Fa> &bull;\n  Any MCP client\n\u003C\u002Fp>\n\n## Quick start\n\n```bash\n# macOS — Desktop app (menu bar, recording UI, AI assistant)\nbrew install --cask silverstein\u002Ftap\u002Fminutes\n\n# macOS — CLI only\nbrew tap silverstein\u002Ftap && brew install minutes\n\n# Any platform — from source (requires Rust + cmake; Windows also needs LLVM)\ncargo install minutes-cli                          # macOS\u002FLinux\ncargo install minutes-cli --no-default-features    # Windows (see install notes below)\n\n# MCP server only — no Rust needed (Claude Code, Codex, OpenCode, Gemini CLI, Claude Desktop, etc.)\nnpx minutes-mcp\n```\n\n```bash\nminutes setup --model small   # Download whisper model (466MB, recommended)\nminutes record                # Start recording\nminutes stop                  # Stop and transcribe\n```\n\n## Docs and agent surfaces\n\nThe README is now the product overview and install guide, not the only home for agent-facing reference.\n\n- Agent entry point: \u003Chttps:\u002F\u002Fuseminutes.app\u002Ffor-agents>\n- MCP tools reference: \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Fmcp\u002Ftools>\n- MCP tools markdown mirror: \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Fmcp\u002Ftools.md>\n- Error reference: \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Ferrors>\n- Concise agent index: \u003Chttps:\u002F\u002Fuseminutes.app\u002Fllms.txt>\n- Full agent index: \u003Chttps:\u002F\u002Fuseminutes.app\u002Fllms-full.txt>\n\n## Choose your surface\n\n- `Desktop app` — `brew install --cask silverstein\u002Ftap\u002Fminutes`\n  Best for first recording, live capture, Recall, and post-meeting artifact work.\n- `MCP server` — `npx minutes-mcp`\n  Best for agent-first search, recall, and meeting-memory workflows in Claude Desktop, Codex, OpenCode, Gemini CLI, and other MCP clients.\n- `CLI` — `brew tap silverstein\u002Ftap && brew install minutes`\n  Best for terminal-first local operator workflows, import, search, and vault sync.\n- `Claude Code plugin` — `claude plugin marketplace add silverstein\u002Fminutes`\n  Best for workflow guidance, prep, debrief, and meeting coaching with the lifecycle skills and hooks.\n- `OpenCode project integration` — built-in `.opencode\u002Fskills\u002F` + `.opencode\u002Fcommands\u002F`\n  Best for OpenCode users who want native `\u002Fminutes-*` commands plus the portable Minutes skill pack in the repo.\n\n## How it works\n\n```\nAudio → Transcribe → Diarize → Summarize → Structured Markdown → Relationship Graph\n         (local)     (local)     (LLM)       (decisions,            (people, commitments,\n        whisper.cpp  pyannote-rs Claude\u002F       action items,          topics, scores)\n        \u002Fparakeet    (native)    Ollama\u002F       people, entities)      SQLite index\n                                Mistral\u002FOpenAI\n```\n\nEverything runs locally. Your audio never leaves your machine (unless you opt into cloud LLM summarization). Speakers are identified via native diarization. The relationship graph indexes people, commitments, and topics across all meetings for instant queries.\n\n## Features\n\n### Record meetings\n```bash\nminutes record                                    # Record from mic\nminutes record --title \"Standup\" --context \"Sprint 4 blockers\"  # With context\nminutes record --language ur                      # Force Urdu (ISO 639-1 code)\nminutes record --device \"AirPods Pro\"             # Use specific audio device\nminutes record --template standup                 # Apply a summary template\nminutes stop                                      # Stop from another terminal\n```\n\n**Recording calls (Zoom, Meet, Teams, Webex):** macOS does not let apps capture system audio directly, so the default mic-only recording only picks up your own voice. To capture the other side of the call too, install BlackHole and route the call through a Multi-Output Device. Full setup in [`docs\u002Faudio-devices.md`](docs\u002Faudio-devices.md).\n\n### Take notes during meetings\n```bash\nminutes note \"Alex wants monthly billing not annual billing\"          # Timestamped, feeds into summary\nminutes note \"Logan agreed\"                       # LLM weights your notes heavily\n```\n\n### Process voice memos\n```bash\nminutes process ~\u002FDownloads\u002Fvoice-memo.m4a        # Any audio format\nminutes watch                                     # Auto-process new files in inbox\n```\n\n### Search everything\n```bash\nminutes search \"pricing\"                          # Full-text search\nminutes search \"onboarding\" -t memo               # Filter by type\nminutes actions                                   # Open action items across all meetings\nminutes actions --assignee sarah                   # Filter by person\nminutes list                                      # Recent recordings\n```\n\n### Relationship intelligence\n\n> *\"What did I promise Sarah?\"* — the query nobody else can answer.\n\n```bash\nminutes people                                     # Who you talk to, how often, about what\nminutes people --rebuild                           # Rebuild the relationship index\nminutes commitments                                # All open + overdue commitments\nminutes commitments --person alex                   # What did I promise Alex?\n```\n\nTracks people, commitments, topics, and relationship health across every meeting. Detects when you're losing touch with someone. Suggests duplicate contacts (\"Sarah Chen\" ↔ \"Sarah\"). Powered by a SQLite index rebuilt from your markdown in \u003C50ms.\n\n### Cross-meeting intelligence\n```bash\nminutes research \"pricing strategy\"               # Search across all meetings\nminutes person \"Alex\"                              # Build a profile from meeting history\nminutes consistency                                # Flag contradicting decisions + stale commitments\n```\n\n### Live transcript (real-time coaching)\n```bash\nminutes live                                     # Start real-time transcription\nminutes stop                                     # Stop live session\n```\nStreams local transcription to a JSONL file in real time — any AI agent can read it mid-meeting for live coaching. Depending on your build and config, live mode can run on Whisper, Parakeet, or the experimental Apple Speech standalone-live path. Apple Speech currently applies to standalone live transcript (`minutes live`) and opt-in dictation finalization, not recording-sidecar or batch transcription, and it falls back to a ready Parakeet backend before Whisper if Apple Speech is unavailable or fails mid-session in live mode. See [docs\u002FAPPLE_SPEECH.md](docs\u002FAPPLE_SPEECH.md) for the current Apple Speech scope. The MCP `read_live_transcript` tool provides delta reads (by line cursor or wall-clock duration). Works with Claude Code, Codex, OpenCode, Gemini CLI, or any agent that reads files. The Tauri desktop app has a Live Mode toggle that starts this with one click.\n\n### Dictation mode\n```bash\nminutes dictate                                  # Speak → text appears as you talk\nminutes dictate --stdout                         # Output to stdout instead of clipboard\n```\nText streams progressively as you speak (partial results every 2 seconds). By default it accumulates across pauses and writes the combined text to clipboard + daily note when dictation ends. Set `[dictation] accumulate = false` to keep the older per-pause behavior. The default backend is local Whisper; on supported macOS builds, `[dictation] backend = \"apple-speech\"` tries Apple DictationTranscriber for final utterances, and `[dictation] backend = \"parakeet\"` tries the installed Parakeet backend for final utterances. Both opt-in paths keep Whisper partials and fallback. Linux clipboard output works through `wl-clipboard` on Wayland or `xclip` \u002F `xsel` on X11; desktop auto-paste only attempts X11 paste automation when `xdotool` is available. Local engines, no cloud.\n\n### Command palette (desktop app)\nPress `⌘⇧K` from anywhere on macOS to open a keyboard-first palette of every Minutes command. Start a recording, drop a note into the active session, jump to the latest meeting, search transcripts, or rename the meeting open in your assistant — all without leaving the keyboard. Backed by a single typed command registry in `minutes-core`, so visibility follows real backend state: stop-recording only appears while you're recording, mid-recording dictation rows are hidden, and the list re-fetches automatically when state changes.\n\nRecents float to the top with their original payload intact (re-running a `Search transcripts: pricing` from history skips the retype). The shortcut defaults on for both fresh installs and upgrades, with a one-time macOS notification on first launch announcing the binding. Disable it from the Settings overlay (Command Palette section) or by setting `[palette] shortcut_enabled = false` in your config file (`$XDG_CONFIG_HOME\u002Fminutes\u002Fconfig.toml` when `XDG_CONFIG_HOME` is set, otherwise `~\u002F.config\u002Fminutes\u002Fconfig.toml`). The Settings dropdown also offers `⌘⇧O` and `⌘⇧U` if `⌘⇧K` collides with your IDE.\n\n### Templates (RFC 0001, Phase 1)\n```bash\nminutes template list                             # Bundled + project + user templates\nminutes template show standup                     # Inspect a template\nminutes record --template standup                 # Apply when recording\nminutes process voice-memo.m4a --template voice-memo\n```\nTemplates layer prompt-level guidance on top of the baseline structured extraction (`KEY POINTS`, `DECISIONS`, `ACTION ITEMS`, `OPEN QUESTIONS`, `COMMITMENTS`, `PARTICIPANTS`). Phase 1 ships four bundled templates (`meeting`, `standup`, `1-on-1`, `voice-memo`) and resolves overrides from `.minutes\u002Ftemplates\u002F` (project) and `~\u002F.minutes\u002Ftemplates\u002F` (user). Custom `extract:` schemas, compliance rules, and clinical templates land in later phases — see [`docs\u002Frfcs\u002F0001-templates.md`](docs\u002Frfcs\u002F0001-templates.md).\n\n### Try it without a mic\n```bash\nminutes demo --full                              # Seed 5 sample meetings (Snow Crash theme)\nminutes demo --query                             # Cross-meeting intelligence demo\nminutes demo --clean                             # Remove sample meetings\n```\n\nThe interactive demo seeds interconnected meetings, then lets you pick a thread to explore. Two storylines, five meetings, zero setup.\n\n### System diagnostics\n```bash\nminutes health                                   # Check model, mic, calendar, disk\nminutes demo                                     # Run a pipeline test (bundled audio, no mic)\n```\n\n## Switching from Granola?\n\nImport your meeting history into Minutes' conversation memory. Once imported, your meetings become searchable context for AI agents, feed the relationship graph for meeting prep, and surface action items and decision patterns across months of conversations.\n\n```bash\nminutes import granola --dry-run    # Preview what will be imported\nminutes import granola              # Import all meetings to ~\u002Fmeetings\u002F\n```\n\nReads from `~\u002F.granola-archivist\u002Foutput\u002F`. Meetings are converted to Minutes' markdown format with YAML frontmatter. Duplicates are skipped automatically. All your data stays local — no cloud, no $18\u002Fmo.\n\n### Want transcripts and AI summaries?\n\n[granola-to-minutes](https:\u002F\u002Fgithub.com\u002Fcalvindotsg\u002Fgranola-to-minutes) exports richer data using [granola-cli](https:\u002F\u002Fgithub.com\u002Fmagarcia\u002Fgranola-cli), a community-built CLI tool (not affiliated with Granola Labs) that accesses Granola's internal API:\n\n| | `minutes import granola` | `granola-to-minutes` |\n|---|---|---|\n| **Data source** | Local export (`~\u002F.granola-archivist\u002Foutput\u002F`) | Granola internal API via [granola-cli](https:\u002F\u002Fgithub.com\u002Fmagarcia\u002Fgranola-cli) |\n| **Notes & transcript** | ✓ | ✓ |\n| **AI-enhanced summaries** | — | ✓ |\n| **Action items & decisions** | — | ✓ (extracted via Claude) |\n| **Speaker attribution** | — | ✓ (`speaker_map` in frontmatter) |\n| **Setup** | Export from Granola desktop app | `npm install -g granola-to-minutes` |\n| **Works on free tier** | ✓ | ✓ |\n| **API stability** | N\u002FA (local files) | Internal API — may change without notice |\n\n```bash\nnpx granola-to-minutes export    # Export to ~\u002Fmeetings\u002F\n```\n\n## Output format\n\nMeetings save as markdown with structured YAML frontmatter:\n\n```yaml\n---\ntitle: Q2 Pricing Discussion with Alex\ntype: meeting\ndate: 2026-03-17T14:00:00\nduration: 42m\ncontext: \"Discuss Q2 pricing, follow up on annual billing decision\"\naction_items:\n  - assignee: mat\n    task: Send pricing doc\n    due: Friday\n    status: open\n  - assignee: sarah\n    task: Review competitor grid\n    due: March 21\n    status: open\ndecisions:\n  - text: Run pricing experiment at monthly billing with 10 advisors\n    topic: pricing experiment\n---\n\n## Summary\n- Alex proposed lowering API launch timeline from annual billing to monthly billing\u002Fmo\n- Compromise: run experiment with 10 advisors at monthly billing\n\n## Transcript\n[SPEAKER_0 0:00] So let's talk about the pricing...\n[SPEAKER_1 4:20] I think monthly billing makes more sense...\n```\n\nWorks with [Obsidian](https:\u002F\u002Fobsidian.md), grep, or any markdown tool. Action items and decisions are queryable via the CLI and MCP tools.\n\n## Phone → desktop voice memo pipeline\n\nNo phone app needed. Record a thought on your phone, and it becomes searchable memory on your desktop. Claude even surfaces recent memos proactively — \"you had a voice memo about pricing yesterday.\"\n\nThe watcher is folder-agnostic — it processes any audio file that lands in a watched folder. Pick the sync method that matches your setup:\n\n| Phone | Desktop | Sync method |\n|-------|---------|-------------|\n| **iPhone** | **Mac** | iCloud Drive (built-in, ~5-30s) |\n| **iPhone** | **Windows\u002FLinux** | iCloud for Windows, or Dropbox\u002FGoogle Drive |\n| **Android** | **Any** | Dropbox, Google Drive, Syncthing, or any folder sync |\n| **Any** | **Any** | AirDrop, USB, email — drop the file in the watched folder |\n\n### Setup (one-time)\n\n**Step 1: Create a sync folder** — pick one that syncs between your phone and desktop:\n\n```bash\n# macOS + iPhone (iCloud Drive)\nmkdir -p ~\u002FLibrary\u002FMobile\\ Documents\u002Fcom~apple~CloudDocs\u002Fminutes-inbox\n\n# Any platform (Dropbox)\nmkdir -p ~\u002FDropbox\u002Fminutes-inbox\n\n# Any platform (Google Drive)\nmkdir -p ~\u002FGoogle\\ Drive\u002Fminutes-inbox\n\n# Or just use the default inbox (manually drop files into it)\n# ~\u002F.minutes\u002Finbox\u002F  ← already exists\n```\n\n**Step 2: Add the sync folder to your watch config** in your config file (`$XDG_CONFIG_HOME\u002Fminutes\u002Fconfig.toml` when `XDG_CONFIG_HOME` is set, otherwise `~\u002F.config\u002Fminutes\u002Fconfig.toml`):\n\n```toml\n[watch]\npaths = [\n  \"~\u002F.minutes\u002Finbox\",\n  # Add your sync folder here — uncomment one:\n  # \"~\u002FLibrary\u002FMobile Documents\u002Fcom~apple~CloudDocs\u002Fminutes-inbox\",  # iCloud\n  # \"~\u002FDropbox\u002Fminutes-inbox\",                                       # Dropbox\n  # \"~\u002FGoogle Drive\u002Fminutes-inbox\",                                  # Google Drive\n]\n```\n\n**Step 3: Set up your phone**\n\n\u003Cdetails>\n\u003Csummary>\u003Cstrong>iPhone (Apple Shortcuts)\u003C\u002Fstrong>\u003C\u002Fsummary>\n\n1. Open the **Shortcuts** app on your iPhone\n2. Tap **+** → Add Action → search **\"Save File\"**\n3. Set destination to `iCloud Drive\u002Fminutes-inbox\u002F` (or your Dropbox\u002FGoogle Drive folder)\n4. Turn OFF \"Ask Where to Save\"\n5. Tap the **(i)** info button → enable **Share Sheet** → set to accept **Audio**\n6. Name it **\"Save to Minutes\"**\n\nNow: Voice Memos → Share → **Save to Minutes** → done.\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cstrong>Android\u003C\u002Fstrong>\u003C\u002Fsummary>\n\nUse any voice recorder app + your cloud sync of choice:\n\n- **Dropbox**: Record with any app → Share → Save to Dropbox → `minutes-inbox\u002F`\n- **Google Drive**: Record → Share → Save to Drive → `minutes-inbox\u002F`\n- **Syncthing** (no cloud): Set up a Syncthing share between phone and desktop pointing at your watched folder. Fully local, no cloud.\n- **Tasker\u002FAutomate** (power users): Auto-move new recordings from your recorder app to the sync folder.\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cstrong>Manual (any phone)\u003C\u002Fstrong>\u003C\u002Fsummary>\n\nNo sync setup needed — just get the audio file to your desktop's watched folder:\n- **AirDrop** (Apple): Share → AirDrop to Mac → move to `~\u002F.minutes\u002Finbox\u002F`\n- **Email**: Email the recording to yourself → save attachment to watched folder\n- **USB**: Transfer directly\n\u003C\u002Fdetails>\n\n**Step 4: Start the watcher** (or install as a background service):\n\n```bash\nminutes watch                  # Run in foreground\nminutes service install        # Install all background services (macOS launchd \u002F Linux systemd)\nminutes service status         # Check what's running\nminutes service restart        # Restart all services (e.g. after upgrading the binary)\n```\n\n`minutes service install` sets up three agents:\n\n| Agent | Schedule | What it does |\n|-------|----------|--------------|\n| **watcher** | Always on | Processes voice memos from `~\u002F.minutes\u002Finbox\u002F` |\n| **weekly-summary** | Sundays 7pm | Generates a weekly digest to `~\u002F.minutes\u002Fautomations\u002F` |\n| **proactive-context** | Daily 8am | Builds a context bundle (recent meetings, stale commitments, losing-touch alerts) |\n\n> **Upgrading?** `minutes service install` is idempotent. Re-running it after a binary\n> upgrade rewrites all plists\u002Funits and reloads with the new binary path.\n\n### How it works\n\n```\nPhone (any)                   Desktop (any)\n───────────                   ─────────────\nRecord voice memo        →    Cloud sync \u002F manual transfer\nShare to sync folder               │\n                                   ▼\n                            minutes watch detects file\n                                   │\n                            probe duration (\u003C2 min?)\n                              ├── yes → memo pipeline (fast, no diarization)\n                              └── no  → meeting pipeline (full)\n                                   │\n                            transcribe → save markdown\n                                   │\n                            ├── event: VoiceMemoProcessed\n                            ├── daily note backlink\n                            └── surfaces in next Claude session\n```\n\nShort voice memos (\u003C2 minutes) automatically route through the fast memo pipeline — no diarization, no heavy summarization. Long recordings get the full meeting treatment. The threshold is configurable: `dictation_threshold_secs = 120` in `[watch]`.\n\n### Optional: sidecar metadata\n\nIf your phone workflow also saves a `.json` file alongside the audio (same name, `.json` extension), Minutes reads it for enriched metadata:\n\n```json\n{\"device\": \"iPhone\", \"source\": \"voice-memos\", \"captured_at\": \"2026-03-24T08:41:00-07:00\"}\n```\n\nThis adds `device` and `captured_at` to the meeting's frontmatter. Works with any automation tool (Apple Shortcuts, Tasker, etc.).\n\nSupports `.m4a`, `.mp3`, `.wav`, `.ogg`, `.webm`. Format conversion is automatic — uses [ffmpeg](https:\u002F\u002Fffmpeg.org\u002F) when available (recommended for non-English audio), falls back to [symphonia](https:\u002F\u002Fgithub.com\u002Fpdeljanov\u002FSymphonia).\n\n### Vault sync (Obsidian \u002F Logseq)\n\n```bash\nminutes vault setup              # Auto-detect vaults, configure sync\nminutes vault status             # Check health\nminutes vault sync               # Copy existing meetings to vault\n```\n\nThree strategies: **symlink** (zero-copy), **copy** (works with iCloud\u002FObsidian Sync), **direct** (write to vault). `minutes vault setup` detects your vault and recommends the right strategy automatically.\n\n## Claude integration\n\nminutes is a native extension for the Claude ecosystem. **No API keys needed** — Claude summarizes your meetings when you ask, using your existing Claude subscription.\n\n```\nYou: \"Summarize my last meeting\"\nClaude: [calls get_meeting] → reads transcript → summarizes in conversation\n\nYou: \"What did Alex say about pricing?\"\nClaude: [calls search_meetings] → finds matches → synthesizes answer\n\nYou: \"Any open action items for me?\"\nClaude: [calls list_meetings] → scans frontmatter → reports open items\n```\n\n### Any MCP client (Claude Code, Codex, OpenCode, Gemini CLI, Claude Desktop, or your own agent)\n\nMinutes exposes a standard MCP server. Point any MCP-compatible client at it:\n\n```json\n{\n  \"mcpServers\": {\n    \"minutes\": {\n      \"command\": \"npx\",\n      \"args\": [\"minutes-mcp\"]\n    }\n  }\n}\n```\n\nCanonical MCP reference now lives at:\n\n- \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Fmcp\u002Ftools>\n- \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Fmcp\u002Ftools.md>\n- \u003Chttps:\u002F\u002Fuseminutes.app\u002Fllms.txt>\n\nThe MCP surface currently includes recording control, meeting search\u002Fretrieval, relationship memory, structured insights, live transcript reading, dictation, QMD integration, and an interactive dashboard resource. Tool names, resource URIs, and prompt templates are generated from the live product surface instead of hand-maintained in this README.\n\n**Interactive dashboard (Claude Desktop):** tools render an inline interactive UI via [MCP Apps](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2025-03-26\u002Fserver\u002Futilities\u002Fapps) — meeting list with filter\u002Fsearch, detail view with fullscreen + \"Send to Claude\" context injection, People tab with relationship cards and click-through profiles, and consistency reports. Text-only clients see the same data as plain text.\n\n### OpenCode CLI\n\nMinutes now ships a project-local OpenCode integration layer:\n\n- `.opencode\u002Fskills\u002Fminutes-*` for OpenCode's one-level skill discovery\n- `.opencode\u002Fcommands\u002Fminutes-*.md` so you can run native slash commands like `\u002Fminutes-brief`\n- the same portable runtime helpers used by the Codex\u002FGemini skill pack\n\nOpenCode also reads this repo's `AGENTS.md`, so the project rules carry over automatically.\n\nFor MCP tools in OpenCode, the official CLI flow is:\n\n```bash\nopencode mcp add\n```\n\nChoose a local stdio server and point it at:\n\n```bash\nnpx minutes-mcp\n```\n\nIf you're wiring OpenCode against this repo before the next npm release is cut,\npoint it at the repo-local entrypoint instead:\n\n```bash\nnpm --prefix \u002Fabsolute\u002Fpath\u002Fto\u002Fminutes\u002Fcrates\u002Fmcp exec tsx src\u002Findex.ts\n```\n\nFor the native skill\u002Fcommand workflow, just launch OpenCode in this repo:\n\n```bash\nopencode\n```\n\nThen use commands like:\n\n```text\n\u002Fminutes-brief\n\u002Fminutes-prep Alex\n\u002Fminutes-debrief\n\u002Fminutes-weekly\n\u002Fminutes-video-review \u002Fabsolute\u002Fpath\u002Fto\u002Fdemo.mp4\n```\n\n### Pi coding agent\n\nMinutes works with Mario Zechner's `pi` coding agent in two places:\n\n- `engine = \"agent\"` can call `pi` directly for local meeting summarization.\n- The desktop Recall panel can launch Pi when `[assistant].agent = \"pi\"`.\n- Pi auto-discovers this repo's existing `.agents\u002Fskills\u002Fminutes\u002F` skill pack, so there is no separate `.pi\u002Fskills` tree to keep in sync.\n\nInstall Pi, log in or configure a provider, then set:\n\n```toml\n[summarization]\nengine = \"agent\"\nagent_command = \"pi\"\n```\n\nMinutes invokes Pi in non-interactive, no-tools mode with a private prompt file. Configure provider\u002Fmodel defaults in Pi itself; Minutes does not currently forward extra `[summarization]` CLI flags. That keeps summarization opt-in and prevents the agent from writing to the repo while it is turning a transcript into notes.\n\nFor the interactive Recall panel, Minutes launches Pi directly and passes `[assistant].agent_args` through. Pi still owns provider auth and model selection: use Pi's `\u002Flogin` and `\u002Fmodel` flows first. If a GitHub Copilot model reports that personal access tokens are unsupported, refresh the Pi Copilot login instead of adding a GitHub PAT to Minutes.\n\nThis is separate from Inflection's Pi chatbot\u002Fmodel. Inflection's Pi models are optimized for warmth and emotional intelligence, but the Inflection API terms say not to send regulated personal data. Meeting transcripts often contain personal data, so Minutes does not route transcripts to Inflection by default.\n\n### Mistral Vibe\n\nAdd Minutes to your `~\u002F.vibe\u002Fconfig.toml`:\n\n```toml\n[[mcp_servers]]\nname = \"minutes\"\ntransport = \"stdio\"\ncommand = \"npx\"\nargs = [\"minutes-mcp\"]\n```\n\nAll 29 tools are available in Vibe as `minutes_*` (e.g. `minutes_start_recording`, `minutes_search_meetings`).\n\n### Claude Code (Plugin)\n\nInstall the plugin from the marketplace:\n```bash\n# First-time install\nclaude plugin marketplace add silverstein\u002Fminutes\nclaude plugin install minutes\n# Restart Claude Code to load skills, hooks, and the meeting-analyst agent\n```\n\n**Upgrading?** `claude plugin marketplace add` is a no-op when the marketplace is already on disk — it won't fetch new versions. To pick up new skills and hooks after a release, refresh the marketplace mirror first, then update the plugin:\n```bash\nclaude plugin marketplace update minutes    # git pulls the local marketplace mirror\nclaude plugin update minutes@minutes        # installs the new version into the cache\n# Restart Claude Code to apply\n```\n\n19 skills, 1 agent, 2 hooks:\n```\n├── Capture:      \u002Fminutes-record, note, list, recap, cleanup, verify, setup\n├── Search:       \u002Fminutes-search\n├── Lifecycle:    \u002Fminutes-brief, prep, debrief, weekly\n├── Coaching:     \u002Fminutes-tag, mirror\n├── Knowledge:    \u002Fminutes-ideas, lint, ingest\n├── Intelligence: \u002Fminutes-graph\n├── Artifacts:    \u002Fminutes-video-review\n├── Agent:        meeting-analyst (cross-meeting intelligence)\n└── Hooks:        SessionStart meeting briefings + PostToolUse recording alerts\n```\n\n**Meeting lifecycle skills** — inspired by [gstack](https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgstack)'s interactive skill pattern:\n\n```\n\u002Fminutes-brief                      → fast one-pager (or fired automatically by hook 15 min before calls)\n  ↓\n\u002Fminutes-prep \"call with Alex\"      → deeper relationship brief + talking points + goal-setting\n  ↓\nminutes record → minutes stop       → hook alerts if decisions conflict with prior meetings\n  ↓\n\u002Fminutes-tag won|lost|stalled       → 5-second outcome label (unlocks mirror correlation)\n  ↓\n\u002Fminutes-debrief                    → \"You wanted to resolve pricing. Did you?\"\n  ↓\n\u002Fminutes-mirror                     → talk-time, hedging, what your winning meetings have in common\n  ↓\n\u002Fminutes-weekly                     → themes, decision arcs, stale items, Monday brief\n  ↓\n\u002Fminutes-video-review \u003Cvideo-or-url> → durable artifact bundle from a Loom, ScreenPal, or local walkthrough\n  ↓\n\u002Fminutes-graph \"everyone who mentioned Stripe\"  → cross-meeting entity queries\n```\n\nFor the stable public agent-facing docs surface, use:\n\n- \u003Chttps:\u002F\u002Fuseminutes.app\u002Ffor-agents>\n- \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Fmcp\u002Ftools>\n- \u003Chttps:\u002F\u002Fuseminutes.app\u002Fdocs\u002Ferrors>\n\n### Minutes Desktop Assistant\n\nThe Tauri menu bar app includes a built-in AI Assistant window backed by the\nsame local meeting artifacts. It runs as a singleton assistant session:\n\n- `AI Assistant` opens or focuses the persistent assistant window\n- `Discuss with AI` reuses that same assistant and switches its active meeting focus\n- Recall writes matching `CLAUDE.md` and `AGENTS.md` instructions into its assistant workspace so Claude-style and AGENTS.md-aware terminal agents get the same meeting context\n- Auto-updates from GitHub Releases with signed artifacts, never interrupting a recording\n\n### Cowork \u002F Dispatch\nThe currently verified path for Cowork is plugin-oriented, not “raw MCP automatically appears everywhere.” Minutes ships a Cowork extension scaffold under `integrations\u002Fclaude-cowork-extension\u002F` and a local bundle build script at `scripts\u002Fbuild_cowork_extension.sh`. On this machine, the bundle build is verified; actual in-Cowork install\u002Fuse remains a proof-of-life workflow, not a guaranteed default path. Treat Dispatch-triggered recording and other mobile workflows as experimental until the plugin-native path is installed and checked end to end.\n\n### Optional: automated summarization\n\n```toml\n# Use your existing Claude Code, Codex, OpenCode, or Pi subscription (recommended)\n[summarization]\nengine = \"agent\"\nagent_command = \"claude\"  # or \"codex\" \u002F \"opencode\" \u002F \"pi\"\n\n# Or use Mistral API (requires MISTRAL_API_KEY)\n[summarization]\nengine = \"mistral\"\nmistral_model = \"mistral-large-latest\"\n\n# Or use a free local LLM\n[summarization]\nengine = \"ollama\"\nollama_model = \"llama3.2\"\n\n# Or use any OpenAI-compatible gateway\u002Flocal server.\n# Desktop users can paste cloud gateway keys in Settings; Minutes stores them\n# in macOS Keychain and hydrates its own runtime secret without rewriting this\n# shared config. CLI users can set any env var and name it below. Local servers\n# can leave it blank.\n[summarization]\nengine = \"openai-compatible\"\nopenai_compatible_base_url = \"https:\u002F\u002Fopenrouter.ai\u002Fapi\u002Fv1\"\nopenai_compatible_model = \"openai\u002Fgpt-4o-mini\"\nopenai_compatible_api_key_env = \"OPENROUTER_API_KEY\" # leave blank for local servers\n```\n\n### File-backed automation primitives\n\nMinutes can emit small automation artifacts that are easy to schedule with\n`launchd`, `cron`, or any external runner.\n\n```bash\nminutes automate weekly-summary --json\nminutes automate proactive-context --json\n```\n\nEach run writes:\n\n- a markdown artifact under `~\u002F.minutes\u002Fautomation-runs\u002F`\n- a matching JSON run record beside it\n\nThis is intentionally simple: explicit files, explicit output paths, and no\nhidden scheduler subsystem.\n\n### Codex epic runner\n\nWhen you want Codex to keep draining a `bd` epic instead of stopping after one\nchild bead, use the repo-local epic runner:\n\n```bash\nnode scripts\u002Fcodex_epic_runner.mjs \u003Cepic-id> -- --full-auto\n```\n\nWhat it does:\n\n- uses `bd` as the source of truth for epic ancestry and ready work\n- picks the next ready non-epic descendant bead under the target epic\n- claims that bead, runs `codex exec` against it, then checks whether the bead was actually closed\n- continues only after a real close; pauses on blocked\u002Fneeds-human outcomes instead of guessing\n\nDry-run the order first:\n\n```bash\nnode scripts\u002Fcodex_epic_runner.mjs \u003Cepic-id> --dry-run\n```\n\nIf you install a Taskmaster-style Codex wrapper later, use it as the per-bead\nengine without changing the epic logic:\n\n```bash\nnode scripts\u002Fcodex_epic_runner.mjs \u003Cepic-id> --taskmaster -- --sandbox danger-full-access -a never\n```\n\nThis is intentionally separate from the Claude plugin hooks. The Minutes plugin\nhooks are Claude-specific today; the Codex epic runner is a repo-local workflow\nlayer on top of `bd` and `codex exec`.\n\n### Optional: knowledge base integration\n\nMaintain a living knowledge base from your conversations — person profiles, decision history, and a chronological log that compounds over time. Inspired by [Karpathy's LLM Wiki pattern](https:\u002F\u002Fgist.github.com\u002Fkarpathy\u002F442a6bf555914893e9891c11519de94f).\n\n```toml\n[knowledge]\nenabled = true\npath = \"~\u002Fwiki\"        # or your Obsidian vault, PARA system, etc.\nadapter = \"wiki\"       # \"wiki\" (flat markdown), \"para\" (atomic facts), \"obsidian\" (wiki + [[links]])\nengine = \"none\"        # \"none\" = structured YAML only (safest), \"agent\" = LLM extraction\nmin_confidence = \"strong\"\n```\n\nAfter each meeting, structured facts (decisions, action items, commitments) flow into person profiles automatically. Every fact carries provenance back to its source meeting.\n\n```bash\nminutes ingest --dry-run --all   # Preview what would be extracted\nminutes ingest --all              # Backfill existing meetings\nminutes ingest ~\u002Fmeetings\u002Fcall.md # Process a single meeting\n```\n\nThree output formats:\n- **Wiki** — `people\u002F{slug}.md` with facts grouped by category\n- **PARA** — `areas\u002Fpeople\u002F{slug}\u002Fitems.json` with atomic facts (id, status, supersededBy)\n- **Obsidian** — Wiki format with `[[wikilinks]]` for cross-references\n\nSafety: default `engine = \"none\"` extracts only from parsed YAML frontmatter. No LLM call, zero hallucination risk. Confidence thresholds filter speculative facts. Corrupt data is backed up, never silently destroyed.\n\n## Install\n\n### macOS\n\n```bash\n# Desktop app (menu bar, recording UI, AI assistant)\nbrew install --cask silverstein\u002Ftap\u002Fminutes\n\n# CLI only (terminal recording, search, vault sync)\nbrew tap silverstein\u002Ftap\nbrew install minutes\n\n# Or from source (requires Rust + cmake)\nexport CXXFLAGS=\"-I$(xcrun --show-sdk-path)\u002Fusr\u002Finclude\u002Fc++\u002Fv1\"\ncargo install --path crates\u002Fcli\n```\n\n### Windows\n\n```powershell\n# Download pre-built binary from GitHub releases, or build from source:\n# Requires: Rust, cmake, MSVC build tools, LLVM (for libclang)\n\n# Install LLVM (needed by whisper-rs bindgen):\nwinget install LLVM.LLVM\n[Environment]::SetEnvironmentVariable(\"LIBCLANG_PATH\", \"C:\\Program Files\\LLVM\\bin\", \"User\")\n# Restart your terminal after setting LIBCLANG_PATH\n\n# Full build (includes speaker diarization):\ncargo install --path crates\u002Fcli\n\n# Without speaker diarization:\ncargo install --path crates\u002Fcli --no-default-features\n```\n\n> **Note:** If diarization fails to compile on Windows, use `--no-default-features`.\n> This is a [known upstream issue](https:\u002F\u002Fgithub.com\u002Fsilverstein\u002Fminutes\u002Fissues\u002F27)\n> with `pyannote-rs`'s ONNX Runtime dependency. Everything except speaker labels works without it.\n\n### Linux\n\n```bash\n# Debian\u002FUbuntu — full dep list:\nsudo apt-get install -y \\\n  build-essential cmake pkg-config \\\n  clang libclang-dev \\\n  libasound2-dev libpipewire-0.3-dev libspa-0.2-dev \\\n  ffmpeg\n\ncargo install minutes-cli\n# or, from a checkout:\ncargo install --path crates\u002Fcli\n```\n\n**Why each dep is needed:**\n- `build-essential`, `cmake` — whisper.cpp build\n- `clang`, `libclang-dev` — bindgen (used by `whisper-rs` and `pipewire-sys`)\n- `libasound2-dev` — cpal's ALSA backend\n- `libpipewire-0.3-dev`, `libspa-0.2-dev` — cpal's PipeWire backend (compiled unconditionally on Linux)\n- `ffmpeg` — preferred audio decoder for `.m4a`\u002F`.mp3`\u002F`.ogg` (falls back to pure-Rust symphonia if absent)\n\n**Other distros** (best-effort — Debian\u002FUbuntu is the validated path; please [open an issue](https:\u002F\u002Fgithub.com\u002Fsilverstein\u002Fminutes\u002Fissues) if any package name is wrong on your distro):\n\n- **Fedora\u002FRHEL**: `sudo dnf install -y gcc-c++ cmake pkgconf-pkg-config clang clang-devel alsa-lib-devel pipewire-devel ffmpeg-free`\n- **Arch**: `sudo pacman -S --needed base-devel cmake clang alsa-lib pipewire ffmpeg`\n\n### Chromebook (Crostini)\n\nYes, Minutes runs on a Chromebook via the Linux development environment (Crostini). The CLI is the supported path — there's no native ChromeOS build and the Tauri desktop app isn't exercised there, but the core engine, folder watcher, and MCP server all work.\n\n**One-time ChromeOS setup:**\n\n1. **Turn on Linux.** Settings → About ChromeOS → Developers → Linux development environment → Turn on. Pick a disk size of 10 GB or more (whisper models plus build artifacts).\n2. **Grant microphone access to the Linux container.** Settings → Developers → Linux development environment → toggle **Allow Linux to access your microphone**. This is off by default and is the single most common reason `minutes record` produces silence on a Chromebook.\n3. **Open the Linux terminal** and follow the [Debian\u002FUbuntu](#linux) install above (`apt-get install …` + `cargo install minutes-cli`).\n\n**Verify the environment** before your first real recording:\n\n```bash\nminutes health          # confirms model, mic, disk, watcher\nminutes record          # speak for 5 seconds\nminutes stop\n```\n\nIf `minutes health` flags the mic as missing, the ChromeOS mic toggle is off — not a cpal bug. Flip it on in Settings and re-run.\n\n**What works well on a Chromebook:**\n\n- `minutes watch` is the killer flow. Drop voice memos from your phone into a synced Google Drive \u002F Dropbox folder that also mounts inside Crostini, and Minutes auto-transcribes them. No mic permission dance, no hotkey fight.\n- CLI recording and transcription with the `tiny` \u002F `base` \u002F `small` models. Expect CPU-only performance — Crostini doesn't expose GPU acceleration to Linux apps, so skip `--features metal\u002Fcuda\u002Fvulkan` and pick a smaller model than you would on a Mac.\n- The MCP server (`npx minutes-mcp`) for Claude Desktop or other MCP clients running inside the container.\n\n**What to expect less of:**\n\n- **No global hotkeys or tray app.** ChromeOS doesn't surface system-level shortcuts to Crostini. `minutes record` \u002F `minutes stop` from the terminal is the intended flow.\n- **No Tauri desktop app support.** It may build, but it isn't tested and the live-coaching \u002F AI Assistant surface assumes a macOS-style window server.\n- **Slower transcription.** A Chromebook CPU on the `small` model is usually 2–4x realtime for English. Budget accordingly, or lean on the folder watcher where latency doesn't matter.\n\nIf Crostini support breaks for you, please [open an issue](https:\u002F\u002Fgithub.com\u002Fsilverstein\u002Fminutes\u002Fissues) — Chromebook isn't a first-class test target yet, so real bug reports are the fastest way to harden it.\n\n### GPU acceleration\n\nmacOS release binaries (DMG + `cargo install minutes-cli` from published CI\nartifacts) ship with Metal enabled — `large-v3` runs ~2× faster than the\nCPU-only build and offloads nearly all work to the GPU. Other backends remain\nopt-in at build time.\n\n| Backend | Platform | Feature flag | Prerequisites | Default in release |\n|---------|----------|-------------|---------------|--------------------|\n| Metal | macOS | `metal` | Xcode Command Line Tools | **Yes** |\n| CoreML | macOS | `coreml` | Xcode Command Line Tools + `.mlmodelc` bundle | No |\n| CUDA | Windows\u002FLinux | `cuda` | [CUDA Toolkit](https:\u002F\u002Fdeveloper.nvidia.com\u002Fcuda-toolkit) | No |\n| ROCm\u002FHIP | Linux | `hipblas` | [ROCm](https:\u002F\u002Frocm.docs.amd.com\u002F) 6.1+ (`hipcc`, `hipblas`, `rocblas`) | No |\n| Vulkan | Windows\u002FLinux | `vulkan` | [Vulkan SDK](https:\u002F\u002Fvulkan.lunarg.com\u002Fsdk\u002Fhome) (+ `vulkan-headers` on Arch) | No |\n\nMetal is the only backend that is exercised daily by the maintainer. CUDA, ROCm\u002FHIP,\nand Vulkan should be considered experimental: they wire through to whisper.cpp via\nwhisper-rs and are expected to work, but have not been validated in CI.\n\n```bash\n# Apple Metal (macOS) — already enabled in the release DMG; use this for source builds\ncargo install --path crates\u002Fcli --features metal\n\n# Apple CoreML (macOS Neural Engine) — encoder-only; see note below\ncargo install --path crates\u002Fcli --features metal,coreml\n\n# NVIDIA GPU (Windows\u002FLinux)\ncargo install --path crates\u002Fcli --features cuda\n\n# AMD GPU via ROCm (Linux — experimental)\ncargo install --path crates\u002Fcli --features hipblas\n\n# Vulkan (Windows\u002FLinux — experimental)\ncargo install --path crates\u002Fcli --features vulkan\n```\n\n> **CoreML note:** `--features coreml` only accelerates the Whisper encoder on\n> the Apple Neural Engine. It requires the companion `ggml-\u003Cmodel>-encoder.mlmodelc`\n> bundle next to the `.bin` weights (e.g. for `large-v3`, download\n> [`ggml-large-v3-encoder.mlmodelc.zip`](https:\u002F\u002Fhuggingface.co\u002Fggerganov\u002Fwhisper.cpp\u002Fresolve\u002Fmain\u002Fggml-large-v3-encoder.mlmodelc.zip)\n> and unzip into `~\u002F.minutes\u002Fmodels\u002F`). Without it, whisper.cpp silently falls\n> back to the CPU\u002FMetal encoder. Stack it with `metal` for the best of both\n> worlds — a subsequent PR will fetch the bundle automatically from\n> `minutes setup --model large-v3 --coreml`.\n\n> **Windows CUDA users:** You may need to set environment variables before building:\n> ```powershell\n> $env:CUDA_PATH = \"C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v12.4\"\n> $env:CMAKE_CUDA_COMPILER = \"$env:CUDA_PATH\\bin\\nvcc.exe\"\n> $env:LIBCLANG_PATH = \"C:\\Program Files\\LLVM\\bin\"\n> $env:CMAKE_GENERATOR = \"NMake Makefiles\"\n> ```\n> The first CUDA build takes longer than usual (compiling GPU kernels) — this is a one-time cost.\n\n> **ROCm\u002FHIP users:** The build expects ROCm installed at `\u002Fopt\u002Frocm`. If your\n> installation is elsewhere, set `HIP_PATH` before building:\n> ```bash\n> export HIP_PATH=\u002Fpath\u002Fto\u002Frocm\n> ```\n>\n> **Vulkan users:** On Windows and macOS, set `VULKAN_SDK` to your SDK install\n> root before building. On Linux, `whisper-rs-sys` links against the system\n> `libvulkan`.\n\n### Setup (all platforms)\n\n```bash\n# Download whisper model (also downloads Silero VAD model for non-English audio)\nminutes setup --model small   # Recommended (466MB, good accuracy)\nminutes setup --model tiny    # Fastest (75MB, but misses quiet audio)\nminutes setup --model base    # Middle ground (141MB)\n\n# Install ffmpeg for best transcription quality (strongly recommended for non-English audio)\nbrew install ffmpeg           # macOS\n# apt install ffmpeg          # Linux\n# Without ffmpeg, symphonia handles m4a\u002Fmp3 decoding — works for English but may\n# produce loops on non-English audio. ffmpeg is optional but recommended.\n\n# Enable speaker diarization (optional, ~34MB ONNX models)\nminutes setup --diarization\n\n# Alternative: use Parakeet engine (opt-in, local GPU via parakeet.cpp)\n# Requires (1) parakeet.cpp installed (https:\u002F\u002Fgithub.com\u002FFrikallo\u002Fparakeet.cpp)\n# AND (2) a Minutes CLI compiled with `--features parakeet`. The downloadable\n# DMG and tagged CLI release binaries include the feature; the Homebrew Formula\n# CLI (`brew install silverstein\u002Ftap\u002Fminutes`) and bare `cargo install minutes-cli`\n# do not. See docs\u002FPARAKEET.md for the source-build walkthrough.\nminutes setup --parakeet                          # Multilingual v3 (tdt-600m, ~1.2GB)\nminutes setup --parakeet --parakeet-model tdt-ctc-110m  # English-only compact model (~220MB)\n# Also installs native Silero VAD weights for the parakeet.cpp --vad path\n\n# Enroll your voice for automatic speaker identification\nminutes enroll              # Records 10s of your voice\nminutes voices              # View enrolled profiles\n```\n\n### Speaker identification\n\nMinutes maps anonymous speaker labels (`SPEAKER_1`, `SPEAKER_2`) to real names using four levels of confidence-aware attribution:\n\n| Level | How | Confidence | Requires |\n|-------|-----|-----------|----------|\n| **0** | Calendar attendees + `identity.name` → deterministic mapping for 1-on-1 meetings | Medium | Calendar access, `[identity] name` in config |\n| **1** | LLM analyzes transcript context clues and maps speakers to attendees | Medium (capped) | Attendees known + summarization engine or agent CLI |\n| **2** | Your enrolled voice is matched against speaker segments | High | `minutes enroll` (one-time 10s recording) |\n| **3** | You confirm \"SPEAKER_1 is Sarah\" after a meeting | High | `minutes confirm --meeting \u003Cpath>` |\n\nOnly **High**-confidence attributions rewrite transcript labels. Medium\u002FLow are stored in frontmatter (`speaker_map`) for Claude to surface when asked — \"SPEAKER_1 is likely Sarah.\"\n\n```bash\n# Set your name (required for Levels 0-2)\n# In your config file (`$XDG_CONFIG_HOME\u002Fminutes\u002Fconfig.toml` when set,\n# otherwise `~\u002F.config\u002Fminutes\u002Fconfig.toml`):\n[identity]\nname = \"Your Name\"\n\n# Enroll your voice (Level 2)\nminutes enroll                    # Record 10s sample\nminutes enroll --file sample.wav  # Or from existing audio\n\n# Confirm attributions after a meeting (Level 3)\nminutes confirm --meeting ~\u002Fmeetings\u002F2026-03-25-standup.md\nminutes confirm --meeting path.md --speaker SPEAKER_1 --name \"Sarah\" --save-voice\n\n# Manage voice profiles\nminutes voices              # List profiles\nminutes voices --json       # JSON output\nminutes voices --delete     # Remove all profiles\n```\n\n**Privacy**: Voice enrollment is self-only (no enrolling others). Level 3 confirmed profiles require explicit opt-in per person. Voice embeddings are stored locally in `~\u002F.minutes\u002Fvoices.db` with 0600 permissions. Nothing leaves your machine.\n\n> **Platform notes:** Calendar integration (auto-detecting meeting attendees) requires macOS. Screen context capture works on macOS and Linux. The voice memo pipeline works on all platforms — any folder sync (iCloud, Dropbox, Google Drive, Syncthing) can feed the watcher. The `minutes service install` auto-start command requires macOS (launchd); on Linux, use systemd or cron. Speaker diarization (`pyannote-rs`) works on all platforms (CLI, Tauri app, and via MCP). All other features — recording, transcription, search, action items, person profiles — work on all platforms.\n\n### Desktop app\n\n```bash\n# macOS — Homebrew cask (recommended)\nbrew install --cask silverstein\u002Ftap\u002Fminutes\n\n# macOS — build from source\nexport CXXFLAGS=\"-I$(xcrun --show-sdk-path)\u002Fusr\u002Finclude\u002Fc++\u002Fv1\"\nexport MACOSX_DEPLOYMENT_TARGET=11.0\ncargo tauri build --bundles app --features parakeet,metal\n\n# macOS — local desktop development with stable permissions\n.\u002Fscripts\u002Finstall-dev-app.sh\n```\n\nThe notarized Homebrew cask\u002Fupdate feed currently tracks the Apple Silicon desktop build. Intel Macs on macOS 15+ can still use the desktop app by building from source with the commands above.\n\n```powershell\n# Windows — build desktop installer from source\ncargo install tauri-cli --version 2.10.1 --locked\ncd tauri\u002Fsrc-tauri\ncargo tauri build --ci --bundles nsis --no-sign\n```\n\nTagged GitHub releases can include both a Windows NSIS installer as `minutes-desktop-windows-x64-setup.exe` and a raw desktop binary as `minutes-desktop-windows-x64.exe`. The installer is currently unsigned, so treat it as an advanced-user \u002F preview distribution surface until Windows signing is added.\n\nThe desktop app adds a system tray icon, recording controls, audio visualizer, Recall, and a meeting list window. The current Windows desktop build covers recording, transcription, search, settings, and Recall. Calendar suggestions, call detection, tray copy\u002Fpaste automation, and the native dictation hotkey remain macOS-only for now.\n\nRelease workflow details live in:\n\n- [docs\u002FRELEASE-MACOS.md](docs\u002FRELEASE-MACOS.md)\n- [docs\u002FRELEASE-WINDOWS.md](docs\u002FRELEASE-WINDOWS.md)\n\nFor macOS development, use a dedicated signed dev app identity:\n\n- Production app: `\u002FApplications\u002FMinutes.app` (`com.useminutes.desktop`)\n- Development app: `~\u002FApplications\u002FMinutes Dev.app` (`com.useminutes.desktop.dev`)\n\nIf you are testing hotkeys, Screen Recording, Input Monitoring, or repeated macOS permission prompts, launch only `Minutes Dev.app` via `.\u002Fscripts\u002Finstall-dev-app.sh`. Avoid the repo symlink `.\u002FMinutes.app`, raw `target\u002F` binaries, or ad-hoc local bundles for TCC-sensitive testing.\n\nThis repository is open source, so local development does not require the\nmaintainer's Apple signing credentials:\n\n- `.\u002Fscripts\u002Finstall-dev-app.sh` works with ad-hoc signing by default\n- for more stable macOS permission behavior across rebuilds, set\n  `MINUTES_DEV_SIGNING_IDENTITY` to a consistent local codesigning identity\n- release signing and notarization remain maintainer\u002Frelease workflows\n\nFor dictation, the recommended path is the standard shortcut in the desktop app\n(`Cmd\u002FCtrl + Shift + D` by default). The raw-key path for keys like `Caps Lock`\nis available as an advanced option but remains more fragile and permission-heavy.\n\n**Privacy:** All Minutes windows are hidden from screen sharing by default — other participants on Zoom\u002FMeet\u002FTeams won't see the app. Toggle via the tray menu: \"Hide from Screen Share ✓\".\n\n### Troubleshooting\n\n**No speech detected \u002F blank audio:**\nThe most common cause is microphone permissions. Check System Settings → Privacy & Security → Microphone and ensure your terminal app (or Minutes.app) has access.\n\n**tmux users:** tmux server runs as a separate process that doesn't inherit your terminal's mic permission. Either run `minutes record` from a direct terminal window (not inside tmux), or use the Minutes.app desktop bundle which gets its own mic permission.\n\n**Build fails with C++ errors on macOS 26+:**\nwhisper.cpp needs the SDK include path. Set `CXXFLAGS` as shown above before building.\n\n**Dictation hotkey still fails after you enabled it in System Settings:**\nThe native hotkey uses macOS Input Monitoring, which is separate from Screen Recording. The fastest way to test the exact installed desktop identity is:\n\n```bash\n.\u002Fscripts\u002Fdiagnose-desktop-hotkey.sh \"$HOME\u002FApplications\u002FMinutes Dev.app\"\n```\n\nUse `.\u002Fscripts\u002Finstall-dev-app.sh` first so you are testing the stable development app identity rather than a raw `target\u002F` build. The helper intentionally launches the app through LaunchServices; direct shell execution of `Contents\u002FMacOS\u002Fminutes-app --diagnose-hotkey` can misreport TCC status.\n\n### Updating\n\n```bash\n# macOS desktop app (Homebrew cask)\nbrew upgrade --cask silverstein\u002Ftap\u002Fminutes\n\n# macOS CLI (Homebrew)\nbrew upgrade silverstein\u002Ftap\u002Fminutes\n\n# From source (CLI)\ngit pull && cargo install --path crates\u002Fcli --features parakeet,metal\n\n# From source (desktop app)\ngit pull\nexport CXXFLAGS=\"-I$(xcrun --show-sdk-path)\u002Fusr\u002Finclude\u002Fc++\u002Fv1\"\ncargo tauri build --bundles app --features parakeet,metal\n# Then replace \u002FApplications\u002FMinutes.app with the new build from\n# target\u002Frelease\u002Fbundle\u002Fmacos\u002FMinutes.app\n\n# GitHub release (desktop app)\n# Download the latest .dmg from https:\u002F\u002Fgithub.com\u002Fsilverstein\u002Fminutes\u002Freleases\n# and drag Minutes.app to \u002FApplications, replacing the old version\n```\n\nFor local source builds, keep the CLI and desktop app on the same transcription feature set. The repo build scripts now default to `MINUTES_BUILD_FEATURES=parakeet,metal`; override that env var only if you intentionally want a narrower build flavor.\n\nCheck your current version with `minutes --version` (CLI) or the Settings gear in the desktop app.\n\n## Configuration\n\nOptional — minutes works out of the box.\n\n```toml\n# By default: ~\u002F.config\u002Fminutes\u002Fconfig.toml\n# Or: $XDG_CONFIG_HOME\u002Fminutes\u002Fconfig.toml when XDG_CONFIG_HOME is set\n\n[transcription]\nengine = \"whisper\"        # \"whisper\" (default), \"parakeet\" (opt-in, lower WER), or \"apple-speech\" (experimental)\nmodel = \"small\"           # whisper: tiny (75MB), base, small (466MB), medium, large-v3 (3.1GB)\n# language = \"ur\"          # Force transcription language (ISO 639-1 code, e.g. \"en\", \"ur\", \"es\", \"zh\")\n                          # Default: auto-detect. Set this for similar-sounding languages (Urdu\u002FHindi, etc.)\n# engine = \"apple-speech\"  # Experimental: standalone `minutes live` only. Configure via config file or CLI, not desktop settings.\n#                         # If Apple Speech cannot run, standalone live falls back to a ready Parakeet backend, then Whisper.\n#                         # See docs\u002FAPPLE_SPEECH.md for current scope and limitations.\n# parakeet_model = \"tdt-600m\"                    # parakeet: tdt-ctc-110m (English), tdt-600m (multilingual v3)\n# parakeet_binary = \"parakeet\"                   # Path to parakeet.cpp binary (or name in PATH)\n# parakeet_boost_limit = 25                      # Experimental: boost top graph-derived phrases (0 disables)\n# parakeet_boost_score = 2.0                     # Experimental tuning for parakeet.cpp --boost-score\n# parakeet_fp16 = true                           # Default on macOS Apple Silicon: ~35% faster transcription with lower GPU memory (see docs\u002Fdesigns\u002Fparakeet-perf-2026-04-14.md)\n# parakeet_vocab = \"tdt-600m.tokenizer.vocab\"      # Safer when multiple Parakeet models are installed\n# vad_model = \"silero-v6.2.0\"     # Silero VAD model (auto-downloaded by setup). Empty = disable.\n                                   # Prevents whisper hallucination loops on non-English\u002Fnoisy audio.\n\n[summarization]\nengine = \"none\"           # Default: Claude summarizes conversationally via MCP\n                          # \"auto\" = auto-detect an installed agent CLI for pipeline summaries\n                          # \"agent\" = uses your Claude Code, Codex, OpenCode, or Pi subscription (no API key)\n                          # \"ollama\" = local, free\n                          # \"openai-compatible\" = OpenRouter, Vercel\u002FCloudflare gateways, llama.cpp, LM Studio, etc.\n                          # \"claude\" \u002F \"openai\" = direct API key (legacy)\nagent_command = \"claude\"  # Which CLI to use when engine = \"agent\" (claude, codex, opencode, pi, etc.)\nollama_url = \"http:\u002F\u002Flocalhost:11434\"\nollama_model = \"llama3.2\"\nopenai_compatible_base_url = \"http:\u002F\u002Flocalhost:11434\u002Fv1\"\nopenai_compatible_model = \"llama3.2\"\nopenai_compatible_api_key_env = \"\" # Blank means no Authorization header for local endpoints. Desktop cloud endpoints can still use a saved Keychain key without rewriting config.\n\n[diarization]\nengine = \"auto\"           # \"auto\" (default — uses pyannote-rs if models downloaded, otherwise skips),\n                          # \"pyannote-rs\" (always on — native Rust, no Python),\n                          # \"pyannote\" (legacy — requires pip install pyannote.audio),\n                          # \"none\" (explicitly disabled)\n# embedding_model = \"cam++\"  # \"cam++\" (default) or \"cam++-lm\" (~12% lower EER on benchmarks).\n                          # Note: cam++-lm produces lower cosine similarities, so if you switch\n                          # to it you should also lower voice.match_threshold to ~0.1–0.2.\n# threshold = 0.5         # Speaker similarity threshold (0.0–1.0). Lower = fewer speakers.\n\n[voice]\n# enabled = true          # Voice profile matching during diarization (default: true if enrolled)\n# match_threshold = 0.65  # Cosine similarity threshold for voice matching (higher = stricter).\n                          # If using embedding_model = \"cam++-lm\", lower this to ~0.1–0.2.\n\n[search]\nengine = \"builtin\"        # builtin (regex) or qmd (semantic)\n\n[watch]\npaths = [\"~\u002F.minutes\u002Finbox\"]\nsettle_delay_ms = 2000              # Cloud sync safety delay (wait for file to finish syncing)\ndictation_threshold_secs = 120      # Files shorter than this → memo (skip diarize). 0 = disable.\n# Add cloud sync folders to watch for phone voice memos:\n# paths = [\"~\u002F.minutes\u002Finbox\", \"~\u002FDropbox\u002Fminutes-inbox\"]\n\n[screen_context]\nenabled = false           # Opt-in: capture screenshots during recording for LLM context\ninterval_secs = 30        # How often to capture (seconds)\nkeep_after_summary = false # Delete screenshots after summarization (default: clean up)\n\n[call_detection]\nenabled = true            # macOS-only today\npoll_interval_secs = 1\ncooldown_minutes = 5\n# Default apps stay conservative:\n# apps = [\"zoom.us\", \"Microsoft Teams\", \"Webex\"]\n#\n# Browser-based integrations such as Google Meet are opt-in on purpose.\n# If you want to dogfood browser detection, add the sentinel explicitly:\n# apps = [\"zoom.us\", \"Microsoft Teams\", \"Webex\", \"google-meet\"]\n\n[assistant]\nagent = \"claude\"          # CLI launched by the Tauri AI Assistant\nagent_args = []           # Optional extra args, e.g. [\"--dangerously-skip-permissions\"]\n```\n\n## Architecture\n\n```\nminutes\u002F\n├── crates\u002Fcore\u002F          45 Rust modules — the engine (shared by all interfaces)\n├── crates\u002Fcli\u002F           CLI binary — 52 commands (recording, search, health, storage, templates, workflows)\n├── crates\u002Fwhisper-guard\u002F Anti-hallucination toolkit (VAD gating, dedup, noise trimming)\n├── crates\u002Freader\u002F        Lightweight read-only meeting parser (no audio deps)\n├── crates\u002Fassets\u002F        Bundled assets (demo.wav)\n├── crates\u002Fsdk\u002F           TypeScript SDK — `npm install minutes-sdk` (query meetings programmatically)\n├── crates\u002Fmcp\u002F           MCP server — 29 tools + 7 resources + interactive dashboard\n│   └── ui\u002F               MCP App dashboard (vanilla TS → single-file HTML)\n├── tauri\u002F                Menu bar app — system tray, recording UI, singleton AI Assistant\n└── .claude\u002Fplugins\u002Fminutes\u002F   Claude Code plugin — 19 skills + 1 agent + 2 hooks\n```\n\nSingle `minutes-core` library shared by CLI, MCP server, and Tauri app. Zero code duplication.\n\n### Building your own agent on Minutes\n\nMinutes is designed as infrastructure for AI agents. Files are the durable substrate; MCP is the active interface; live transcript JSONL and the local event log are the real-time paths. The MCP server is the primary integration surface today:\n\n- **Read meetings**: `list_meetings`, `search_meetings`, `get_meeting` return structured JSON\n- **Track people**: `get_person_profile` builds cross-meeting profiles with topics, open commitments\n- **Monitor consistency**: `consistency_report` flags conflicting decisions and stale commitments\n- **Record + process**: `start_recording`, `stop_recording`, `process_audio` for pipeline control\n- **Live coaching**: `start_live_transcript`, `read_live_transcript` for real-time mid-meeting access\n- **Local event stream**: `minutes events --follow --since-seq N` tails newline-delimited events, including finalized live utterances, for agents that want a durable cursor\n- **Voice profiles**: `list_voices`, `confirm_speaker` for speaker identification workflows\n- **Resources**: Stable URIs (`minutes:\u002F\u002Fmeetings\u002Frecent`, `minutes:\u002F\u002Factions\u002Fopen`) for agent context injection\n\nAny agent framework that speaks MCP can use Minutes as its conversation memory layer — the agent handles the intelligence, Minutes handles the recall.\n\n**TypeScript SDK** — for direct programmatic access without MCP:\n\n```bash\nnpm install minutes-sdk\n```\n\n```typescript\nimport { listMeetings, searchMeetings, parseFrontmatter } from \"minutes-sdk\";\n\nconst meetings = await listMeetings(\"~\u002Fmeetings\", 20);\nconst results = await searchMeetings(\"~\u002Fmeetings\", \"pricing\");\n```\n\n**Built with:** Rust, [whisper.cpp](https:\u002F\u002Fgithub.com\u002Fggerganov\u002Fwhisper.cpp) (transcription), [pyannote-rs](https:\u002F\u002Fgithub.com\u002Fpyannote\u002Fpyannote-rs) (speaker diarization), [Silero VAD](https:\u002F\u002Fgithub.com\u002Fsnakers4\u002Fsilero-vad) (voice activity detection), [symphonia](https:\u002F\u002Fgithub.com\u002Fpdeljanov\u002FSymphonia) (audio decoding), [cpal](https:\u002F\u002Fgithub.com\u002FRustAudio\u002Fcpal) (audio capture), [Tauri v2](https:\u002F\u002Fv2.tauri.app\u002F) (desktop app), [ureq](https:\u002F\u002Fgithub.com\u002Falgesten\u002Fureq) (HTTP). Optional: [ffmpeg](https:\u002F\u002Fffmpeg.org\u002F) (recommended for non-English audio decoding).\n\n## Star History\n\n[![Star History Chart](https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=silverstein\u002Fminutes&type=Date)](https:\u002F\u002Fstar-history.com\u002F#silverstein\u002Fminutes&Date)\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nMIT — Built by [Mat Silverstein](https:\u002F\u002Fgithub.com\u002Fsilverstein), founder of [X1 Wealth](https:\u002F\u002Fx1wealth.com)\n","minutes 是一个开源的对话记忆工具，它能够通过AI技术将会议、想法和语音笔记变得可搜索。项目采用Rust语言编写，注重隐私保护，支持语音转文字等功能，并且可以与多种AI助手集成使用。其核心功能包括本地化存储所有对话记录为Markdown文件，提供CLI命令行工具和MCP工具接口，使得用户可以直接查询历史对话内容而无需依赖云服务或第三方API。适用于需要长期保存并快速检索重要对话信息的个人及团队场景，特别适合频繁开会或者需要记录大量语音笔记的专业人士。",2,"2026-06-11 03:50:25","high_star"]