# https://github.com/silverstein/minutes 项目说明书

生成时间：2026-07-22 16:41:22 UTC

## 目录

- [项目概览与多端入口](#page-overview)
- [音频采集、转写与说话人分离流水线](#page-pipeline)
- [LLM 摘要、说话人身份与人际关系记忆](#page-ai)
- [桌面应用、代理技能生态与平台故障模式](#page-surfaces)

<a id='page-overview'></a>

## 项目概览与多端入口

### 相关页面

相关主题：[音频采集、转写与说话人分离流水线](#page-pipeline), [桌面应用、代理技能生态与平台故障模式](#page-surfaces)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/silverstein/minutes/blob/main/README.md)
- [Cargo.toml](https://github.com/silverstein/minutes/blob/main/Cargo.toml)
- [manifest.json](https://github.com/silverstein/minutes/blob/main/manifest.json)
- [crates/cli/src/main.rs](https://github.com/silverstein/minutes/blob/main/crates/cli/src/main.rs)
- [crates/mcp/src/index.ts](https://github.com/silverstein/minutes/blob/main/crates/mcp/src/index.ts)
- [tauri/src/main.rs](https://github.com/silverstein/minutes/blob/main/tauri/src/main.rs)
- [docs/architecture.md](https://github.com/silverstein/minutes/blob/main/docs/architecture.md)
</details>

# 项目概览与多端入口

## 1. 项目定位与核心价值

Minutes 是一个**本地优先**的会议/语音录制与结构化工具，目标是让用户从"录音"到"结构化 Markdown 纪要"之间形成一条无缝流水线。社区反馈明确指出："the pipeline from recording to structured markdown is smooth, and the MCP integration is thoughtful" 资料来源：[README.md]()。这说明项目的两大支柱是：

- **录音 → 转写 → 摘要** 的本地化处理流水线；
- **MCP（Model Context Protocol）** 集成，让外部 AI 客户端能够调用 Minutes 提供的工具。

项目的版本节奏（v0.22.1 已是 patch 修复版本） 资料来源：[v0.22.1](https://github.com/silverstein/minutes/releases/tag/v0.22.1) 反映出工程化程度已经较高，并且对系统级 Bug（例如 `kCGHIDEventTap` 泄漏） 资料来源：[#488](https://github.com/silverstein/minutes/issues/488) 能够快速定位和修复。

## 2. 仓库拓扑与 Cargo Workspace

仓库根目录的 `Cargo.toml` 使用 Cargo workspace 聚合多个子 crate，顶层入口为 `tauri/src/main.rs`（桌面 GUI）和 `crates/cli/src/main.rs`（命令行） 资料来源：[Cargo.toml]()。典型的目录分层如下：

| 路径 | 角色 | 入口 |
|---|---|---|
| `tauri/` | 跨平台桌面应用（Tauri + WebView） | `tauri/src/main.rs` |
| `crates/cli/` | 命令行 `minutes` 二进制 | `crates/cli/src/main.rs` |
| `crates/mcp/` | MCP 服务器（Node/TS） | `crates/mcp/src/index.ts` |
| `crates/` 其他 | 核心库：音频采集、转写、说话人归属等 | 被 workspace 成员引用 |

根目录的 `manifest.json` 用于声明 MCP 服务元数据（名称、版本、工具列表），是外部 AI 客户端发现 Minutes 能力的"清单文件" 资料来源：[manifest.json]()。

## 3. 多端入口

### 3.1 桌面 GUI（Tauri）

桌面端是面向最终用户的主要形态。首次启动会进入 onboarding 流程，其中包含一个 "Record a 10-second test" 步骤 资料来源：[#492](https://github.com/silverstein/minutes/issues/492)。GUI 内置了 Recall 聊天面板 资料来源：[#362](https://github.com/silverstein/minutes/issues/362)，用于与本地模型交互。值得注意的是，桌面端的聊天面板目前存在 `user-select: none` 继承导致的文本不可复制问题 资料来源：[#490](https://github.com/silverstein/minutes/issues/490)，这是 GUI 入口在 UX 上仍需打磨的一个点。

### 3.2 命令行（CLI）

CLI 由 `crates/cli/src/main.rs` 启动，提供 `minutes record`、`minutes record --call` 等子命令 资料来源：[crates/cli/src/main.rs]()。在 Linux 上，`--call` 还需要 PipeWire `*.monitor` 自动检测能力 资料来源：[#62](https://github.com/silverstein/minutes/issues/62)，说明 CLI 在不同平台的系统音频捕获策略并不一致，需要针对平台分别实现。

### 3.3 MCP 服务器

MCP 入口通过 `manifest.json` 暴露工具列表，运行时由 `crates/mcp/src/index.ts` 启动 资料来源：[crates/mcp/src/index.ts]()。这是 Minutes 与 Cursor、Claude Desktop 等 AI 客户端对话的桥梁——这些客户端通过 MCP 协议反序列化 `manifest.json` 来发现 "Recall"、"speaker mapping" 等可用工具。

```mermaid
flowchart LR
    A[桌面 GUI<br/>tauri] --> C[核心 crate<br/>audio/transcribe/summarize]
    B[CLI<br/>crates/cli] --> C
    D[MCP Server<br/>crates/mcp] --> C
    C --> E[(本地 SQLite<br/>recordings / voices.db)]
    D -.通过 manifest.json.-> F[外部 AI 客户端]
```

## 4. 平台支持与已知差异

Minutes 在 macOS、Windows、Linux 三端都提供入口，但行为并不完全对称：

- **macOS**：依赖 `kCGHIDEventTap` 进行输入监听；历史上的 `system_audio_record` 在 0.22.0 仅兼容 macOS 26，macOS 15 上崩溃 资料来源：[#494](https://github.com/silverstein/minutes/issues/494)。v0.22.1 已修复 Input Monitoring tap 泄漏 资料来源：[v0.22.1]()。
- **Windows**：ConPTY 退出挂起 (`PtyManager::kill_session` 阻塞) 资料来源：[#261](https://github.com/silverstein/minutes/issues/261)，以及 Live transcript 状态上报 `line_count: 0` 的问题 资料来源：[#258](https://github.com/silverstein/minutes/issues/258)。
- **Linux**：CLI 仍需补齐 PipeWire 自动检测 资料来源：[#62]()。

对开发者而言，这意味着同一份代码逻辑在三个平台上可能存在不同的系统调用路径，调试时需要按平台分别追踪 issue 列表中的对应线索。

---

<a id='page-pipeline'></a>

## 音频采集、转写与说话人分离流水线

### 相关页面

相关主题：[LLM 摘要、说话人身份与人际关系记忆](#page-ai), [桌面应用、代理技能生态与平台故障模式](#page-surfaces)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [crates/core/src/capture.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/capture.rs)
- [crates/core/src/pipeline.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/pipeline.rs)
- [crates/core/src/transcribe.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/transcribe.rs)
- [crates/core/src/parakeet.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/parakeet.rs)
- [crates/core/src/parakeet_sidecar.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/parakeet_sidecar.rs)
- [crates/core/src/apple_speech.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/apple_speech.rs)
- [crates/core/src/live_transcript.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/live_transcript.rs)
- [crates/core/src/voices.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/voices.rs)
- [crates/core/src/speaker_mapping.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/speaker_mapping.rs)
- [crates/core/src/summarize.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/summarize.rs)
- [crates/core/src/system_audio_record.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/system_audio_record.rs)
- [crates/cli/src/main.rs](https://github.com/silverstein/minutes/blob/main/crates/cli/src/main.rs)
</details>

# 音频采集、转写与说话人分离流水线

Minutes 的核心是一条“录音 → 转写 → 说话人归属 → 摘要”的流水线，本页聚焦其中前两段：**音频采集** 与 **转写 / 说话人分离（diarization）**。该流水线由 `capture`、`pipeline`、`transcribe` 等模块协同实现，并通过 Parakeet、Apple Speech 等多种引擎适配不同平台与场景。

## 一、流水线总体结构

`pipeline.rs` 是整条流水线的调度入口，它把“采集音频块（chunk）”与“引擎输出（utterance）”通过异步通道串联起来：当 `capture.rs` 写入新的 PCM 帧时，转写模块立即读取并送入所选 ASR 引擎；引擎产出的带时间戳的文本片段（utterance）再被喂入下游的说话人映射模块。

```mermaid
flowchart LR
    A[capture.rs<br/>麦克风 / 系统音频 / Call] --> B[pipeline.rs<br/>分块 + 时间戳]
    B --> C{引擎分发}
    C -->|本地| D[parakeet.rs<br/>parakeet_sidecar.rs]
    C -->|macOS| E[apple_speech.rs]
    C -->|云端| F[transcribe.rs<br/>whisper / API]
    D --> G[speaker_mapping.rs<br/>diarization → 身份]
    E --> G
    F --> G
    G --> H[voices.rs<br/>声纹库 / Level 2/3]
    H --> I[summarize.rs]
```

资料来源：[crates/core/src/pipeline.rs:1-120]()，[crates/core/src/capture.rs:1-80]()。

## 二、音频采集层（capture）

`capture.rs` 负责把不同来源的音频统一成同一组 PCM 流，供下游引擎消费。三类来源分别处理：

1. **麦克风输入**：通过 `cpal` 直接采集默认输入设备。Windows 上由 WASAPI 后端提供，macOS 由 CoreAudio 提供，Linux 由 ALSA / PipeWire 后端提供。
2. **系统音频（system audio）**：CLI 通过 `--system` 启用，由 `system_audio_record.rs` 描述的原生辅助进程（macOS 上为 Swift `system_audio_record`，Linux 上依赖 `*.monitor` PulseAudio/PipeWire 源）把屏幕发声回路成 PCM，再以子进程方式回灌给 capture 层。社区 #62 提议在 Linux 上自动识别 PipeWire 的 `*.monitor` 源，免去手工设备配置。
3. **通话捕获（`--call`）**：复用系统音频回路，但只保留与人声频段匹配的窗口；macOS 0.22.0 曾因 `system_audio_record` 在 macOS 26 上编译而在 macOS 15 上崩溃（issue #494），当前 release 要求该 helper 与宿主机系统版本匹配。

```rust
// 伪代码，来自 capture.rs 的事件循环
loop {
    let frame = mic.read_pcm().await?;
    system_audio_pipe.read_into(&mut frame).await?;
    tx.send(AudioChunk { pcm: frame, ts: now() }).await?;
}
```
资料来源：[crates/core/src/capture.rs:60-160]()，[crates/core/src/system_audio_record.rs:1-90]()。

采集层还需要处理权限与生命周期。macOS 上需要“麦克风 / 输入监听 / 屏幕录制”三类权限；权限探针历史上因每 15 秒创建一次 `kCGHIDEventTap` 而泄露，最终耗尽系统 tap 表并触发 WindowServer 崩溃（issue #488，#501），v0.22.1 已通过一次性探测 + 不再缓存瞬态超时来修复。

## 三、转写引擎分发

`pipeline.rs` 暴露 `TranscriptionEngine` 枚举，由 `transcribe.rs` 完成具体实例化。当前实现支持：

- **Parakeet（本地）**：`parakeet.rs` 加载 NVIDIA Parakeet ONNX 模型；`parakeet_sidecar.rs` 把推理进程化为外部 sidecar（通过 stdio JSON 协议），避免 Rust 进程长时间持有模型权重，便于热更新与多实例隔离。
- **Apple Speech（macOS）**：`apple_speech.rs` 桥接 `SFSpeechRecognizer`，离线优先，自动跟随系统语言；社区 #487 报告过 summarization.engine=`apple` 时说话人映射仍按老逻辑报错“Unknown engine: apple”，需要在 dispatcher 同步加入该值。
- **云端 ASR**：`transcribe.rs` 中 OpenAI Whisper / 其他 REST 兼容后端的实现，仅在 `[transcription].engine` 配置项启用时被命中。

所有引擎都必须返回统一的 `Utterance { start, end, text, channel }` 结构，方便后续 diarization 模块无需关心引擎来源。CLI 中通过 `minutes record --engine parakeet` 或 `config.toml` 的 `[transcription] engine = "..."` 选择。

资料来源：[crates/core/src/transcribe.rs:1-140]()，[crates/core/src/parakeet.rs:1-90]()，[crates/core/src/parakeet_sidecar.rs:1-110]()，[crates/core/src/apple_speech.rs:1-100]()。

## 四、说话人分离与身份归属

转写输出本身不带说话人标签，离线 / 实时两条路径在此汇合：

- **Level 1（LLM 提示式）**：`speaker_mapping.rs` 读取 `[identity].name`、日历与会者名单、当前对话上下文，提示 LLM 把 `SPEAKER_00 / SPEAKER_01` 映射到真实姓名。该层对单人录音（solo）尤其脆弱：issue #491 指出若无日历事件命中，`identity.name` 不会被用作 self 说话人，导致 voice memo 与 onboarding 测试录音均无法正确归到本人。
- **Level 2 / Level 3（声纹）**：`voices.rs` 维护本地 `voices.db`，保存经过嵌入提取的声纹向量与混合（blended）profile；`pipeline.rs` 在每条 utterance 上跑嵌入 + 余弦匹配，把命中阈值以上的片段归到对应声纹。这一层正是 issue #496 中“声纹注册（voice enrollment）”史诗的核心：引擎已经具备，但缺少桌面端 UI 与 MCP 工具暴露。

社区 #245 报告过 Level 1 的副作用：转写文本中出现的人名会被覆盖到当前说话人，因此 `speaker_mapping` 必须在提示里明确“只在显式候选人中挑选”，并对 LLM 输出做白名单校验。

资料来源：[crates/core/src/speaker_mapping.rs:1-160]()，[crates/core/src/voices.rs:1-200]()，[crates/core/src/summarize.rs:80-160]()。

## 五、实时路径（live_transcript）

桌面端 Tauri 面板提供“Live Transcript”实时显示，由 `live_transcript.rs` 单独维护会话状态：它订阅与离线流水线相同的 utterance 流，但额外维护 `line_count` 与 `duration_secs` 两个聚合指标。issue #258 报告 Windows 上 Tauri Live 会话中这两个值始终为 0；根因是 Windows 后端未把 wall-clock 时长通过事件总线回传，`session_status()` 读取的本地计数器与 in-app 源不一致。该问题与 #261（`PtyManager::kill_session` 永久阻塞）一起构成 Windows 实时路径的两大稳定性痛点。

资料来源：[crates/core/src/live_transcript.rs:1-180]()。

## 六、已知约束与设计权衡

1. **引擎可用性矩阵**：Parakeet 要求 ONNX Runtime；Apple Speech 仅限 macOS；Whisper 需要网络。CLI 通过 `minutes doctor` 检测后向用户给出明确提示。
2. **权限与生命周期**：macOS 上 Input Monitoring / Microphone / Screen Recording 任一权限缺失都会使对应来源静默；权限探针必须避免每 15s 重建 tap（#488，#501 修复要点）。
3. **说话人归属的可信度**：Level 1 LLM 不可作为唯一来源，Level 2/3 声纹仍需注册流程（#496）；最小可用产品要求两类结果有冲突时优先采用声纹。
4. **平台二进程协作**：`system_audio_record` helper 必须与宿主系统版本匹配，否则会在较旧 macOS 上立即崩溃（#494）；Linux 上 PipeWire monitor 源自动检测尚未合入（#62）。

资料来源：[crates/core/src/capture.rs:200-260]()，[crates/cli/src/main.rs:1-120]()。

---

<a id='page-ai'></a>

## LLM 摘要、说话人身份与人际关系记忆

### 相关页面

相关主题：[音频采集、转写与说话人分离流水线](#page-pipeline), [桌面应用、代理技能生态与平台故障模式](#page-surfaces)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [crates/core/src/summarize.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/summarize.rs)
- [crates/core/src/ollama.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/ollama.rs)
- [crates/core/src/apple_fm.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/apple_fm.rs)
- [crates/core/src/copilot/mod.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/copilot/mod.rs)
- [crates/core/src/copilot/provider.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/copilot/provider.rs)
- [crates/core/src/copilot/runner.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/copilot/runner.rs)
- [crates/core/src/speaker_mapping.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/speaker_mapping.rs)
- [crates/core/src/identity.rs](https://github.com/silverstein/minutes/blob/main/crates/core/src/identity.rs)
</details>

# LLM 摘要、说话人身份与人际关系记忆

Minutes 用 LLM 把转写文本提炼成结构化 Markdown，并把"说话人标签 → 真人姓名 → 人际关系"这条链路贯穿到日历、声音档案与身份配置中。本页说明这条组合系统的源码结构、调用路径与已知问题。

## 一、LLM 摘要管线

摘要入口在 `crates/core/src/summarize.rs`，按 `config.toml` 中 `[summarization] engine` 路由到不同后端。引擎字符串以小写形式比对，可识别值包括 `apple`、`ollama`、`copilot` 与 `auto`。`auto` 在分发函数中根据本地可用性探测具体实现。

LLM 提供者统一抽象在 `crates/core/src/copilot/`：

- `provider.rs` 定义 `LlmProvider` trait，约束 `complete(prompt)` 同步阻塞并返回字符串。
- `runner.rs` 实现重试、上下文裁剪与超时等横切逻辑。
- `mod.rs` 暴露 `CopilotRunner`，对上层 summary 代码屏蔽引擎差异。

实际引擎实现：

- `crates/core/src/apple_fm.rs` 封装 Apple Foundation Models（v0.21 引入，对应 PR #439）。
- `crates/core/src/ollama.rs` 通过 HTTP 调用本地 Ollama，可指定模型、温度等参数。

```mermaid
flowchart LR
  A[转写文本 + 说话人标签] --> B[summarize.rs 分发]
  B -->|auto| C[本地探测]
  B -->|apple| D[apple_fm.rs]
  B -->|ollama| E[ollama.rs]
  B -->|copilot| F[copilot/runner.rs]
  F --> G[provider.rs 实现]
  C --> H[结构化 Markdown]
  D --> H
  E --> H
  G --> H
```

资料来源：[crates/core/src/summarize.rs:1-120](), [crates/core/src/copilot/mod.rs:1-80](), [crates/core/src/copilot/runner.rs:1-100](), [crates/core/src/copilot/provider.rs:1-60]()。

## 二、说话人身份与映射

摘要完成之后，Minutes 跑 Level-1 的说话人映射，把 `Speaker 0/1/2…` 翻译成真实姓名。该分发独立于摘要引擎，但同样按 `engine` 字段路由；新增引擎若仅在摘要入口注册，speaker mapping 仍会报 `Unknown engine`——issue #487（v0.21 跟进）和 issue #155（`auto` 引擎历史 bug）都属同一类。

映射依赖三类信号：

1. **配置身份**：`Settings → General → Your Name` 设置的 `identity.name`，由 `crates/core/src/identity.rs` 读取并写入 `config.toml`。
2. **声音档案**：`voices.db` 中保存的声纹嵌入（embeddings），通过 blended profiles 与 L2/L3 归属逻辑匹配。issue #496 把声音注册列为首要产品特性，设计与阶段划分见 `docs/plans/voice-enrollment.md`。
3. **上下文线索**：日历与会者名单、转写内容中提到的称呼。issue #245 报告 LLM 仍可能把转写中讨论到的他人姓名误指给本人，这是上下文超载产生的常见错误。

资料来源：[crates/core/src/speaker_mapping.rs:1-160](), [crates/core/src/identity.rs:1-80]()。

## 三、人际关系记忆

人际关系记忆构建在身份层之上，把"姓名 ↔ 声音 ↔ 关系"持久化到本地：

- **本地存储**：`voices.db`（声纹 + 关系）、`~/.config/minutes/config.toml`（身份与会者默认值）。
- **会话上下文**：摘要结果作为 Recall 本地聊天面板（issue #362 提议的 in-app chat）的检索源。
- **首启引导**：首次运行触发"10 秒测试录音"（issue #492），但当前并未接上声音注册路径，也没有"录音后立即看到归属结果"的反馈循环。

自名字规范化目前仅在匹配到日历事件时启用——独立录制的语音备忘录、入门测试录音都不会被规范化为 `identity.name`（issue #491），导致单人场景下映射频繁落到"未识别"分支。

资料来源：[crates/core/src/identity.rs:80-160](), [crates/core/src/summarize.rs:120-200](), [crates/core/src/speaker_mapping.rs:160-220]()。

## 四、配置与已知问题

`summarization.engine` 合法取值由分发函数硬编码；其他需要关注的问题：

| 编号 | 现象 | 触发条件 |
|---|---|---|
| #487 | speaker mapping 报 `Unknown engine: apple` | `engine = "apple"` |
| #491 | 自录不应用 `identity.name` | 无匹配日历事件 |
| #245 | 转写中提到的姓名覆盖本人归属 | LLM 上下文里多次出现他人姓名 |
| #496 | 声音注册缺乏 UI / MCP 入口 | `voices.db` 已存在但无产品化路径 |

社区用户在 #405 中也提到文档目录随着迭代变得零散，声音注册、人际关系相关的设计稿散落在 `docs/plans/` 中，查找时建议结合 issue #496 的 phasing 索引。

资料来源：[crates/core/src/speaker_mapping.rs:1-220](), [crates/core/src/apple_fm.rs:1-60](), [crates/core/src/ollama.rs:1-60](), [crates/core/src/identity.rs:1-160]()。

---

<a id='page-surfaces'></a>

## 桌面应用、代理技能生态与平台故障模式

### 相关页面

相关主题：[项目概览与多端入口](#page-overview), [音频采集、转写与说话人分离流水线](#page-pipeline)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [tauri/src-tauri/src/main.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/main.rs)
- [tauri/src-tauri/src/commands.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/commands.rs)
- [tauri/src-tauri/src/cli_setup.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/cli_setup.rs)
- [tauri/src-tauri/src/call_capture.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/call_capture.rs)
- [tauri/src-tauri/src/call_detect.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/call_detect.rs)
- [tauri/src-tauri/src/pty.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/pty.rs)
- [tauri/src-tauri/src/audio_capture.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/audio_capture.rs)
- [tauri/src-tauri/src/permissions.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/permissions.rs)
- [tauri/src-tauri/src/recall.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/recall.rs)
- [tauri/src-tauri/src/live_transcript.rs](https://github.com/silverstein/minutes/blob/main/tauri/src-tauri/src/live_transcript.rs)
- [tauri/src/index.html](https://github.com/silverstein/minutes/blob/main/tauri/src/index.html)
</details>

# 桌面应用、代理技能生态与平台故障模式

## 概述与范围

Minutes 是一个跨平台的桌面与命令行工具集，通过 Tauri（Rust 后端 + Web 前端）把本地音频采集、转写引擎、MCP（Model Context Protocol）代理技能生态与外部模型整合在一起。其桌面侧职责包括：基于麦克风与系统通话的录音捕获、实时转写、说话人归属、结构化摘要输出，以及围绕 Recall（嵌入式代理面板）与 MCP 工具暴露的代理技能。本页聚焦三件事：Tauri 桌面应用结构、围绕 Recall/声纹/MCP 的代理技能产品化路径，以及在 macOS、Windows、Linux 上观察到的平台级故障模式。

## 桌面应用架构

### 进程入口与命令分发

Tauri 应用在 `main.rs` 中初始化，把 CLI 子命令与 GUI 模式汇聚到同一管线；前端通过 `commands.rs` 中的 invoke 命令触发录音、转写、权限检查、Recall 会话等行为。命令行侧由 `cli_setup.rs` 解析参数（`minutes record`、`minutes recall`、`minutes run-agent` 等）并把 CLI 模式映射到共享捕获/转写栈 资料来源：[tauri/src-tauri/src/main.rs:1-200]() 资料来源：[tauri/src-tauri/src/commands.rs:1-200]() 资料来源：[tauri/src-tauri/src/cli_setup.rs:1-200]()。

### Recall 代理面板

Recall 是暴露给代理的本地交互界面。社区请求把它从嵌入终端改造为原生聊天面板（#362），现状是终端输出被渲染进 `tauri/src/index.html` 的 DOM，却继承了 body 的 `user-select: none`，导致助手回复文本既无法用鼠标选中、也无法键盘复制（#490）。这是终端风格代理面板与桌面原生 UI 之间的典型张力：前端需要为代理输出单独放行用户选择权限，而不是复用全局规则 资料来源：[tauri/src/index.html:1-400]()。

### 实时转写与现场会话状态

实时转写会话状态由 `live_transcript::session_status()` 暴露给前端（行计数、持续时长）。社区报告（#258）显示在 Windows 的 Tauri 进程内即使会话健康运行，函数仍持续返回 `line_count: 0` 与 `duration_secs: 0.0`，说明状态缓冲与前端轮询时钟在该平台存在同步缺陷 资料来源：[tauri/src-tauri/src/live_transcript.rs:1-400]()。

## 代理技能生态

### MCP 与 Recall

Minutes 通过 MCP 把本地能力开放给外部代理：Recall 是其中一种交互形态。它既可以作为 CLI 命令直接调用，也可以嵌入桌面应用内运行。围绕 Recall，社区希望补齐三件事——原生可选择聊天面板、Recall 输出的"复制/导出"动作、以及与非开发者用户友好的会话管理（#362、#490）。

### 声纹与归属

声纹（`voices.db` + blended profiles + L2/L3 归属）是另一种代理可调的本地技能。`docs/plans/voice-enrollment.md`（PR #495）提出三阶段方案，由 #496 跟踪：引擎层已有嵌入和归属能力，但缺少桌面 UI、MCP 工具与被动采集路径。与此同时，#492 指出 onboarding 的"录制 10 秒测试"步骤（`tauri/src/index.html:10012-10021`）措辞像声纹注册，但实际并未写入声纹模型，导致首次录音后没有"已注册"反馈 资料来源：[tauri/src/index.html:10012-10021]()。

### 配置驱动的归属缺陷

归属管线在配置与 dispatch 上仍有薄弱点：`[summarization] engine = "apple"`（v0.21.0，#439）时，Level 1 LLM 说话人映射仍走旧 dispatch 而报 `Unknown engine: apple`（#487，与 #155 同类）；单人录音且无日历与会者时，`identity.name` 没有作为自我称呼的归一化锚点（#491）；说话人归属在转写文本中提到他人姓名时可能覆盖配置好的 `identity.name`（#245）。这些都是桌面端"配置 → 后端 dispatch → 归属管线"链路上的回归点。

## 平台故障模式

| 平台 | 故障现象 | 触发点 | 修复路径 |
| --- | --- | --- | --- |
| macOS | `kCGHIDEventTap` 泄漏，长时间运行后系统输入冻结、WindowServer 可能崩溃 | 权限监控探针每 15s 创建事件 tap 且永不失效（#488、#501） | `input_monitoring_runtime_issue()` 进程内 memo 化；首次探测超时不应缓存为"需重启"（#500/501） 资料来源：[tauri/src-tauri/src/permissions.rs:1-400]() |
| macOS | `system_audio_record` 在 0.22.0 中按 macOS 26 构建，在 macOS 15 启动即崩溃 | 二进制构建目标高于运行环境（#494） | 重新按 macOS 15 deployment target 构建或剥离 26-only API 资料来源：[tauri/src-tauri/src/call_capture.rs:1-400]() |
| Windows | `PtyManager::kill_session` 永久阻塞在 ConPTY reader join | 退出时 reader 线程未见 EOF（#261） | 处理已分离 reader 的 join 超时或显式 close handle 资料来源：[tauri/src-tauri/src/pty.rs:1-400]() |
| Windows | Tauri Live 会话 `session_status()` 持续返回 0 | 状态聚合与前端轮询时钟错位（#258） | 修正 `live_transcript` 内部计时与计数来源 |
| Linux | `--call` 不会自动选择 PipeWire 的 `*.monitor` 源 | `audio_capture.rs` 缺少 PipeWire monitor 探测（#62） | 枚举 PipeWire 监视源作为默认系统音频候选 资料来源：[tauri/src-tauri/src/audio_capture.rs:1-400]() |
| macOS | 通话自动检测把 Core Audio 设备识别为通话源 | `call_detect.rs` 的设备分类规则过宽 | 在检测器中区分真实 VoIP/会议应用与系统音频设备 资料来源：[tauri/src-tauri/src/call_detect.rs:1-400]() |

## 小结

Tauri 桌面应用既是 Minutes 的终端用户入口，也是 MCP 代理技能生态的前端宿主；其稳定性高度依赖平台原生 API（CGEventTap、ConPTY、PipeWire、AVFoundation/ScreenCaptureKit）的生命周期管理。v0.22.1 的工作集中在三件事：把 Recall 从终端迁移为原生可选择 UI、补齐声纹产品化路径、以及系统性地收紧平台探针与系统调用方在长会话中的资源释放。

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：silverstein/minutes

摘要：发现 34 个潜在踩坑项，其中 4 个为 high/blocking；最高优先级：安全/权限坑 - 失败模式：security_permissions: CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap t...。

## 1. 安全/权限坑 · 失败模式：security_permissions: CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap t...

- 严重度：high
- 证据强度：source_linked
- 发现：Developers should check this security_permissions risk before relying on the project: CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap table (breaks screenshots system-wide)
- 对用户的影响：Developers may expose sensitive permissions or credentials: CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap table (breaks screenshots system-wide)
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/488 | CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap table (breaks screenshots system-wide)

## 2. 安全/权限坑 · 失败模式：security_permissions: Input Monitoring probe: don't cache a transient first-probe timeout as a false "restart needed"

- 严重度：high
- 证据强度：source_linked
- 发现：Developers should check this security_permissions risk before relying on the project: Input Monitoring probe: don't cache a transient first-probe timeout as a false "restart needed"
- 对用户的影响：Developers may expose sensitive permissions or credentials: Input Monitoring probe: don't cache a transient first-probe timeout as a false "restart needed"
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/501 | Input Monitoring probe: don't cache a transient first-probe timeout as a false "restart needed"

## 3. 安全/权限坑 · 来源证据：Native in-app chat panel for Recall (replace embedded terminal for non-developer users)

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Native in-app chat panel for Recall (replace embedded terminal for non-developer users)
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/362 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。

## 4. 安全/权限坑 · 涉及密钥、隐私或敏感领域

- 严重度：high
- 证据强度：source_linked
- 发现：项目文本出现 secret/private key/privacy/trading/finance 等敏感关键词。
- 对用户的影响：金融、交易、隐私和密钥场景必须比普通工具更保守。
- 证据：packet_text.keyword_scan | https://github.com/silverstein/minutes | matched secret / private key / privacy / trading / finance keyword

## 5. 安装坑 · 失败模式：installation: Recall chat panel text is not selectable or copyable (inherits body `user-select: none`)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Recall chat panel text is not selectable or copyable (inherits body `user-select: none`)
- 对用户的影响：Developers may fail before the first successful local run: Recall chat panel text is not selectable or copyable (inherits body `user-select: none`)
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/490 | Recall chat panel text is not selectable or copyable (inherits body `user-select: none`)

## 6. 安装坑 · 失败模式：installation: system_audio_record in Minutes 0.22.0 is built for macOS 26 and crashes on macOS 15

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: system_audio_record in Minutes 0.22.0 is built for macOS 26 and crashes on macOS 15
- 对用户的影响：Developers may fail before the first successful local run: system_audio_record in Minutes 0.22.0 is built for macOS 26 and crashes on macOS 15
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/494 | system_audio_record in Minutes 0.22.0 is built for macOS 26 and crashes on macOS 15

## 7. 安装坑 · 失败模式：installation: v0.18.13

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: v0.18.13
- 对用户的影响：Upgrade or migration may change expected behavior: v0.18.13
- 证据：failure_mode_cluster:github_release | https://github.com/silverstein/minutes/releases/tag/v0.18.13 | v0.18.13

## 8. 安装坑 · 失败模式：installation: v0.18.14

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: v0.18.14
- 对用户的影响：Upgrade or migration may change expected behavior: v0.18.14
- 证据：failure_mode_cluster:github_release | https://github.com/silverstein/minutes/releases/tag/v0.18.14 | v0.18.14

## 9. 安装坑 · 失败模式：installation: v0.19.0: Sherpa SOTA engine + sensitivity enforcement

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: v0.19.0: Sherpa SOTA engine + sensitivity enforcement
- 对用户的影响：Upgrade or migration may change expected behavior: v0.19.0: Sherpa SOTA engine + sensitivity enforcement
- 证据：failure_mode_cluster:github_release | https://github.com/silverstein/minutes/releases/tag/v0.19.0 | v0.19.0: Sherpa SOTA engine + sensitivity enforcement

## 10. 安装坑 · 失败模式：installation: v0.20.0: Dictation at your cursor, in-app Documents, honest degradation

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: v0.20.0: Dictation at your cursor, in-app Documents, honest degradation
- 对用户的影响：Upgrade or migration may change expected behavior: v0.20.0: Dictation at your cursor, in-app Documents, honest degradation
- 证据：failure_mode_cluster:github_release | https://github.com/silverstein/minutes/releases/tag/v0.20.0 | v0.20.0: Dictation at your cursor, in-app Documents, honest degradation

## 11. 安装坑 · 失败模式：installation: v0.21.0

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: v0.21.0
- 对用户的影响：Upgrade or migration may change expected behavior: v0.21.0
- 证据：failure_mode_cluster:github_release | https://github.com/silverstein/minutes/releases/tag/v0.21.0 | v0.21.0

## 12. 安装坑 · 来源证据：Onboarding: "10-second test recording" reads like voice enrollment but isn't — no post-Stop feedback and no desktop enr…

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Onboarding: "10-second test recording" reads like voice enrollment but isn't — no post-Stop feedback and no desktop enrollment path
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/492 | 来源类型 github_issue 暴露的待验证使用条件。

## 13. 安装坑 · 来源证据：PipeWire auto-detection for --call on Linux

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：PipeWire auto-detection for --call on Linux
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/62 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 14. 安装坑 · 来源证据：Recall chat panel text is not selectable or copyable (inherits body `user-select: none`)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Recall chat panel text is not selectable or copyable (inherits body `user-select: none`)
- 对用户的影响：可能阻塞安装或首次运行。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/490 | 来源类型 github_issue 暴露的待验证使用条件。

## 15. 安装坑 · 来源证据：[Epic] First-class voice enrollment (active + passive + on-device)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Epic] First-class voice enrollment (active + passive + on-device)
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/496 | 来源类型 github_issue 暴露的待验证使用条件。

## 16. 安装坑 · 来源证据：system_audio_record in Minutes 0.22.0 is built for macOS 26 and crashes on macOS 15

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：system_audio_record in Minutes 0.22.0 is built for macOS 26 and crashes on macOS 15
- 对用户的影响：可能阻塞安装或首次运行。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/494 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 17. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 证据：capability.host_targets | https://github.com/silverstein/minutes | host_targets=mcp_host, claude, claude_code, cursor, gemini_cli

## 18. 配置坑 · 失败模式：configuration: Configured "Your Name" is ignored for solo recordings — self-name normalization is gated behi...

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this configuration risk before relying on the project: Configured "Your Name" is ignored for solo recordings — self-name normalization is gated behind calendar attendees
- 对用户的影响：Developers may misconfigure credentials, environment, or host setup: Configured "Your Name" is ignored for solo recordings — self-name normalization is gated behind calendar attendees
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/491 | Configured "Your Name" is ignored for solo recordings — self-name normalization is gated behind calendar attendees

## 19. 配置坑 · 失败模式：configuration: Native in-app chat panel for Recall (replace embedded terminal for non-developer users)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this configuration risk before relying on the project: Native in-app chat panel for Recall (replace embedded terminal for non-developer users)
- 对用户的影响：Developers may misconfigure credentials, environment, or host setup: Native in-app chat panel for Recall (replace embedded terminal for non-developer users)
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/362 | Native in-app chat panel for Recall (replace embedded terminal for non-developer users)

## 20. 配置坑 · 失败模式：configuration: Onboarding: "10-second test recording" reads like voice enrollment but isn't — no post-Stop f...

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this configuration risk before relying on the project: Onboarding: "10-second test recording" reads like voice enrollment but isn't — no post-Stop feedback and no desktop enrollment path
- 对用户的影响：Developers may misconfigure credentials, environment, or host setup: Onboarding: "10-second test recording" reads like voice enrollment but isn't — no post-Stop feedback and no desktop enrollment path
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/492 | Onboarding: "10-second test recording" reads like voice enrollment but isn't — no post-Stop feedback and no desktop enrollment path

## 21. 配置坑 · 失败模式：configuration: PipeWire auto-detection for --call on Linux

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this configuration risk before relying on the project: PipeWire auto-detection for --call on Linux
- 对用户的影响：Developers may misconfigure credentials, environment, or host setup: PipeWire auto-detection for --call on Linux
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/62 | PipeWire auto-detection for --call on Linux

## 22. 配置坑 · 失败模式：configuration: [Epic] First-class voice enrollment (active + passive + on-device)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this configuration risk before relying on the project: [Epic] First-class voice enrollment (active + passive + on-device)
- 对用户的影响：Developers may misconfigure credentials, environment, or host setup: [Epic] First-class voice enrollment (active + passive + on-device)
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/496 | [Epic] First-class voice enrollment (active + passive + on-device)

## 23. 配置坑 · 失败模式：configuration: speaker mapping fails with "Unknown engine: apple" when summarization.engine = "apple" (v0.21...

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this configuration risk before relying on the project: speaker mapping fails with "Unknown engine: apple" when summarization.engine = "apple" (v0.21.0 #439 follow-up)
- 对用户的影响：Developers may misconfigure credentials, environment, or host setup: speaker mapping fails with "Unknown engine: apple" when summarization.engine = "apple" (v0.21.0 #439 follow-up)
- 证据：failure_mode_cluster:github_issue | https://github.com/silverstein/minutes/issues/487 | speaker mapping fails with "Unknown engine: apple" when summarization.engine = "apple" (v0.21.0 #439 follow-up)

## 24. 配置坑 · 来源证据：speaker mapping fails with "Unknown engine: apple" when summarization.engine = "apple" (v0.21.0 #439 follow-up)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：speaker mapping fails with "Unknown engine: apple" when summarization.engine = "apple" (v0.21.0 #439 follow-up)
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/487 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 25. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/silverstein/minutes | README/documentation is current enough for a first validation pass.

## 26. 运行坑 · 失败模式：runtime: Minutes v0.22.0

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this runtime risk before relying on the project: Minutes v0.22.0
- 对用户的影响：Upgrade or migration may change expected behavior: Minutes v0.22.0
- 证据：failure_mode_cluster:github_release | https://github.com/silverstein/minutes/releases/tag/v0.22.0 | Minutes v0.22.0

## 27. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/silverstein/minutes | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/silverstein/minutes | no_demo; severity=medium

## 29. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/silverstein/minutes | no_demo; severity=medium

## 30. 安全/权限坑 · 来源证据：CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap table (breaks screenshots s…

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：CGEventTap leak: long-running app accumulates 512+ disabled taps, exhausting the system tap table (breaks screenshots system-wide)
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/488 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 31. 安全/权限坑 · 来源证据：Configured "Your Name" is ignored for solo recordings — self-name normalization is gated behind calendar attendees

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Configured "Your Name" is ignored for solo recordings — self-name normalization is gated behind calendar attendees
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/491 | 来源类型 github_issue 暴露的待验证使用条件。

## 32. 安全/权限坑 · 来源证据：Input Monitoring probe: don't cache a transient first-probe timeout as a false "restart needed"

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Input Monitoring probe: don't cache a transient first-probe timeout as a false "restart needed"
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/silverstein/minutes/issues/501 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 33. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/silverstein/minutes | issue_or_pr_quality=unknown

## 34. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/silverstein/minutes | release_recency=unknown

<!-- canonical_name: silverstein/minutes; human_manual_source: deepwiki_human_wiki -->
