Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c0e2213
[cask] openless 1.3.16 (auto from release) [skip ci] (#921)
appergb Aug 5, 2026
a580a8f
feat(settings): 本地 ASR 模型管理重构 + 提供商界面颜色/动画统一 (#922)
appergb Aug 5, 2026
29e7eca
feat(settings): 模型 ID 直选 ASR 供应商 + 看板右侧布局改版 + 弹窗重合 (#923)
appergb Aug 5, 2026
f22eb54
fix(windows-ime): TSF 插入后输入法未切回原输入法(#852) (#914)
H-Chris233 Aug 5, 2026
9dbb316
fix(asr): 删除 retranscribe 里重复的 ElevenLabs 匹配分支 (#906)
bigsongeth Aug 5, 2026
115680c
Delete .github/workflows/pr-agent.yml
H-Chris233 Aug 5, 2026
27198b9
feat(overview): 「近 7 天」脱离历史 200 条上限,并支持近 7/30 天 × 条数/字数/时长切换 (#909)
bigsongeth Aug 5, 2026
cd58759
fix(translation): 翻译不会生效时不再进入翻译态(胶囊误报 + 空转 LLM) (#908)
bigsongeth Aug 5, 2026
cd33c89
feat(history): 记录插入目标应用;详情页支持重试与换风格重新润色;条目显示真实风格包名 (#910)
bigsongeth Aug 5, 2026
df1a42c
fix(local-asr): 下载进度全局浮层 + 事件节流 + 取消清理 + 看板过滤 + 3s 文件监测 (#925)
appergb Aug 5, 2026
b62e232
feat(selection-polish): macOS 移植——前台应用+选区文本指纹校验与默认热键 (#926)
appergb Aug 5, 2026
7655dcc
feat(pipeline): 多模态识别管线(实验性),传统/多模态模式与 omni 凭据隔离 (#902) (#924)
H-Chris233 Aug 6, 2026
b68a590
feat(selection-polish): Linux 支持——fcitx5 插件热键路由 + PRIMARY 选区校验 (#927)
appergb Aug 6, 2026
26f928c
fix(local-asr): 下载弹窗全量目录 + 抖动/模糊修复 + HF 模型卡片 (#928)
appergb Aug 6, 2026
ead0948
feat(android): 可选 Shizuku 与三层跨应用粘贴回退 (#932)
HKLHaoBin Aug 7, 2026
b4d1317
feat(providers): LLM/ASR 供应商改成渠道卡片——同一家可存多把 key,排序即优先级 (#918)
bigsongeth Aug 7, 2026
f016e57
feat: 让词典自己长——手改一次,它就记住(光标上下文 + 手改学词 + 热词预算优先级) (#917)
bigsongeth Aug 8, 2026
06a6c38
feat(hotkeys): 风格包直达快捷键——按风格包 ID 绑定自定义全局键(#759) (#930)
bigsongeth Aug 8, 2026
b12fd79
fix(windows): show and activate style packs from tray (#808) (#933)
H-Chris233 Aug 9, 2026
19c65a9
Add .reasonix to .gitignore
H-Chris233 Aug 9, 2026
76357a0
Merge branch 'beta' of https://github.com/Open-Less/openless into beta
H-Chris233 Aug 9, 2026
a92ada4
fix(provider): allow custom LLM HTTP hostnames (#929) (#935)
H-Chris233 Aug 9, 2026
d961248
fix(asr): 火山 ApiKey 模式改用官方端点,修复 45000010 (#931) (#936)
H-Chris233 Aug 9, 2026
4cd93bd
fix(deps): resolve memmap2 and rkyv advisories for #815 (#938)
H-Chris233 Aug 10, 2026
4496eba
feat(marketplace): 支持风格包 ZIP 下载与跨设备导入 (#942)
H-Chris233 Aug 10, 2026
c84bfb9
chore(ci): optimize CI caching, concurrency, and Tauri security (#937)
lispking Aug 10, 2026
40cd136
fix(asr): 火山渠道「验证」接入真实 WS 连通检查,修复必报「API Key 为空」 (#944)
bigsongeth Aug 12, 2026
94db63f
fix(ui): keep vocab delete action visible for long entries (#950) (#951)
H-Chris233 Aug 14, 2026
f008cc6
fix(windows): allow synthetic hotkeys to trigger OpenLess (#948)
H-Chris233 Aug 14, 2026
d88f272
Merge remote-tracking branch 'origin/beta' into release/1.3.17-stable
Aug 15, 2026
2993fde
chore(release): prepare 1.3.17
Aug 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .github/workflows/android-apk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ on:
- 'v*-tauri'
workflow_dispatch:

# 同一 tag 重复推送只跑最新一次;workflow_dispatch 用 run_id 隔离避免互相取消。
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.ref }}
cancel-in-progress: ${{ github.event_name == 'push' }}

jobs:
build-android-apk:
permissions:
Expand All @@ -25,8 +30,8 @@ jobs:
OPENLESS_RELEASE_CHANNEL: ${{ (endsWith(github.ref_name, '-beta-tauri') || contains(github.ref_name, '-Beta.')) && 'beta' || 'stable' }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
# vendor/qwen-asr 仅 macOS 上 build.rs 会编译;Android APK 构建完全不需要
# 子模块,去掉递归拉取省一次网络 fetch + 失败点。

- name: Detect build mode
id: mode
Expand Down Expand Up @@ -136,7 +141,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: 20
node-version: "22"
cache: npm
cache-dependency-path: openless-all/app/package-lock.json

Expand Down Expand Up @@ -179,6 +184,14 @@ jobs:
working-directory: openless-all/app
run: node scripts/merge-android-overlay-manifest.mjs

- name: Merge Shizuku manifest
working-directory: openless-all/app
run: node scripts/merge-android-shizuku-manifest.mjs

- name: Patch Shizuku Gradle dependencies
working-directory: openless-all/app
run: node scripts/patch-android-shizuku-deps.mjs

- name: Merge updater / install manifest
working-directory: openless-all/app
run: node scripts/merge-android-updater-manifest.mjs
Expand Down
40 changes: 34 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ on:
branches: [main, beta]
workflow_dispatch:

# 同一 PR 快速重复推送时取消旧运行;workflow_dispatch 用 run_id 隔离。
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
android-check:
name: Android cargo check
Expand All @@ -22,9 +27,8 @@ jobs:
working-directory: openless-all/app
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

# vendor/qwen-asr 仅 macOS 上 build.rs 会编译(build.rs:49 build_qwen_asr_macos);
# Android/Linux 的 cargo check 不需要,去掉递归拉取省一次网络 fetch + 失败点。
- name: Setup Android SDK + NDK
uses: android-actions/setup-android@v3
with:
Expand Down Expand Up @@ -71,6 +75,10 @@ jobs:
with:
targets: aarch64-linux-android,x86_64-linux-android

- uses: swatinem/rust-cache@v2
with:
workspaces: 'openless-all/app/src-tauri -> target'

- uses: gradle/actions/setup-gradle@v4

- name: Install Linux check dependencies
Expand Down Expand Up @@ -108,6 +116,12 @@ jobs:
- name: Copy Android production and test scaffolding
run: node scripts/copy-android-scaffolding.mjs

- name: Merge Shizuku manifest
run: node scripts/merge-android-shizuku-manifest.mjs

- name: Patch Shizuku Gradle dependencies
run: node scripts/patch-android-shizuku-deps.mjs

- name: Run JVM credential tests and compile instrumentation tests
# These tests are Kotlin-only. The Rust target is checked above; direct Gradle
# rustBuild requires the live Tauri CLI RPC server used by `tauri android build`.
Expand Down Expand Up @@ -164,18 +178,26 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
# vendor/qwen-asr 是 macOS 上 build.rs 必须的 git submodule。Windows
# checkout 也拉一份保持与 release-tauri.yml 一致,开销几秒可以忽略。
submodules: recursive
# vendor/qwen-asr 仅 macOS 上 build.rs 会编译(build.rs:49 build_qwen_asr_macos)。
# Windows/Linux 的 cargo check 不需要子模块;用矩阵条件避免非 macOS job
# 多拉一次 git submodule(省网络 fetch + 去掉一个失败点)。
submodules: ${{ matrix.os == 'macos-latest' && 'recursive' || 'false' }}

- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: openless-all/app/package-lock.json

# 现有测试继续用 stable;额外安装声明的 MSRV,供下方兼容性门禁显式调用。
- uses: dtolnay/rust-toolchain@1.88.0

- uses: dtolnay/rust-toolchain@stable

- uses: swatinem/rust-cache@v2
with:
workspaces: 'openless-all/app/src-tauri -> target'

- name: Install Linux check dependencies
if: runner.os == 'Linux'
run: |
Expand Down Expand Up @@ -236,6 +258,12 @@ jobs:
if: runner.os == 'Windows'
run: cargo test --manifest-path src-tauri/backend-tests/Cargo.toml

- name: Check Tauri backend with Rust 1.88 MSRV
run: cargo +1.88.0 check --locked --manifest-path src-tauri/Cargo.toml

- name: Compile backend tests with Rust 1.88 MSRV
run: cargo +1.88.0 test --locked --manifest-path src-tauri/backend-tests/Cargo.toml --no-run

- name: Verify version sync across all 5 files
# 两个平台都跑这个校验:Windows runner 自带 git-bash,跨 shell 表现一致。
# 一旦版本号 drift 立刻 fail,避免发版时再发现漏改。
Expand Down
74 changes: 0 additions & 74 deletions .github/workflows/pr-agent.yml

This file was deleted.

13 changes: 9 additions & 4 deletions .github/workflows/release-tauri.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ on:
- 'v*-tauri'
workflow_dispatch:

# 同一 tag 重复推送只跑最新一次;workflow_dispatch 用 run_id 隔离避免互相取消。
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.ref }}
cancel-in-progress: ${{ github.event_name == 'push' }}

jobs:
build:
permissions:
Expand Down Expand Up @@ -60,13 +65,13 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
# vendor/qwen-asr macOS 上 build.rs 必须的 git submodule(cc-rs 编译
# Open-Less/qwen-asr fork 的 C 源),不拉就会在 mac 端 cargo build 阶段挂掉
submodules: recursive
# vendor/qwen-asr macOS 上 build.rs 会编译(build.rs:49 build_qwen_asr_macos);
# Windows/Linux 的 cargo build 不需要子模块,去掉非 macOS job 的递归拉取
submodules: ${{ startsWith(matrix.platform, 'macos') && 'recursive' || 'false' }}

- uses: actions/setup-node@v4
with:
node-version: 20
node-version: "22"
cache: npm
cache-dependency-path: 'openless-all/app/package-lock.json'

Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,6 @@ docs/windows-lifecycle-tracking/
docs/windows-ui-tracking/

# 用于本地语音推理的参考文件。
CapsWriter
CapsWriter

.reasonix
6 changes: 3 additions & 3 deletions Casks/openless.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
cask "openless" do
arch arm: "aarch64", intel: "x64"

version "1.3.15"
sha256 arm: "206a0189af6876d727fcdc8ec50c362d20721080f3ce0904ec683fa3cd3d8414",
intel: "b5502dc1bb8b86c42158df767e61c7aa380ea12ae3a11f4be6fef625e54fc42b"
version "1.3.16"
sha256 arm: "2cb55858b1c2104ac4ae818edfac1f125e7eb8547283fabcf756276548fed5ca",
intel: "bd86763ac3226fd90e9206766539bd5a986e1421ac01e94a45a0027b2d1d252d"

url "https://github.com/Open-Less/openless/releases/download/v#{version}-tauri/OpenLess_#{version}_#{arch}.dmg"
name "OpenLess"
Expand Down
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ That is what **authorizing the infrastructure once, at launch** means: on first

## ✨ What's new

Two capabilities that sediment yet more of the coordination you used to repeat every day into defaults:
Capabilities that sediment yet more of the coordination you used to repeat every day into defaults:

- 📖 **A dictionary that learns.** Until now the dictionary only knew what you typed into it by hand. Now, when you correct a word OpenLess just wrote, it asks — once, on a small card — whether to remember it, and one click puts it in. Paired with **cursor context** (opt-in, macOS), which lets the polish model read what you are writing around your cursor, OpenLess stops being a transcriber that guesses at homophones and starts being an input method that knows your words. Every suggestion is reviewed by you; nothing is learned silently.
- 🎨 **Style Pack Marketplace.** OpenLess no longer ships a single fixed "polish" voice. Build your own **style packs** with custom system prompts, switch between them with a hotkey, and **install community packs in one click** — or publish your own to share. When a style is tuned to your exact task (cold emails, commit messages, 小红书 posts, formal reports, your team's tone), the output is not merely cleaner — it is *noticeably better*, because the model is finally writing the way you intend.
- ⚡ **Streaming insertion.** Text now flows to your cursor **character by character** as it is polished, rather than making you wait for the complete result. Perceived latency drops sharply, so dictation feels nearly as fast as thinking — and it automatically falls back to a one-shot paste when an application cannot accept streamed keystrokes.

Expand Down Expand Up @@ -167,7 +168,7 @@ OpenLess does one thing: it **turns speech into usable written text — AI promp

| Tool | Form | How OpenLess differs |
| --- | --- | --- |
| [Typeless](https://www.typeless.com/) | Closed-source macOS / Windows / iOS, subscription | Open source; explicit AI-prompt mode; bring-your-own ASR + LLM; data and dictionary stay on your machine |
| [Typeless](https://www.typeless.com/) | Closed-source macOS / Windows / iOS, subscription | Open source; explicit AI-prompt mode; bring-your-own ASR + LLM; data and dictionary stay on your machine — including what the dictionary learns from your corrections, which is never uploaded and never added without your confirmation |
| [Wispr Flow](https://wisprflow.ai) | Closed-source macOS / Windows, subscription | Open source; bring-your-own ASR + LLM; transparent prompt-handling rules |
| [Lazy](https://heylazy.com) | Closed-source notes / capture tool | Not a notes container — inserts straight into any input field |
| [Superwhisper](https://superwhisper.com) | Closed-source macOS, subscription | Open source; cloud ASR today, local ASR on the roadmap |
Expand Down Expand Up @@ -241,6 +242,8 @@ For the full end-user walkthrough, see [USAGE.md](USAGE.md).

The active codebase lives in `openless-all/app/` (Tauri 2 + Rust + React/TS). The macOS build links a vendored C ASR engine ([`Open-Less/qwen-asr`](https://github.com/Open-Less/qwen-asr), forked from `antirez/qwen-asr`) pulled in as a git submodule under `src-tauri/vendor/qwen-asr/`, so initialize submodules on first clone.

Rust 1.88 is the minimum supported toolchain for source builds; the latest stable Rust is recommended. CI verifies both Rust 1.88 and stable on macOS, Windows, and Linux.

```bash
# First clone only — pull in vendored submodules
git submodule update --init --recursive
Expand Down Expand Up @@ -340,7 +343,16 @@ The dictionary handles your proper nouns, product names, names of people, and ne
- Manually adding the correct spelling, a category, and notes. You do not need to maintain misspellings or context hints.
- Enabled entries are sent to the ASR provider that supports hotwords (Volcengine `context.hotwords`, StepFun `hotwords`, Whisper-compatible `prompt` — except ZenMux, whose JSON protocol does not carry `prompt`/`hotwords`, Bailian vocabulary ID) so they are recognized correctly during transcription. iFlytek realtime ASR has no request-level hotword parameter — configure personalized hotwords in the iFlytek console instead.
- Entries are also injected into the polish prompt: the model decides per sentence whether to substitute. If "Cloud" clearly refers to the AI product `Claude` in context, it is corrected; if it genuinely means cloud computing, it is left as is.
- The app auto-learns candidate corrections such as `Claude`, `ChatGPT`, and `OpenLess` from your history and offers them later.
- **The dictionary learns from you.** When you hand-correct a word OpenLess just typed, a card appears asking whether to remember it. One ✓ and it is in — no settings page, no forms. Every suggestion is reviewed by you: nothing is ever added silently. Requires the opt-in **cursor context** setting below, and is macOS-only for now.
- **Entries that earn their keep get priority.** The hotword budget sent to ASR providers is finite (a few hundred characters). Entries are ranked by hit count, with a few reserved seats for words you just added by hand, so the terms you actually use keep their place instead of being pushed out by whatever you added most recently.

### Cursor context (opt-in, macOS)

Settings → Privacy → Data storage → **Cursor context**. Off by default.

When on, each dictation reads a few hundred characters around your cursor **in the app you are writing in** and sends them with the polish request, so the model knows what you are writing about. Chinese homophones (接口/借口, 大鱼/大禹) are indistinguishable to an acoustic model but obvious from context. This is also what makes dictionary learning possible: OpenLess can only notice that you fixed a word if it can see the text it just typed.

What it never reads: password fields, macOS Secure Input, password managers, and terminals — those are blocked before a single accessibility call is made. While the setting is off, no accessibility calls happen at all and the prompt is byte-for-byte identical to a build without the feature.

The main window is organized as Home / History / Dictionary / Settings. The Dictionary tab opens a separate editor window when you click "New". The Home tab shows total dictation time, total characters, average characters per minute, estimated time saved, and dictionary participation statistics.

Expand Down
Loading
Loading