Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p align="center">
<img src="assets/logo.png" alt="OpenWispr" width="180">
<img src="assets/logo.png" alt="Wisp" width="180">
</p>

<h1 align="center">OpenWispr</h1>
<h1 align="center">Wisp</h1>

<p align="center">
<strong>Open-source, local-first voice dictation for your desktop.</strong><br>
Expand Down Expand Up @@ -40,7 +40,7 @@
## Contents

- [What it is](#what-it-is)
- [Why OpenWispr](#why-openwispr)
- [Why Wisp](#why-openwispr)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the broken TOC anchor for “Why Wisp”.

The link target still points to #why-openwispr, but the heading is now ## Why Wisp (fragment #why-wisp), so the contents link is broken.

Suggested fix
-- [Why Wisp](`#why-openwispr`)
+- [Why Wisp](`#why-wisp`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- [Why Wisp](#why-openwispr)
- [Why Wisp](`#why-wisp`)
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 43-43: Link fragments should be valid

(MD051, link-fragments)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 43, The table of contents link for "Why Wisp" at line 43
references an incorrect anchor fragment. Change the link destination from the
old fragment `#why-openwispr` to the correct fragment `#why-wisp` to match the
actual heading "## Why Wisp" in the document. This will ensure the TOC link
properly navigates to the correct section.

Source: Linters/SAST tools

- [Features](#-features)
- [Quick start](#-quick-start)
- [Install](#-install)
Expand All @@ -62,7 +62,7 @@

## What it is

OpenWispr is a free, open alternative to cloud dictation tools like Wispr Flow.
Wisp is a free, open alternative to cloud dictation tools like Wispr Flow.
Everything runs on your machine — **no cloud, no account, no telemetry, no
subscription**. Your audio never leaves your computer; transcription happens
entirely on-device via [whisper.cpp](https://github.com/ggerganov/whisper.cpp),
Expand All @@ -71,9 +71,9 @@ with Metal GPU acceleration on Apple Silicon.
It lives in your system tray as a small floating "pill" and stays out of the way
until you press your hotkey.

## Why OpenWispr
## Why Wisp

| | OpenWispr | Typical cloud dictation |
| | Wisp | Typical cloud dictation |
| -------------------- | ---------------------------- | ----------------------- |
| **Where audio goes** | Stays on your device | Uploaded to a server |
| **Account required** | No | Usually yes |
Expand Down Expand Up @@ -140,15 +140,15 @@ Grab the installer for your platform from the

## 🔐 Permissions

OpenWispr needs OS-level permissions to hear you and to type for you:
Wisp needs OS-level permissions to hear you and to type for you:

| Permission | Why | Where |
| ------------------------- | ------------------------------------------------------ | -------------------------------------------------------- |
| **Microphone** | Capture your voice | macOS/Win/Linux prompt on first record |
| **Accessibility** (macOS) | Insert text into other apps and read the global hotkey | System Settings → Privacy & Security → **Accessibility** |

On macOS, after an app **update** the system can occasionally drop the
Accessibility grant. OpenWispr detects this and re-prompts; if text stops
Accessibility grant. Wisp detects this and re-prompts; if text stops
inserting after an update, re-enable it under Accessibility (see
[Troubleshooting](#-troubleshooting)).

Expand All @@ -164,7 +164,7 @@ inserting after an update, re-enable it under Accessibility (see
- **Push-to-talk** — hold the hotkey, speak, release.
- **Hands-free** — double-tap the hotkey to start, single-press to stop.
5. The floating pill shows recording state and a quick language switcher. Closing
the main window keeps OpenWispr running in the tray.
the main window keeps Wisp running in the tray.

## ⚙️ Configuration

Expand All @@ -184,7 +184,7 @@ Everything is in **Settings**, persisted to a local `config.toml`:
| **Mute music** | Duck other audio while recording. |
| **Show pill** | Keep the floating pill on screen, or hide until dictating. |
| **Show in Dock** | Toggle Dock icon vs. menu-bar-only (macOS). |
| **Launch at login** | Start OpenWispr automatically. |
| **Launch at login** | Start Wisp automatically. |
| **Theme** | Light or dark. |

## 🧠 Models
Expand Down Expand Up @@ -300,7 +300,7 @@ openwispr/

## 🔄 Updates & releases

OpenWispr updates itself: it checks GitHub Releases and applies signed
Wisp updates itself: it checks GitHub Releases and applies signed
over-the-air updates in the background.

For maintainers, pushing a `v*` tag triggers the
Expand All @@ -318,8 +318,8 @@ git push origin v1.0.0
<summary><strong>It records but no text is inserted</strong></summary>

Grant **Accessibility** permission (macOS: System Settings → Privacy & Security →
Accessibility) so OpenWispr can type into other apps. After a macOS update the
grant can reset — toggle OpenWispr off and on in that list. As a fallback, switch
Accessibility) so Wisp can type into other apps. After a macOS update the
grant can reset — toggle Wisp off and on in that list. As a fallback, switch
the **injection mode** to **paste** in Settings.

</details>
Expand Down Expand Up @@ -364,5 +364,5 @@ feature ideas are great as [issues](https://github.com/hudsonbrendon/openwispr/i

- [whisper.cpp](https://github.com/ggerganov/whisper.cpp) and OpenAI's Whisper for on-device speech recognition
- [Tauri](https://tauri.app) for the native cross-platform shell
- Everyone who tests OpenWispr and files issues
- Everyone who tests Wisp and files issues
</content>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "openwispr",
"name": "wisp",
"private": true,
"version": "1.0.8",
"type": "module",
Expand Down
14 changes: 7 additions & 7 deletions site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>OpenWispr — Local-first voice dictation</title>
<title>Wisp — Local-first voice dictation</title>
<meta
name="description"
content="OpenWispr is open-source, local-first voice dictation. Press a hotkey, speak, and your words appear in any app — transcribed on-device with Whisper. Free for macOS, Windows, and Linux."
content="Wisp is open-source, local-first voice dictation. Press a hotkey, speak, and your words appear in any app — transcribed on-device with Whisper. Free for macOS, Windows, and Linux."
/>
<meta property="og:title" content="OpenWispr — Local-first voice dictation" />
<meta property="og:title" content="Wisp — Local-first voice dictation" />
<meta
property="og:description"
content="Press a hotkey, speak, and your words appear anywhere. 100% local, free and open source."
Expand Down Expand Up @@ -40,7 +40,7 @@

<header class="topbar">
<a class="brand" href="index.html"
><img class="brand-mark" src="assets/logo.png" alt="" width="64" height="64" />OpenWispr<span class="dot">.</span></a
><img class="brand-mark" src="assets/logo.png" alt="" width="64" height="64" />Wisp<span class="dot">.</span></a
>
<nav>
<a class="nav-link" href="#features" data-i18n="nav_features">Features</a>
Expand All @@ -66,7 +66,7 @@ <h1 id="hero-title" class="reveal">
<span data-i18n="hero_title_a">Your voice, typed</span> <em data-i18n="hero_title_b">everywhere</em>.
</h1>
<p class="lede reveal" data-i18n="hero_lede">
OpenWispr is a private voice dictation app. Press a hotkey, speak, and your
Wisp is a private voice dictation app. Press a hotkey, speak, and your
words land in any app — transcribed on-device with Whisper, never in the cloud.
</p>
<div class="hero-actions reveal">
Expand Down Expand Up @@ -215,7 +215,7 @@ <h2 id="platforms-title" data-i18n="plat_head">One app, every desktop.</h2>
<div class="method primary" data-io>
<h3 data-i18n="cta_title">Ready when you are.</h3>
<p data-i18n="cta_body">
Download OpenWispr for your platform and start dictating in minutes. Free, open
Download Wisp for your platform and start dictating in minutes. Free, open
source, and entirely on-device.
</p>
<a class="btn" id="cta-dl" href="https://github.com/hudsonbrendon/openwispr/releases/latest"><span data-i18n="cta_button">Download</span></a>
Comment on lines +218 to 221

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Update landing-site download model to match the Wisp artifact naming.

The CTA copy was rebranded, but the runtime download builder (site/assets/app.js, Lines 153-207) still emits OpenWispr_... filenames and a fallback label of “Download OpenWispr”. That creates a cross-file branding/link contract mismatch and can break fallback downloads if release assets are now Wisp-prefixed.

Suggested fix (cross-file)
--- a/site/assets/app.js
+++ b/site/assets/app.js
@@
-      macApple: base + "OpenWispr_" + version + "_aarch64.dmg",
-      macIntel: base + "OpenWispr_" + version + "_x64.dmg",
-      windows: base + "OpenWispr_" + version + "_x64-setup.exe",
-      linuxAppImage: base + "OpenWispr_" + version + "_amd64.AppImage",
-      linuxDeb: base + "OpenWispr_" + version + "_amd64.deb",
-      linuxRpm: base + "OpenWispr-" + version + "-1.x86_64.rpm",
+      macApple: base + "Wisp_" + version + "_aarch64.dmg",
+      macIntel: base + "Wisp_" + version + "_x64.dmg",
+      windows: base + "Wisp_" + version + "_x64-setup.exe",
+      linuxAppImage: base + "Wisp_" + version + "_amd64.AppImage",
+      linuxDeb: base + "Wisp_" + version + "_amd64.deb",
+      linuxRpm: base + "Wisp-" + version + "-1.x86_64.rpm",
@@
-      fallback: "Download OpenWispr",
+      fallback: "Download Wisp",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/index.html` around lines 218 - 221, The landing page HTML has been
rebranded to use "Wisp" terminology, but the runtime download builder in
site/assets/app.js (lines 153-207) still references "OpenWispr" in the filename
patterns it generates and in the fallback download label. Update the download
builder logic to emit "Wisp_..." prefixed filenames instead of "OpenWispr_..."
filenames and change the fallback label text from "Download OpenWispr" to
"Download Wisp" to maintain consistent branding across the landing page and the
download link generation logic.

Expand All @@ -230,7 +230,7 @@ <h3 data-i18n="cta_title">Ready when you are.</h3>
<footer class="foot">
<div class="wrap">
<a class="brand" href="index.html"
><img class="brand-mark" src="assets/logo.png" alt="" width="64" height="64" />OpenWispr<span class="dot">.</span></a
><img class="brand-mark" src="assets/logo.png" alt="" width="64" height="64" />Wisp<span class="dot">.</span></a
>
<nav>
<a href="https://github.com/hudsonbrendon/openwispr" rel="noopener">GitHub</a>
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn save_config(
Ok(())
}

/// Enable/disable launching OpenWispr at login (managed by the autostart plugin,
/// Enable/disable launching Wisp at login (managed by the autostart plugin,
/// not stored in our config).
#[tauri::command]
pub fn set_launch_at_login(app: AppHandle, enabled: bool) -> Result<(), String> {
Expand All @@ -76,7 +76,7 @@ pub fn set_launch_at_login(app: AppHandle, enabled: bool) -> Result<(), String>
if enabled { mgr.enable() } else { mgr.disable() }.map_err(|e| e.to_string())
}

/// Whether OpenWispr is set to launch at login.
/// Whether Wisp is set to launch at login.
#[tauri::command]
pub fn get_launch_at_login(app: AppHandle) -> bool {
use tauri_plugin_autostart::ManagerExt;
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ mod tests {
dictation_sounds: false,
mute_music: true,
onboarded: true,
dictionary: vec!["OpenWispr".to_string()],
dictionary: vec!["Wisp".to_string()],
replacements: vec![Replacement {
from: "my email".to_string(),
to: "me@example.com".to_string(),
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ fn ensure_accessibility_trusted() -> Result<(), String> {
// user can fix it in one click instead of hunting through settings.
accessibility::prompt();
Err(
"Grant Accessibility permission to OpenWispr (System Settings → \
Privacy & Security → Accessibility). If OpenWispr is already \
"Grant Accessibility permission to Wisp (System Settings → \
Privacy & Security → Accessibility). If Wisp is already \
listed and enabled, toggle it off and on — the previous build's \
permission goes stale after an update."
.to_string(),
Expand Down
8 changes: 4 additions & 4 deletions src-tauri/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ mod tests {

#[test]
fn replaces_case_insensitively() {
let out = apply_replacements("Call OPENWISPR now", &[r("openwispr", "OpenWispr")]);
assert_eq!(out, "Call OpenWispr now");
let out = apply_replacements("Call OPENWISPR now", &[r("openwispr", "Wisp")]);
assert_eq!(out, "Call Wisp now");
}

#[test]
Expand All @@ -90,11 +90,11 @@ mod tests {
#[test]
fn dictionary_prompt_joins_and_trims() {
let words = vec![
" OpenWispr ".to_string(),
" Wisp ".to_string(),
"".to_string(),
"Tauri".to_string(),
];
assert_eq!(dictionary_prompt(&words), "OpenWispr, Tauri");
assert_eq!(dictionary_prompt(&words), "Wisp, Tauri");
assert_eq!(dictionary_prompt(&[]), "");
}
}
Loading
Loading