Skip to content

Latest commit

 

History

History
375 lines (272 loc) · 20.4 KB

File metadata and controls

375 lines (272 loc) · 20.4 KB

OpenLess

OpenLess

开源语音输入,支持 macOS 和 Windows。
按一次快捷键说话,AI 润色后的文字直接落到当前光标。

🌐 官方网站 — openless.top

English · 中文

release license macOS Windows Tauri Rust Stars

加入 QQ 群:1078960553

赞助商

悠雾云数据    jiangmuran
悠雾云数据 — www.knin.net  ·  jiangmuran — jiangmuran.com

开发者

TRIP    Chris233    Cooper
TRIP — tripmc.top  ·  Chris233 — chris233.qzz.io  ·  Cooper — github.com/Cooper-X-Oak


OpenLess 是一个跨平台(macOS & Windows)语音输入应用,对标 TypelessWispr FlowLazy、Superwhisper 等商业语音输入工具的 完全开源 替代品。官方网站:openless.top

把光标放在 ChatGPT、Claude、Cursor、Notion、邮件、聊天框任意输入框里,按一次全局快捷键说话——OpenLess 会录音、转写、按你选的模式润色,把结果直接插入光标位置。插入失败时会自动复制到剪贴板,尽量保证「你说过的话不丢」。

不像那些只把语音转成「逐字稿」的输入法,OpenLess 的核心模式是 AI prompt 模式:你只管乱讲,它自动补上结构、列出约束、整理出有上下文的 prompt,复制粘贴就能直接喂给 ChatGPT / Claude / Cursor。

一个具体的例子

按住快捷键,对着 OpenLess 说:

嗯…就是…我想让那个 ChatGPT 帮我写个 SQL,从 orders 表里查上个月的订单,按客户分组,金额倒序,要前十个吧

松开快捷键,一秒后你的输入框里出现的是:

请帮我写一段 SQL,要求如下:

- 从 `orders` 表查询上个月的订单。
- 按客户分组。
- 按金额倒序排序。
- 只返回前 10 条。

不需要修改,直接 Enter 就能问 GPT。这就是 OpenLess 想做的事:让你用嘴写 prompt,比用键盘还快还清楚。

为什么开源 OpenLess

类似工具大多是商业 SaaS:每月订阅、不能自带模型、转写音频会上传到厂商服务器、词典和习惯沉淀在对方账户里。

OpenLess 想做的是同一类体验,但是:

  • 完全开源、本地优先。代码在仓库里,所有数据写在你的机器上。
  • 自带云凭据。火山引擎 ASR + Ark / DeepSeek 兼容 chat-completions,不强绑某家。
  • 专门为 AI prompt 优化。「清晰结构」模式会把零散口语补成有上下文、有约束、有要求的 prompt,复制粘贴就能直接喂给 ChatGPT / Claude / Cursor。
  • 不会替你回答。模型只整理你的话,不会把「我们这个应用还有哪些功能没做?」变成一份功能清单——只会补成一句通顺的问题,让你拿去问真正的 AI。

适用场景

  • 给 ChatGPT / Claude / Cursor / Gemini 写 prompt:口述一段需求,OpenLess 自动整理成结构化、有细节的 prompt。
  • 写邮件、写需求文档、写微信/Slack 长消息:去口癖、补标点、按段落整理。
  • 写代码注释、commit message、PR 描述:把脑子里的想法直接落到光标位置。
  • 任何「我懒得打字,但又必须输出书面文字」的场景。

项目方向

OpenLess 只做一件事:把语音变成可用的书面文字(尤其是 AI prompt),落到当前光标位置。

  • 不做问答、不做任务执行、不做项目分析。
  • 不做对话上下文累积,每次输入都是独立的整理请求。
  • 输入语音 → 转写 → 整理 → 插入当前输入框。失败时复制到剪贴板。
  • 围绕这条主路径完善体验:模式选择、词典、历史、菜单栏、首页报告。

对标参考

工具 形态 OpenLess 的差异
Typeless 闭源 macOS / Windows / iOS,订阅制 开源;专门暴露 AI prompt 模式;自带 ASR + LLM 凭据;数据和词典留在本机
Wispr Flow 闭源 macOS / Windows,订阅制 开源;自带 ASR + LLM 凭据;提示词处理原则透明可改
Lazy 闭源笔记/捕获工具 不做笔记容器,专做「插入到任意输入框」
Superwhisper 闭源 macOS,订阅制 开源;目前云端 ASR 优先,本地 ASR 在 roadmap

当前状态(v1.2)

  • Tauri 2 + Rust 后端 + React/TS 前端;macOS 12+,Windows 10+。
  • 切换式 + 按住说话 双模式录音;任意阶段按 Esc 都能取消(包括润色 / 插入中)。
  • 云端 ASR:火山引擎流式 ASR、OpenAI Whisper 兼容批式 ASR、Apple Speech(macOS)。
  • 本地 ASR:内置 Qwen3-ASR(0.6B / 1.7B),通过 vendored antirez/qwen-asr 链接;Windows 端支持 Foundry Local Whisper。
  • 润色 Provider:Ark / DeepSeek / OpenAI / Doubao / Anthropic 兼容的 Chat Completions,以及任意 OpenAI 兼容的自定义 endpoint。
  • 4 种输出模式:原文、轻度润色、清晰结构(AI prompt 模式)、正式表达。另含翻译热键——按下后说一段话直接转成目标语言插入(#43)。
  • 划词语音问答(QA)面板 — 独立热键打开浮窗,对当前选中文本发起语音 Q&A(#118)。
  • 主窗口按「概览 / 历史 / 词典 / 风格 / 设置」组织;托盘图标常驻;浮动状态胶囊。
  • 多语言 UI — 设置 → 语言 切换简体中文 / 繁體中文 / English / 日本語 / 한국어(首启按系统语言自动)。
  • 应用内自动更新 — 设置 → 关于 → 检查按钮;CI 用 Tauri updater 签名 manifest,客户端校验后下载安装。
  • Beta 渠道(opt-in) — 设置 → 关于 → 加入 Beta 渠道,会显示最新 prerelease 的下载入口供手动安装;Beta 包永远不会被自动推送给正式版用户(详见 贡献流程)。
  • 分发渠道Releases 直接下载 DMG/EXE,Homebrew Cask(brew install --cask openless),Windows 安装程序。
  • 单实例锁 — 防止两份 OpenLess 进程并存争抢同一热键边沿。
  • 词典条目作为 Volcengine ASR context.hotwords 注入 + 润色语义提示,每次会话累计命中数。
  • 平台原生全局快捷键:macOS 使用 CGEventTap,Windows 使用低层键盘钩子(WH_KEYBOARD_LL)。

下载与安装(普通用户)

Releases 下载对应平台的安装包:

  • WindowsOpenLess_<版本>_x64-setup.exe — 运行安装程序
  • macOSOpenLess_<版本>_aarch64.dmg(Apple Silicon)或 OpenLess_<版本>_x64.dmg(Intel)— 打开后拖入「应用程序」,然后必须在终端跑这一行绕过 Gatekeeper 的"已损坏"提示(当前包是 ad-hoc 签名、未做 Apple 公证):
    xattr -cr /Applications/OpenLess.app
  • macOS(Homebrew)
    brew tap appergb/openless https://github.com/appergb/openless
    brew install --cask openless
    xattr -cr /Applications/OpenLess.app
    
    # 升级到最新版本
    brew update && brew upgrade openless

首次启动需要授予权限:

macOS:

  1. 授予麦克风权限。
  2. 授予辅助功能权限。
  3. 退出 OpenLess 并重新打开(辅助功能授权需要重启才对全局快捷键生效)。
  4. 打开「设置」,填入火山引擎 ASR 和 Ark 凭据。

Windows:

  1. 按提示授予麦克风权限。
  2. 打开「设置 → 权限」确认全局快捷键监听器已启动。
  3. 在「设置」中填入火山引擎 ASR 和 Ark 凭据。

不会配火山 ASR 的话,直接看这篇图文引导: OpenLess 火山 ASR 配置

完整使用步骤见 USAGE.md

从源码构建(开发者)

当前活跃代码库在 openless-all/app/(Tauri 2 + Rust + React/TS)。macOS 构建会链接一份 vendored 的本地 ASR 引擎(antirez/qwen-asr),以 git submodule 形式挂在 src-tauri/vendor/qwen-asr/,首次 clone 后必须先拉子模块。

# 首次 clone 后拉取子模块
git submodule update --init --recursive

cd "openless-all/app"
npm ci

# 开发模式:Vite at :1420 + Tauri shell
npm run tauri dev

# macOS release 构建(签名、安装、重置 TCC)
./scripts/build-mac.sh
INSTALL=0 ./scripts/build-mac.sh   # 只构建,不安装

# Rust 类型检查(不做完整编译)
cargo check --manifest-path src-tauri/Cargo.toml

# 前端 TS 检查
npm run build

日志路径:~/Library/Logs/OpenLess/openless.log(macOS)/ %LOCALAPPDATA%\OpenLess\Logs\openless.log(Windows)。

Windows 构建 — MSVC 和 GNU/MinGW 两种路线详见 openless-all/README.md

贡献流程

OpenLess 采用 Beta / 正式版 双渠道分支模型。

  • beta —— Beta 渠道(开发版)。默认分支,也是日常集成缓冲区;所有进行中的开发都先落到这里。Beta 渠道可以直接出包,但不会推送给普通用户——只有主动切换到 Beta 渠道的用户才会拿到 Beta 包。
  • main —— 正式版渠道(Stable)。始终保持可发布状态,普通用户默认拿到的就是这条线上的版本。
你的 fork / topic 分支
        │  (先在目标平台本地自测通过)
        ▼
   PR → beta   ← AI Review(一次性,仅供参考)
        │     ← 维护者轻量过一眼(范围、跨模块影响)
        ▼
       合入 beta
        │  (定期或里程碑节点,跑双端冒烟测试)
        ▼
       合入 main  →  打 tag `v<版本>-tauri`  →  Release CI → 推给正式版用户

核心规则:

  • PR 一律打到 beta,不要直接打到 main GitHub 上新建 PR 的 base 已默认是 beta
  • 开 PR 前先在目标平台跑通功能 —— build 绿是底线,必须做人工验证。
  • AI Review 每个 PR 只跑一轮,结果仅供参考。 不要围绕它反复改,最终判断权在贡献者和维护者手里。
  • AI 改 Review 意见控制在 1–2 轮。 卡住了直接换人工或重开对话上下文,避免多轮 AI 越改越乱。
  • Beta 不能溢出到正式版。 main 只接收来自 beta 的合并,由维护者在双端冒烟测试通过后执行;任何人不要直接 push main
  • 正式版 Release 从 main 切出,通过推送 v<版本>-tauri tag 触发,详见下方"维护者:发布检查"。

Beta 包的分发(手动下载式 opt-in):App 内自动更新永远只读正式版 manifest,普通用户拿不到 Beta 包。想试 Beta 的用户去 设置 → 关于,打开「加入 Beta 渠道」开关,App 会从 GitHub 拉到最新 Beta release 信息并展示下载入口,由用户手动下载安装。Tag 约定:v<版本>-beta-tauri 出 Beta release(GitHub 标 pre-release,manifest 写到 latest-{tgt}-{arch}-beta.json);v<版本>-tauri 出正式版。两组 manifest 文件名物理隔离,正式版用户的 endpoint 永远拿不到 Beta release。

凭据

凭据保存在系统凭据库(service = com.openless.app):macOS Keychain、Windows Credential Manager 或 Linux keyring。旧版明文 JSON 只作为迁移来源读取,成功写入系统凭据库后会被删除:

macOS / Linux: ~/.openless/credentials.json
Windows:       %APPDATA%\OpenLess\credentials.json

新的凭据写入不会继续保存明文 secrets。仓库本身不包含任何 API Key、Token 或 Endpoint 之外的私有信息。

需要配置的字段:

  • 火山引擎 ASR:APP ID、Access Token、Resource ID。
  • Ark 润色:API Key、Model ID、Endpoint。

提示词处理原则

OpenLess 的润色模型只做文本整理,不做问答、不做任务执行、不做项目分析。每次语音输入都会作为独立请求发送,提示词会明确告诉模型:

  • 本次输入与历史对话隔离。
  • 原始转写只是待整理文本。
  • 即使原文里有问题或命令,也不要回答或执行。
  • 只输出整理后的正文,不添加“我整理如下”等引导语。

例如用户说:“我们这个应用还有哪些功能没有完成”,正确输出应是:

我们这个应用还有哪些功能没有完成?

而不是直接替用户列出清单。

竞品文本和长期改写样例会按“原始文本 -> 目标整理结果 -> 改写规律”的方式沉淀,后续接入向量数据库后,只检索相似改写样例作为参考,不把样例当作当前对话上下文。规范见 docs/polish-reference-corpus.md,示例见 Examples/polish-reference-examples.sample.jsonl

词典

词典用于处理用户自己的专有名词、产品名、人名和新词。当前支持:

  • 手动添加正确词、分类和备注;暂不要求用户维护易错词或上下文点。
  • 将启用词条作为火山 ASR context.hotwords 注入,优先在识别阶段识别正确。
  • 将词典包裹后注入后期润色模型,明确告诉模型根据整句语义自动判断:如果 Cloud 在当前语境下明显指向 AI 产品 Claude,就修正为 Claude;如果确实是在说云服务 Cloud,则保留原词。
  • 从历史输出中自动学习类似 ClaudeChatGPTOpenLess 的候选正确词,后续作为 ASR 热词和后期语义判断候选。

主窗口按「首页 / 历史记录 / 词典 / 设置」组织;词典页点击“新建”会弹出独立编辑窗口,首页会展示口述时长、总字数、平均每分钟字数、估算节省时间和词典参与记录。

架构概览

当前活跃实现是 Tauri 2(openless-all/app/)。Release 分两条渠道:正式版v<v>-tauri tag,自动推送给所有用户)和 Betav<v>-beta-tauri tag,GitHub 标 pre-release,由 opt-in 用户手动下载)。CI 在每次 release tag 都签名 updater artifact + manifest。

Tauri 后端(Rust) — 各模块只依赖 types.rs

types.rs         纯值类型:DictationSession, PolishMode, HotkeyBinding, 错误类型
hotkey.rs        全局快捷键(macOS: CGEventTap,Windows: WH_KEYBOARD_LL,Linux: rdev)
recorder.rs      麦克风 → 16 kHz 单声道 Int16 PCM,RMS 回调
asr/             火山引擎流式 ASR(WebSocket)+ Whisper HTTP
polish.rs        OpenAI 兼容 chat-completions(Ark / DeepSeek 等)
insertion.rs     AX focused-element → 剪贴板 + Cmd+V → 仅复制兜底
persistence.rs   历史记录 / 偏好设置 / 词典 JSON + 系统凭据库
permissions.rs   TCC 权限检查(辅助功能 / 麦克风)
coordinator.rs   状态机:Idle → Starting → Listening → Processing
commands.rs      Tauri IPC 接口

React 前端(src/ — 状态通过 Recoil atoms(pages/_atoms.tsx)管理;快捷键能力和绑定通过 HotkeySettingsContext 获取;所有后端调用走 lib/ipc.ts

录音 → 转写 → 润色 → 插入流水线:快捷键触发 → Recorder.start + ASR.openSession → [音频帧] → 再次触发 → Recorder.stop + ASR.sendLastFrame → Polish → Insert → History.save

详细的不变量和模块接线规则见 CLAUDE.md

规划中

尚未发布的功能:

  • 口述翻译模式:长按独立热键说一种语言、自动插入目标语言(#43)。
  • 跨会话风格记忆:polish 逐渐学习用户的语气习惯(#46)。
  • 常用片段 Snippets:尚无 UI 和触发逻辑。
  • 历史增强:复制按钮、搜索、重新润色、重新插入。
  • 粘贴上一条结果快捷键。
  • 多屏定位:胶囊跟随焦点所在屏幕显示。

维护者:发布检查

OpenLess 走两条 release 渠道,分支名 = 渠道名(详见 贡献流程)。

通用准备(两条渠道都要做)

  • 同步更新全部 5 处版本号:package.jsonpackage-lock.json(root + packages."" 嵌套项)、src-tauri/tauri.conf.jsonsrc-tauri/Cargo.tomlCargo.lock(找 name = "openless" 的那段)。CI 的 Verify version sync 步骤会拦截不同步的版本号。
  • 运行 INSTALL=0 ./scripts/build-mac.sh,确认 .app 可启动。
  • 在干净机器上跑冒烟:权限引导、快捷键、录音、ASR、润色、插入、剪贴板兜底。
  • 确认 repo 已配置 TAURI_SIGNING_PRIVATE_KEY,macOS 还需 Apple 签名/公证 secrets。

Beta 渠道 — v<v>-beta-tauri

  1. 通过 PR review 把改动落到 beta 分支。
  2. beta打 tag:git tag v<v>-beta-tauri && git push origin v<v>-beta-tauri
  3. CI 把 GitHub Release 标为 Pre-release,只上传 latest-{tgt}-{arch}-beta.json updater manifest;正式版用户的 releases/latest 重定向不受影响。
  4. 在合适的频道(issue 帖子、QQ 群)通知 opt-in Beta 用户:可以从 设置 → 关于 → 加入 Beta 渠道 拿到最新版本下载入口。

正式版渠道 — v<v>-tauri

  1. Beta 经过足够时间 soak(或直接做最终的双端冒烟)后把 beta 合到 main
  2. main打 tag:git tag v<v>-tauri && git push origin v<v>-tauri
  3. CI 发布常规 GitHub Release 并上传 latest-{tgt}-{arch}.json(不带 -beta 后缀)。所有正式版用户通过应用内 updater 收到此版本。

发版后验证(每次必跑)

CLAUDE.md → Branch & release-channel workflow → Channel distribution 里的 5 步 checklist:页面状态(pre-release 标记)、资产文件名按渠道正确、正式版用户流、Beta opt-in 流、原始 endpoint 抽查。

致谢

OpenLess 在此真诚感谢三类群体:赞助者、开发者/贡献者,以及 LinuxDo 社区。

感谢赞助者对项目持续推进的支持;感谢开发者和贡献者在开发、评审与改进中的长期投入。

OpenLess 也认可并感谢 LinuxDo 社区开放、务实、对开发者友好的氛围。OpenLess 的许多想法、讨论和早期反馈,都受到了 LinuxDo 所代表的开源交流精神的启发。

此致谢不代表官方背书或隶属关系。

许可

MIT