Files
TRIPandHKLHaoBin 6f9af89583 release: OpenLess 2.0.0-Beta.4+build.20260930 (#1126)
Integrate ASR/Omni fixes, API Route, Android IME and confirmation-based vocabulary learning. Complete settings transitions and macOS single-item credential storage. Synchronize all application versions to 2.0.0-Beta.4+build.20260930.

Integrated PRs: #1116, #1120, #1121, #1123, #1124, #1067 and #1128. Linux #1117 remains independent and is excluded from automatic release.

Validated: full cross-platform CI, 18 UI motion cases, 112 frontend test files, 1245 Core tests (1 ignored) and 572 macOS native tests.

Co-authored-by: HKLHaoBin <we3q@qq.com>
2026-09-30 20:32:53 +08:00

441 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<p align="center">
<img src="openless-all/app/src-tauri/icons/128x128@2x.png" alt="OpenLess" width="128" height="128" />
</p>
<h1 align="center">OpenLess</h1>
<p align="center">
<strong>面向 macOS、Windows 与 Linux 的开源语音输入工具</strong>
</p>
<p align="center">
按住快捷键说话,经 AI 润色的文本会实时插入到光标处——<br/>
以<em>你</em>选择的写作风格呈现。
</p>
<p align="center">
<a href="https://openless.top"><strong>官网</strong></a>
&nbsp;·&nbsp;
<a href="https://github.com/Open-Less/openless/releases/latest"><strong>下载</strong></a>
&nbsp;·&nbsp;
<a href="README.md">English</a>
&nbsp;/&nbsp;
<a href="README.zh.md">中文</a>
</p>
<p align="center">
<a href="https://github.com/Open-Less/openless/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/Open-Less/openless?style=flat-square&color=2c5282" /></a>
<a href="https://github.com/Open-Less/openless/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/Open-Less/openless?style=flat-square&color=2f855a" /></a>
<a href="https://github.com/Open-Less/openless/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/Open-Less/openless?style=flat-square&color=805ad5" /></a>
<a href="https://discord.gg/vTZHTFGFm"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord&logoColor=white" /></a>
</p>
<p align="center">
<img alt="macOS" src="https://img.shields.io/badge/macOS-12%2B-1f425f?style=flat-square&logo=apple&logoColor=white" />
<img alt="Windows" src="https://img.shields.io/badge/Windows-10%2B-0078d4?style=flat-square&logo=windows&logoColor=white" />
<img alt="Linux" src="https://img.shields.io/badge/Linux-egui-fcc624?style=flat-square&logo=linux&logoColor=black" />
<img alt="Tauri" src="https://img.shields.io/badge/Tauri-2-24c8db?style=flat-square&logo=tauri&logoColor=white" />
<img alt="Rust" src="https://img.shields.io/badge/Rust-2021-ce422b?style=flat-square&logo=rust&logoColor=white" />
</p>
<p align="center">
💬 &nbsp;<a href="https://discord.gg/vTZHTFGFm"><strong>加入 Discord 社区</strong></a> &nbsp;·&nbsp; QQ 群&nbsp; <strong>1078960553</strong>
</p>
<br/>
<h2 align="center">赞助商</h2>
<p align="center">
<em>OpenLess 的持续开发,离不开赞助商的慷慨支持。</em>
</p>
<p align="center">
<a href="https://www.knin.net" target="_blank" rel="noopener">
<img alt="悠雾云数据 (Youwu Cloud Data)" src="https://www.knin.net/upload/logo.png" height="52" />
</a>
<br/>
<a href="https://www.knin.net" target="_blank" rel="noopener">悠雾云数据 · Youwu Cloud Data (knin.net)</a>
</p>
<h2 align="center">开发者</h2>
<table align="center">
<tr>
<td align="center" width="170">
<img src="assets/people/tripmc.png" width="80" height="80" alt="TRIP" /><br/>
<strong><a href="https://tripmc.top/" target="_blank" rel="noopener">TRIP</a></strong><br/>
<sub>作者</sub>
</td>
<td align="center" width="170">
<img src="assets/people/Chris233.png" width="80" height="80" alt="Chris233" /><br/>
<strong><a href="https://github.com/H-Chris233" target="_blank" rel="noopener">Chris233</a></strong><br/>
<sub>作者/维护者</sub>
</td>
<td align="center" width="170">
<img
src="https://image.bigsong.site/file/1787214963742_b40cd86b033a60bcc8562f7f053c4900.jpg"
width="80"
height="80"
alt="bigsong"
/><br/>
<strong><a href="https://bigsong.site" target="_blank" rel="noopener">bigsong</a></strong><br/>
<sub>贡献者/测试</sub>
</td>
</tr>
<tr>
<td align="center" width="170">
<img src="https://github.com/HKLHaoBin.png" width="80" height="80" alt="HKLHaoBin" /><br/>
<strong><a href="https://github.com/HKLHaoBin" target="_blank" rel="noopener">HKLHaoBin</a></strong><br/>
<sub>安卓版作者 / 安卓版维护者</sub>
</td>
<td align="center" width="170">
<img src="assets/people/cooper.png" width="80" height="80" alt="Cooper" /><br/>
<strong><a href="https://github.com/Cooper-X-Oak" target="_blank" rel="noopener">Cooper</a></strong><br/>
<sub>贡献者</sub>
</td>
<td align="center" width="170">
<img src="https://github.com/aeoform.png" width="80" height="80" alt="aeoform" /><br/>
<strong><a href="https://github.com/aeoform" target="_blank" rel="noopener">aeoform</a></strong><br/>
<sub>贡献者 / Linux 维护者</sub>
</td>
</tr>
<tr>
<td align="center" width="170">
<img src="assets/people/jimmy54.png" width="80" height="80" alt="jimmy54" /><br/>
<strong><a href="https://github.com/jimmy54" target="_blank" rel="noopener">jimmy54</a></strong><br/>
<sub>macOS 打包与开发者账号</sub>
</td>
</tr>
</table>
OpenLess 是一款跨平台(macOS 与 Windows)语音输入应用,是 [Typeless](https://www.typeless.com/)、[Wispr Flow](https://wisprflow.ai)、[Lazy](https://heylazy.com)、Superwhisper 等商业工具的完全开源替代品。官网:[openless.top](https://openless.top)。
把光标放在任意文本框中——ChatGPT、Claude、Cursor、Notion、邮件草稿、聊天框——按下一个全局快捷键,然后开口说话。OpenLess 会录音、转写,按你选定的模式润色文本,并将结果插入到光标处。如果插入被阻止,文本会改为复制到剪贴板,你说过的话不会丢失。
与只产出逐字转写稿的听写工具不同,OpenLess 的核心能力是 **AI Prompt 模式**:你自由地说,它来补充结构、整理你的约束条件,生成一段包含上下文的提示词,可直接粘贴进 ChatGPT、Claude 或 Cursor。
## 从工具到基础设施
真正高级的系统都在做同一件事:**把今天的沟通,变成明天的默认规则。** 互联网赢,不是因为 HTTP 更快,而是因为没人再讨论数据怎么传;Git 赢,不是因为代码更优,而是因为团队不用每天协调版本;Stripe 赢,不是因为支付更快,而是因为开发者不用再协调银行。
OpenLess 做的不是“更快的听写”,而是**消灭“想法 → 干净文字”之间的每一次协调**。过去,把脑子里的话落成能用的文字,你要一遍遍临时决定:这段用什么语气?这个名字怎么拼?落到哪个输入框、复制还是粘贴?模型的钥匙放哪、谁有权限?OpenLess 把这些反复的临时协商,逐层**沉降**成默认规则:
- **语气** 沉降成**风格包**——命名、可切换,热键一按即生效,不必每次重新决定。
- **专有名词** 沉降成**词典热词**——ASR 端识别、润色端语义提示,不必逐次纠正。
- **文字落点** 沉降成**唯一插入协议**——按住 → 说 → 落在光标处,失败自动回退剪贴板。
- **模型与凭据** 沉降进**操作系统保管库**——开屏授权一次,此后永不重谈。
这就是**开屏即授权完基础设施**:首次启动,你只授权一次麦克风、辅助功能与云端凭据;从那一刻起,“开口说话 → 光标处出现干净文字”不再是一次次的操作协商,而是一条你可以忘记它存在的默认协议。衡量 OpenLess 的价值,不在于它快了多少,而在于它替你**消灭了多少协调**。
## ✨ 更新亮点
下面这些能力,把过去每天都要重复的协调,进一步沉降成了默认规则:
- 📖 **会自己长的词典。** 在此之前,词典里只有你亲手敲进去的东西。现在,当你改掉 OpenLess 刚写出来的某个词,它会在屏幕角落弹一张小卡片问一声要不要记住,点一下就进去了。配合**光标上下文**(需手动开启,仅 macOS)——让润色模型读得到你光标周围正在写的内容——OpenLess 不再是一个靠猜同音词的转写工具,而开始成为**一个认得你的词的输入法**。每一条建议都由你过目,没有任何东西是悄悄学走的。
- 🎨 **风格包市场(Style Pack Marketplace)。** OpenLess 不再只内置一种固定的“润色”语气。你可以用自定义系统提示词构建自己的**风格包**,用快捷键在它们之间切换,并**一键安装社区分享的风格包**——也可以发布自己的与他人分享。当风格与你的具体任务高度契合(冷启动邮件、commit message、小红书文案、正式报告、团队语气)时,产出的文本不只是更干净,而是*明显更好*,因为模型终于在按你真正想要的方式写作。
- ⚡ **流式插入。** 文本现在会随润色**逐字符**写入光标,而不必等待完整结果生成。感知延迟大幅下降,听写几乎和思考一样快——当某个应用无法接受流式按键时,它会自动回退为一次性粘贴。
## 一个实际例子
按住快捷键,说:
> 嗯…那个,我要给客户回个邮件,就是上次他们提的那个方案嘛,我们内部讨论了一下觉得大方向没问题,但是有几个细节要改,第一个就是交付时间太紧了我们希望延两周,第二个是预算那块他们报的价格比我们预期高了大概百分之二十能不能谈一下,然后整体合作意向是积极的让他们放心,语气客气一点别太生硬
松开快捷键。片刻之后,你的输入框里出现:
```text
给客户回邮件,关于上次他们提的方案,我们内部讨论后认为大方向没问题,但有几个细节需要调整:
1. 交付时间
(a) 目前交付时间太紧,希望延长两周。
2. 预算
(a) 他们的报价比我们预期高了大约 20%,能否再谈一下?
整体合作意向是积极的,语气上请客气一点,不要太生硬。
```
无需任何修改——直接粘贴给 ChatGPT 或 Claude,让它替你把邮件写完。这就是核心理念:**用嘴写提示词,比打字更快、更干净。**
## 为什么 OpenLess 选择开源
最接近的替代品都是订阅制 SaaS:按月付费、无法自带模型、音频上传到厂商、你的词典和习惯都存在它们的账户里。
OpenLess 追求同样的终端体验,但:
- **完全开源、本地优先。** 代码就在本仓库,你的所有数据都留在自己的机器上。
- **自带云端凭据。** Volcengine 流式 ASR + Ark / DeepSeek 兼容的 chat completions,不绑定任何厂商。
- **为 AI 提示词而调优。** 结构化模式会把零散的口语重塑为带有上下文、约束与诉求的提示词,可直接粘贴进 ChatGPT、Claude 或 Cursor。
- **它不会替你作答。** 模型只负责清理你的文字。如果你说“这个应用还需要哪些功能?”,它会原样返回为一个干净的问句——而不会给你列一份功能清单。那种事,去问 AI 本体。
## 适用场景
- **为 ChatGPT / Claude / Cursor / Gemini 写提示词**——口述需求,OpenLess 将其转为结构化、细节充分的提示词。
- **起草邮件、规格说明、较长的 Slack 或微信消息**——去除口头语、修正标点、整理段落。
- **代码注释、commit message、PR 描述**——把脑子里的想法直接落到光标处。
- **任何**你必须产出文字、却又不想打字的场景。
## 风格包与市场
**风格包**是一种带有专属系统提示词的、命名的输出风格。你不再被限定于唯一的内置“润色”语气,而是可以精确塑造口语的呈现方式——风格越贴近你的真实任务,效果就越好。
- **创建与自定义。** 在**风格(Style)**页面新增一个风格包,写入自定义系统提示词(例如“简洁的工程 commit message”“温暖的客服回复”“带 emoji 的小红书文案”)。用快捷键切换当前生效的风格包。
- **从社区安装。** 打开**市场(Marketplace)**,浏览、搜索并一键安装他人分享的风格包,并为好用的点赞。
- **发布自己的。** 用 GitHub 身份登录(设置 → Marketplace),然后在风格页选择**发布到 Marketplace**。上传内容会经过审核后才公开展示。
市场由 OpenLess 自有的、经过审核的后端提供服务,因此目录是经过策展的,而非放任的大杂烩。
## 项目定位
OpenLess 只做一件事:**把语音变成可用的书面文字(尤其是 AI 提示词),并落在当前光标处。**
- 它不回答问题、不执行任务、不分析你的项目。
- 它不积累对话上下文;每次听写都是一次独立的清理请求。
- 流程是:语音 → 转写 → 清理 → 插入到光标,失败时回退到剪贴板。
- 其余的一切(模式、词典、历史、菜单栏、首页报告)都为这唯一的路径服务。
## 对比
| 工具 | 形态 | OpenLess 的不同之处 |
| --- | --- | --- |
| [Typeless](https://www.typeless.com/) | 闭源 macOS / Windows / iOS,订阅制 | 开源;显式的 AI 提示词模式;自带 ASR + LLM;数据与词典留在本机——包括词典从你的手改中学到的东西,不上传,也不会在你确认之前加进去 |
| [Wispr Flow](https://wisprflow.ai) | 闭源 macOS / Windows,订阅制 | 开源;自带 ASR + LLM;文本处理规则透明 |
| [Lazy](https://heylazy.com) | 闭源的笔记 / 速记工具 | 不是笔记容器——直接插入到任意输入框 |
| [Superwhisper](https://superwhisper.com) | 闭源 macOS,订阅制 | 开源;目前云端 ASR,本地 ASR 在路线图中 |
## 当前状态
本 Fork 的 Android 输入法架构、四个面板的使用说明、截图和从 fork 基线开始的功能时间线,见 [Android 输入法:架构、功能与 fork 演进](docs/android-ime.md)。
下面每一项,都是一层已经沉降为默认、你授权一次之后就不必再操心的能力——这就是开屏之后你所站立的基础设施:
- 共享 Rust 后端位于 `openless-core`。macOS 与 Windows 使用薄 Tauri 2 宿主和 React/TypeScript 前端;Android 暂时保留 Tauri mobile 宿主;Linux 使用独立原生宿主,不编译 Tauri 或 WebKitGTK。
- 🎨 **风格包市场**——在应用内的 Marketplace 浏览、安装、点赞社区**风格包**,并发布自己的(每个包一套自定义系统提示词,可用快捷键切换)。由经过审核的市场后端支撑;上传内容公开前会经过审核。
- ⚡ **流式插入**——润色后的文本逐字符写入光标以降低感知延迟,并带有自动的一次性粘贴回退。可在 设置 → 录音 中切换。
- **切换式与按住说话(push-to-talk)** 两种录音模式,外加 **MediaPlayPause 触发**,让有线耳机的线控也能开始 / 停止录音。`Esc` 可在任意阶段取消,包括润色与插入。
- **云端 ASR**:Volcengine 流式 ASR(bigasr)、腾讯云混元实时 ASR(Hy-ASR)、讯飞实时语音转写(RTASR)、阿里云百炼(经典实时 / Qwen3 实时 / Fun-ASR-Flash 录音文件)、阶跃星辰 StepAudio(批式 + 实时)、智谱 GLM-ASR、小米 MiMo ASR、OrcaRouter 音频输入 Gemini、ElevenLabs Scribe、OpenAI 兼容批量转写(OpenAI Whisper / Groq / 硅基流动 SenseVoice / OpenRouter / ZenMux),以及 Apple Speech(macOS)。
- **本地 ASR**:通过 vendored 的 `Open-Less/qwen-asr` 内置 Qwen3-ASR(0.6B / 1.7B)(macOS);Windows 上的 Foundry Local Whisper 与 sherpa-onnx(实验性)变体。
- **润色提供方**:Ark(火山方舟)、DeepSeek、OpenAI、Google Gemini、Codex OAuth、硅基流动、Atlas Cloud、小米 MiMo、腾讯云 TokenHub、CometAPI、OpenRouter、Requesty、API Route、OrcaRouter、阿里云 Coding Plan、CodingPlanX、MiniMax、StepFun、OpenCode Zen,以及你自带的任意 OpenAI 兼容端点。
- **四种输出模式**:原文、轻度润色、结构化(**AI 提示词模式**)、正式。另有一个**翻译快捷键**,将语音直接转换为所配置的目标语言([#43](https://github.com/Open-Less/openless/issues/43))。
- **选区问答面板**——一个独立快捷键打开浮动面板,针对任意应用中被高亮选中的文本进行语音问答([#118](https://github.com/Open-Less/openless/issues/118))。
- **主窗口**:概览 / 历史 / 词典 / 风格 / 市场 / 设置。常驻托盘图标,以及一个浮于屏幕、并跟随你正在输入的显示器的迷你状态胶囊(多显示器)。
- **本地模型管理**——在设置中管理本地 ASR 模型在磁盘上的存储。
- **多语言界面**——设置 → 语言 可在 简体中文 / 繁體中文 / English / 日本語 / 한국어 之间切换(首次启动自动检测)。
- **Tauri 宿主内自动更新**——macOS、Windows 与 Android 通过 设置 → 关于 → 检查 获取签名产物;Linux deb/rpm 不提供应用内更新或 AppImage 更新清单。
- **Beta 频道(可选加入)**——设置 → 关于与更新 → 加入 Beta 频道,切换至 Beta 更新源;也可在 Releases 下载安装包。Beta 版本绝不会自动推送给 Stable 用户(见[贡献流程](#贡献流程))。
- **分发渠道**——从 [Releases](https://github.com/Open-Less/openless/releases) 直接下载 DMG/EXE、Homebrew Cask(须先添加项目 tap,见下方安装步骤)、Windows 安装包。Linux deb/rpm 在独立真机验收后,由管理员把已验证的包附到已有 Release。
- **单实例锁**——防止两个 OpenLess 进程争抢同一个快捷键边沿。
- 词典条目注入到支持热词的 ASR 提供方(Volcengine 的 `context.hotwords`、StepFun 的 `hotwords`、Whisper 兼容的 `prompt`(ZenMux 除外——其 JSON 协议不携带 `prompt`/`hotwords`)、百炼的 vocabulary_id),并在润色时作为语义提示;命中次数按会话累计。讯飞实时语音转写标准版没有请求级热词参数,需在讯飞控制台配置个性化热词。
- 平台原生全局快捷键:macOS 上为 CGEventTap,Windows 上为低级键盘钩子(`WH_KEYBOARD_LL`)。
## 下载与安装(终端用户)
前往 [Releases](https://github.com/Open-Less/openless/releases) 下载:
- **macOS**:`OpenLess_<version>_aarch64.dmg`(Apple Silicon)或 `OpenLess_<version>_x64.dmg`(Intel)。打开后将应用拖入 `/Applications`,**然后在终端执行一次以下命令,以绕过 Gatekeeper 的“已损坏”提示**(该构建为 ad-hoc 签名,未经 Apple 公证):
```bash
xattr -cr /Applications/OpenLess.app
```
- **Windows**:`OpenLess_<version>_x64-setup.exe`——运行安装程序。
- **Android**(GitHub Release 提供 release APK;Actions artifact 提供 debug 冒烟包):
- **真机推荐**:`OpenLess_<version>_arm64-v8a.apk`
- **旧款 32 位 ARM**:`OpenLess_<version>_armeabi-v7a.apk`
- **64 位模拟器**:`OpenLess_<version>_x86_64.apk`
- **32 位模拟器**:`OpenLess_<version>_x86.apk`
- 应用内更新(设置 → 关于)读取 `latest-android-{arch}.json`;Beta 用户在高级设置加入 Beta 渠道。
- 调试包:`OpenLess-android-debug-{abi}-*.apk`(workflow_dispatch 产物)。
- 不确定时执行 `adb shell getprop ro.product.cpu.abi`,下载对应 ABI 的包。
- **Linux**:原 Tauri/WebView 构建已退出 Linux 路线。基于共享 Core 2.0 服务的原生 `eframe` 宿主经 CI 和 Ubuntu 真实音频、输入、安装、升级、回滚验收后,随共用 Release 提供 deb/rpm 和 `SHA256SUMS`。要求 glibc ≥ 2.39(Ubuntu 24.04 或同等级发行版);没有 AppImage 或应用内更新。
- **macOS(Homebrew)**:
```bash
brew tap Open-Less/openless https://github.com/Open-Less/openless
brew install --cask openless
xattr -cr /Applications/OpenLess.app
# 升级到最新版本
brew update && brew upgrade openless
```
首次启动时,请授予应用所请求的权限。
**macOS:**
1. 授予麦克风访问权限。
2. 授予辅助功能(Accessibility)访问权限。
3. **退出并重新打开应用**——辅助功能权限需重启后才生效。
4. 打开设置,填入你的 Volcengine ASR + Ark 凭据。
**Windows:**
1. 在提示时授予麦克风访问权限。
2. 打开 设置 → 权限,确认全局快捷键监听已激活。
3. 在设置中填入你的 Volcengine ASR + Ark 凭据。
完整的终端用户指南见 [USAGE.md](USAGE.md)。
## 从源码构建(开发者)
活跃 workspace 位于 `openless-all/app/`:`crates/openless-core` 是框架无关后端,`src-tauri` 承载 macOS/Windows/Android,`linux-egui` 包含 Linux 原生 UI 与平台 Adapter。源码构建 Tauri 前需初始化子模块:即使不编译对应平台代码,Cargo 仍会解析 manifest 中的本地 path 依赖,其中包括 `src-tauri/vendor/` 下的 macOS ASR 引擎,如 [`Open-Less/qwen-asr`](https://github.com/Open-Less/qwen-asr)。根 Core/Linux workspace 排除了 `src-tauri`,其独立检查不解析 Tauri manifest,也不要求这些子模块。阅读入口为 [docs/index.md](docs/index.md)、[架构](docs/architecture.md)和[目录结构](docs/structure.md)。
Rust 1.88 是桌面应用源码(`openless-core`、`src-tauri`)所支持的最低工具链版本;建议使用最新 stable Rust。CI 在 macOS 与 Windows 上同时验证 Rust 1.88 与 stable;Linux egui 宿主需要 Rust 1.95,按 stable 验证。
Apple Silicon 编译可选的 Qwen3-ASR MLX 后端时需要 Xcode 的 MetalToolchain 组件。执行 `xcodebuild -downloadComponent MetalToolchain` 安装,并用 `xcrun --find metal` 验证。它只属于源码构建依赖,已打包的 OpenLess 应用运行时不需要该组件。
```bash
cd "openless-all/app"
npm ci
# macOS/Windows/Android:Vite 运行于 :1420 + Tauri 宿主
# 解析 Tauri manifest 前先初始化子模块。
git submodule update --init --recursive
npm run tauri dev
# macOS 发布构建(签名、安装、重置 TCC)
./scripts/build-mac.sh
INSTALL=0 ./scripts/build-mac.sh # 仅构建,跳过安装
# 共享后端与 Linux Host/UI(不含 Tauri/WebKitGTK)
cargo check -p openless-core
cargo check -p openless-linux-egui --all-targets
# Tauri host 类型检查
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-all/README.md)。
## 贡献流程
OpenLess 采用双频道分支模型。
- **`beta`**——**Beta 频道**。默认分支与集成缓冲区;所有进行中的开发都汇入这里。Beta 构建可能存在,但**不会推送给普通用户**——只有显式加入 Beta 频道的人才能拿到。
- **`main`**——**Stable 频道(正式版)**。始终可发布;所有人默认获得的构建。
```text
your fork / topic branch
│ (test locally on your target platform first)
▼
PR → beta ← AI review (one pass, advisory only)
│ ← maintainer lightweight glance (scope, cross-module impact)
▼
merged into beta
│ (periodically, after a two-platform smoke build)
▼
merged into main → tag `v<version>-tauri` → release CI → Stable users
```
经验法则:
- **向 `beta` 提 PR,绝不要向 `main` 提。** GitHub 对新 PR 已默认将基准分支设为 `beta`。
- **在提 PR 之前,先在你的目标平台上验证改动**——构建通过是必要条件,人工验证是必需的。
- **AI review 每个 PR 只跑一次,且仅供参考。** 不要围着它打转;请运用自己的判断。
- **AI 返工轮次保持精简(1–2 轮)。** 如果某处修复迟迟搞不定,去找真人,或带着全新上下文重来——在这里多轮的 AI 来回往往弊大于利。
- **Beta 的工作不得泄漏到 Stable。** `main` 只接受来自 `beta` 的合并,由维护者在一次成功的双平台冒烟构建之后执行。不允许直接向 `main` 推送。
- **Stable 发布从 `main` 切出**,通过推送 `v<version>-tauri` 标签完成——见下方的维护者发布清单。
Beta 发布的分发(手动下载、可选加入):应用内的更新器始终读取 Stable 清单,因此普通用户绝不会通过自动更新拿到 Beta 构建。想尝试 Beta 的用户打开 **设置 → 关于**,启用“加入 Beta 频道”,再从应用从 GitHub 获取的链接处手动下载最新的 Beta 安装包。标签约定:`v<version>-beta-tauri` 产出 Beta 发布(标记为 GitHub pre-release;清单写为 `latest-{tgt}-{arch}-beta.json`),而 `v<version>-tauri` 产出 Stable 发布。两份清单文件互不重叠,因此 Stable 用户的更新器源不会拾取到 Beta 发布。
## 凭据
凭据存放在操作系统的凭据保管库中(service = `com.openless.app`):macOS Keychain、Windows 凭据管理器,或 Linux keyring。旧的明文 JSON 文件仅作为迁移来源被读取,并在成功写入保管库后删除:
```text
macOS / Linux: ~/.openless/credentials.json
Windows: %APPDATA%\OpenLess\credentials.json
```
新的凭据写入不会持久化明文密钥。本仓库不包含任何 API key、token 或私有端点。
你需要准备:
- **Volcengine 流式 ASR**:APP ID、Access Token、Resource ID。
- **讯飞实时语音转写(RTASR)**:AppID、API Key。见 [docs/xfyun-asr.md](docs/xfyun-asr.md)。
- **Ark 润色**:API Key、Model ID、Endpoint。Ark 默认端点为 `https://ark.cn-beijing.volces.com/api/v3/chat/completions`。
## 文本处理原则
OpenLess 的润色模型只重塑文本。它不回答问题、不执行任务、不分析你的项目。每次听写都是一次独立请求,提示词中明确告知模型:
- 该输入与任何先前对话相隔离。
- 原始转写稿是待清理的文本,而非待回答的问题。
- 即使输入中包含问题或命令,也不要回复或执行。
- 只输出清理后的文本——不要“以下是清理后的版本”之类的开场白。
例如,当用户说“这个应用还需要哪些功能”时,正确的输出是:
```text
这个应用还需要哪些功能?
```
……而不是一份缺失功能的清单。
长期参考改写的 `raw → polished → rule` 三元组格式见 [Examples/polish-reference-examples.sample.jsonl](Examples/polish-reference-examples.sample.jsonl)。该文件说明参考数据格式;当前模块职责见[架构文档](docs/architecture.md)。
## 词典
词典负责处理你的专有名词、产品名、人名以及新词。目前支持:
- 手动添加正确拼写、分类与备注。你无需维护错误拼写或上下文提示。
- 启用的条目作为 Volcengine ASR 的 `context.hotwords` 发送,以便在转写时被正确识别。
- 条目同样注入润色提示词:模型逐句判断是否替换。如果“Cloud”在上下文中明显指 AI 产品 `Claude`,就会被纠正;如果它确实指云计算,则保持原样。
- **手改学词(实验)。** 在「设置 → 实验与扩展 → 手改学词」进入独立配置页,设置观察时长(10–60 秒,默认 60)、建议保留时长(5–60 秒,默认 10)及自动建议最大词长(2–32 个字符,默认 12)。功能默认关闭,不跟随光标上下文或云同步授权。macOS、Windows 和 Android 可在支持的编辑器中观察插入后的修改,候选需在有效期内逐条确认才加入词典。修改参数会结束当前观察并清空待确认建议,下次听写生效。Android 需要无障碍服务。无法观察时,可在历史详情点击「记住词汇」手动输入正确词;Android 输入法编辑结果也提供默认不勾选的加入词典选项。所有入口均需明确确认,不自动创建全局替换规则。
- **真正在用的词优先。** 发给 ASR 的热词预算是有限的(几百字符)。条目按命中次数排序,并给刚手动添加的词留几个保底席位——这样你天天在用的那些词不会被「最近刚加的」挤出去。
### 光标上下文(需手动开启,仅 macOS)
设置 → 隐私 → 数据存储 → **光标上下文**。默认关闭。
开启后,每次听写会读取**你正在写的那个应用里**光标附近的几百个字,随润色请求一起发出,让模型知道你在写什么。中文同音词(接口/借口、大鱼/大禹)声学模型分不出来,但上下文能分。手改学词是独立的本地功能,不需要开启此设置。观察文本本身不会发送给模型;确认加入词典的词会按词典规则参与后续 ASR/润色。
光标上下文排除密码输入框、macOS Secure Input、已知密码管理器和终端。关闭此开关后不会为润色读取光标上下文;其他已授权的辅助功能(如手改学词或插入)独立工作。手改学词关闭后会停止观察并清空待确认建议。
主窗口组织为 首页 / 历史 / 词典 / 设置。点击“新建”时,词典页会打开一个独立的编辑窗口。首页展示总听写时长、总字数、平均每分钟字数、估算节省的时间,以及词典参与统计。
## 架构
应用只有一套共享后端 Interface,并由各平台宿主适配:
```
React UI ── Tauri Adapter(macOS/Windows/Android)──┐
├── openless-core
egui UI ── Linux Adapter(无 Tauri/WebKitGTK)───┘
```
`openless-core` 负责稳定 DTO、错误、语义事件、repository、凭据契约和面向宿主的 use-case Interface。IPC、窗口、托盘、权限、更新、keyring、fcitx5 与打包资源路径等宿主能力由 Adapter 实现。旧 React command/event 名称只保留在 Tauri 兼容 Adapter;Linux 与 core 同进程,通过类型化 Rust Interface 调用。详细契约见 [`docs/linux-egui-backend-contract.md`](docs/linux-egui-backend-contract.md)。
`v<version>-tauri` / `v<version>-Beta.N-tauri` 工作流构建 macOS、Windows、Android 宿主以及独立的 Linux egui deb/rpm。Linux 真机验收完成、管理员创建 tag 后,验证过的 Linux 包自动附到共用 Release;Beta 资产先留在草稿中供管理员核对发布。Linux 不提供 AppImage 或应用内更新清单。
听写流水线:`hotkey edge → Recorder.start + ASR.openSession → [audio frames] → hotkey edge → Recorder.stop + ASR.sendLastFrame → Polish → Insert → History.save`。
贡献与发布规则见[贡献流程](#贡献流程)和[发布规范](RELEASING.md),模块职责与接线见[架构文档](docs/architecture.md)。
## 路线图
已规划但尚未发布:
- 跨会话风格记忆:润色随时间学习用户的语气([#46](https://github.com/Open-Less/openless/issues/46))。
- 片段(Snippets,尚无 UI 或触发逻辑)。
- 历史增强:复制按钮、搜索、重新润色、重新插入。
- “粘贴上次结果”快捷键。
## 维护者发布清单
[RELEASING.md](RELEASING.md) 统一维护管理员权限、版本同步、平台验收、草稿资产、签名和更新清单校验。新 Beta 标签使用 `v<X.Y.Z>-Beta.<N>-tauri`,历史 `-beta-tauri` 后缀仅作兼容。
## 致谢
OpenLess 衷心感谢它的赞助商、开发者与贡献者,以及更广泛的 LinuxDo 社区。
我们感谢赞助商让项目的持续工作成为可能,也感谢开发者与贡献者对 OpenLess 的构建、评审与改进。
OpenLess 同样认可并感谢 LinuxDo 社区开放、务实、对开发者友好的氛围。围绕 OpenLess 的许多想法、讨论与早期反馈,都受到了 LinuxDo 所代表的更广阔开源精神的启发。
本致谢不意味着任何官方背书或隶属关系。
## 许可证
OpenLess 2.0.0-Beta.1 基于 [AGPL-3.0-only 许可证](LICENSE) 发布。
已发布的 1.x 版本继续沿用原 MIT 许可证。