Hold a key, speak, release — AI-polished text appears at your cursor in any app. Open-source voice input for macOS & Windows. (按住快捷键说话,松开即得润色后的文字)
See the code
Open-source voice input for macOS, Windows & Linux
Hold a hotkey, speak, and watch AI-polished text stream straight to your cursor —
in the writing style you choose.
Website · Download · English / 中文
💬 Join our Discord · QQ Group 1078960553
OpenLess is sustained by the generous support of its sponsors.
悠雾云数据 · Youwu Cloud Data (knin.net)
![]() TRIP Author |
![]() Chris233 Author / Maintainer |
![]() bigsong Contributor / Tester |
![]() HKLHaoBin Android author / Android Maintainer |
![]() Cooper Contributor |
![]() aeoform Contributor / Linux Maintainer |
![]() jimmy54 macOS packaging & developer account |
OpenLess is a cross-platform (macOS and Windows) voice-input application — a fully open-source alternative to commercial tools such as Typeless, Wispr Flow, Lazy, and Superwhisper. Official site: openless.top.
Place your cursor in any text field — ChatGPT, Claude, Cursor, Notion, an email draft, a chat box — press a single global hotkey, and speak. OpenLess records the audio, transcribes it, polishes the text in the mode you selected, and inserts the result at the cursor. If insertion is blocked, the text is copied to the clipboard instead, so nothing you said is lost.
Unlike dictation tools that simply emit a word-for-word transcript, OpenLess's headline capability is its AI-prompt mode: you speak freely, and it adds structure, captures your constraints, and produces a context-rich prompt that you can paste directly into ChatGPT, Claude, or Cursor.
Advanced systems all do the same thing: they turn today's communication into tomorrow's default rules. The Internet won not because HTTP was faster, but because no one negotiates how data is transmitted anymore. Git won not because the code was better, but because teams stopped coordinating versions every day. Stripe won not because payments were faster, but because developers stopped coordinating with banks.
What OpenLess does is not "faster dictation" — it eliminates every act of coordination between a thought and clean text. Turning what's in your head into usable text used to mean deciding, over and over: what tone for this one? how is that name spelled? which input field, copy or paste? where does the model's key live, and who has access? OpenLess sediments those repeated negotiations, layer by layer, into defaults:
That is what authorizing the infrastructure once, at launch means: on first run you grant the microphone, accessibility, and cloud credentials exactly once; from that moment, "speak → clean text at the cursor" is no longer a negotiation you run each time, but a default protocol you can forget is even there. Judge OpenLess not by how much faster it is, but by how much coordination it removes.
Capabilities that sediment yet more of the coordination you used to repeat every day into defaults:
Hold the hotkey and say:
uh… so… I need to reply to the client about the proposal they sent last time, we talked it over internally and the overall direction is fine but a few details need changing, first the delivery timeline is too tight we'd like to push it back two weeks, second on budget their quote came in about twenty percent higher than we expected can we negotiate that, and overall we're positive about working together so reassure them, keep the tone polite not too blunt
Release the hotkey. A moment later, your input box reads:
Reply to the client about the proposal they sent. After internal discussion, the overall direction is fine, but a few details need adjusting:
1. Delivery timeline
(a) The current timeline is too tight; we'd like to extend it by two weeks.
2. Budget
(a) Their quote is about 20% higher than we expected — can we renegotiate?
Keep the overall message positive about the partnership, and keep the tone polite rather than blunt.
No edits are required — paste it into ChatGPT or Claude and let it draft the email. That is the core idea: compose prompts by speaking, faster and more cleanly than typing them.
The closest alternatives are subscription SaaS products: a monthly fee, no option to bring your own model, your audio uploaded to the vendor, and your dictionary and habits stored in their account.
OpenLess targets the same end-user experience, but:
A style pack is a named output style with its own system prompt. Rather than being constrained to one built-in "polish" voice, you can shape exactly how your speech is rendered — and the closer the style matches your real task, the better the result.
The marketplace is served by OpenLess's own moderated backend, so the catalog remains curated rather than a free-for-all.
OpenLess does one thing: it turns speech into usable written text — AI prompts in particular — at the current cursor.
| Tool | Form | How OpenLess differs |
|---|---|---|
| Typeless | 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 | Closed-source macOS / Windows, subscription | Open source; bring-your-own ASR + LLM; transparent prompt-handling rules |
| Lazy | Closed-source notes / capture tool | Not a notes container — inserts straight into any input field |
| Superwhisper | Closed-source macOS, subscription | Open source; cloud ASR today, local ASR on the roadmap |
Every item below is one more layer sedimented into a default — a capability you authorize once and then never manage again. This is the infrastructure you stand on after launch:
openless-core. macOS and Windows use a thin Tauri 2 host with the React/TypeScript frontend; Android keeps the Tauri mobile host. Linux uses a separate native host and will not compile Tauri or WebKitGTK.Esc cancels at any phase, including polish and insertion.Open-Less/qwen-asr (macOS); Windows Foundry Local Whisper and sherpa-onnx (experimental) variants.context.hotwords and as semantic hints during polish; hits accumulate per session.WH_KEYBOARD_LL) on Windows.Go to Releases and download:
OpenLess_<version>_aarch64.dmg (Apple Silicon) or OpenLess_<version>_x64.dmg (Intel). Open it, drag the app to /Applications, then run the following once in Terminal to bypass the Gatekeeper "damaged" warning (the build is ad-hoc signed, not Apple-notarized):
xattr -cr /Applications/OpenLess.app
OpenLess_<version>_x64-setup.exe — run the installer.OpenLess_<version>_arm64-v8a.apkOpenLess_<version>_armeabi-v7a.apkOpenLess_<version>_x86_64.apkOpenLess_<version>_x86.apklatest-android-{arch}.json manifests; Beta users join Beta in Advanced settings.OpenLess-android-debug-{abi}-*.apk from workflow_dispatch artifacts.adb shell getprop ro.product.cpu.abi and pick the matching APK.eframe host uses the shared Core 2.0 services. After CI and real Ubuntu audio, input, install, upgrade and rollback acceptance, the shared release includes deb/rpm packages and SHA256SUMS. Linux requires glibc ≥ 2.39 (Ubuntu 24.04 or a comparable distribution); there is no AppImage or in-app updater.brew tap Open-Less/openless https://github.com/Open-Less/openless
brew install --cask openless
xattr -cr /Applications/OpenLess.app
# Upgrade to the latest version
brew update && brew upgrade openless
On first launch, grant the permissions the app requests.
macOS:
Windows:
For the full end-user walkthrough, see USAGE.md.
The active workspace lives in openless-all/app/. crates/openless-core is the framework-independent backend, src-tauri hosts macOS/Windows/Android, and linux-egui contains the native Linux UI and its platform adapters. Initialize submodules before a Tauri source build: its manifest resolves local path dependencies even when their target-specific code is not compiled. These include macOS ASR engines such as Open-Less/qwen-asr under src-tauri/vendor/. The root Core/Linux workspace excludes src-tauri, so its independent checks do not parse the Tauri manifest or require those submodules. Start with the documentation index, architecture, and source structure.
Rust 1.88 is the minimum supported toolchain for the desktop application sources (openless-core, src-tauri); the latest stable Rust is recommended. CI verifies both Rust 1.88 and stable on macOS and Windows; the Linux egui host requires Rust 1.95 and is verified on stable.
On Apple Silicon, compiling the optional Qwen3-ASR MLX backend requires Xcode's MetalToolchain component. Install it with xcodebuild -downloadComponent MetalToolchain and verify it with xcrun --find metal. This is a source-build dependency; packaged OpenLess applications do not require it at runtime.
cd "openless-all/app"
npm ci
# macOS/Windows/Android: Vite at :1420 + Tauri host
# Initialize submodules before resolving the Tauri manifest.
git submodule update --init --recursive
npm run tauri dev
# macOS release build (signs, installs, resets TCC)
./scripts/build-mac.sh
INSTALL=0 ./scripts/build-mac.sh # build only, skip install
# Shared backend and Linux Host/UI (no Tauri/WebKitGTK)
cargo check -p openless-core
cargo check -p openless-linux-egui --all-targets
# Tauri host type-check
cargo check --manifest-path "src-tauri/Cargo.toml"
# Frontend TS check
npm run build
Logs: ~/Library/Logs/OpenLess/openless.log (macOS) / %LOCALAPPDATA%\OpenLess\Logs\openless.log (Windows).
Windows build — see openless-all/README.md for the MSVC and GNU/MinGW routes.
OpenLess uses a two-channel branching model.
beta — the Beta channel. The default branch and integration buffer; all in-progress development lands here. Beta builds may exist but are not pushed to regular users — they reach only those who explicitly opt into the Beta channel.main — the Stable channel (正式版). Always releasable; the build everyone receives by default.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
Rules of thumb:
beta, never against main. GitHub already defaults the base branch to beta for new PRs.main receives merges only from beta, performed by maintainers after a successful two-platform smoke build. No direct pushes to main.main by pushing a v<version>-tauri tag — see the maintainer release checklist below.Beta release distribution (manual-download opt-in): the in-app updater always reads the Stable manifest, so regular users never receive Beta builds via auto-update. Users who want to try Beta open Settings → About, enable "Join Beta channel", and download the latest Beta installer manually from the link the app fetches from GitHub. Tag convention: v<version>-beta-tauri produces the Beta release (marked as a GitHub pre-release; manifest written as latest-{tgt}-{arch}-beta.json), while v<version>-tauri produces the Stable release. The two manifest files never overlap, so Stable users' updater feed cannot pick up Beta releases.
Credentials live in the OS credential vault (service = com.openless.app): macOS Keychain, Windows Credential Manager, or the Linux keyring. A legacy plaintext JSON file is read only as a migration source and removed after a successful vault write:
macOS / Linux: ~/.openless/credentials.json
Windows: %APPDATA%\OpenLess\credentials.json
New credential writes do not persist plaintext secrets. The repository contains no API keys, tokens, or private endpoints.
You will need:
https://ark.cn-beijing.volces.com/api/v3/chat/completions.OpenLess's polish model only reshapes text. It does not answer questions, run tasks, or analyze your project. Each dictation is an independent request, and the prompt explicitly instructs the model:
For example, if the user says "what features does this app still need", the correct output is:
What features does this app still need?
…not a list of missing features.
Long-term reference rewrites are represented as raw → polished → rule triples in Examples/polish-reference-examples.sample.jsonl. The sample format describes reference data; current module responsibilities are documented in Architecture.
The dictionary handles your proper nouns, product names, names of people, and new words. Today it supports:
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.Claude in context, it is corrected; if it genuinely means cloud computing, it is left as is.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. Local vocabulary learning has a separate switch and does not require cursor context. Observed text is not sent to a model; words explicitly added to the dictionary participate in future ASR and polish requests as described above.
On Windows, cursor context is read via UI Automation from the focused text control: it prefers TextPattern2's caret range, with a TextPattern selection fallback for controls that only support collapsed selections. When the caret cannot be reliably located, it is skipped rather than guessed — wrong context is worse than none, and dictation continues normally either way.
Chromium-based editors (VS Code, Electron apps) only keep their accessibility tree's caret position in sync once they detect an active accessibility client, so with default settings the position UI Automation reads back can be stale. In VS Code, set editor.accessibilitySupport to on (Settings → search "accessibility support"; a window reload may be needed) to get accurate cursor context; the same applies to other Electron-based editors with similar settings. Plain Chrome/Edge text fields do not need this.
On Android, the OpenLess keyboard reads the text before and after the caret straight from its own InputConnection at the moment recording starts — no Accessibility permission involved, one read, no retry. Dictation, quick notes and cloud notes all use it for polishing, but the context only informs how the spoken words are written: it is never copied into the note, the history, the cloud note webhook or the logs. With a cloud polish model it is sent to that provider as part of the polish request. The floating overlay does not read cursor context yet.
Cursor context excludes password fields, macOS Secure Input, Windows UIA password controls, Android editors that are password-typed or ask for no personalized learning, known password managers and terminals. Turning it off stops reading cursor context for polishing; other authorized accessibility features, including local vocabulary learning and insertion, work independently. Turning vocabulary learning off stops observation and clears pending suggestions.
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.
The application has one shared backend Interface and platform hosts:
React UI ── Tauri Adapter (macOS/Windows/Android) ──┐
├── openless-core
egui UI ── Linux Adapter (no Tauri/WebKitGTK) ────┘
openless-core owns the stable DTOs, errors, semantic events, repositories, credentials contract, and host-facing use-case Interface. Host-only concerns—IPC, windows, tray, permissions, updater, keyring, fcitx5, and package resource paths—are implemented by Adapters. Legacy React command/event names stay in the Tauri compatibility Adapter; Linux calls the typed Rust Interface in process. See docs/linux-egui-backend-contract.md.
The v<version>-tauri / v<version>-Beta.N-tauri workflows build the macOS, Windows and Android hosts alongside the independent Linux egui deb/rpm workflow. After Linux device acceptance and an admin's tag, verified Linux packages attach to the shared Release; Beta assets remain in a draft until an admin publishes them. Linux has no AppImage or in-app updater manifest.
The dictation pipeline: hotkey edge → Recorder.start + ASR.openSession → [audio frames] → hotkey edge → Recorder.stop + ASR.sendLastFrame → Polish → Insert → History.save.
See Contributing workflow and Releasing for contribution and release rules, and Architecture for module responsibilities and wiring.
Planned but not yet shipped:
RELEASING.md is the canonical release procedure, including administrator authority, version synchronization, platform acceptance, draft assets, signing, and updater verification. New Beta tags use v<X.Y.Z>-Beta.<N>-tauri; the historical -beta-tauri suffix is compatibility-only.
OpenLess sincerely thanks its sponsors, developers and contributors, and the broader LinuxDo community.
We appreciate our sponsors for making sustained project work possible, and we thank our developers and contributors for building, reviewing, and improving OpenLess.
OpenLess also recognizes and appreciates the LinuxDo community for its open, practical, and developer-friendly atmosphere. Many of the ideas, discussions, and early feedback around OpenLess were inspired by the broader open-source spirit that LinuxDo represents.
This acknowledgement does not imply official endorsement or affiliation.
OpenLess 2.0.0-Beta.1 is released under the AGPL-3.0-only license. Published 1.x releases remain available under their original MIT license.
486 followers · starred Aug 2026
75 followers · starred May 2026
66 followers · starred Jun 2026
8 followers · starred May 2026
Hold a key, speak, release — AI-polished text appears at your cursor in any app. Open-source voice input for macOS & Windows. (按住快捷键说话,松开即得润色后的文字)
See the code
Open-source voice input for macOS, Windows & Linux
Hold a hotkey, speak, and watch AI-polished text stream straight to your cursor —
in the writing style you choose.
Website · Download · English / 中文
💬 Join our Discord · QQ Group 1078960553
OpenLess is sustained by the generous support of its sponsors.
悠雾云数据 · Youwu Cloud Data (knin.net)
![]() TRIP Author |
![]() Chris233 Author / Maintainer |
![]() bigsong Contributor / Tester |
![]() HKLHaoBin Android author / Android Maintainer |
![]() Cooper Contributor |
![]() aeoform Contributor / Linux Maintainer |
![]() jimmy54 macOS packaging & developer account |
OpenLess is a cross-platform (macOS and Windows) voice-input application — a fully open-source alternative to commercial tools such as Typeless, Wispr Flow, Lazy, and Superwhisper. Official site: openless.top.
Place your cursor in any text field — ChatGPT, Claude, Cursor, Notion, an email draft, a chat box — press a single global hotkey, and speak. OpenLess records the audio, transcribes it, polishes the text in the mode you selected, and inserts the result at the cursor. If insertion is blocked, the text is copied to the clipboard instead, so nothing you said is lost.
Unlike dictation tools that simply emit a word-for-word transcript, OpenLess's headline capability is its AI-prompt mode: you speak freely, and it adds structure, captures your constraints, and produces a context-rich prompt that you can paste directly into ChatGPT, Claude, or Cursor.
Advanced systems all do the same thing: they turn today's communication into tomorrow's default rules. The Internet won not because HTTP was faster, but because no one negotiates how data is transmitted anymore. Git won not because the code was better, but because teams stopped coordinating versions every day. Stripe won not because payments were faster, but because developers stopped coordinating with banks.
What OpenLess does is not "faster dictation" — it eliminates every act of coordination between a thought and clean text. Turning what's in your head into usable text used to mean deciding, over and over: what tone for this one? how is that name spelled? which input field, copy or paste? where does the model's key live, and who has access? OpenLess sediments those repeated negotiations, layer by layer, into defaults:
That is what authorizing the infrastructure once, at launch means: on first run you grant the microphone, accessibility, and cloud credentials exactly once; from that moment, "speak → clean text at the cursor" is no longer a negotiation you run each time, but a default protocol you can forget is even there. Judge OpenLess not by how much faster it is, but by how much coordination it removes.
Capabilities that sediment yet more of the coordination you used to repeat every day into defaults:
Hold the hotkey and say:
uh… so… I need to reply to the client about the proposal they sent last time, we talked it over internally and the overall direction is fine but a few details need changing, first the delivery timeline is too tight we'd like to push it back two weeks, second on budget their quote came in about twenty percent higher than we expected can we negotiate that, and overall we're positive about working together so reassure them, keep the tone polite not too blunt
Release the hotkey. A moment later, your input box reads:
Reply to the client about the proposal they sent. After internal discussion, the overall direction is fine, but a few details need adjusting:
1. Delivery timeline
(a) The current timeline is too tight; we'd like to extend it by two weeks.
2. Budget
(a) Their quote is about 20% higher than we expected — can we renegotiate?
Keep the overall message positive about the partnership, and keep the tone polite rather than blunt.
No edits are required — paste it into ChatGPT or Claude and let it draft the email. That is the core idea: compose prompts by speaking, faster and more cleanly than typing them.
The closest alternatives are subscription SaaS products: a monthly fee, no option to bring your own model, your audio uploaded to the vendor, and your dictionary and habits stored in their account.
OpenLess targets the same end-user experience, but:
A style pack is a named output style with its own system prompt. Rather than being constrained to one built-in "polish" voice, you can shape exactly how your speech is rendered — and the closer the style matches your real task, the better the result.
The marketplace is served by OpenLess's own moderated backend, so the catalog remains curated rather than a free-for-all.
OpenLess does one thing: it turns speech into usable written text — AI prompts in particular — at the current cursor.
| Tool | Form | How OpenLess differs |
|---|---|---|
| Typeless | 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 | Closed-source macOS / Windows, subscription | Open source; bring-your-own ASR + LLM; transparent prompt-handling rules |
| Lazy | Closed-source notes / capture tool | Not a notes container — inserts straight into any input field |
| Superwhisper | Closed-source macOS, subscription | Open source; cloud ASR today, local ASR on the roadmap |
Every item below is one more layer sedimented into a default — a capability you authorize once and then never manage again. This is the infrastructure you stand on after launch:
openless-core. macOS and Windows use a thin Tauri 2 host with the React/TypeScript frontend; Android keeps the Tauri mobile host. Linux uses a separate native host and will not compile Tauri or WebKitGTK.Esc cancels at any phase, including polish and insertion.Open-Less/qwen-asr (macOS); Windows Foundry Local Whisper and sherpa-onnx (experimental) variants.context.hotwords and as semantic hints during polish; hits accumulate per session.WH_KEYBOARD_LL) on Windows.Go to Releases and download:
OpenLess_<version>_aarch64.dmg (Apple Silicon) or OpenLess_<version>_x64.dmg (Intel). Open it, drag the app to /Applications, then run the following once in Terminal to bypass the Gatekeeper "damaged" warning (the build is ad-hoc signed, not Apple-notarized):
xattr -cr /Applications/OpenLess.app
OpenLess_<version>_x64-setup.exe — run the installer.OpenLess_<version>_arm64-v8a.apkOpenLess_<version>_armeabi-v7a.apkOpenLess_<version>_x86_64.apkOpenLess_<version>_x86.apklatest-android-{arch}.json manifests; Beta users join Beta in Advanced settings.OpenLess-android-debug-{abi}-*.apk from workflow_dispatch artifacts.adb shell getprop ro.product.cpu.abi and pick the matching APK.eframe host uses the shared Core 2.0 services. After CI and real Ubuntu audio, input, install, upgrade and rollback acceptance, the shared release includes deb/rpm packages and SHA256SUMS. Linux requires glibc ≥ 2.39 (Ubuntu 24.04 or a comparable distribution); there is no AppImage or in-app updater.brew tap Open-Less/openless https://github.com/Open-Less/openless
brew install --cask openless
xattr -cr /Applications/OpenLess.app
# Upgrade to the latest version
brew update && brew upgrade openless
On first launch, grant the permissions the app requests.
macOS:
Windows:
For the full end-user walkthrough, see USAGE.md.
The active workspace lives in openless-all/app/. crates/openless-core is the framework-independent backend, src-tauri hosts macOS/Windows/Android, and linux-egui contains the native Linux UI and its platform adapters. Initialize submodules before a Tauri source build: its manifest resolves local path dependencies even when their target-specific code is not compiled. These include macOS ASR engines such as Open-Less/qwen-asr under src-tauri/vendor/. The root Core/Linux workspace excludes src-tauri, so its independent checks do not parse the Tauri manifest or require those submodules. Start with the documentation index, architecture, and source structure.
Rust 1.88 is the minimum supported toolchain for the desktop application sources (openless-core, src-tauri); the latest stable Rust is recommended. CI verifies both Rust 1.88 and stable on macOS and Windows; the Linux egui host requires Rust 1.95 and is verified on stable.
On Apple Silicon, compiling the optional Qwen3-ASR MLX backend requires Xcode's MetalToolchain component. Install it with xcodebuild -downloadComponent MetalToolchain and verify it with xcrun --find metal. This is a source-build dependency; packaged OpenLess applications do not require it at runtime.
cd "openless-all/app"
npm ci
# macOS/Windows/Android: Vite at :1420 + Tauri host
# Initialize submodules before resolving the Tauri manifest.
git submodule update --init --recursive
npm run tauri dev
# macOS release build (signs, installs, resets TCC)
./scripts/build-mac.sh
INSTALL=0 ./scripts/build-mac.sh # build only, skip install
# Shared backend and Linux Host/UI (no Tauri/WebKitGTK)
cargo check -p openless-core
cargo check -p openless-linux-egui --all-targets
# Tauri host type-check
cargo check --manifest-path "src-tauri/Cargo.toml"
# Frontend TS check
npm run build
Logs: ~/Library/Logs/OpenLess/openless.log (macOS) / %LOCALAPPDATA%\OpenLess\Logs\openless.log (Windows).
Windows build — see openless-all/README.md for the MSVC and GNU/MinGW routes.
OpenLess uses a two-channel branching model.
beta — the Beta channel. The default branch and integration buffer; all in-progress development lands here. Beta builds may exist but are not pushed to regular users — they reach only those who explicitly opt into the Beta channel.main — the Stable channel (正式版). Always releasable; the build everyone receives by default.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
Rules of thumb:
beta, never against main. GitHub already defaults the base branch to beta for new PRs.main receives merges only from beta, performed by maintainers after a successful two-platform smoke build. No direct pushes to main.main by pushing a v<version>-tauri tag — see the maintainer release checklist below.Beta release distribution (manual-download opt-in): the in-app updater always reads the Stable manifest, so regular users never receive Beta builds via auto-update. Users who want to try Beta open Settings → About, enable "Join Beta channel", and download the latest Beta installer manually from the link the app fetches from GitHub. Tag convention: v<version>-beta-tauri produces the Beta release (marked as a GitHub pre-release; manifest written as latest-{tgt}-{arch}-beta.json), while v<version>-tauri produces the Stable release. The two manifest files never overlap, so Stable users' updater feed cannot pick up Beta releases.
Credentials live in the OS credential vault (service = com.openless.app): macOS Keychain, Windows Credential Manager, or the Linux keyring. A legacy plaintext JSON file is read only as a migration source and removed after a successful vault write:
macOS / Linux: ~/.openless/credentials.json
Windows: %APPDATA%\OpenLess\credentials.json
New credential writes do not persist plaintext secrets. The repository contains no API keys, tokens, or private endpoints.
You will need:
https://ark.cn-beijing.volces.com/api/v3/chat/completions.OpenLess's polish model only reshapes text. It does not answer questions, run tasks, or analyze your project. Each dictation is an independent request, and the prompt explicitly instructs the model:
For example, if the user says "what features does this app still need", the correct output is:
What features does this app still need?
…not a list of missing features.
Long-term reference rewrites are represented as raw → polished → rule triples in Examples/polish-reference-examples.sample.jsonl. The sample format describes reference data; current module responsibilities are documented in Architecture.
The dictionary handles your proper nouns, product names, names of people, and new words. Today it supports:
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.Claude in context, it is corrected; if it genuinely means cloud computing, it is left as is.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. Local vocabulary learning has a separate switch and does not require cursor context. Observed text is not sent to a model; words explicitly added to the dictionary participate in future ASR and polish requests as described above.
On Windows, cursor context is read via UI Automation from the focused text control: it prefers TextPattern2's caret range, with a TextPattern selection fallback for controls that only support collapsed selections. When the caret cannot be reliably located, it is skipped rather than guessed — wrong context is worse than none, and dictation continues normally either way.
Chromium-based editors (VS Code, Electron apps) only keep their accessibility tree's caret position in sync once they detect an active accessibility client, so with default settings the position UI Automation reads back can be stale. In VS Code, set editor.accessibilitySupport to on (Settings → search "accessibility support"; a window reload may be needed) to get accurate cursor context; the same applies to other Electron-based editors with similar settings. Plain Chrome/Edge text fields do not need this.
On Android, the OpenLess keyboard reads the text before and after the caret straight from its own InputConnection at the moment recording starts — no Accessibility permission involved, one read, no retry. Dictation, quick notes and cloud notes all use it for polishing, but the context only informs how the spoken words are written: it is never copied into the note, the history, the cloud note webhook or the logs. With a cloud polish model it is sent to that provider as part of the polish request. The floating overlay does not read cursor context yet.
Cursor context excludes password fields, macOS Secure Input, Windows UIA password controls, Android editors that are password-typed or ask for no personalized learning, known password managers and terminals. Turning it off stops reading cursor context for polishing; other authorized accessibility features, including local vocabulary learning and insertion, work independently. Turning vocabulary learning off stops observation and clears pending suggestions.
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.
The application has one shared backend Interface and platform hosts:
React UI ── Tauri Adapter (macOS/Windows/Android) ──┐
├── openless-core
egui UI ── Linux Adapter (no Tauri/WebKitGTK) ────┘
openless-core owns the stable DTOs, errors, semantic events, repositories, credentials contract, and host-facing use-case Interface. Host-only concerns—IPC, windows, tray, permissions, updater, keyring, fcitx5, and package resource paths—are implemented by Adapters. Legacy React command/event names stay in the Tauri compatibility Adapter; Linux calls the typed Rust Interface in process. See docs/linux-egui-backend-contract.md.
The v<version>-tauri / v<version>-Beta.N-tauri workflows build the macOS, Windows and Android hosts alongside the independent Linux egui deb/rpm workflow. After Linux device acceptance and an admin's tag, verified Linux packages attach to the shared Release; Beta assets remain in a draft until an admin publishes them. Linux has no AppImage or in-app updater manifest.
The dictation pipeline: hotkey edge → Recorder.start + ASR.openSession → [audio frames] → hotkey edge → Recorder.stop + ASR.sendLastFrame → Polish → Insert → History.save.
See Contributing workflow and Releasing for contribution and release rules, and Architecture for module responsibilities and wiring.
Planned but not yet shipped:
RELEASING.md is the canonical release procedure, including administrator authority, version synchronization, platform acceptance, draft assets, signing, and updater verification. New Beta tags use v<X.Y.Z>-Beta.<N>-tauri; the historical -beta-tauri suffix is compatibility-only.
OpenLess sincerely thanks its sponsors, developers and contributors, and the broader LinuxDo community.
We appreciate our sponsors for making sustained project work possible, and we thank our developers and contributors for building, reviewing, and improving OpenLess.
OpenLess also recognizes and appreciates the LinuxDo community for its open, practical, and developer-friendly atmosphere. Many of the ideas, discussions, and early feedback around OpenLess were inspired by the broader open-source spirit that LinuxDo represents.
This acknowledgement does not imply official endorsement or affiliation.
OpenLess 2.0.0-Beta.1 is released under the AGPL-3.0-only license. Published 1.x releases remain available under their original MIT license.
486 followers · starred Aug 2026
75 followers · starred May 2026
66 followers · starred Jun 2026
8 followers · starred May 2026