# VoiceSnap TODO ## Workflow - 每次修改前先检查本文件。 - 如果用户提出的新需求不在清单中,先新增到 `Todo` 或 `In Progress`。 - 开始做任务时,把任务移动到 `In Progress`。 - 任务完成并验证后,把任务移动到 `Done`,补一句完成结果。 ## In Progress - 无 ## Todo - 无 ## Done - [2026-05-18] 重做 VoiceSnap macOS 图标为 SVG 矢量母版。 - 目标: 白色圆角方形底、蓝色麦克风,风格参考 TagLauncher,避免毛边、截图白边和尺寸忽大忽小。 - 最终选择: B 版白底蓝色麦克风,并为中间麦克风加入轻微层次阴影。 - SVG 母版: `VoiceSnapGo/design/icon-candidates/voicesnap_icon_B_thin-blue-glyph.svg` - 当前打包图标: `VoiceSnapGo/build/darwin/icon.icns` - 备用 ICNS: `VoiceSnapGo/build/darwin/VoiceSnap-selected-B-shadow.icns` - 版本: `2.1.4` - build: `20260518.1748` - [2026-05-18] 增加语音输入交互方式设置。 - 新增配置 `HotkeyMode`,默认 `hold`。 - 设置页新增“语音输入方式”分段控件,支持“点按”和“长按”。 - 点按: 点一下快捷键开始说话,再点一下结束并识别输入。 - 长按: 长按快捷键开始录音,松开后结束并识别输入。 - 版本: `2.1.3` - build: `20260518.1651` - [2026-05-18] 修复全屏窗口下语音输入悬浮指示器不显示。 - 根因: macOS 全屏 Space 下普通 `NSWindow` + `NSFloatingWindowLevel` 不稳定,容易被全屏 App 压在下层。 - 修复: 悬浮指示器改为非激活 `NSPanel`,窗口层级提升到 `kCGStatusWindowLevelKey`,并补充 `Transient`、`IgnoresCycle`、`FullScreenAuxiliary`、`CanJoinAllSpaces` 行为。 - 版本: `2.1.2` - build: `20260518.1623` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.2-build20260518.1623-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.2-arm64-local.dmg` - 已安装到 `/Applications/VoiceSnap.app`;签名验证为 `VoiceSnap Local Code Signing`。 - [2026-05-18] 将 macOS 后台活动/登录项纳入权限检查面板。 - 说明: 系统设置里的 “VoiceSnap Local” 是本地稳定签名证书的开发者名,下面挂着 VoiceSnap 的登录项/后台活动。 - 它不是右 Alt、录音、自动上屏的必需隐私权限,但会影响登录后是否自动在后台运行。 - 面板新增“后台活动 / 登录项”,标为“可选”,不影响核心权限总绿灯。 - build: `20260518.1604` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260518.1604-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`;启动日志验证 build `20260518.1604`。 - [2026-05-18] 修复右 Alt 事件进入但被 macOS 物理状态查询误判为未按下的问题。 - 日志显示 R-Alt `flagsChanged` 事件正常进入,`flags=0x80140`,但 `physicalDown=false` 导致 `pollDown=false`。 - 修复: 按事件 keyCode 区分左右 Alt,并用该事件的 modifier flags 判定按下/释放。 - 验证: 重新打包安装后模拟右 Alt,日志显示 `eventDown=true`、`pollDown=true`,并成功触发录音流程。 - build: `20260518.1554` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260518.1554-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`;启动日志验证 build `20260518.1554`。 - [2026-05-18] 增加权限检查设置面板。 - 新增“权限”设置页,清晰列出麦克风、辅助功能、输入监控三个权限。 - 权限状态由后端调用 macOS 原生 API 检查;已授权显示绿灯,未授权显示红灯。 - 支持刷新状态和“去授权”按钮,点击后请求系统授权并打开对应系统设置页。 - build: `20260518.1541` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260518.1541-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`;启动日志验证 build `20260518.1541`。 - [2026-05-18] 修复 VoiceSnap 设置窗口不可见时右 Alt 全局热键无法触发的问题。 - 观察: 设置窗口在前台可触发,窗口隐藏或被遮挡后按右 Alt 没有热键日志。 - 修复: macOS 热键监听改为专用线程运行,并在 event tap 未启动时自动重试。 - 修复: 右/左修饰键检测增加物理按键状态轮询兜底,避免只依赖窗口前台状态下的 event tap;同时去掉 Option 组 flags 对左右 Alt 的兜底混用,继续保持右 Alt/左 Alt 严格区分。 - 修复: 启动时开启系统 activity,降低隐藏窗口后被 App Nap 影响的概率。 - 日志增强: 右 Alt 诊断日志现在记录 `source`、`physicalDown`、`trackedDown`、`recentDown`、event tap 启动尝试/失败/禁用次数。 - build: `20260518.0230` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260518.0230-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`;启动日志验证 build `20260518.0230`,辅助功能权限已通过,event tap 已启动。 - [2026-05-18] 将本地 macOS 打包从 ad-hoc 签名改为固定本地 Code Signing 身份,减少辅助功能权限失效。 - 新增 `VoiceSnapGo/scripts/build-local-macos.sh`,用于本地构建、稳定签名、生成 DMG,可选安装到 `/Applications`。 - 自动创建/复用钥匙串身份 `VoiceSnap Local Code Signing`,签名 `.app`、内部 dylib 和 `.dmg`。 - 当前安装包签名已验证: `Authority=VoiceSnap Local Code Signing`。 - build: `20260518.0211` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260518.0211-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`;本次签名身份变化后需要在系统设置里重新添加一次辅助功能权限。 - [2026-05-18] 修复停止录音时 `ma_device_stop` 与音频回调互等导致 App 假死的问题。 - 根因: `Recorder.StopAndGetSamples()` 持有录音互斥锁调用 `device.Stop()`;底层 `ma_device_stop` 等待音频回调结束,而音频回调同时等待同一把锁,形成互等。 - 修复: 停止录音时先在锁内摘除设备并标记非录音,释放锁后再调用 `Stop/Uninit`,避免底层停止设备时阻塞音频回调。 - 增加停止设备过程日志: `Stopping audio device`、`Audio device stopped`、`Audio device uninitialized`。 - build: `20260518.0125` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260518.0125-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`,并在日志中验证一次完整停止链路。 - [2026-05-17] 放大菜单栏图标的有效绘制区域,改善深色菜单栏里图标过小的问题。 - `VoiceSnapGo/build/darwin/tray_icon.png` 的有效内容区域从约 `156x156` 放大到约 `220x220`。 - build: `20260517.2306` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.2306-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`。 - [2026-05-17] 使用重新生成并已确认满意的 macOS 26 风格麦克风图标,制作透明边缘 icns 并重新打包。 - 图标来源: `/Users/ar/.codex/generated_images/019e2f69-755a-74a2-9a61-0e390fda0463/ig_0a6e87fd2c8e3f65016a09c4c865688191ade9691cb608b2e4.png` - 透明 PNG: `VoiceSnapGo/build/darwin/macos26_mic_app_icon.png` - 当前打包图标: `VoiceSnapGo/build/darwin/icon.icns` - 备用 ICNS: `VoiceSnapGo/build/darwin/VoiceSnap-macos26-mic.icns` - build: `20260517.2142` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.2142-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - 已安装到 `/Applications/VoiceSnap.app`,安装后图标 `hasAlpha: yes`。 - [2026-05-17] 恢复用户指定的精致麦克风图标,并重新打包。 - 图标来源: `VoiceSnapGo/build/darwin/app_icon_source.png` - PNG: `VoiceSnapGo/build/darwin/refined_mic_app_icon.png` - ICNS: `VoiceSnapGo/build/darwin/VoiceSnap-refined-mic.icns` - 当前打包图标: `VoiceSnapGo/build/darwin/icon.icns` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.2046-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - [2026-05-17] 将 App 图标回退到最早源码自带的蓝底白色声波图标,并重新打包。 - 图标来源: `/Users/ar/Downloads/VoiceSnap-2.1.1/VoiceSnapGo/build/windows/icon.ico` - PNG: `VoiceSnapGo/build/darwin/original_app_icon.png` - ICNS: `VoiceSnapGo/build/darwin/VoiceSnap-original.icns` - 当前打包图标: `VoiceSnapGo/build/darwin/icon.icns` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.2039-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - [2026-05-17] 调整用户词库默认显示顺序,最新添加的词语显示在最上面。 - 后端 `UserDictService.GetAll` 返回时按 `createdAt` 倒序排列,时间相同时按 `id` 倒序兜底。 - 前端加载词库时做同样的保险排序;新增词条后直接插到列表最上方。 - 替换规则执行顺序保持原存储顺序,不影响识别文本替换行为。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.1811-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - [2026-05-17] 修复组合键检测使用残留按键状态导致右 Alt 突然失效的问题。 - 组合键判定改为只认“热键按下之后新按下的其他键”,不再被旧的残留按键状态拦截。 - macOS 增加 `Hotkey combination source` 日志,后续如果还被判定组合键,可以直接看到触发源。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.1631-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - [2026-05-17] 修复右 Alt 被误判为组合键的问题,避免 macOS 把同组 Option 状态误报成左 Alt 后阻止录音。 - 日志定位到右 Alt 按下后被 `Hotkey marked as combination` 拦截,原因是 macOS 侧边 Option 查询会把左 Alt 误报为按下。 - 侧边修饰键改为只信任 event tap 记录的物理 keyCode 状态,不再用会混淆左右的即时轮询。 - 组合键判断中跳过同一修饰键组,避免 R-Alt 被 L-Alt 假状态拦截。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.1622-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - [2026-05-17] 给 App 增加 build 编号显示,并在启动日志记录版本、build、可执行文件路径和数据目录。 - About 页版本显示改为 `2.1.1 (build 20260517.1614)`。 - `CFBundleVersion` 改为 `20260517.1614`,安装后的 `/Applications/VoiceSnap.app` 已验证。 - 启动日志现在记录 `version`、`build`、`executable` 和 `dataDir`。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-build20260517.1614-arm64-local.dmg` - 兼容输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` 已替换为同一份新包。 - [2026-05-17] 增加热键诊断日志,记录 macOS 原始 Alt 事件、App 轮询状态和触发/忽略原因。 - 记录 event tap 是否启动,以及 `L-Alt/R-Alt` 原始事件序号、事件类型、flags、事件状态、轮询状态。 - 记录 App 层热键状态变化、按下接受、释放、短按/长按动作、组合键判定和被忽略原因。 - 日志位置: `~/Library/Application Support/VoiceSnap/app.log` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 修正 macOS `flagsChanged` 修饰键状态逻辑,避免重复事件把右 Alt 状态翻转错误。 - event tap 移到独立后台 run loop,避免主线程 run loop 状态影响键盘监听。 - 修饰键状态改为按事件后 modifier flag 直接置 true/false,不再用 toggle。 - 给短按增加 120ms 状态缓冲,避免 30ms 轮询错过很快的点击。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 修复 macOS 右 Alt 热键时灵时不灵的问题,改为单一 `CGEventTap` 事件源追踪键盘状态。 - 移除 local/global 双监听导致的修饰键状态翻转不同步风险。 - 现在由一个 listen-only HID event tap 统一记录 KeyDown/KeyUp/FlagsChanged。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 日志每行时间戳改为完整日期和几点几分几秒,方便排查问题。 - 日志格式改为 `[2026-05-17 15:24:08] INFO ...`。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 修复上版 macOS 右 Alt 无法触发语音输入的问题,改用 `flagsChanged` 事件追踪左右修饰键状态。 - 左右 Alt/Ctrl/Shift/Cmd 现在由 macOS 修饰键变更事件记录物理键状态,并保留系统物理按键状态查询作为辅助。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 将配置、用户词库、历史、模型缓存迁移到 macOS `Application Support/VoiceSnap`,避免更新 App 后丢失。 - 新数据目录: `~/Library/Application Support/VoiceSnap` - 持久化内容: `config.json`、`userdict.json`、`history.json`、`models/sensevoice`、`app.log` - 首次启动会从旧 `.app/Contents/MacOS` 位置复制缺失数据到新目录,不覆盖已有新数据。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 将默认触发热键改为右侧 Alt。 - 新配置默认值从 `R-Ctrl` 改为 `R-Alt`。 - [2026-05-17] 修复 macOS 下左右 Alt 被当成同一个键的问题:设置 `R-Alt` 时左 Alt 不能触发。 - macOS 左右 Ctrl/Alt/Shift/Cmd 改为按物理 keyCode 检测,不再依赖不区分左右的系统 modifier flag。 - [2026-05-17] 用户词库导出默认文件名追加当前日期和时分时间戳。 - 默认文件名形如 `userdict-20260517-1503.json`。 - [2026-05-17] 简化用户词库导出 JSON,只保留用户真正关心的 `from` 和 `to` 字段。 - 导入功能兼容旧版完整字段和新版简化字段。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 重新迭代 App 图标,修复 Dock 深色背景上的白边问题,并打包进新版 `.app/.dmg`。 - 图标资源: `VoiceSnapGo/build/darwin/app_icon.png` - ICNS: `VoiceSnapGo/build/darwin/icon.icns` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 改进用户词库导出体验:导出时让用户选择保存位置,并在成功后显示实际路径。 - 导出按钮现在会弹出 macOS 保存文件对话框,默认文件名为 `userdict.json`。 - 用户取消保存时不报错;保存成功后界面显示实际保存路径。 - [2026-05-17] 将用户确认的新 App 图标打包进新版 `.app/.dmg`,本次只替换图标资源,不改业务代码。 - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap.app` - 输出: `VoiceSnapGo/build/local/arm64/VoiceSnap-2.1.1-arm64-local.dmg` - [2026-05-17] 保存用户确认满意的新 App 图标,并生成可手动替换的 `.icns`。 - PNG: `VoiceSnapGo/build/darwin/approved_app_icon.png` - ICNS: `VoiceSnapGo/build/darwin/VoiceSnap-approved.icns` - 用户便捷取用副本: `/Users/ar/Downloads/VoiceSnap-approved.icns`