紧急修复 v1.11.0 的启动缺陷。如果你已经装了 1.11.0,请更新到本版。
- 启动后永远停在黑屏转圈,主界面出不来 — 首屏的「加载中 / 引导页 / 主界面」三态是挂在
MacosApp.home上切换的,而 Flutter 的home只用来生成导航栈的初始路由:首帧一旦把加载页压进栈,之后再改home也换不掉它。于是只要配置初始化慢于第一帧,画面就永久停在加载页 —— 而程序状态其实早就绪了(强制重建一下界面立刻恢复正常,这也是定位到它的确证)。现在三态改在路由内部切换,不再依赖导航栈替换初始路由- 这其实是一条长期潜伏的竞态,并非 1.11.0 新引入:谁快谁赢,初始化抢在首帧前完成就正常,慢一步就黑屏。1.11.0 之所以人人都撞上,是因为装新版必然是全新启动,正是最容易输的场景
- 启动时一段原生初始化被整段跳过 — v1.11.0 给
applicationDidFinishLaunching加的父类调用在运行时并不存在(Flutter 的 AppDelegate 未实现该可选方法),异常在方法第一行就抛出,导致其后的闪念目录权限恢复与录音浮窗通道注册全部没有执行
本版没有新功能,是一次覆盖全仓的缺陷清查:自 v1.10.0 起 109 次提交、167 个文件。 逐模块 review → 修复 → 复审直到无 P2+,自动化测试增至 896 项。下面只列你能感知到的部分。
- 最低系统从 macOS 11.0 提升到 macOS 13.4 — 随包的 ONNX Runtime 本来就要求 13.4,而工程一直声明 11.0,等于对 11.0–13.3 的用户承诺了一个跑不起来的组合。现在 App、Pods 与 README 统一为 13.4,并回查最终产物的 load command 确认一致。macOS 13.4 以下的机器请留在 v1.10.0
- 云账户的新增 / 修改 / 删除可能根本没落盘 — 写入用的是
_prefs?.setString(...),初始化尚未完成时这个?.会让整次保存静默变成空操作:界面显示保存成功,重启后改动消失。现在所有写操作先等加载完成,并按成败提交,失败会回滚到写之前的状态(列表和凭证值一起还原) - 云账户加载失败是无声的 — 读取出错时页面只是一片空白,导入失败则被吞成「导入 0 条」,两种情况都不告诉你出了什么事。现在如实报错
- 模型「安装成功」可能是假的 — 此前只要压缩包里存在 tokens 文件就算装好,一个内容残缺但格式合法的包会被记为可用模型,直到你按下快捷键才发现识别起不来。现在按模型类型校验该 Provider 实际要读的文件组合,先在暂存目录解压再原子替换,安装中途退出会在下次启动时自动恢复
- 导入配置失败会留下半套配置 — 现在先完整校验版本、类型与云账户结构再批量写入,平台写入失败时逆序回滚
- 导出的诊断日志里没有错误日志 — 「导出诊断日志」只在你设过自定义日志目录时才收集应用日志,没设过的用户导出来是空的 —— 报障时最关键的错误记录恰好全部拿不到。现在两个来源都收
- 云端识别经常丢掉最后一句 — 阿里云的
stop()只固定等 500ms 就返回,服务端收尾稍慢,最后一段文字直接没了;讯飞 / 腾讯 / 火山则在stop()里写死 5 秒,与各自声明的 6 秒预算对不上,超时后引擎会连已识别的部分文本一起丢弃。现在内层等待总和统一收在 4 秒,与外层 6 秒预算留足余量 - 上一段录音的识别结果会串到下一段 — 5 个云端识别引擎每次开始录音都新建连接与监听,但旧监听从不取消。上一次的迟到帧不只是把过期文字发出来,还会改写当前文本、提前结束新会话、甚至关掉新连接。现在每个连接都带代次守卫,整段监听(数据 / 错误 / 结束)一并隔离
- 切换识别引擎失败后,界面还停在原来那档、按快捷键毫无反应 — 切换失败时只把配置改了回去,而引擎已经被释放掉了,全程零异常提示。现在回滚连引擎一起重建
- 蓝牙耳机连接瞬间界面卡顿 — 设备变化回调里做了全量设备枚举,蓝牙协商期间这个调用会阻塞主线程。现在启动和回调只取轻量快照,完整列表留到你真正打开设置页时再枚举
- 麦克风切换失败仍然显示成功并写进偏好 — 现在按实际成败提交
- 「蓝牙麦克风提醒」开关关掉后重启又自己回来 — 该开关此前不持久化
- 讯飞的动态修正在特定分片下会越界;录音收尾的尾部音频不再被丢弃
- 润色中断会把你的文档写成两倍 — 打字机模式是边收边往输入框粘的,网络中途断开时兜底逻辑会无条件再吐一遍原文,于是文档里留下「半段润色文本 + 完整原文」,还撤不回来。现在只有一个字都没吐出去时才回退原文
<think>标签会被直接打进输入框 — 非流式路径一直有清理,流式路径漏了:SSE 逐字返回会把标签切成两半,正则救不回来。现在用状态机逐段过滤,未闭合的思考段整体丢弃;Anthropic / Ollama 这类「整段一次性返回」的伪流式也补上了同样的清理- 连接测试的失败信息乱码,非 JSON 响应报的错指错方向;旧版 LLM 配置的协议判断改以服务商注册表为准
- 剪贴板原本是空的时候,注入的文字会永久留在剪贴板里
- 注入失败是静默的 — 现在会明确告知,不再表现为「按了没反应」
- 注入进行中拒绝执行复制 — 否则你在这个窗口里按下的 Cmd+C 会被注入流程静默抹掉
- 检查更新失败会被呈现成「已是最新」 — 网络或服务异常时你看到的是一个假的安心结论。现在如实告知检查失败
- 同版本号的修复包收不到更新提示 — 此前只比较版本号,不看 build 号
- 断点续传可能把半个包当成完整包 — 现在下载走
.part临时文件 + 完成标记,续传时校验服务端返回的 Range 起点与总长 - 升级重启后可能 App 退了、更新却没起来 — 安装脚本改为确认启动成功后 App 才落盘退出
- macOS 上所有 SnackBar 提示都是坏的,其中「导出 / 导入配置」整个功能坏死 — 本 App 的窗口根节点没有 SnackBar 所需的祖先组件,调用必然抛异常;而导出、导入把这个调用写在了按钮响应的第一句,对话框根本弹不出来,点了完全没反应。另外 8 处(账单页、模式页「已保存」、关于页导入导出、日志打包、聊天页)表现为提示静默丢失。全部改走 App 内真正接了消费者的通知系统
- 聊天页的「复制」按钮是个空函数;「存为笔记」不检查成败,失败也显示成功
- 云账户弹窗连点保存会重复提交;保存失败后按钮永久禁用,只能重开弹窗
- 词典 CSV 解析下沉到服务层,词库加载不再与首次识别抢跑
- 升级流程存在命令注入(P0) — 远端返回的版本号被原样拼进升级脚本,只要其中含引号即可闭合并执行任意命令,且发生在签名校验之前。现在两个版本来源统一收口,只放行纯数字的三段版本号,非法值一律视为没拿到更新信息
- 云账户导出会写出明文密钥(P0) — v1.9.0 做的「导出排除密钥」只覆盖了配置备份,云账户导出这条同源路径漏了,而它就挂在普通用户的按钮上、弹窗也没有任何提示。现在只导出字段名清单,密钥值由你导入后重填
- 日志里的敏感信息脱敏残留清零;配置备份与云账户导出都不再迁移本机身份标识
- 英文界面下不再中英混杂 — 云账户页 23 处、聊天页 17 处,以及工具确认弹窗、词典、模式、关于页、各类错误提示中的硬编码中文全部改走本地化,并清掉 40 个过期文案条目
- 系统权限说明随包提供中英文 — 首次授权时麦克风、辅助功能弹窗里的说明文字会跟随系统语言
- 状态栏、录音浮窗与通知的状态文案改由结构化事件驱动,不再靠匹配中文字符串判断状态
- 逐模块(UI / Config / Models / 模型管理 / Services / Engine / FFI / 原生与 macOS 集成 / 网关更新与统计链)走完 review → 修复 → 复审,直到最新一轮无 P2+ 缺陷
- 测试口径从「源码里能找到这行」升级为行为验证:新增测试均配变异探针(把被守护的代码改坏,确认测试真的变红),并新增可执行的原生并发宿主验证事务交错
- 网关的版本上报改为有界统计,
/stats分页兼容旧数据并按平台上限批量读取
- 默认模型随包内置,装完即用 — 此前首次启动必须先下载 229MB 的 SenseVoice 才能说第一句话,网络差时这一步很容易劝退。现在默认模型直接打进安装包:安装包从 50MB 变为约 212MB,但用户总下载量基本不变(原本是 50MB 安装包 + 165MB 模型包),且省掉了首启等待与下载失败的风险。选择其他模型仍按需下载
- 超能力从 5 个减到 3 个 — 保留「闪念笔记 / AI 梳理 / 即时翻译」,移除「纠错反馈」和「AI 一键调试」。这两个功能使用频次低、维护面却很宽(纠错反馈要为每次录音构造完整 pipeline trace,AI 一键调试要维护基础键+数字槽位的组合热键、截屏、窗口激活)。移除后代码净减 1663 行
- 不再需要「屏幕录制」权限 — 截屏仅「AI 一键调试」使用,功能移除后该权限一并取消。首次安装的授权项从 4 项降到 3 项(输入监控 / 辅助功能 / 麦克风)
- 云账户页默认只展示常用服务商 — 此前会把全部 15 家一次铺开。现在默认显示已配置、已启用以及推荐的几家(阿里云百炼 / DeepSeek / OpenAI / Groq),其余收进「更多服务商」随时可展开。能力不变,只是不再一上来就糊一屏
- 云端识别模式此前完全不可用 — 切到云端后按快捷键没有任何反应,日志报
Aliyun Config Missing,指向的却是早已废弃的「阿里云 NLS 旧版」。根因是走云账户体系的前提是用户显式选过 ASR 账户,而多数人从未主动选择,于是一路掉进 legacy 分支。现补上账户兜底(凭证完整性按能力判断,讯飞需 app_id+api_key+api_secret、火山需独立的 asr_api_key) - 界面显示的服务商与实际连接的不一致 — 下拉里勾着「火山引擎」,引擎实际连的却是阿里云百炼;而且那个「已选中」从不落盘。根因是 UI 与引擎各写了一套回退逻辑。现收敛为唯一入口,两边读同一份判断
- 火山引擎 ASR 自接入起从未跑通 — 二进制帧解析漏了协议中的序列号字段,
payload_size读成了序列号,识别结果永远为空。此前无人发现,是因为默认走阿里云百炼,而想手动切到火山又被上面两个问题挡住 - 火山的服务端错误全部被吞掉 — 错误帧布局与普通响应不同(错误码在前),却按同一路径解析,错误码被当成长度后静默丢弃。鉴权失败、配额超限、参数错误都只表现为「等待超时 + 空结果」。现错误帧独立处理,会给出真实错误码与信息
- 长语音只保留最后一段的隐患 — 请求参数改用全量返回模式,与客户端的取值方式对齐
- Kimi 账户 100% 调用失败 — Kimi K 系列只接受
temperature=1,而程序固定传 0.3,服务端直接返回 400。现对整个 K 系列(含 K3 及各渠道转售形式)特殊处理;默认模型同时从 K2.5 换为 K2.6,实测中位耗时从 13.0s 降到 6.8s - 讯飞的 LLM 凭证判断错误 — 推荐逻辑只检查
api_key,而讯飞 LLM 用的是api_password;它另有一个供语音识别用的api_key,导致「只配了语音识别」的讯飞账户会被选去做润色然后失败 - DeepSeek 旧模型别名已停用,自动迁移到 V4-Flash —
deepseek-chat/deepseek-reasoner已于 2026-07-24 被官方永久停用(无宽限期),仍配置这两个名字的用户 AI 润色会直接调用失败。现默认改为deepseek-v4-flash,并在启动时自动迁移存量配置(全局模型设置 + 云账户内保存的模型名)。按官方映射,两个旧别名都对应 V4-Flash 且价格不变;未迁往v4-pro,那是另一档、单价约 3 倍
- 翻译模式下无法切换识别引擎 — 「输入=自动检测 + 输出=简体中文」这一常见配置会被判定为翻译模式,进而把「纯离线 / 云端识别」两张卡片全部锁死且不给任何说明。翻译实际只发生在润色环节,与用哪种识别引擎无关,该限制是早期版本的遗留
- 引导页「现在试一次」按快捷键无反应 — 完成页从未启动键盘监听;从「上次停在完成页」恢复进入时,语音模型也不会重建
- 说话中途被误报「未检测到声音,请检查麦克风」 — 原判据是「连续 2 秒无声」,换气和思考停顿必然触发。现仅在整段录音自始至终没有捕获到任何声音时才提示
- Flutter 应用完全收不到注入的文字 — 合成的 Cmd+V 缺少 Command 键自身的按下/抬起、缺少设备相关标志位,且四个事件连发会被系统合并。原生控件与 Chromium 对此宽容,唯独 Flutter 认不出。同一缺陷还影响 AI 梳理所用的 Cmd+C
- 注入后剪贴板还原可能覆盖你新复制的内容 — 还原前比对剪贴板变更计数,已易主则放弃还原;还原等待时间也从 200ms 放宽到 800ms(Electron 类应用读取剪贴板明显更慢)
- 概览页仍在宣传已移除的「纠错反馈 / AI 调试」
- 导出配置写着「含明文密钥」,实际会先询问且默认不含
- AI Plus 页提示「请到识别引擎页打开 AI 润色开关」,而同一张卡片里就有那个开关
- 「自动优化音频」声称蓝牙时自动切换麦克风,实际只是弹提醒等你点;已改名为「蓝牙麦克风提醒」并如实描述
- 侧栏「超能力」分区标题与其下条目同名,屏幕上连着出现两次
- 长按与单击设为同一个键时不再无从分辨——补上「按住超过 1 秒为长按」的说明
- AI Plus 的模型选型参考数据过期三个月,更新为最新实测值
- 「AI 润色」不受影响,仍是可独立开关、可叠加在本地/云端任一模式上的能力
- 已设置过被移除功能的快捷键不会再触发;SharedPreferences 中的旧配置项成为无害的孤儿数据,不影响使用
- 新增云端服务商基准测试工具(质量 + 延迟),并把「代码内写死的模型清单 vs 线上实际可用」对账加入发版清单——DeepSeek 停用旧模型那次就是这么炸的
- 新增架构约束测试,防止「界面显示 A、实际用 B」再度出现
- 补齐参数特判与账户兜底的回归测试;新增剪贴板竞态的原生层验证工具
- 模型下载测试可按带宽裁剪(
MODEL_TEST_MAX_MB),并修掉了一个会让整轮测试级联崩塌的隔离缺陷
- 清理工作模式简化遗留的"智能模式"文案 — v1.9.0 将"智能模式"降级为独立「AI 润色」开关后,识别引擎页仍有两处引用已不存在的"智能/Smart 模式":① 开启 AI 润色做翻译时,横幅仍误报"请切换到「智能模式」";② "Smart 模式需在 AI Plus 配置 LLM"。现修正为按 AI 润色开关状态判断显示、文案统一为「AI 润色」
- 工作模式简化为「本地 / 云端」+ 独立「AI 润色」开关 — 此前三模式(离线 / 智能 / 云端)中,"智能"实际只是"离线识别 + AI 润色"、并非自动选择,容易让人误以为系统会自动判断网络/隐私/延迟。现简化为两个识别模式(本地 / 云端),AI 润色升级为可独立开关、可叠加在任一模式上。旧"智能"用户自动迁移为「本地 + AI 润色开」,无感知
- 超能力入口合并 — 设置侧栏的 5 个超能力入口(闪念笔记 / AI 梳理 / 即时翻译 / 纠错反馈 / AI 调试)合并为单一「⚡超能力」入口,一页展示,减少侧栏层级
- 删除当前使用的模型不再卡住 — 删除正在使用的识别模型时自动切换到其他已下载模型,不再留下悬空状态(此前需重启才能恢复)
- LLM 模型与账户绑定 — 切换 LLM 服务商时不再误把上一个服务商的自定义模型名带过去
- 云端识别失败不再显示"无语音" — OpenAI / Groq / 阿里云 NLS 在鉴权失败、欠费、网络错误时,现在显示真实错误提示,而非误导性的"未检测到语音"导致用户反复重试
- 自更新安全加固 — ① 原子安装:先复制新版到临时位置、校验通过后再替换,失败自动回滚,不再"先删旧版再复制"(复制失败会丢失 app);② 安装前强制校验代码签名(Developer ID + Team ID + Bundle ID),来源被篡改则拒绝;③ 下载增加超时;④ 关于页新增安装完成态入口
- 配置导出默认排除密钥 — 导出配置默认不含 API Key / AccessKey 等凭证(可手动选择包含);更新云账户时清理已移除的残留凭证
- 阿里云 token 接口改用 HTTPS
- Gateway
/stats运营数据接口加管理员鉴权、补齐 CORS,鉴权改为 fail-closed - 关闭详细日志时释放日志文件句柄与定时器
- LLM 默认兜底走推荐优先级,避开豆包 lite — 此前
selectedLlmAccountId失效或为空时回退到账户列表第一个,一般是火山豆包 lite。豆包 lite 对 prompt 元评论禁令服从性差,模糊语音输入下会输出"这段文本不太清晰…仅供参考…"等多余解释段落(实测一次 63 字 ASR → 342 字 LLM 输出,含 280 字元评论)。新增pickRecommendedLlmAccount()helper 按 [DeepSeek > Anthropic > OpenAI > 智谱 > 阿里云百炼 > Kimi > Gemini > MiniMax > 火山 > Groq > 讯飞] 顺序兜底已配 API key 的账户 - LLM 模糊语音输入加禁止元评论 — system prompt 第 5 条扩写:禁止任何解释/评论/建议/追问/Markdown/标签或引号包裹;含两个 few-shot 示例(含模糊输入反例)。跨模型通用约束
- Dock 图标点击恢复窗口 + 托盘 Quit 真退出 — Dock 图标点击不再无响应,正确恢复主窗口;托盘 Quit 真退出(此前只 hide)
- DeepSeek V4 默认关 thinking mode — V4 升级后默认开 thinking 导致 LLM 调用慢一倍,关掉恢复正常性能
- 设置 sidebar「前往账户中心配置」跳转修复 — 此前点击无反应;sidebar 同步加云账户入口
- DeepSeek 升级到 V4 系列 — DeepSeek V4 Flash(推荐,1M 上下文)/ V4 Pro 双预设;测速脚本同步修复
- 引入 AGENTS.md 文档体系(4 层结构) — 根 AGENTS + 6 个子模块 AGENTS(lib/engine、lib/services、lib/ui、lib/ffi、native_lib、gateway)+ 5 个 ADR(不上 Sparkle / 剪贴板注入 / 云账户体系 / Context-Aware 试点策略 / V4 thinking 默认关)+ 6 个反模式归档。改代码前按层查,避免重新 Discover
- AX Probe Phase 0 探针 —
tools/ax_probe/独立 Swift menu bar app,全局 F19 热键 + 状态栏菜单 dump 当前焦点 AX 上下文(焦点元素 / 选区 / 周边 / 父链 / 浏览器 URL)。Context-Aware Voice (v1.9 规划中) 的 macOS Accessibility 能力探测工具
- 设置 → 识别引擎 页面布局重排
- "语言设置"单卡拆成"输入语言"和"输出语言"两张并列卡,移到模式选择上方(语言决定后续模型语种,逻辑上应先选)
- 模型卡片改为高级开关二态切换:关显示「当前模型」信息卡,开显示「非流式模型库」操作大卡。之前两张卡同时显示且标题撞名(都是"非流式模型(高精度)")易混淆
- 通用页权限卡加授权状态徽标 — 辅助功能 / 输入监听 / 麦克风 / 屏幕录制 4 张卡现在显示「已授权 / 未授权」徽标,无需切到系统设置才能确认
- 录音 WAV 调试文件只剩 0.2s 残尾 —
save_recording_wav之前用ringReadPos算起点,ASR 流式消费 ring buffer 后 readPos 已追上 writePos,保存出来只剩最后一个 chunk。改用独立recordingStartPos记录录音起点后保存完整音频- 仅影响开发者模式下的
~/Library/Application Support/com.speakout.speakout/recordings/调试文件,不影响 ASR 识别本身
- 仅影响开发者模式下的
- 断点续传 — 下载中断(关电脑、断网、app 退出等)后重试会从断点继续下,不再每次从头 53 MB 重下
- HTTP
Range: bytes=N-请求,206 响应 append 写入 - GitHub Release DMG 走 Azure Blob CDN 原生支持 Range
- 服务器不认 Range 时自动 fallback 全量
- 416 Range Not Satisfiable(partial 文件过期)自动删除重试
- HTTP
- 下载失败时保留 partial 文件 — 此前失败会 delete partial,浪费已下载的字节;现在保留供下次续传
- 大小校验 — 下载完对比
Content-Length,不一致判失败;文件小于 20 MB 视为损坏自动删除 - failed 状态显示错误原因 — 此前只有「重试」按钮不告诉你失败原因。现在 pill 旁边显示错误摘要(HTTP 状态、异常描述),hover 看完整
errorMessage
- 自动更新 DMG 重复下载 — 此前每次点「下载更新」都完整下载 53 MB,app 重启后 state 重置还会再下(Surge 流量监控显示过 11.95 GB 浪费)。现在:
- DMG 路径带版本号(
SpeakOut-update-{version}.dmg),不同版本不串台 - 检测到新版后扫描
$TMPDIR有无完整缓存,存在则跳过下载直接「安装并重启」 - 下载中防并发:重复点击不会启动第二次下载
- 启动时清理旧版本 DMG 缓存
- DMG 路径带版本号(
- AI 调试屏幕录制权限前置检查 — 未授权时 AI 调试页顶部显示橙色警告横幅 +「打开系统设置」按钮。之前漏给此权限会静默导致绑定目标窗口只显示 App 名("终端"),没窗口标题
- 通用页权限段新增「屏幕录制」卡 — AI 调试必需权限(macOS 10.15+ 读取其他 app
kCGWindowName要求),之前只列了辅助功能/输入监控/麦克风 3 个漏了这个
- 修复「安装并重启」后弹出 DMG 让手动拖的 bug — root cause: helper 脚本用
awk '{print $NF}'解析 hdiutil 挂载点,遇到带空格的 mount point(如/Volumes/SpeakOut 1,发生在用户已经手动开过 DMG 时)只取到"1",找不到 .app,触发 fallback 弹 DMG - 新逻辑:
- 用
hdiutil -plist输出,从<string>/Volumes/...</string>直接 grep(天然支持空格/unicode) - 启动前先 detach 所有
/Volumes/SpeakOut*避免占用导致系统重命名 - mount 命令兜底解析
- 全程详细日志写到
~/Library/Logs/speakout-updater.log,下次出问题直接看日志定位
- 用
- NSTask 输出也改写到日志(之前 /dev/null,启动期失败完全看不见)
⚠️ 老用户(v1.8.0/1.8.1)首次升级到 v1.8.2 仍可能触发 bug(修复在新版的代码里)。如果点「安装并重启」后弹出 DMG 窗口,请手动把 SpeakOut 拖到 Applications 完成。升到 v1.8.2 之后,下次再升级就稳了。
- 设置页一键更新 — 设置 → 概览检测到新版后显示「下载更新」按钮,支持后台下载(带进度条)+「安装并重启」一键升级(之前需手动去 GitHub 下载)
- 状态化 UI:橙色「下载更新 vX.Y.Z」→ 蓝色「下载中 X%」→ 绿色「安装并重启」→ 失败可「重试」
- 专业词汇标注 Beta — 标题旁加橙色 Beta 徽章,关闭状态显示「试验性功能,准确率因 LLM 模型而异,正在持续优化」
- 横 5-Tab → 左侧 Sidebar — 概览 / 通用 / 识别引擎 / AI Plus / 词典 / 5 个超能力 / 开发者选项,按功能分组,找配置不再靠记忆
- 概览页 — App 图标 + 版本 + 检查更新置顶,4 个核心功能卡片直达,新用户首次打开就明白能干什么
- 通用页三合一 — 快捷键、基础设置、系统权限合到一页,按使用频率排序,权限缺失时橙色警告横幅兜底
- 录制 Modal — 弹窗式录制,8s 倒计时 + 实时按键预览,ESC 取消
- 冲突检测 — 设置时实时检查与所有功能键冲突,弹窗提示
- 每个键旁加 × 清除 — 不想用直接清空
- 单击说话(Tap to Talk) — 原"单击切换 (Toggle)"改名,行为更清晰
- 最大录音时长 — 单击说话时未主动停止可自动结束(1/3/5/10 分钟可选)
- 闪念笔记 / AI 梳理 / 即时翻译 / 纠错反馈 / AI 调试 — 每个独立成页
- Hero 常驻 — 启用前后位置不变,禁用时显示 3 条功能 bullets 引导
- 统一标题区 — 大图标 + 标题 + 描述 + 紧凑 header
- LLM 单下拉合并 — 服务商 × 模型平铺为一个下拉,每个服务商末尾"自定义..."项可填模型名
- 凭证集中管理 — 云账户页统一编辑,不再散落各处
- 一键导出日志包 — 系统日志 + 应用详细日志 + 诊断信息打包为 zip,报 bug 时一个文件搞定(原"系统日志"只导出 macOS log)
- 页面整理 — 模型目录挪到末尾(脱离日志语义)
- README 补充微信二维码 + X (@4over7)
- 旧 5-Tab 设置页整套移除,sidebar 成为唯一设置入口
- 140+ i18n key 补充,中英文全覆盖
- 测试用例 598 全过
- 长按 modifier 键瞬时断开修复 — 长按 Right Option / Left Option / Shift / Command / Fn 等 modifier 作为 PTT 键时,录音约 600ms 后自动断开、悬浮窗只闪一下。根因:watchdog 用的
CGEventSourceKeyState对 modifier 键不可靠,连续 3 次误报为"已松开"就强制停止。改用CGEventSourceFlagsState+ device-specific mask 判断,与事件监听逻辑一致,能正确区分 Left/Right modifier。
- 修复组合键设置失败 — 之前按 Cmd+K 会被错误记成 Left Command。新增延迟捕获逻辑:非修饰键立即捕获,修饰键等待 400ms 看是否有后续按键组合
- Cmd+K 和 Option+K 可共存 — 运行时改为精确匹配,不再把
Cmd+Shift+K错当Cmd+K触发;设置侧冲突检测与运行时完全对齐 - 每个热键旁加 × 清除按钮 — 忘记设的是什么键?一键清空重设
- 主页取消录音按钮 — 录音中的主页显示"取消录音"按钮,不记得热键时也能终止
- 按键名映射补全 — 显示 "K" 而不是 "Key 40",字母、数字、功能键、小键盘、导航键全覆盖
- 分别诊断输入监控 / 辅助功能 — 之前只检查辅助功能,现在精确告知缺哪项权限
- 从系统设置返回自动恢复 — 不再依赖错误文案字符串匹配,基于真实权限状态
- 引导页权限跳转后轮询检测 — 用户操作完系统设置自动识别,不再只等 2 秒
- 降级状态正确显示 — 缺辅助功能但有输入监控时显示 Warning,不再误报"已就绪"
- 闪念笔记关闭后冲突误报修复 — 之前主开关关了但 toggle 键还被算作占用
- 弹窗文案修正 — 冲突提示改用真实功能名,不再固定写"文本注入和闪念笔记"
- 词库去重 — 同一词条多次反馈只保留最新版本,不再膨胀
- 导入去重 — 同一文件内或跨次导入都按 timestamp 去重
- Finder 列表/系统权限列表不再糊 — 补全 icns 的 10 个尺寸(原本只有 4 个,缺 32/64/256/512/1024)
- flutter analyze: 55 → 0 issues — 清理未使用 import/field/element、BuildContext async gap、测试脚本 print 等
- 新增 30 个热键语义测试 — 覆盖运行时 modifiersMatch、设置侧 findHotkeyConflict、HotkeyCapturer 捕获流程、跨层一致性
- 文档说真话 — README/CHANGELOG 修正过时表述(凭证存储、日志隐私、测试基线)
- 为 AI Coding 而生 — 按住快捷键截屏+语音描述 bug,松开后自动发送到绑定的 AI 工具窗口
- 支持绑定多个窗口(最多 5 个),基础按键 + 数字键(1-5)快速选择目标
- 自动采集前台 App 名称和窗口标题,报告包含截图路径+文字描述+环境信息
- 兼容 Claude Code (Ghostty/Terminal)、Cursor 等主流 AI 编程工具
- 卡片最小高度 100px,双列布局更整齐
- 快捷键一览改为双列网格,只显示已启用项
- 各功能描述文案优化,突出产品价值
- 「启用 AI 梳理」简化为「AI 梳理」
- install.sh 改为热替换,开发中不再中断正在运行的 SpeakOut
- 原生层默认日志目录统一到 Application Support(与 Dart 层一致)
- 每段累积 ≥30 秒才允许分段,避免短片段降低识别质量
- 每段保持在 ASR 模型最优时长区间(30-60s)
- PTT 和 Toggle 允许设为同一个键(短按=切换,长按=按住说话)
- 新安装默认 PTT 键改为 Right Option(减少冲突)
- 通用 Tab 下拉框宽度统一
- 语音输入 Tab 左右布局优化(语言/快捷键左,AI 配置右)
- 删除废弃代码(-1029 行)
- 全新配色:翡翠绿主题(深色 #00B074 / 浅色 #009660),深浅模式自适应
- 窗口放大:800×600 → 960×720
- 设置页重构:Sidebar 替换为水平 Tab 栏,Tab 结构重组为 通用 | 语音输入 | ⚡超能力 | 云账户 | 关于
- 卡片化布局:所有设置项改为双列卡片网格,消灭留白
- 语音输入 Tab:三列模式选择卡 + AI 润色/语言/快捷键/模型双列配置 + 模式切换动画
- ⚡超能力 Tab:闪念笔记/AI 梳理/即时翻译/纠错反馈 四大功能独立卡片展示,彩色左边框区分
- 云账户:预置所有服务商(新用户不再空白页),双列卡片,未配置显示"配置"按钮
- 聊天页:气泡样式改为时间线布局(日期分组 + 左侧时间轴 + 右侧内容卡片)
- 专业词汇:行业词典(左) | 个人词库+说明(右) 双列布局
- 录音中检测到 3 秒停顿,自动将已积累音频发送给离线模型后台解码
- 分段切点选在停顿起始处(最后有声音的 chunk),避免切入新语音
- 停止录音时只需解码最后一段,显著减少等待时间
- 修复闪念笔记目录已授权仍显示警告的问题
- 修复云账户列表排序导致的 unmodifiable list 崩溃
- 一键纠错 — 修改识别错误后按纠错快捷键,自动对比并学习词汇(Cmd+A 全选 → Cmd+C → LLM 提取差异)
- 纠错数据导出/导入(JSONL 格式)
- 云服务账户页面新增"导入"和"导出"按钮
- 支持跨设备迁移账户配置(含凭证)
- 修复 6 处资源泄漏:CoreEngine Timer、ChatService/NotificationService/UpdateService StreamController、AppLog Timer
- 新增 AppService.dispose() 统一资源清理
- Dart 回退路径改用
extractFileToDisk()全流式解压,大模型不再需要整个文件加载到内存
- DMG 签名改用 Developer ID Application 证书
- 新增 Apple Notarization(公证),用户下载后双击即可打开,无 Gatekeeper 警告
- 所有 Frameworks/dylib 递归签名 + hardened runtime + 安全时间戳
- 主界面 AI 润色标签可点击,跳转聊天页查看 ASR vs LLM 对比详情
- 所有快捷键允许清空(包括 PTT 和闪念笔记 PTT)
- 系统权限区新增签名变更提示横幅
- Watchdog 改为连续 3 次确认,减少修饰键误判
- 双渠道编译 —
--dart-define=DISTRIBUTION=appstore控制 App Store / GitHub 版本差异 - App Store 版本自动禁用更新检查和自动更新功能
- 新增
AppStore.entitlements(沙盒模式)+build_appstore.sh打包脚本 - 新增
NSAccessibilityUsageDescription隐私描述 - 关于页新增隐私政策链接
- 翻译快捷键优先级提升,不再被 PTT/shared key 拦截
- 翻译录音跳过 watchdog(修饰键 CGEventSourceKeyState 不可靠)
- 闪念笔记关闭时 toggle 快捷键不再拦截按键
- 交叉冲突检测只检查已启用功能,已关闭功能不阻止设置
- 冲突弹窗提示,不再静默拒绝
- DMG 下载 URL 改从 Gateway 获取(私有仓库 GitHub API 不返回 assets)
- 通用设置新增「系统权限」快捷入口(辅助功能/输入监控/麦克风)
- 关于页版本号与 tagline 间距调整
⚠️ 本版本更换了代码签名证书,更新后需在「系统设置 → 隐私与安全性」中重新授权「输入监控」和「辅助功能」。
- 一键翻译 — 按住翻译快捷键说话,结果自动翻译为目标语言,不影响正常录音设置
- 即使 AI 润色关闭也能触发翻译(临时启用 LLM)
- 触发方式 tab 新增翻译设置(快捷键 + 目标语言)
- 点击即更新 — 发现新版本后点击横幅直接下载 DMG,带进度条显示
- 下载完成后一键"安装并重启",无需手动操作
- 无 DMG 时自动回退到浏览器下载
- 全局快捷键一览 — 触发方式 tab 底部新增总览面板,展示所有功能快捷键及启用状态
- 智能冲突检测 — 已关闭功能的快捷键不阻止其他功能设置;重新启用时若冲突则自动清除
- 冲突弹窗提示,不再静默拒绝
- 新增 8 款非流式模型 — FireRedASR v2 CTC (496MB)、SenseVoice+FunASR Nano (179MB)、Whisper Turbo (538MB)、Dolphin Base (77MB) 等,按推荐度排序
- 隐藏 8 款不合格模型 — Zipformer(重复)、TeleSpeech(质量极差)、Whisper Large-v3/Distil/AISHELL(中文差)、FunASR Nano/Moonshine(SDK 不兼容)、FireRedASR v1(被 v2 取代)
- 标点模型自动联动 — 切换到无标点模型时自动加载标点模型或弹窗提示下载
- 模型激活失败回滚 — 初始化失败不再误显示"使用中",自动恢复上一个可用模型
- sherpa-onnx SDK 升级 — 1.12.28 → 1.12.33
- 三态显示 — 成功(✨ AI 润色 · 精简 X 字)、无修改(✨ AI 润色 · 无修改)、失败(
⚠️ AI 润色未生效) - 用户可直观判断 LLM 是否正常工作
- 日志目录修复 — AppLog 正确读取用户设置的日志目录,Dart 和原生层日志统一
- i18n 修正 — "离线模式/模型"统一为"非流式模型",避免与工作模式概念混淆
- 诊断日志增强 — OfflineSherpaProvider 记录模型名、chunks 数、samples 数
- 根目录精简 — 移除 wiki 子模块、tools 目录、.metadata、视频文件
- 557 测试通过
- 主界面润色标签 — 语音输入后结果气泡底部显示「✨ AI 润色 · 精简 X 字」,直观体现智能模式价值
- 聊天页对比详情 — Dictation 气泡可折叠展开查看 ASR 原始识别文字,对比 LLM 润色改动
- 日志完整记录 — ASR 和 LLM 输出不再截断,完整记录每步文字变化,便于调试和案例分析
- 设备自动刷新 — 插拔音频设备时设置页列表自动更新,无需退出重进
- 切换内置麦克风修复 — 点击"切换到内置麦克风"按钮现在正确生效并持久化
- 蓝牙警告精准化 — 仅在"系统默认"且系统默认为蓝牙时显示警告,用户手动选择设备后不再打扰
- AI 梳理 — 选中任意文字按快捷键,AI 深度重组逻辑结构、专业化表达,结果追加在原文下一行(不替换原文)
- LLM 选型推荐 — 智能模式配置区新增选型参考,基于实测数据推荐 DeepSeek(最快 129ms)和阿里云百炼 qwen-turbo(最稳定 573ms)
- 讯飞未验证警告 — 讯飞服务商标记"未验证",云账户编辑对话框和列表卡片显示橙色警告
- 设置页新增「AI 梳理」tab,含启用开关、快捷键配置、可自定义 prompt
- 悬浮窗蓝绿色 (#1ABC9C) 配色,区分语音输入(绿色)和闪念笔记(紫色)
- 复用工作模式中已配置的 LLM 服务商,无需额外配置
- 支持所有文字编辑场景:邮件改写、笔记整理、消息润色
- 闪念笔记紫色悬浮窗 — 录音悬浮窗按模式显示不同颜色(语音输入=绿色,闪念笔记=紫色)
- 配置导出/导入 — 关于页新增配置备份功能,导出所有设置和凭证到 JSON 文件,一键恢复
- 凭证可见性切换 — 云服务账户编辑时密钥输入框支持眼睛图标切换明文/密文
- 测试连接分行显示 — LLM 和 ASR 测试结果各一行,清晰标注每项服务状态
- 离线模型 30 秒提醒 — Toggle 模式下录音超过 30 秒时提示效果可能下降
- 打字机模式全应用支持 — 终端应用不再跳过打字机效果
- LLM 性能对比 — Wiki 页面 提供各服务商延迟实测数据
- 火山引擎 ASR 简化 — 切换到新版单 API Key 鉴权(旧版 3 字段 → 1 字段)
- MiniMax URL 修正 — 国内接口地址已更新
- LLM 超时时间调整 — 流式首 token 8 秒(更短),非流式完整结果 15 秒(更长)
- 悬浮窗模式切换 — 从笔记切到语音输入时颜色正确更新
- 云服务账户启用校验 — 凭证未填写时禁止启用
- 凭证存储回退 SharedPreferences — 解决 Keychain 签名不稳定导致凭证丢失
- 讯飞 LLM 凭证字段修复 —
api_password不再被当作api_key读取,讯飞 LLM 现在可正常使用 - 云端 ASR 多语言过滤 — 云端模式下输入语言下拉仅显示当前 ASR 模型支持的语言,不再静默退回中文
- 删除账户清理选择 — 删除正在使用的云服务账户后,自动清理已选 ID,防止重启后走错分支
- 测试隔离修复 — 修复单独执行时失败的 LLM 测试用例
- 常量集中管理 — 约 25 个硬编码常量收拢到 AppConstants,每个加注释
- Ring buffer 扩容 — 30s → 60s(容错余量)
- 开发者模式录音保存 — 保留最近 10 次录音 WAV 文件,便于调试
- 付费系统 — 完整实现(Gateway + 客户端),暂隐藏等待支付宝开通
- 图标 squircle 圆角 — 所有 macOS 版本显示统一圆角(Big Sur~Tahoe 兼容)
- 静态分析清理 —
dart analyze lib test大幅清理(后续版本新增代码引入部分新 warning) - Flaky test 修复 — 测试套件稳定通过(后续版本测试数已增至 564+)
- 凭证迁移到系统 Keychain —
⚠️ 已在 v1.5.17 回退至 SharedPreferences(Keychain 签名不稳定导致凭证丢失) - 日志隐私治理 — LLMService/CoreEngine 日志统一走 AppLog;
⚠️ 开启详细日志后仍会记录原始输入/输出文本用于调试
- 火山引擎 Seed-ASR — V3 BigModel 二进制帧协议,中文精度最高
- 讯飞实时语音听写 — WebSocket 流式识别,支持 202 种方言
- 腾讯云实时语音识别 — WebSocket 流式识别,每月 5 小时免费
- LLM 15 秒超时保护 — API 卡住时自动放弃润色,直接输出原文
- AppLog 异步缓冲 — 日志不再阻塞主线程,try-catch 兜底永不 crash 调用方
- Gateway 版本自动同步 — build 脚本自动从 pubspec.yaml 同步版本号
- 静态分析 warning 清零 — 0 warning, 531 测试通过
- 剪贴板注入替代键盘事件 — GUI 应用统一使用 Cmd+V 粘贴注入,解决微信等重 UI 应用长文本丢字问题;剪贴板内容 200ms 后自动恢复(含富文本)
- 语言设置移入工作模式 — 输入/输出语言与工作模式在同一页面,所见即所得
- 口译模式联动 — 输出语言与输入不同时,自动灰掉不支持翻译的离线/云端模式
- 新增 5 种语言 — 西班牙语、法语、德语、俄语、葡萄牙语,输入输出均可选
- 模型按语言过滤 — 高级设置中,模型列表根据输入语言自动过滤
- 语言文案优化 — 输入语言"自动检测"、输出语言"跟随输入语言",消除歧义
- 录音卡死修复 — stopRecording 用 try/finally 保证状态恢复,LLM 超时或注入失败不再导致快捷键失效
- 打字机模式保护 — LLM 流出错时确保剪贴板会话正确结束
- OpenAI ASR 语言硬编码 — 不再强制中文,改为根据输入语言动态设置
- 翻译模式检测 — 输入=自动检测 + 输出=指定语言时,正确识别为翻译模式
- DashScope 超时修复 — 说完话后偶发文字未注入的问题:
stop()改为等待服务器返回task-finished事件(最多 4s),替代原来的盲等 500ms;CoreEngine 超时从 2s 放宽到 6s
- 云端 ASR 无法识别 — DashScope 模型名修正为
paraformer-realtime-v2(原paraformer-v2不支持 WebSocket 流式协议) - DashScope 错误提示 — 鉴权失败等错误现在在悬浮窗显示真实错误码,而非 "Unknown error"
- LLM 模型选择不生效 — 修复 AI 润色始终使用服务商默认模型的问题,现在正确使用用户选择的模型
- LLM 测试按钮报错 — 修复"API Key 未设置"误报,现在正确读取已保存账户的凭证
- Groq whisper-turbo 价格 — 修正为 $0.04/h(0.29 元/h),之前显示错误
- 账户测试连接 — 云服务账户编辑对话框新增"测试连接"按钮,保存前可验证 LLM 凭证是否有效
- 笔记目录权限验证 — 开启闪念笔记模式时自动检测目录写入权限,无法写入时显示红色警告并引导重新授权
- Groq:移除已废弃的
gemma2-9b-it;Kimi K2 model ID 更新为kimi-k2-instruct-0905 - 智谱:
glm-4-airx修正为glm-z1-airx - Gemini:默认模型改为
gemini-2.5-flash;gemini-2.0-flash标注将于 2026-06 下线 - 火山引擎:豆包 LLM 价格修正(之前偏高约 20x)
- 日志目录文案修正:空状态不再误导显示"~/Downloads(默认)"
- Left/Right 修饰键区分 — 用 device-specific modifier masks 替代共用 flag,修复按住 Left Option 时按 Right Option 导致录音无法停止的问题
- 日志增强 — FlagsChanged 事件同时记录 Left/Right Option 的 keyCode 和 devFlags
- 组合键触发 — 支持如 "L.Cmd + Right Option" 等组合键作为热键,减少误触发
- 自动识别 — 设置热键时自动捕获当前按住的修饰键,显示组合名称
- 全链路支持 — 原生层传递 modifier flags → FFI → CoreEngine 匹配 → ConfigService 存储
- 持久更新横幅 — 检测到新版本后,主界面左下角常驻橙色 "x.x.x 可用" 提示,直到用户更新
- 下载按钮 — 关于页检测到新版本时显示"查看更新"按钮,点击直接打开下载页
- 不再自动消失 — 去掉 10 秒自动消失的临时通知,避免用户错过更新
- 合并设置 Tab — 将"语音模型"和"AI 润色"合并为"工作模式",设置页从 6 个 tab 精简为 5 个
- 三种模式 — 纯离线(绿)、智能模式(蓝/推荐)、云端识别(橙),一键切换
- 差异化视觉 — 选中模式加左色条 + 浅色背景高亮,三种模式各有专属颜色
- 向后兼容 — 旧用户升级后自动从已有配置推断对应模式
- Sidebar 跟随主题 — 禁用原生 vibrancy,亮色模式下 sidebar 正确显示浅灰色背景
- Sidebar 文字可见 — 未选中的 tab 文字/图标在亮色模式下使用深灰色
- 推荐 Badge — 改为实心填充背景,更醒目
- 窗口隐藏 — 点击关闭按钮时最小化到系统托盘,而非退出应用
- 托盘菜单 — Show / Hide / Quit,Quit 真正退出
- 后台运行 — 关闭窗口后语音输入功能继续在后台工作
- 麦克风无声提醒 — 录音开始后连续 2 秒未检测到音频信号,自动提醒用户检查麦克风
- 悬浮窗微提示 — 悬浮窗下方显示半透明小标签("🎤 未检测到声音"),不干扰主界面
- 主界面 Banner — 同时在主界面显示非阻塞通知
- 全程监测 — 整个录音过程持续检测,10 秒冷却避免重复提醒;检测到声音后自动隐藏提示
- 跨功能排他 — 文本注入和闪念笔记的热键不允许设置为相同按键
- 实时检测 — 设置时即时弹出提示对话框,告知冲突原因
- 自动跳过 — 检测到前台应用为终端模拟器时,自动跳过打字机逐批注入,回退到整段粘贴
- 支持终端 — Ghostty、iTerm2、Terminal、Alacritty、Warp、Kitty、Hyper、WezTerm
- 自动卸载旧卷 — 打包和装载 DMG 前自动关闭 Finder 窗口并卸载所有同名已装载卷
- 核心理念 — 生成测试用例时屏蔽实现代码,仅从需求文档推导,避免 "AI 写码 + AI 测试" 的共同盲区
- 覆盖 10 个模块 — LLMService、VocabService、ConfigService、ChatService、NotificationService、DiaryService、CoreEngine、ModelManager、ASRResult、AliyunTokenService
- 406 个黑盒测试用例,加上原有 143 个,总计 549 个测试全通过
- AliyunTokenService 段错误 —
generateToken返回Token.Id时未做类型安全检查,当阿里云返回非字符串类型(如 int)时导致 Dart VM segfault。修复:添加?.toString()
| 模块 | 用例数 | 覆盖内容 |
|---|---|---|
| ConfigService | 115 | 全部配置项默认值、setter、组合状态、国际化、引导页、边界条件 |
| LLMService | 45 | 4 种开关组合、Cloud/Ollama 双引擎、hints 注入、安全性、并发 |
| CoreEngine utils | 43 | 文本去重、短语去重、标点检测、中英混合、emoji |
| VocabService | 42 | 替换逻辑、hints 生成、用户词条 CRUD、持久化、边界 |
| ModelManager | 39 | 模型元数据完整性、ID 唯一性、URL 格式、查询 |
| ChatService | 39 | 5 种消息类型、持久化、自动裁剪、stream、损坏恢复 |
| NotificationService | 30 | 通知类型、stream 广播、操作按钮、多订阅者、边界 |
| AliyunTokenService | 21 | 成功/失败场景、网络异常、HTTP 错误码、响应格式、空凭证 |
| ASRResult | 17 | 构造函数、工厂方法、默认值、可选字段 |
| DiaryService | 15 | 并发追加、超长文本、特殊路径、空路径、边界输入 |
- 重命名 — "AI 纠错" 更名为 "AI 润色",正面表述
- 独立 Tab — AI 润色从通用设置提升为左侧导航栏独立 tab(含 LLM 配置 + 专业词汇)
- 词典注入 LLM — 专业术语不再直接替换文本,改为通过
<vocab_hints>标签注入 LLM prompt,由 AI 结合语境智能判断是否替换 - 离线回退 — AI 关闭时回退到精确字符串替换,保留基础纠错能力
- 风险提示 — AI 润色页面顶部添加橙色警告横幅,提醒用户 AI 可能修改原意
- System Prompt 升级 — 默认 prompt 新增 vocab_hints 处理指令和 5 条润色规则
- TSV/CSV 导入导出 — 自定义词条支持文件批量导入(TSV/CSV/TXT)和导出
- Beta 标签 — 专业词汇开关标注 Beta
- 移除音近匹配 — 删除 lpinyin 依赖、拼音缓存、Levenshtein 算法、音近匹配 UI(阈值滑块等)
- 移除 phonetic 配置 — ConfigService 中 vocabPhoneticEnabled / vocabPhoneticThreshold 已删除
- 包体积优化 — 减少 ~2MB(去除 lpinyin)
- 143 测试全通过,新增 vocab hints 集成测试(验证 Cloud/Ollama 模式下 hints 注入)
- Golden 测试更新为新版 prompt
- NativeInputFFI 共用基类 — 提取 FFI 绑定公共代码,消除 macOS/Windows 间 ~400 行重复。所有平台只需实现动态库路径查找。
- 工厂方法分发 —
createNativeInput()按Platform自动选择NativeInput(macOS) /NativeInputWindows(Windows) /NativeInputLinux(Linux)。 - Windows 原生库 —
native_input.cpp(~550 行 C++) 实现全部 21 个导出函数:WH_KEYBOARD_LL 键盘监听、SendInput 文本注入、WASAPI 音频采集、IMMDeviceEnumerator 设备管理。 - Windows UI — 4 个 fluent_ui 页面 (FluentApp + NavigationView):首页、设置、聊天、系统托盘。
- Linux 原生库 —
native_input.c(~350 行 C) 实现全部 21 个导出函数:evdev 键盘监听、xdotool/wtype 文本注入、PulseAudio 音频采集、Ring Buffer。 - Linux UI — 4 个 Material Design 3 页面 (MaterialApp + TabBar):首页、设置、聊天、系统托盘。
- Linux 平台 runner —
flutter create --platforms=linux生成标准 runner 配置。 - ConfigService 条件化 —
MacOsOptions仅在 macOS 生效,其他平台使用默认 SecureStorage。 - OverlayController 兼容 — 非 macOS 平台 no-op,不依赖 NSPanel。
- 三平台 CI — macOS / Windows / Linux 并行构建:静态分析 → 测试 → 原生库编译 → Flutter 构建。
- 全部 134 测试通过 — 三个平台测试全绿。
- 跨平台测试兼容 — 修复文件系统大小写敏感性差异 (NTFS/HFS+/ext4) 和行尾格式差异 (CRLF/LF)。
- 手动导入 — 下载失败时可选择本地
.tar.bz2文件导入,解决 GitHub 访问受限或网络不稳定的问题。 - 设置页增强 — 语音模型 tab 未下载状态新增「导入」按钮和 GitHub 直链图标,方便用户在浏览器中手动下载。
- 引导页增强 — 下载失败 UI 新增「导入」按钮和「手动下载」链接,提供完整备用方案。
- ModelManager 重构 — 提取
_extractAndInstallModel公共方法,下载和导入共用解压→验证→激活流程。 - 原生文件选择器 — AppDelegate 新增
pickFile方法(NSOpenPanel),过滤.bz2文件类型。 - i18n — 新增 4 个国际化键 (
importModel,manualDownload,importModelDesc,importing)。
- FN 键双事件去重 — macOS 26 的 FN/Globe 键同时产生
FlagsChanged 63和KeyDown/Up 179两种事件,到达顺序不固定。原去重仅处理「179 先到」场景,导致「63 先到」时 179 的 keyDown 被误判为 Toggle 二次点击而立即停止录音。改为双向去重:先到者处理并记录时间戳,100ms 内到达的另一方抑制。 - Toggle keyUp 守卫 — Toggle 模式下忽略 PTT/diary 的 keyUp 事件,防止同键 keyUp 穿透到 PTT 停止逻辑。
- 通用 tab 精简 — 移走 PTT 快捷键、Toggle 模式、ASR 去重 3 个分组,仅保留语言、音频输入、AI 纠错。
- 新增「触发方式」tab — 原「闪念笔记」tab 扩展重命名,合并所有触发相关设置:文本注入组(PTT + Toggle)、闪念笔记组(启用 + PTT + Toggle + 保存目录)、录音保护组(最大时长 + ASR 去重 + 提示)。
- 提取
_buildKeyCaptureTile辅助方法 — 消除快捷键 UI 重复代码,5 处快捷键编辑复用同一组件。 - i18n 新增 5 个键 —
tabTrigger、pttMode、toggleModeTip、textInjection、recordingProtection;移除 3 个旧键。
- 单击切换录音 — 新增 Toggle 录音模式:单击开始录音,再次单击结束并自动输出文字。适合走动、站立等不方便长按的场景。
- 双 Toggle 快捷键 — 支持「文本注入」和「闪念笔记」两个独立 Toggle 快捷键,各自独立配置。
- 共用键智能判定 — Toggle 键可与 PTT 键设为同一个键,系统用时间阈值自动区分:按住 < 1 秒释放为 Toggle 模式(录音继续),按住 ≥ 1 秒释放为 PTT 模式(立即停止)。
- 最大录音时长保护 — 可选 1/3/5/10 分钟上限,到时自动停止录音,防止忘记关闭。设为「不限制」则无上限。
- 设置页 UI — 在「触发按键」下方新增「Toggle 模式」设置组,含快捷键编辑/清除、时长下拉、操作提示。
- 完整 i18n — 中英文 8 个新增 l10n 键。
- 测试体系扩展 — 新增 ~117 个测试用例(总计 134),覆盖 CoreEngine、ChatService、DiaryService、LLM Golden。
- 共享测试基础设施 — 提取
test/helpers/(MockPathProvider, FakeASRProvider)、Golden 测试锁定 LLM prompt。 - 新增脚本 —
scripts/test_all.sh(analyze + test + 覆盖率)、docs/release_checklist.md。
- 引导页全量 l10n — 提取 ~40 个硬编码中文字符串到 ARB 文件,覆盖欢迎、权限、模型选择、下载、完成全部 5 个步骤。英文系统全英文,中文系统全中文,不再混杂。
- 设置页模型列表 l10n — 流式模型和离线模型的名称/描述从
model.name改为_localizedModelName()/_localizedModelDesc(),中文环境正确显示中文。 - 新增 ~30 个 l10n 键 — 包含参数化字符串 (
onboardingBrowseModels(count),onboardingDownloading(name), 下载百分比等)。 - 修正 ARB 模型大小描述 — Zipformer
85MB→490MB, Paraformer230MB→1GB,与实际下载一致。
- 数据流超时保护 —
_downloadWithResume添加 30 秒无活动超时 (stream.timeout),防止 GitHub 传输卡住时 UI 永远停在"下载中"。超时后自动重试(最多 5 次,间隔递增)。
- DMG 代码签名 —
create_styled_dmg.sh加入 Apple Development 证书签名流程(dylib 先签、app bundle 后签),分发给他人后权限可跨重装保留。
- CoreEngine 录音状态机 — 用
RecordingState { idle, starting, recording, stopping, processing }枚举替换 5 个布尔标记 (_isRecording,_isStopping,_isDiaryMode,_audioStarted部分),消除非法状态组合。 - RecordingMode 参数化 —
startRecording({required RecordingMode mode})替代先设标记再调用的模式,PTT 和日记模式统一入口。 - 提取 OverlayController 单例 — 新增
lib/services/overlay_controller.dart,统一 overlay MethodChannel 调用(原散布在 CoreEngine + main.dart 两处),消除双重更新竞态。 - 统一边沿检测 — 提取
_handleModeKey()方法,PTT 和日记的按键处理共用同一逻辑。 - 消除硬编码延迟 — 移除
stopRecording()中多余的 10ms/200msFuture.delayed,provider 已内含尾部处理。
- 删除调试残留 — 移除
_audioDumpSink、_audioBuffer、_modelPath、_startTime、_isInit等从未使用或仅调试用的字段。 - 修复 144 个 flutter analyze 问题 — 从 144 issues 降到 0:
- 移除 20+ 个 unused import (
dart:io,dart:convert,dart:typed_data,shared_preferences,crypto等) - 移除 10+ 个 unused field (
_heartbeatInterval,_startCompleter,_lastBluetoothDeviceName,_checkPermission等) withOpacity()→withValues(alpha:)全局替换 (28 处,适配 Flutter 3.33+)print()→debugPrint()全局替换 (40+ 处)- 修复
curly_braces_in_flow_control_structures(10+ 处) - 修复
unnecessary_string_interpolations、prefer_interpolation_to_compose_strings - 添加
path_provider_platform_interface和plugin_platform_interface到 dev_dependencies
- 移除 20+ 个 unused import (
- CoreEngine 瘦身 — 从 ~800 行降到 ~700 行,删除 ~115 行死代码。
- 全部 17 个测试通过,无需修改测试用例(重构未改变 ASRProvider 接口和 Service 层 API)。
- Gateway: 移除 CORS 全开放 — 不再设置
Access-Control-Allow-Origin: *,桌面客户端不需要 CORS。 - Gateway: 注释 Stripe Webhook — 未完成的支付模块暂时禁用,避免无签名验证的端点暴露。
- Gateway: 注释 /token 路由 — 当前客户端本地生成 Token,Gateway 端占位代码暂时禁用。
- Gateway: 充值码改用
crypto.getRandomValues()— 替换不安全的Math.random()。 - Gateway: /redeem TOCTOU 缓解 — 先标记卡密已用再增加余额,防止并发双充。
- Gateway: /admin/generate 输入验证 — 增加 amount/count/prefix 类型校验,count 上限 100。
- Gateway: /report 类型校验 —
total_seconds增加typeof检查。
- native_input.m: 修复
va_list双重消费 — 使用va_copy创建副本,消除未定义行为。 - native_input.m: 修复
CFStringRef泄漏 —getDeviceStringProperty使用__bridge_transfer正确转移所有权给 ARC。 - native_input.m: Ring Buffer 游标改用
_Atomic— 替换volatile,使用memory_order_acquire/release保证正确的 acquire-release 语义。 - native_input.m: CGEventTap 改用
kCGEventTapOptionListenOnly— 仅监听不修改事件,降低权限需求。 - native_input.m: CGEvent 创建增加 NULL 检查 —
inject_via_keyboard和inject_via_clipboard中防止 NULL 解引用。 - native_input.m:
deviceChangeCallback竞态修复 — 本地拷贝回调指针,避免 CoreAudio 线程与主线程之间的 TOCTOU。
- CoreEngine:
stopRecording防重入 — 入口检查_isStopping,防止 watchdog 和按键释放并发触发。 - CoreEngine: 新增
dispose()方法 — 关闭所有 StreamController、释放 NativeCallable、free_pollBuffer原生内存。 - CoreEngine: 同步日志改异步 —
writeAsStringSync→writeAsString().ignore(),不再阻塞音频处理热路径。 - CoreEngine: 清理 AGC 死代码 — 移除无效的
rawPeak计算循环和dynamicGain = 1.0常量,以及未使用的_lastAppliedGain字段。 - AliyunProvider: Token 刷新逻辑 — 基于
_tokenExpireTime在过期前 1 小时自动刷新,不再永不刷新。 - AliyunProvider:
_pendingBuffer上限 — 最多缓存 200 个音频块(~10 秒),防止握手卡住时 OOM。 - AliyunProvider:
dispose()设置_isReady = false— 防止 dispose 后仍被调用。 - AliyunProvider: 清理空心跳 Timer — 移除空操作的定时器,WebSocket 协议层自动处理 ping/pong。
- AliyunProvider: JSON 解析错误不再静默吞掉 — 输出日志便于调试。
- SherpaProvider:
dispose()关闭_textController— 防止 StreamController 泄漏。 - SherpaProvider:
_recognizer.free()— 正确释放 FFI 对象的原生内存。
- LLMService: 修复 HTTP Client 泄漏 — 使用共享的
_defaultClient实例替代每次创建新 Client。 - ConfigService:
init()并发保护 — 使用Completer防止多次并发初始化。 - ChatService: 写入序列化 —
_scheduleSave()确保_saveHistory顺序执行,防止并发文件写入竞态。 - ChatService: 截断后通知 UI —
_saveHistory截断消息后发送 stream 事件。 - ModelManager: 下载 sink 异常安全 —
try-finally确保网络中断时正确关闭IOSink和http.Client。 - ModelManager:
firstWhere→firstOrNull— 无效 ID 不再抛 StateError,改为安全返回。
- SettingsPage: 修复
TextEditingController在 build 中创建 — AI Prompt 输入框改用initState中创建的_aiPromptController,解决光标重置和内存泄漏。 - SettingsPage: 移除双层
SingleChildScrollView— 删除复制粘贴产生的多余嵌套。 - SettingsPage:
dispose()释放所有 Controller — 补齐_akIdController、_akSecretController、_appKeyController、_aiPromptController的释放。 - SettingsPage: 保存成功提示改用 SnackBar — 不再用
_showError显示成功消息。 - main.dart: Stream subscription 生命周期管理 — 5 个 subscription 存储为字段,
dispose()中统一 cancel。 - main.dart: 波形数组长度 5→7 — 与 UI 渲染的 7 个 bar 一致,消除模运算导致的视觉重复。
- ChatPage: 新增
dispose()— 释放_textCtrl和_scrollCtrl。
- 删除死代码
RecordingOverlay— 已被原生覆盖层替代,移除文件和 import。 offline_debug.dart移到tools/— 不属于测试,移出test/目录。run_tests.sh修复 — 使用set -e+flutter test全量运行,替换引用不存在文件的旧命令。- SettingsPage: 移除重复注释 —
// Model State去重。
- 新增
CLAUDE.md— 项目指引文件,包含构建命令、架构设计、关键模块路径。 - 新增代码评审报告 —
docs/wiki/code_review_2026_02_26.md,45 个问题的完整审查记录。
- 新增 Onboarding 引导流程:新用户首次启动时展示权限授权和模型下载的引导页面。
- 修复权限检测类型错误:
native_input.dart中checkPermission()错误地将bool与int比较 (result == 1),导致权限检测永远返回 false。 - 修复键盘监听器未启动:
CoreEngine.init()使用_isInit作为守卫条件,但initASR()也设置了该标志,导致 onboarding 后键盘监听器无法启动。现改为检查_isListenerRunning。 - 修复模型下载进度显示:解决提取阶段显示
-100%的问题,现显示"解压中..."。 - 移除静默标点模型下载:避免用户混淆 Zipformer 和标点模型的下载状态。
- 新增权限自动刷新:HomePage 实现
WidgetsBindingObserver,从系统设置返回后自动重新检测权限状态。 - 修复 dylib 路径解析:Release 版本中添加
flutter_assets路径检测,确保原生库正确加载。
- 新增数据清理脚本:
scripts/clear_data.sh用于完整清理 FTUE 测试数据。 - 清理遗留 MCP 文件:删除不再使用的
add_server_dialog.dart。
- 确认修复 ASR 幻觉重复问题:通过系统性诊断确认问题根源在 Native 库编译/打包环节,重新编译
libnative_input.dylib并重新打包后,语音识别重复问题(如"测测测试")已彻底消除。 - 诊断方法论:本次修复采用了"证据先行"的调试方法 —— 先分析
/tmp/audio_dump.pcm确认音频采集层无重复,再排查 ASR 逻辑,最终定位到 Native 库需要重新编译。
- 修复底层音频缓冲区竞争 (Native Buffer Decoupling):重大底层重构。针对用户反馈的“幻觉重复”,识别出原生 AudioQueue 缓冲区在被 Dart 读取前可能已被系统复写。
- 内存安全异步拷贝:底层 C 代码现在会立即申请独立内存并拷贝采样数据,彻底解决了 Native 与 Dart 之间的时序竞争。
- 后台音频采集:将音频采集移出 UI 主线程,使用独立的系统后台线程处理,确保在高负载(如渲染 UI)时依然能维持 100% 连续的声谱信号,从根源消除断点导致的 ASR 幻觉。
- 关闭所有数字增益处理 (Raw Signal Bypass):按照用户提议进行极限测试,彻底关闭了软件层面的所有自动增益(AGC)和平滑逻辑。ASR 引擎现在直接接收 1.0x 的原始麦克风信号,用于排查是否为增益计算本身导致了幻觉重复。
- 采样级增益插值 (Sample-level Interpolation):针对用户反馈的“音频截断”感,将增益调整优化为采样点级别的线性插值。现在 100ms 分块之间的音量过渡是绝对平滑的,消除了所有可能导致 ASR 误判的波形突变。
- 彻底移除后置去重:完全删除了输出端的文本去重逻辑,确保 100% 还原 ASR 原始输出。
- 平滑 AGC 增益:引入指数移动平均(EMA)平滑音量增益,消除由于瞬时增益大幅跳变导致的 ASR 信号失真和幻觉重复。
- 深度逻辑审计推倒重排:优化去重顺序,优先处理单字幻觉,后处理词组重复。
- AGC 噪声门控:防止在安静环境下过度放大底噪导致的 ASR 幻觉(修复“测测试三”类重复)。
- 代码除垢:清理了
CoreEngine中多处冗余的清理逻辑。
- 移除输出端硬编码的去重逻辑,优先通过 AGC (自动增益控制) 预防 ASR 幻觉。
- 保留自然的重复表达支持。
-
动态增益控制 (Adaptive Gain Control):
- 事前预防:实现了动态音频增益逻辑。每 100ms 自动检测输入音量,如果原始声音已经足够强,则自动降低增益至 1.0x(无放大),严防数字削波(Clipping)。
- 字幕重复现象最根本的诱因——“爆音失真”——在音频进入 ASR 引擎前就被物理阻断了。
-
去重逻辑优化:
- 维持 v1.2.12 的智能去重逻辑作为“事后”第二道防线,双重保险确保护正常文字上屏。
- 智能去重 (Smart Clean-up):
- 优化了
_deduplicateFinal算法,解决了“误杀”问题。 - 保护数字:现在不会误将
100识别为10,确保金额和电话号码的准确性。 - 保护叠词:单字重复 2 次(如“看看”、“妈妈”)将被保留,符合中文表达习惯;只有重复 3 次及以上才判定为故障并去重。
- 短语纠错:依然精准识别并消除如“原因原因”这类 2-4 字的词组重复点。
- 优化了
-
消除重复字 (Deduplication):
- 激活了原本处于休eting状态的
_deduplicateFinal逻辑。 - 现在无论是实时显示还是最终上屏,都会自动过滤由引擎引起的连续字/词重复。
- 激活了原本处于休eting状态的
-
音频增益优化 (Gain Optimization):
- 将强制数字增益从 8.0x 调低至 3.0x。
- 证据发现:8倍增益在灵敏度高的麦克风上会导致严重的“削波失真”,从而误导 ASR 引擎产生重复幻觉。调低后可显著提升在大音量下的识别准确度。
-
流处理加固:
- 确保实时文字流(Partial Stream)也经过了去重处理,提升悬浮窗显示的观感。
-
App 沙盒兼容:
- 修复了
bzip2 -t完整性校验在 macOS 沙盒环境下失效的问题。 - 现在依赖
tar -xf解压成功作为完整性验证,兼容性更强。
- 修复了
-
断点续传优化:
- 新增 Content-Range 验证:校验服务器返回的数据起始位置与请求匹配,防止 CDN 返回错位数据导致文件损坏。
- 修复 416 错误处理:使用 HEAD 请求二次验证文件完整性,不再依赖不可靠的响应头。
-
解压流程加固:
- macOS 使用原生
tar命令解压,避免 Dartarchive包的内存限制问题。 - 解压后自动执行
chmod 755修复权限。 - 使用原生
find命令搜索关键文件,绕过 Dart 文件系统遍历的兼容性问题。
- macOS 使用原生
- 实时转写架构重构:
- 修复了切换模型后,悬浮窗和主界面无法显示实时文字的问题。
- 重构
CoreEngine,引入持久的PartialResult中转流,确保 UI 始终监听正确的事件源。 - 彻底解决了因引擎实例销毁重建导致的 UI 监听失效问题。
- 移除了 v1.2.9 中受 macOS 沙盒限制的 bzip2 校验代码。
The first commercial-ready release with Hybrid Payment System support.
- Payment System (Hybrid):
- Pro License: Support for CD-Key redemption (
/redeem) and Stripe Webhooks. - Flexible Top-up: Integrated "Buy Credits" link and manual code entry.
- Account Tab: Dedicated settings page for license management.
- Pro License: Support for CD-Key redemption (
- UI/UX Refactor:
- Settings Redesign: Moved "Account" to a primary tab; optimized layout for better readability.
- Visuals: Updated App Icon to 160px rounded rectangle; standardized README headers.
- Documentation:
- Bilingual Architecture: Added Mermaid diagrams to both English and Chinese README sections.
- Icons: Enhanced Chinese product introduction with visual emojis.
The first public stable release of SpeakOut.
- Open Source: Complete code release under MIT License.
- Key Features:
- Tri-Force Engine: Offline ASR (Sherpa) + Flash Notes (Diary) + MCP Agents.
- Privacy First: Local-only processing by default.
- Extension System: Full support for Model Context Protocol (MCP) to extend capabilities.
- Documentation: Comprehensive README (EN/ZH) and Architecture Diagrams.
- Sandbox 持久化修复 (Persistence Fix):
- 修复了 macOS 沙盒环境下,聊天记录和日志无法写入
~/Documents的问题。 - 现在数据正确存储于 App 的沙盒容器中 (
Library/Containers/...)。
- 修复了 macOS 沙盒环境下,聊天记录和日志无法写入
- 历史记录清理 (Clear History):
- Chat 界面新增 垃圾桶 按钮,支持一键清空当前对话列表(带确认保护)。
- 该操作仅清理 UI 显示,不会删除 已经归档的闪念笔记文件。
- 全局错误通知 (Global Error Banner):
- 实现了顶层通知系统。任何文件保存失败或系统错误都会以红色横幅形式在顶部弹出。
- 关于页面自动化:
- 版本号现在自动同步,不再需要手动更新文档。
-
MCP 代理集成 (Agentic MCP Integration):
- SpeakOut 现在支持 Model Context Protocol (MCP),可以动态连接外部工具(Skills)。
- 动态发现: 只需配置 MCP Server,App 会自动学习其能力并在合适时调用。
- 设置指南: 移除了硬编码的 Demo,现在可以通过设置页的指南手动添加自定义 MCP(如日历集成)。
-
双重持久化 (Dual Persistence):
- 您的语音输入现在会并行处理:
- 立即保存为 闪念笔记 (Diary)。
- 同时发送给 Agent 大脑 分析意图。
- 确保数据绝对安全,不会因为 AI 分析失败而丢失原始想法。
- 您的语音输入现在会并行处理:
- 人机交互确认 (HITL Confirmation):
- 为了防止 AI 误操作,Agent 执行任何命令前都会弹出 "执行 Agent 命令?" 确认框。
- 只有在您点击 允许 后,操作才会真正执行。
- 并行调用链: 重构了核心引擎,实现了 ASR 结果的非阻塞分发。
- 独立路由模型: 可以在设置中为 Agent Router 单独指定模型(如
gpt-4o-mini),与文本校正模型解耦。
- 闪念笔记 (Flash Note):
- 独立记录模式: 这是一个区别于普通语音输入的全新功能。按住独立的快捷键(默认为 Right Option),即可快速记录当下的想法。
- 自动归档: 您的笔记不再是一次性的,而是会作为文本自动追加保存到您指定的文件夹中。
- 每日归档: 系统会按天自动创建文件(如
2024-01-09.md),将一天的想法有条理地组织在一起。
- 原生文件夹管理 (Native Directory):
- 笔记存储路径的选择现在调用 macOS 原生文件选择器。
- 您可以直接在选择器窗口中新建文件夹,操作习惯与 Finder 完全一致。
- 独立的设置空间:
- 为了不干扰原有功能,我们将笔记设置移至了独立的 "闪念笔记" 标签页,界面更加清爽。
- 关于界面 (About Info):
- 在 设置 -> 通用 页面的最底部增加了版本号显示 (例如:
SpeakOut v3.5.4+1006)。 - 方便您确认当前运行的是否为最新版本。
- 在 设置 -> 通用 页面的最底部增加了版本号显示 (例如:
- 多句累积修复 (Multi-sentence Accumulation):
- 修复了当语音较长时,阿里云返回多个句子结果 (Completed Events),但程序只记录了最后一句导致前面内容丢失的问题。
- 现在程序会自动累积所有已完成的句子,确保长语音记录完整。
- 停止保护 (Stop Safety):
- 增强了停止录音时的鲁棒性,确保在握手未完成前不会强制关闭连接,防止短语音丢失。
- 音频缓冲机制 (Audio Buffering):
- 为了防止等待云端握手时丢失开头的语音,我们实现了一个内存缓冲区。
- 现在:按下按键 -> 立刻开始录音 (无需等待网络) -> 录音暂存 -> 等握手成功后自动补发。
- 效果:彻底消除了说话被掐头的问题,同时保证了与阿里云的完美兼容。
- 阿里云网关错误修复 (Gateway Error Fix):
- 修复了
MESSAGE_INVALID错误。之前是因为在服务器尚未准备好时就发送了音频数据。 - 现在会等待服务器返回
TranscriptionStarted信号后才开始传输音频,彻底解决握手失败问题。
- 修复了
- 标点确认:
- 确认阿里云配置中
enable_punctuation_prediction已开启 (True)。
- 确认阿里云配置中
- 智能标点策略 (Smart Punctuation Strategy):
- 当切换到 阿里云 (Cloud) 引擎时,会自动禁用本地标点模型,避免“双重标点”问题。
- AI 纠错 保持开启,继续为您提供语义润色和去口语化服务。
- 视觉重构 (Visual Refactor):
- 首页主视觉由显示技术参数的“就绪状态”改为大号品牌名 "子曰"。
- 动态状态栏: 只有在出错或初始化时才显示技术状态。正常情况下,仅显示简洁的 "按住 {Key} 键开始说话"。
- 应用标题 (App Title):
- 找回了消失的中文名 “子曰”。
- 现在标题栏统一显示为 "子曰 · SpeakOut" (中文环境) 或 "SpeakOut · 子曰" (英文环境)。
- 提示词语法重构 (Refactor Prompt to Triple Quotes):
- 将
AppConstants.dart中的多行字符串拼接改为 Dart 标准的"""三引号语法,提高可读性和维护性。
- 将
- 默认 AI 提示词 (Default AI Prompt):
- 更新了系统内置的默认提示词,去除了“英文缩写修正”规则,专注于语气词保留和语义标点。
- 新规则现在作为“恢复默认”时的基准。
- AI 设置重构 (Refactored AI Settings):
- 恢复了 AI 提示词 (Correction Prompt) 的编辑框,现在可以直接在界面修改指令。
- 隐藏了 API 配置 (Key/URL),勾选 "Use Custom API" 后才会显示,界面更加整洁。
- AI 主导,本地兜底 (AI-First Punctuation):
- Prompt: 明确要求 AI “通过理解语义,在适当的情况下增加标点符号”。
- Fallback: 代码会自动检测 AI 的输出。如果 AI 忘记加标点(句号/问号等),本地模型会自动补位。如果 AI 已经加了,本地模型则静默,避免重复。
- 效果: 既能利用大模型的高级语义断句,又保证了格式的绝对规范。
- 标点兜底 (Force Punctuation):
- 修复了当 AI 纠错修改过文本时,本地标点模型被错误的跳过的问题。
- 现在:无论 AI 是否修改了内容,只要最终结果缺乏标点,本地模型就会进行补充。
- 设置入口 (Settings Entry):
- 加大了主页右上角的设置齿轮图标 (28 -> 36)。
- 增加了边缘间距 (10 -> 16),使其更易点击且视觉更平衡。
- 提示词温和化 (Conservative Prompt):
- 调整了 AI 纠错的指令,从“删除口水词”改为“仅删除口吃”。
- 明确保护: 强制要求保留句末的语气词(如“看看吧”、“呢”、“啊”),避免 AI 误伤自然口语。
- 缩写: 保留了如
'a p'->'APP'的有用纠错。
- 增益增强 (Signal Boost): 将软件数字增益从 5.0x 提升至 8.0x (+18dB)。
- 原因: 离线分析显示部分录音 RMS 能量仅 0.02 (极低),导致 ASR 引擎难以捕捉尾音或将音识别错误。
- 解码缓冲清空 (Flush Decoder): 将注入的静音填充从 0.5s 增加至 0.8s。
- 原因: 确保强制将解码器缓冲区内残留的最后几个字推出来。
- 停止延迟优化: 将录音停止后的缓冲等待时间 (Stop Delay) 从 200ms 增加至 500ms。
- 原因: 200ms 的窗口对于语速较快的情况过于激进,导致部分尾音(如"一下"的"下")还在系统缓冲区未被处理就被截断。
- 效果: 确保所有语音数据都能完整传输给识别引擎。
- 音频转储恢复: 恢复了
/tmp/audio_dump.pcm原始音频保存功能。- 方便在出现识别问题时,通过分析原始音频判断是麦克风收音问题还是引擎识别问题。
-
波形动画复刻 (Waveform Match):
- 彻底重写了主界面麦克风的波形动画,现在与系统悬浮窗完全一致。
- 细节: 7 条波形条,80ms 刷新率,真随机高度 (8-48px),采用
Curves.easeInOut平滑过渡。
-
布局坚如磐石 (Layout Stability):
- 重构: 废弃了依赖内容尺寸的
Center布局,改用LayoutBuilder+Stack实现像素级绝对定位。 - 效果: 无论状态文字如何变化(变长、换行、消失),麦克风图标都保持纹丝不动。
- 重构: 废弃了依赖内容尺寸的
-
视觉减负:
- 移除了录音状态下文字变红的逻辑,保持界面清爽一致。
- 配置修复:
- 修复了
AppConstants默认值未生效导致 "API Key MISSING" 的问题。 - 关键修复: 将
assets/llm_config.json正确添加到pubspec.yaml资源列表中,确保配置文件被打包。 - 效果: AI 纠错功能现已正常工作,自动去除口水词(如"呃"、"那个")。
- 修复了
- 边说边出字: 恢复实时显示部分识别结果功能。
- 新增
partialTextStreamgetter,转发 ASR Provider 的实时结果流。 - UI 现在同时订阅最终结果和部分结果,实现真正的"边说边出"。
- 悬浮窗可见性: 修复悬浮窗在录音结束后立即消失的问题。
- 现在悬浮窗会在有文字时保持显示,即使录音已结束。
- 主界面文字显示: 添加
resultStream订阅,识别结果现在会显示在主界面。 - 悬浮窗文字显示: 将识别结果绑定到悬浮窗的
statusText。 - 清理冗余诊断日志,移除
Data Received每帧日志。
- 恢复
_asrProvider.start()调用: 重构时遗漏,导致 Sherpa 内部 stream 为 null,所有音频数据被丢弃。 - 这是 v3.5.0 "No Speech" 问题的根本原因。
- 添加
Data Received: XXX bytes入口日志,用于验证音频数据流。
- 移除
permission_handler插件: 该插件在 macOS Release/沙盒模式下无限阻塞。 - 改用
record插件原生的hasPermission()方法。 - 修复 PTT 按键无响应问题。
本次更新彻底重写了音频采集层,以最严谨的逻辑解决“无声”、“麦克风不可用”和“识别率低”的问题。
-
原生 16000Hz 采集:
- 移除了所有中间层的“降采样”算法,改为直接向底层系统申请 16k 音频。
- 优势: 消除数字信号处理带来的杂音和精度损失,降低 CPU 占用。
- 兼容性: 完美适配 Sherpa 语音引擎的要求。
-
权限卫士 (Permission Guard):
- 引入了严格的“安检机制”。在录音启动前 0.1 秒,必须通过系统级权限验证。
- 彻底杜绝了“UI 再转但后台没权限”的假死状态。
-
纯净数字增益 (Clean Digital Gain):
- 移除了不可靠的 VPIO 硬件开关。
- 采用 5.0x 软件线性增益。无论麦克风硬件音量多小,都保证有足够的电平供给识别引擎。
-
总结: 这是一个“返璞归真”的版本。不做花哨的硬件处理,只做最扎实的数据传输。
- 核心路线修正:
- 我们放弃了在您设备上不稳定的 VPIO 硬件增益模式(导致“麦克风不可用”的元凶)。
- 回归到 标准音频采集 + 软件智能增益 的组合。
- 数字增益: 无论原始声音多小,软件内核直接将其放大 5 倍,确保识别引擎听得清清楚楚。
- 总结: 这是一个“兼容性”和“效果”的终极平衡版本。
- VPIO 全面回归:
- 既然权限问题已解决,我们重新启用了所有高级音频特性。
- 自动增益 (AGC): 解决“声音太小不识别”的问题。
- 回声消除 (AEC): 解决“听到自己声音”的问题。
- 降噪 (NS): 提供纯净的语音流。
- 48k 原生采样: 恢复高品质音频采集,并由内核进行高质量降采样。
- 总结: 这应该是本次调试的终点。权限正常 + 增益正常 = 完美识别。
- 音频文件导出:
- 我们确认数据流已经通畅(不再是静音全0),但音量极低。
- 此版本会将麦克风听到的原始声音保存到
/tmp/audio_dump.pcm。 - 请运行录音一次,然后我们可以分析这个文件,看看是麦克风增益问题还是只有电流底噪。
- "全零" 数据预警:
- 新增了对音频数据流内容的深度检测。
- 如果应用检测到收到的数据包全都是
0x00(绝对静音),会发出明确的警告日志。这通常意味着 macOS 的隐私权限虽然表面允许,但底层仍处于被系统静音 (Muted) 的状态。
- 环境重置:
- 此版本建议配合
tccutil reset Microphone com.speakout.speakout命令使用,以彻底重置系统的 TCC 权限状态。
- 此版本建议配合
- 缺失的权限标识:
- 我们发现了导致“有动画无文字”的终极原因:Release 版本中缺失了
com.apple.security.device.audio-input关键权限标识。 - 这导致 macOS 系统虽然弹窗询问了权限,但随后默默地屏蔽了实际的音频数据流(Input Muted)。
- 修复: 已补全该权限标识,这是彻底解决“静默录音”问题的核心。
- 我们发现了导致“有动画无文字”的终极原因:Release 版本中缺失了
- 配置保持: 暂时继续保持 16k 标准模式,待确认数据通畅后再逐步开放 VPIO 高级功能。
- 设备缓存清理:
- 当录音设备启动失败时,立即失效 之前的缓存设备 ID。
- 强制以
null(系统默认设备) 重新发起录音请求。 - 这专门修复了当用户拔掉外接麦克风后,App 仍然死守着旧设备 ID 导致无法录音的问题。
- 强制 16k 基线:
- 为了排查 48k 采样率可能导致的静默问题,此版本强制回退到 16000Hz 采样率。
- 关闭所有高级音频处理 (VPIO, AutoGain, NoiseSuppress),以最原始的方式请求音频流。
- 流状态监控:
- 增加了对音频数据包的实时监控,如果内核在 5 秒内未收到任何音频数据,会明确记录日志。
- RMS 能量检测:
- 内核增加了实时音频能量 (RMS) 检测与日志记录。
- 用于判断麦克风是否在采集真实声音,还是被系统静音。
- 这是为了排查“有波形动画但无文字结果”问题的关键调试版本。
- 禁用 VPIO (Disable VPIO):
- 为了兼容更多种类的外接麦克风(特别是部分 USB 麦克风和虚拟声卡),我们默认即用标准的 CoreAudio 模式,不再强制开启回声消除 (VPIO)。
- 此举虽然牺牲了部分降噪能力,但极大提升了设备兼容性,彻底解决了“有录音动画但转文字为空”的静默问题。
- 48k 原生处理: 依然保持 48kHz 的原生采样请求,手动进行降采样,确保底层稳定性。
- USB 麦克风热插拔保护:
- 修复了当指定的外接麦克风(如 USB 麦克风)ID 发生变化或不可用时,App 直接报错退出的问题。
- 自动回退 (Auto Fallback): 现在,如果指定的麦克风打开失败,系统会无缝(< 50ms)切换回 系统默认麦克风 并继续录音,确保录音操作不中断。
- 诊断增强: 增加了更详细的设备连接错误日志,方便排查硬件兼容性问题。
- VPIO 48k 原生采样:
- 强制请求 48000Hz 音频流(macOS 声卡的原生频率),配合 VPIO 模式确保在所有 Mac 设备(包括 Intel/M1/M2/M3)上都能稳定采集数据。
- 解决了部分设备因 VPIO 拒绝 16k 请求而导致的 "Error 1852797029" 或 静默录音 问题。
- 手动降采样 (Manual Downsampling): 实现高效的 3:1 降采样算法 (48k -> 16k),确保识别引擎获得标准音频数据。
- 设备记忆恢复 (Smart Device Cache):
- 恢复了对用户指定麦克风的记忆功能。如果“系统默认”设备不可用(如被虚拟声卡劫持),App 会智能切换回您上次选择的 内置麦克风。
本次更新彻底重构了底层音频架构,解决了所有已知的稳定性和延迟痛点。
- 0 延迟启动 (Parallel Startup):
- 彻底重写
startRecording逻辑,并行启动 UI 悬浮窗与麦克风引擎。 - 消除了约 200ms 的串行等待时间,确保按下即录,彻底解决“首字丢失” (Head Truncation) 问题。
- 彻底重写
- 200ms 智能收尾:
- 将录音停止后的 "Tail Delay" 从 600ms 精确缩减至 200ms。
- 既能完美覆盖硬件缓冲区延迟(防止吞尾字),又保证了极佳的跟手感。
- VPIO 语音处理模式 (Voice Processing IO):
- 废弃了不稳定的手动重采样方案,全面启用 macOS 原生 VPIO 模式 (与 Zoom/WeChat 同款)。
- 彻底修复 "Error 1852797029" (麦克风失效) 问题,利用系统级回声消除与降噪算法,保证全天候稳定运行。
- 互斥锁保护 (Mutex Safety):
- 引入
_isStopping原子锁机制。 - 智能识别并忽略毫秒级的极速连按冲突,彻底杜绝 因快速操作导致的 App 崩溃或死锁。
- 引入
- 默认 AI 纠错: AI 智能纠错现在默认开启,并配合本地标点模型作为双重保障。
- 默认设备直连: 为了追求极致速度,默认优先使用系统设定麦克风,跳过耗时的设备枚举过程。
- 全新薄荷绿主题:采用
#2ECC71作为主色调,界面更清新现代。 - 扁平化首页:移除发光特效,采用原生风格的扁平化麦克风按钮。
- 悬浮窗重设计:原生 Swift 实现的全局悬浮窗,采用磨砂玻璃药丸设计,移除红点,优化音波动画。
- 一致性优化:统一 Light/Dark 模式下的布局和配色,严格遵循 macOS 原生设计规范。
- 音频稳定性增强:重构设备选择逻辑,强制刷新设备 ID,解决因设备 ID 变更导致的录音卡死问题。
- 智能纠错升级:优化 LLM Prompt,专门针对 "APP" 等英文缩写进行纠错增强,解决字母被拆分的问题。
- 性能优化:通过原生代码实现悬浮窗,大幅降低内存占用。
- Visual Refresh: 全新 "SpeakOut · 子曰" 视觉语言。
- Teal Theme: 采用青色 (Teal) 作为品牌主色,寓意沉稳文雅。
- Breathing Mic: 首页新增呼吸光效麦克风,录音状态更直观。
- Card Layout: 设置页采用 macOS 系统级卡片式布局,分组更清晰。
- Dark Mode: 深度优化的深色模式体验。
- UX: 优化了 API Key 隐藏/显示、模型状态指示等交互细节。
- 多语言架构 (Multi-language): 全面支持英文 (English) 与简体中文界面。
- 动态切换: 设置中增加了语言切换选项 (跟随系统/中文/英文),即时生效。
- 本地化优化: 针对不同语言环境优化了提示文案与状态显示。
- 中文提示词 (Chinese Prompt): 将 AI 纠错的默认 System Prompt 重写为全中文,去除具体案例,增强同音字纠错的通用性。
- 配置优化 (UI Polish):
- 默认未修改的 API 参数现在显示为空白,占位符 (Placeholder) 显示系统默认值,区分更直观。
- 修复了空 API Key 会覆盖系统默认配置的 Bug。
- 语音引擎优化:
- 遇到录音设备失效(Silent/Error)时,明确显示 "🔇 未检测到语音" 提示,避免误导。
- 增加了录音重启的稳定延时,解决偶发的音频设备死锁问题。
- 同音字修复 (Homophone Fix): 针对 "统一字" -> "同音字" 等特定 ASR 错误进行了 Prompt 进行定向优化。
- UI 交互重构: 实现了 "Placeholder as Default" 模式,未配置的项显示为空,清晰展示底层默认值。
- 静音检测 (Silence Detection): 修复了麦克风失效导致录入空音频时,UI 仍显示成功勾选的 Bug。
- 稳定性: 增加了音频回退重试的延时 (500ms),防止底层死锁。
- 配置修复: 修复了空字符串会覆盖默认配置文件的 Bug。
- Prompt 升级: 初步增加了同音字纠错指令。
- 配置文件支持: 新增
assets/llm_config.json支持,允许通过文件预设 API Key。 - 阿里云适配: 深度适配阿里云百炼 (Qwen) 模型参数。
- 核心功能: 首个集成 AI 纠错的版本,支持 OpenAI 兼容接口。
- UI: 新增 AI 纠错开关及配置面板。
- 音频: 实施了第二轮录音死锁保护 (Recorder Reset)。
- 智能安装 (Smart Install):
- 新增自动化安装脚本
scripts/install.sh。 - 自动检测并关闭正在运行的 App,实现一键编译并覆盖安装到
/Applications,开发体验极大飞跃。
- 新增自动化安装脚本
- 配置安全 (Secure Config):
- 将敏感的阿里云 API Key 移出代码库,改为从
assets/aliyun_config.json读取。 - 默认加载本地配置文件,支持 Git 忽略,彻底解决开源泄密风险。
- 将敏感的阿里云 API Key 移出代码库,改为从
- 错误显性化 (Foreground Error Overlay):
- 当云端识别出错(如断网、Key 无效)时,悬浮窗现在会显示醒目的红色 ❌ 错误提示,而不是静默失败。
- 引擎选择优化 (Engine Selection):
- 设置页面的引擎选择从“开关”改为更直观的 垂直单选组 (Radio Group),明确区分“配置”与“激活”状态。
- 标点优化 (Smart Punctuation):
- 当使用阿里云引擎(自带高精度标点)时,自动跳过本地标点模型,避免双重标点和不必要的 CPU 消耗。
- 初始化竞争 (Init Race Condition):
- 修复了切换引擎设置后,因初始化标志位未重置导致的引擎加载失败(表现为录音无反应)的问题。
- 文字丢失 (Empty Result Fix):
- 修复了云端引擎在停止那一刻可能不返回最后一段文字的 Bug,强制从缓存中捕获最终结果。
- 混合云引擎架构 (Hybrid Engine Architecture):
- 双引擎支持: 可以在“本地离线 (Privacy)”和“云端在线 (Accuracy)”模式间无缝切换。
- 阿里云集成 (Aliyun Cloud): 引入阿里云智能语音服务 (NUI WebSocket),提供超高精度的在线识别能力。
- 架构重构: 重写了核心音频流水线 (CoreEngine),支持动态插拔不同的 ASR 提供商。
- 云端配置 (Cloud Config): 设置页新增阿里云 API Key 配置入口,支持用户自带 Key (BYOK)。
- 实时流式识别: 实现了 WebSocket 音频流式上传,延迟极低。
- Settings UI: 重新设计了设置页面布局,新增“引擎模式”切换开关。
- 稳定性: 修复了多处因引擎切换导致的初始化状态竞争问题。
- 国际化: 修正了部分英文提示,全面回归中文界面。
- 优化音频延迟 (Audio Startup Latency):
- 移除了每次按下快捷键时重复扫描所有音频硬件的耗时操作 (由 ~1.8秒 降至 <0.1秒)。
- 实现了输入设备缓存机制 (
InputDevice Cache),仅在应用启动或设置变更时刷新设备列表。 - 现在按下快捷键后,悬浮窗和录音几乎是瞬时响应。
- 修复空闲停止死锁 (Fix Stop on Idle Recorder):
- 解决了当录音启动尚未完成(例如正在检查权限)时,立刻停止录音会导致
AudioRecorder.stop()挂起,进而导致整个 App 界面卡死的严重 Bug。 - 引入了
_audioStarted状态原子锁,确保只有在录音流真正建立后,才允许调用停止指令。
- 解决了当录音启动尚未完成(例如正在检查权限)时,立刻停止录音会导致
- 修复按键释放卡死 (Fix Overlay Freeze on Release):
- 解决了当用户快速按下并释放 Option 键(未说话)时,悬浮窗未能正确关闭导致的界面卡死问题。
- 增加了录音状态的原子性检查,防止在停止录音后仍继续执行初始化逻辑。
- 修复启动崩溃 (Crash on Launch Fix):
- 修复了 Release 模式下因缺少
app_icon.png资源导致的闪退/白屏问题。 - 修正了
native_lib在 App Bundle 环境下的路径加载逻辑,确保持久化兼容性。 - 恢复了 DMG 安装包的标准样式 (大图标、居中布局、拖拽安装)。
- 修复了 Release 模式下因缺少
- 修复录音截断 (Truncation Fix):
- 核心引擎现会在处理结束前自动注入 0.5 秒静音帧。
- 这强制解码器必须处理完缓冲区里最后的几个字,彻底解决了“说话太快被吞字”的问题。
- 修复: 修正了离线 ASR 对比工具的配置错误,现在可以正确生成对比日志了。
- 升级: 将最低系统要求提升至 macOS 11.0 (Big Sur),以消除底层依赖警告并提升稳定性。
- 界面微调 (UI Polish):
- 加大了主界面设置图标 (Icon Size) 方便点击。
- 设置页重构: 将 "快捷键" 标签改为 "通用" (General),并将 音频输入设备 选项移至此处,归类更合理。
- 精简列表: 移除了冗余的语音模型,仅保留推荐的双语模型。
- 智能麦克风回退 (Fallback Protection):
- 修复了指定麦克风不可用时导致的 App 崩溃 (Error 1852797029)。
- 现在会自动无缝切换回系统默认麦克风,并给出明确提示。
- 悬浮窗状态显示 (Overlay Status):
- 重新设计了录音悬浮窗 (加大尺寸),现在会明确显示当前使用的麦克风名称 (如 "MacBook Pro Mic")。
- 让你时刻确信正在使用正确的设备录音。
- 音频输入设备选择 (Audio Input Selection):
- 在设置中新增"音频输入设备"选项,允许用户强制指定录音麦克风。
- 彻底解决了蓝牙耳机 (HFP) 音质差的问题,推荐手动选择 MacBook 内置麦克风。
- 录音状态栏智能提示当前使用的麦克风名称(仅在非默认设备时显示)。
- CoreEngine 稳定性: 修复了核心引擎类结构导致的潜在崩溃问题。
- 音频采样率: 强制统一使用 16kHz/16-bit 采样率,提高识别兼容性。
- 架构升级:引入
AppService和ConfigService,实现更稳健的状态管理和启动逻辑。 - UI 重设计:设置页面全面采用 macOS 原生风格(扁平化设计,优化的间距)。
- 初始化修复:解决 "Initialize sherpa-onnx first" 报错,强制执行严格的初始化顺序 (ASR -> 标点)。
- 按键修复:修复自定义快捷键失效问题,确保原生键盘监听器在 App 启动时立即运行。
- 自愈机制:增加标点模型自修复机制(检测到损坏自动删除)。
- 模型管理:在设置页面恢复标点模型的手动管理功能(下载/删除)。
- 标点符号恢复 (Beta):集成
sherpa-onnx离线标点模型,让语音转文字更自然通顺。 - 系统主题自适应:应用现在会自动跟随 macOS 系统外观(深色/浅色模式)。
- 闪退修复:修复了标点模型初始化时因路径判定错误导致的 App 崩溃问题。
- DMG 安装包:修复了安装包样式丢失无法显示背景和图标布局的问题。
- UI 体验升级:
- 加大了默认窗口尺寸 (800x600),解决内容显示不全的问题。
- 设置与模型合并:使用紧凑的顶部标签页设计。
- 录音截断修复:在
_audioRecorder.stop()之前 等待 500ms,让最后的音频数据有时间被处理。
- 设置页面 UI 重构:移除 Sidebar 依赖,改用顶部导航,适配小窗口。
- 原生按键捕获:支持直接捕获 FN 等特殊修饰键作为 PTT 热键。
- 主界面设置按钮:右上角添加直达设置的入口。
- 录音解码优化:改进 pre/post decode 策略,利用
inputFinished信号减少丢字。 - 图标微调:声波使用更深颜色增加对比度。
- 项目结构清理:移除根目录冗余文件,规范化工程结构。
- 动态文案:UI 中的按键提示文案现在会根据实际设置动态变化 (如从 "Left Option" 变为 "Fn")。
- 最终图标设计:青绿色气泡+声波设计,全尺寸图标更新。
- 图标迭代:尝试新的配色方案 (Teal v2)。
- 提高快捷键优先级:将事件捕获级别从
kCGSessionEventTap改为kCGHIDEventTap- HID 级别的优先级最高,可以在系统快捷键处理之前拦截按键
- 这应该允许 FN 键被正确捕获,而不会触发系统输入法切换
- 修复最后几个字丢失:停止录音后添加 200ms 延迟 + 最多 50 次解码循环
- 波形动画:悬浮提示改为 5 个动态蓝色波形条 + 红色圆点脉冲
- 系统级录音悬浮提示:录音时在屏幕显示红点脉冲动画
- 在所有应用上层显示,即使 SpeakOut 窗口不在前台
- 红色圆点 + 脉冲动画 + "正在录音..." 文字
- 使用 MethodChannel 与 Flutter 通信
- 修复快捷键无法触发录音:Flutter 使用 USB HID 码,macOS 使用 CGKeyCode,两者不兼容
- 添加
_getCGKeyCode()函数正确映射修饰键(Left Option=58, FN=63 等)
- 添加
- 改进 FN 键检测:使用状态跟踪替代单纯 flags 检测,解决某些键盘型号的兼容问题
- FN 键支持:现在可以将 FN 键设置为 PTT 快捷键
- 在
native_input.m中添加 keyCode=63 检测,使用kCGEventFlagMaskSecondaryFn标志位
- Design B UI 重构:Settings 页面改为双栏布局(左侧边栏导航,右侧内容区)
- 录音悬浮提示:按住快捷键时屏幕底部显示波形动画提示
- 中文界面:首页和设置页面全部改为中文
- 模型激活状态显示:用 ✓ 绿色标记和"使用中"标签标识当前模型
- 首页麦克风图标录音时变红,提供视觉反馈
- 状态文字改为中文("正在录音..."、"处理中...")
- 下载进度显示:下载模型时显示实时百分比和进度条
- 使用流式 HTTP 下载,边下载边更新进度
- 自定义快捷键:Settings 页面支持自定义 PTT 按键
- 配置持久化存储,重启后仍然生效
- 音频日志 + 离线 ASR 对比:录音时保存原始音频到
/tmp/ - 停止录音后运行离线 ASR 并在日志中对比结果
- 日志格式优化,显示 STREAMING vs OFFLINE 对比
- 方案3:稳定前缀提交:实现 Stable Prefix Commit 算法
- 最终去重:正则表达式移除连续重复字符/词组
- 使用
_longestCommonPrefix()追踪稳定前缀 - 连续3次 LCP 相同时锁定为 committed
- 方案1:Partial Replace + Final Commit
- UI 实时更新假设,只在松开按键时注入最终结果
- 实时解码 + 简单去重
- 添加
_deduplicateText()函数移除重复字词
- 启用 Sherpa-ONNX endpoint 检测
- 配置
rule1MinTrailingSilence、rule2MinTrailingSilence
- 修复 ASR 输出重复问题初步尝试
- 添加实时 decode 调用
- 核心功能:ASR 引擎集成、PTT 监听、文字注入、模型管理。