feat: live dictation demo + ethics/privacy positioning for lawyers #4747
71 changed files+14450−852
Modified.github/workflows/build.yml+3−3View fileUnifiedSplit
@@ -1,4 +1,4 @@
1name: Build & Release Marco Reid Voice
1name: Build & Release Voxlen
22
33on:
44 push:
@@ -138,9 +138,9 @@ jobs:
138138 uses: softprops/action-gh-release@v2
139139 with:
140140 tag_name: v${{ steps.version.outputs.version }}
141 name: Marco Reid Voice v${{ steps.version.outputs.version }}
141 name: Voxlen v${{ steps.version.outputs.version }}
142142 body: |
143 Marco Reid Voice v${{ steps.version.outputs.version }} — AI-powered voice dictation for professionals.
143 Voxlen v${{ steps.version.outputs.version }} — AI-powered voice dictation for professionals.
144144
145145 Download the installer for your OS below.
146146
Modifieddocs/API.md+1−1View fileUnifiedSplit
@@ -1,4 +1,4 @@
1# Marco Reid Voice IPC Reference
1# Voxlen IPC Reference
22
33This document enumerates every Tauri `invoke` command and every event emitted from the Rust backend. Types are given in their serialized (JSON) shape.
44
Modifieddocs/ARCHITECTURE.md+2−2View fileUnifiedSplit
@@ -1,6 +1,6 @@
1# Marco Reid Voice Architecture
1# Voxlen Architecture
22
3This document describes the high-level structure of Marco Reid Voice. For a line-by-line IPC reference, see [API.md](./API.md).
3This document describes the high-level structure of Voxlen. For a line-by-line IPC reference, see [API.md](./API.md).
44
55## Stack
66
Modifieddocs/CONTRIBUTING.md+2−2View fileUnifiedSplit
@@ -1,4 +1,4 @@
1# Contributing to Marco Reid Voice
1# Contributing to Voxlen
22
33Thanks for your interest in contributing. This document covers the conventions we follow and how to get a dev environment running.
44
@@ -76,4 +76,4 @@ See [RELEASE.md](./RELEASE.md) for the release process, including auto-updater k
7676
7777## Reporting bugs
7878
79File an issue with clear reproduction steps and your platform (OS + version, Marco Reid Voice version). For security-sensitive reports, follow [SECURITY.md](./SECURITY.md) instead.
79File an issue with clear reproduction steps and your platform (OS + version, Voxlen version). For security-sensitive reports, follow [SECURITY.md](./SECURITY.md) instead.
Modifieddocs/PRIVACY.md+9−9View fileUnifiedSplit
@@ -1,28 +1,28 @@
1# Marco Reid Voice Privacy Notes
1# Voxlen Privacy Notes
22
33This page describes what leaves your machine, what stays on your machine, and what you can delete. This is an engineering-level summary — treat it as the source of truth for the app's actual behavior.
44
55## TL;DR
66
7- **No telemetry.** Marco Reid Voice does not contact any analytics, metrics, or crash-reporting service.
8- **No cloud sync.** Your data never touches Marco Reid Voice-operated servers.
7- **No telemetry.** Voxlen does not contact any analytics, metrics, or crash-reporting service.
8- **No cloud sync.** Voxlen never stores your data. With a Voxlen account, requests pass transiently through zero-retention voxlen.ai endpoints to reach the AI providers; nothing is logged or retained.
99- **Third-party calls are strictly on your behalf**, to the providers you select.
1010
1111## What gets sent off your device
1212
13Marco Reid Voice only talks to two categories of endpoints, and only when you ask it to:
13Voxlen only talks to two categories of endpoints, and only when you ask it to:
1414
1515| Outbound traffic | Destination | When |
1616| ---------------- | ------------------------------------------- | -------------------------------------------------------------------- |
1717| Audio frames | Deepgram or OpenAI Whisper (your choice) | Only while dictation is active, and only to the engine you selected |
1818| Text | Anthropic (Claude) or OpenAI (your choice) | Only when grammar correction is enabled **and** you trigger a pass |
19| App update check | `https://releases.marcoreid.com/...` (placeholder — replace with real host) | When the updater plugin runs (configurable) |
19| App update check | `https://releases.voxlen.ai/...` (placeholder — replace with real host) | When the updater plugin runs (configurable) |
2020
2121No other outbound traffic originates from the desktop app.
2222
2323## What is stored locally
2424
25Everything Marco Reid Voice retains lives on your machine, under the Tauri app data directory:
25Everything Voxlen retains lives on your machine, under the Tauri app data directory:
2626
2727| File | Contents |
2828| ----------------- | ----------------------------------------------------------------- |
@@ -38,7 +38,7 @@ API keys are written to `settings.json` in plaintext. They are not encrypted at
3838- **Single session:** History panel → select session → delete.
3939- **All history:** History panel → "Clear all".
4040- **Settings and keys:** Settings → Reset to defaults (clears API keys in memory and on disk).
41- **Nuclear option:** Remove the Marco Reid Voice data directory while the app is closed.
41- **Nuclear option:** Remove the Voxlen data directory while the app is closed.
4242
4343## Telemetry
4444
@@ -54,8 +54,8 @@ When you send audio to Deepgram or OpenAI, or text to Anthropic or OpenAI, the v
5454
5555## iOS keyboard
5656
57The iOS keyboard extension is a separate bundle (`ios/VoxKeyboard`). It only transmits text when the user taps the grammar action, and only to the provider configured in the main Marco Reid Voice iOS app. Extensions run in a sandbox with network access granted explicitly via `RequestsOpenAccess`.
57The iOS keyboard extension is a separate bundle (`ios/VoxKeyboard`). It only transmits text when the user taps the grammar action, and only to the provider configured in the main Voxlen iOS app. Extensions run in a sandbox with network access granted explicitly via `RequestsOpenAccess`.
5858
5959## Questions
6060
61Security-impacting privacy questions: `security@marcoreid.com` (placeholder).
61Security-impacting privacy questions: `security@voxlen.ai` (placeholder).
Modifieddocs/RELEASE.md+10−10View fileUnifiedSplit
@@ -1,19 +1,19 @@
11# Release Process
22
3This document covers cutting a Marco Reid Voice release and the one-time setup for the auto-updater signing key.
3This document covers cutting a Voxlen release and the one-time setup for the auto-updater signing key.
44
55## One-time: generate the updater signing key
66
77The Tauri updater verifies release bundles against a public key embedded in `src-tauri/tauri.conf.json`. Generate the keypair **once** for the project:
88
99```bash
10npm run tauri signer generate -- -w ~/.tauri/marcoreid-voice.key
10npm run tauri signer generate -- -w ~/.tauri/voxlen.key
1111```
1212
1313This produces:
1414
15- `~/.tauri/marcoreid-voice.key` — **private** key (protect this; never commit)
16- `~/.tauri/marcoreid-voice.key.pub` — **public** key (paste into `tauri.conf.json`)
15- `~/.tauri/voxlen.key` — **private** key (protect this; never commit)
16- `~/.tauri/voxlen.key.pub` — **public** key (paste into `tauri.conf.json`)
1717
1818### Wire up the public key
1919
@@ -23,14 +23,14 @@ Open `src-tauri/tauri.conf.json` and replace the placeholder in the updater bloc
2323"updater": {
2424 "active": true,
2525 "endpoints": [
26 "https://releases.marcoreid.com/{{target}}/{{current_version}}"
26 "https://releases.voxlen.ai/{{target}}/{{current_version}}"
2727 ],
2828 "dialog": true,
2929 "pubkey": "PASTE_PUBLIC_KEY_HERE"
3030}
3131```
3232
33> The `releases.marcoreid.com` host is a placeholder. Replace with your actual release server before shipping.
33> The `releases.voxlen.ai` host is a placeholder. Replace with your actual release server before shipping.
3434
3535### Wire up CI secrets
3636
@@ -38,7 +38,7 @@ In GitHub → Settings → Secrets and variables → Actions, add:
3838
3939| Secret name | Value |
4040| --------------------- | -------------------------------------------------------------- |
41| `TAURI_PRIVATE_KEY` | Contents of `~/.tauri/marcoreid-voice.key` (base64 or raw text) |
41| `TAURI_PRIVATE_KEY` | Contents of `~/.tauri/voxlen.key` (base64 or raw text) |
4242| `TAURI_KEY_PASSWORD` | The passphrase you set when generating (empty string if none) |
4343| `APPLE_CERTIFICATE` | Apple Developer ID signing certificate (base64) |
4444| `APPLE_CERTIFICATE_PASSWORD` | Certificate password |
@@ -55,9 +55,9 @@ The `build.yml` workflow already references these names.
55552. Bump `version` in `package.json`, `src-tauri/tauri.conf.json`, and `src-tauri/Cargo.toml` — these three must agree.
56563. Commit: `chore(release): vX.Y.Z`.
57574. Tag: `git tag vX.Y.Z && git push --tags`.
585. The `Build & Release Marco Reid Voice` workflow will:
585. The `Build & Release Voxlen` workflow will:
5959 - Build for macOS (aarch64 + x86_64), Windows, and Linux.
60 - Attach signed bundles to a draft GitHub Release named `Marco Reid Voice vX.Y.Z`.
60 - Attach signed bundles to a draft GitHub Release named `Voxlen vX.Y.Z`.
61616. Review the draft release, then promote it (un-draft) to trigger auto-update delivery.
6262
6363## Updater endpoint
@@ -65,7 +65,7 @@ The `build.yml` workflow already references these names.
6565The updater polls:
6666
6767```
68https://releases.marcoreid.com/{{target}}/{{current_version}}
68https://releases.voxlen.ai/{{target}}/{{current_version}}
6969```
7070
7171Your release server must respond with a signed JSON manifest per the [Tauri updater spec](https://v2.tauri.app/plugin/updater/#server-support). Until that host exists, the updater is wired but no updates will be delivered.
Modifieddocs/SECURITY.md+5−5View fileUnifiedSplit
@@ -2,15 +2,15 @@
22
33## Reporting a vulnerability
44
5If you believe you have found a security issue in Marco Reid Voice, please report it privately rather than filing a public issue.
5If you believe you have found a security issue in Voxlen, please report it privately rather than filing a public issue.
66
7**Contact:** `security@marcoreid.com` (placeholder — replace with a real inbox before shipping)
7**Contact:** `security@voxlen.ai` (placeholder — replace with a real inbox before shipping)
88
99Please include:
1010
1111- A description of the issue and its impact.
1212- Steps to reproduce (or a proof-of-concept).
13- The Marco Reid Voice version and your operating system.
13- The Voxlen version and your operating system.
1414- Whether you would like to be credited.
1515
1616We will acknowledge receipt within 3 business days and aim to provide an initial assessment within 7 days. Coordinated disclosure timelines are negotiable based on severity.
@@ -43,8 +43,8 @@ Please read these before reporting — they are documented trade-offs, not undis
4343
4444- **API keys are stored in plaintext** on disk via `tauri-plugin-store` (`settings.json`). They are not encrypted at rest and are readable by any process running as the current user. Hardware-backed keystore integration is on the roadmap.
4545- **Transcripts are stored in plaintext** in `history.json`. Users can delete sessions or clear the history from the History panel.
46- **Audio and text are sent to the providers you configure.** Marco Reid Voice itself does not proxy or log this data, but the upstream vendor's privacy policy applies to any data you send them.
47- **No telemetry** is collected by Marco Reid Voice.
46- **Audio and text are sent to the providers you configure.** Voxlen itself does not proxy or log this data, but the upstream vendor's privacy policy applies to any data you send them.
47- **No telemetry** is collected by Voxlen.
4848
4949## Signed releases
5050
Modifiedios/VoxKeyboard/VoxApp/VoxApp.swift+12−12View fileUnifiedSplit
@@ -1,7 +1,7 @@
11import SwiftUI
22
33@main
4struct MarcoReidVoiceApp: App {
4struct VoxlenApp: App {
55 private var settingsManager = SettingsManager()
66
77 var body: some Scene {
@@ -32,16 +32,16 @@ struct ContentView: View {
3232 HStack {
3333 Image(systemName: "mic.fill")
3434 .font(.system(size: 32))
35 .foregroundColor(.blue)
35 .foregroundColor(Color(red: 0.45, green: 0.27, blue: 0.82))
3636 .frame(width: 56, height: 56)
37 .background(Color.blue.opacity(0.1))
37 .background(Color(red: 0.45, green: 0.27, blue: 0.82).opacity(0.1))
3838 .cornerRadius(12)
3939
4040 VStack(alignment: .leading) {
4141 Text("Voxlen Keyboard")
4242 .font(.title2)
4343 .fontWeight(.bold)
44 Text("AI-Powered Grammar Correction")
44 Text("AI Voice Dictation for Professionals")
4545 .font(.caption)
4646 .foregroundColor(.secondary)
4747 }
@@ -124,7 +124,7 @@ struct ContentView: View {
124124 // MARK: - Voice Dictation
125125 Section {
126126 Picker("STT Engine", selection: $settings.sttEngine) {
127 Text("Deepgram Nova-2").tag(STTEngine.deepgram)
127 Text("Deepgram Nova-3").tag(STTEngine.deepgram)
128128 Text("Apple Speech").tag(STTEngine.apple)
129129 }
130130
@@ -158,7 +158,7 @@ struct ContentView: View {
158158 } header: {
159159 Label("Voice Dictation", systemImage: "waveform")
160160 } footer: {
161 Text("Deepgram Nova-2 provides superior accuracy. Get your API key at console.deepgram.com")
161 Text("Deepgram Nova-3 provides best-in-class accuracy. Get your API key at console.deepgram.com")
162162 }
163163
164164 // MARK: - AI Provider
@@ -185,10 +185,10 @@ struct ContentView: View {
185185
186186 // MARK: - What's New
187187 Section {
188 WhatsNewRow(icon: "waveform.badge.mic", text: "Deepgram Nova-2 voice engine — 95%+ accuracy")
188 WhatsNewRow(icon: "waveform.badge.mic", text: "Deepgram Nova-3 — industry-leading accuracy")
189 WhatsNewRow(icon: "doc.text", text: "Legal & accounting smart formatting")
189190 WhatsNewRow(icon: "globe", text: "20+ language support")
190 WhatsNewRow(icon: "hand.tap.fill", text: "Haptic feedback on every key")
191 WhatsNewRow(icon: "ipad.landscape", text: "iPad optimized layout")
191 WhatsNewRow(icon: "ipad.landscape", text: "iPad optimised layout")
192192 } header: {
193193 Label("What's New", systemImage: "star.fill")
194194 }
@@ -204,14 +204,14 @@ struct ContentView: View {
204204 Link(destination: URL(string: "https://voxlen.ai/privacy")!) {
205205 HStack {
206206 Image(systemName: "hand.raised.fill")
207 .foregroundColor(.blue)
207 .foregroundColor(.purple)
208208 Text("Privacy Policy")
209209 }
210210 }
211211 Link(destination: URL(string: "https://voxlen.ai/support")!) {
212212 HStack {
213213 Image(systemName: "questionmark.circle.fill")
214 .foregroundColor(.blue)
214 .foregroundColor(.purple)
215215 Text("Support")
216216 }
217217 }
@@ -241,7 +241,7 @@ struct WhatsNewRow: View {
241241 var body: some View {
242242 HStack(spacing: 12) {
243243 Image(systemName: icon)
244 .foregroundColor(.blue)
244 .foregroundColor(Color(red: 0.45, green: 0.27, blue: 0.82))
245245 .frame(width: 24)
246246 Text(text)
247247 .font(.subheadline)
Modifiedlanding/index.html+6−6View fileUnifiedSplit
@@ -62,7 +62,7 @@
6262 "logo": "https://voxlen.ai/vox-icon.svg",
6363 "screenshot": "https://voxlen.ai/og-image.png",
6464 "softwareVersion": "1.0.9",
65 "releaseNotes": "Nova-3 transcription engine, Claude Sonnet grammar AI, legal clause library, privileged mode for sensitive matters",
65 "releaseNotes": "Nova-3 transcription engine, Claude Sonnet grammar AI, legal clause library, zero-retention privacy for sensitive matters",
6666 "offers": [
6767 {
6868 "@type": "Offer",
@@ -85,7 +85,7 @@
8585 "price": "79",
8686 "priceCurrency": "USD",
8787 "billingIncrement": "P1M",
88 "description": "Legal and accounting teams — SSO, privileged mode, clause library"
88 "description": "Legal and accounting teams — SSO, clause library, strictest zero-retention controls"
8989 },
9090 {
9191 "@type": "Offer",
@@ -99,10 +99,10 @@
9999 "Real-time voice dictation",
100100 "AI grammar correction powered by Claude",
101101 "Legal clause library with voice triggers",
102 "Privileged mode for sensitive matters",
102 "Privileged Mode for sensitive matters (coming soon)",
103103 "Speaker diarization for depositions",
104104 "20+ language support",
105 "Offline mode",
105 "Offline mode (coming soon)",
106106 "Universal text injection into any app",
107107 "Domain-specific formatting for legal and accounting",
108108 "Billable time tracking via voice commands"
@@ -130,7 +130,7 @@
130130 "name": "What is the best voice dictation software for lawyers?",
131131 "acceptedAnswer": {
132132 "@type": "Answer",
133 "text": "Voxlen is purpose-built for legal professionals. It includes a clause library with 15+ pre-built legal clauses (indemnity, governing law, confidentiality), privileged mode that blocks all cloud processing for sensitive matters, legal smart formatting for court filings and depositions, and speaker diarization for multi-party meetings. It is more accurate and more feature-rich than Dragon NaturallySpeaking for legal use cases."
133 "text": "Voxlen is purpose-built for legal professionals. It includes a clause library with 15+ pre-built legal clauses (indemnity, governing law, confidentiality), Privileged Mode (coming soon) that will block all cloud processing for sensitive matters, legal smart formatting for court filings and depositions, and speaker diarization for multi-party meetings. It is more accurate and more feature-rich than Dragon NaturallySpeaking for legal use cases."
134134 }
135135 },
136136 {
@@ -154,7 +154,7 @@
154154 "name": "Is voice dictation software GDPR compliant for law firms?",
155155 "acceptedAnswer": {
156156 "@type": "Answer",
157 "text": "Voxlen's Privileged Mode enables fully offline transcription — audio never leaves your device. For cloud processing, Voxlen uses zero-retention endpoints with all AI providers. The Professional plan includes the strictest data handling controls for law firms handling client-privileged information."
157 "text": "Voxlen uses zero-retention endpoints with all AI providers — Voxlen never stores your audio or transcripts, and nothing is retained. Privileged Mode (coming soon) will enable fully offline, on-device transcription so audio never leaves your device. The Professional plan includes the strictest data handling controls for law firms handling client-privileged information."
158158 }
159159 },
160160 {
Modifiedlanding/public/ai-dictation-software/index.html+14−14View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>AI Dictation Software — Voxlen | Voice to Text with AI Grammar</title>
7 <meta name="description" content="AI dictation software that thinks like a professional. Voxlen uses advanced AI grammar correction, learns your writing style, and delivers 99% accuracy — no more typos, no manual editing. Free trial." />
7 <meta name="description" content="AI dictation software that thinks like a professional. Voxlen uses advanced AI grammar correction, learns your writing style, and delivers 95%+ accuracy — no more typos, no manual editing. Free trial." />
88 <meta name="keywords" content="AI dictation software, AI voice dictation, artificial intelligence dictation, AI speech to text, AI voice to text, smart dictation software, AI transcription, voice recognition AI" />
99 <link rel="canonical" href="https://voxlen.ai/ai-dictation-software" />
1010 <meta property="og:title" content="AI Dictation Software — Voxlen | Voice to Text with AI Grammar" />
11 <meta property="og:description" content="The AI dictation software that thinks like a professional. Context-aware AI grammar, learns your style, 99% accuracy. Free 14-day trial." />
11 <meta property="og:description" content="The AI dictation software that thinks like a professional. Context-aware AI grammar, learns your style, 95%+ accuracy. Free 14-day trial." />
1212 <meta property="og:type" content="article" />
1313 <meta property="og:url" content="https://voxlen.ai/ai-dictation-software" />
1414 <meta property="og:site_name" content="Voxlen" />
@@ -38,7 +38,7 @@
3838 "name": "Pro",
3939 "price": "29",
4040 "priceCurrency": "USD",
41 "description": "Unlimited dictation, AI grammar, style learning, offline mode"
41 "description": "Unlimited dictation, AI grammar, style learning, offline mode (coming soon)"
4242 },
4343 {
4444 "@type": "Offer",
@@ -82,7 +82,7 @@
8282 "name": "Does AI dictation software work offline?",
8383 "acceptedAnswer": {
8484 "@type": "Answer",
85 "text": "Voxlen's Privileged Mode enables fully offline AI dictation — both transcription and AI grammar correction run entirely on-device. This is critical for professionals working with sensitive or confidential content where no audio or text should leave the device. In standard mode, Voxlen uses cloud-based Deepgram Nova-3 for transcription (your own API key) plus Claude or GPT-4o for AI grammar (also your own key). Nothing ever touches Voxlen's servers."
85 "text": "Voxlen's Privileged Mode (coming soon) will enable fully offline AI dictation — both transcription and AI grammar correction running entirely on-device. This matters for professionals working with sensitive or confidential content where no audio or text should leave the device. Today, Voxlen uses cloud-based Deepgram Nova-3 for transcription plus Claude or GPT-4o for AI grammar — all AI costs are included in your subscription, no API keys to manage. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."
8686 }
8787 },
8888 {
@@ -98,7 +98,7 @@
9898 "name": "Is AI dictation software secure for professionals?",
9999 "acceptedAnswer": {
100100 "@type": "Answer",
101 "text": "Voxlen is designed with security as a first principle. Your audio and transcripts never touch Voxlen's servers. When using cloud transcription, your audio is processed by Deepgram or OpenAI using your own API key under your own data processing agreements — Voxlen is simply the client application. For maximum security, Privileged Mode processes everything on-device with no external network calls at all. This makes Voxlen safe for lawyers, accountants, medical professionals, and anyone handling confidential information."
101 "text": "Voxlen is designed with security as a first principle. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. For maximum security, Privileged Mode (coming soon) will process everything on-device with no external network calls at all. This makes Voxlen safe for lawyers, accountants, medical professionals, and anyone handling confidential information."
102102 }
103103 }
104104 ]
@@ -867,7 +867,7 @@
867867 </div>
868868 <h1>The AI Dictation Software<br><span>That Thinks Like a Professional</span></h1>
869869 <p class="hero-sub">
870 Context-aware AI grammar, a model that learns your writing style, and 99% accuracy
870 Context-aware AI grammar, a model that learns your writing style, and 95%+ accuracy
871871 out of the box — no training, no typos, no manual editing.
872872 </p>
873873 <div class="hero-ctas">
@@ -880,7 +880,7 @@
880880 <div class="hero-trust">
881881 <div class="trust-item">
882882 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
883 99% transcription accuracy
883 95%+ transcription accuracy
884884 </div>
885885 <div class="trust-item">
886886 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
@@ -936,7 +936,7 @@
936936 <div class="feature-badge">Flagship</div>
937937 <div class="feature-icon">🧠</div>
938938 <h3>AI Grammar Correction</h3>
939 <p>Every dictation session is post-processed by Claude Sonnet or GPT-4o (your own API key). The AI understands context, fixes grammar, removes fillers, applies correct punctuation, and produces document-ready text — not raw transcription.</p>
939 <p>Every dictation session is post-processed by Claude Sonnet or GPT-4o — included in your subscription. The AI understands context, fixes grammar, removes fillers, applies correct punctuation, and produces document-ready text — not raw transcription.</p>
940940 </div>
941941
942942 <div class="feature-card featured">
@@ -961,7 +961,7 @@
961961 <div class="feature-card">
962962 <div class="feature-icon">🛡️</div>
963963 <h3>Privacy-First Architecture</h3>
964 <p>Your audio and transcripts never touch Voxlen's servers. Audio goes directly to your chosen provider (Deepgram or OpenAI) under your own API key. For maximum privacy, Privileged Mode processes everything on-device with zero network calls.</p>
964 <p>Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. For maximum privacy, Privileged Mode (coming soon) will process everything on-device with zero network calls.</p>
965965 </div>
966966
967967 <div class="feature-card">
@@ -1022,7 +1022,7 @@
10221022 </tr>
10231023 <tr>
10241024 <td class="feature-name">Offline / On-Device Mode</td>
1025 <td class="voxlen-col"><span class="yes">✓ Privileged Mode</span></td>
1025 <td class="voxlen-col">🔜 Coming soon</td>
10261026 <td><span class="yes">✓ Yes</span></td>
10271027 <td><span class="no">✗ Cloud only</span></td>
10281028 <td><span class="yes">✓ Yes</span></td>
@@ -1072,7 +1072,7 @@
10721072 <div class="step-num">2</div>
10731073 <div>
10741074 <h3>AI Understands</h3>
1075 <p>The raw transcript is sent to Claude Sonnet or GPT-4o (using your API key). The AI applies grammar correction, removes filler words, resolves contextual ambiguities, and formats the text for your target document type — all in under a second.</p>
1075 <p>The raw transcript is sent to Claude Sonnet or GPT-4o — included in your subscription. The AI applies grammar correction, removes filler words, resolves contextual ambiguities, and formats the text for your target document type — all in under a second.</p>
10761076 </div>
10771077 </div>
10781078 <div class="step">
@@ -1117,7 +1117,7 @@
11171117 <li><span class="check">✓</span> Full AI grammar (Claude / GPT-4o)</li>
11181118 <li><span class="check">✓</span> On-device style learning</li>
11191119 <li><span class="check">✓</span> Real-time translation (30+ languages)</li>
1120 <li><span class="check">✓</span> Privileged Mode (offline)</li>
1120 <li><span class="check">🔜</span> Privileged Mode (offline) — coming soon</li>
11211121 <li><span class="check">✓</span> iOS keyboard app</li>
11221122 <li><span class="check">✓</span> Speaker diarization</li>
11231123 </ul>
@@ -1181,7 +1181,7 @@
11811181 </button>
11821182 <div class="faq-answer" role="region">
11831183 <div class="faq-answer-inner">
1184 Voxlen's Privileged Mode enables fully offline AI dictation — both transcription and grammar correction run entirely on-device. This is critical for professionals handling sensitive or confidential content where no audio or text should leave the device. In standard mode, Voxlen uses cloud-based Deepgram Nova-3 for transcription (your own API key) plus Claude or GPT-4o for AI grammar (also your own key). Nothing ever touches Voxlen's own servers regardless of which mode you use.
1184 Voxlen's Privileged Mode (coming soon) will enable fully offline AI dictation — both transcription and grammar correction running entirely on-device. This matters for professionals handling sensitive or confidential content where no audio or text should leave the device. Today, Voxlen uses cloud-based Deepgram Nova-3 for transcription plus Claude or GPT-4o for AI grammar — all AI costs are included in your subscription, no API keys to manage. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained.
11851185 </div>
11861186 </div>
11871187 </div>
@@ -1205,7 +1205,7 @@
12051205 </button>
12061206 <div class="faq-answer" role="region">
12071207 <div class="faq-answer-inner">
1208 Voxlen is designed with security as a first principle. Your audio and transcripts never touch Voxlen's servers. When using cloud transcription, your audio is processed by Deepgram or OpenAI using your own API key under your own data processing agreements. Voxlen is simply the client application that orchestrates the pipeline. For maximum security, Privileged Mode processes everything on-device with zero external network calls. This makes Voxlen safe for lawyers, accountants, medical professionals, executives, and anyone handling confidential information.
1208 Voxlen is designed with security as a first principle. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. For maximum security, Privileged Mode (coming soon) will process everything on-device with zero external network calls. This makes Voxlen safe for lawyers, accountants, medical professionals, executives, and anyone handling confidential information.
12091209 </div>
12101210 </div>
12111211 </div>
Modifiedlanding/public/best-voice-to-text-software/index.html+18−18View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Best Voice to Text Software 2026 — Voxlen | Accurate & Fast</title>
7 <meta name="description" content="The best voice-to-text software for professionals in 2026. Voxlen delivers 99% accuracy with AI grammar correction. Works on Mac, Windows and iPhone. Free trial." />
7 <meta name="description" content="The best voice-to-text software for professionals in 2026. Voxlen delivers 95%+ accuracy with AI grammar correction. Works on Mac, Windows and iPhone. Free trial." />
88 <meta name="keywords" content="best voice to text software, best speech to text software 2026, voice to text software comparison, most accurate voice recognition, voice dictation software, speech recognition software" />
99 <link rel="canonical" href="https://voxlen.ai/best-voice-to-text-software" />
1010 <meta property="og:title" content="Best Voice to Text Software 2026 — Voxlen | Accurate & Fast" />
11 <meta property="og:description" content="The best voice-to-text software for professionals in 2026. Voxlen delivers 99% accuracy with AI grammar correction. Works on Mac, Windows and iPhone. Free trial." />
11 <meta property="og:description" content="The best voice-to-text software for professionals in 2026. Voxlen delivers 95%+ accuracy with AI grammar correction. Works on Mac, Windows and iPhone. Free trial." />
1212 <meta property="og:type" content="article" />
1313 <meta property="og:url" content="https://voxlen.ai/best-voice-to-text-software" />
1414 <meta property="og:site_name" content="Voxlen" />
@@ -23,7 +23,7 @@
2323 "name": "Voxlen",
2424 "applicationCategory": "BusinessApplication",
2525 "operatingSystem": "macOS, Windows, iOS",
26 "description": "The best voice to text software for professionals in 2026. Real-time AI dictation with 99% accuracy, cross-platform support (Mac, Windows, iPhone), AI grammar correction, and offline mode.",
26 "description": "The best voice to text software for professionals in 2026. Real-time AI dictation with 95%+ accuracy, cross-platform support (Mac, Windows, iPhone), AI grammar correction, and offline mode (coming soon).",
2727 "url": "https://voxlen.ai/",
2828 "offers": [
2929 {
@@ -38,7 +38,7 @@
3838 "name": "Pro",
3939 "price": "29",
4040 "priceCurrency": "USD",
41 "description": "Unlimited dictation, AI grammar, offline mode, iOS app"
41 "description": "Unlimited dictation, AI grammar, offline mode (coming soon), iOS app"
4242 },
4343 {
4444 "@type": "Offer",
@@ -74,7 +74,7 @@
7474 "name": "What is the most accurate voice to text software in 2026?",
7575 "acceptedAnswer": {
7676 "@type": "Answer",
77 "text": "Voxlen is the most accurate voice to text software for professionals in 2026. It uses Deepgram Nova-3 — the highest-accuracy publicly available speech recognition model — achieving ~99% word accuracy without any voice training period. Layered on top, Claude Sonnet or GPT-4o AI post-processing corrects grammar, removes filler words, and resolves contextual ambiguities. The combination outperforms Dragon NaturallySpeaking, Apple Dictation, and Google Docs Voice Typing on professional document creation tasks."
77 "text": "Voxlen is the most accurate voice to text software for professionals in 2026. It uses Deepgram Nova-3 — the highest-accuracy publicly available speech recognition model — achieving 95%+ word accuracy without any voice training period. Layered on top, Claude Sonnet or GPT-4o AI post-processing corrects grammar, removes filler words, and resolves contextual ambiguities. The combination outperforms Dragon NaturallySpeaking, Apple Dictation, and Google Docs Voice Typing on professional document creation tasks."
7878 }
7979 },
8080 {
@@ -90,7 +90,7 @@
9090 "name": "Does voice to text software work without internet?",
9191 "acceptedAnswer": {
9292 "@type": "Answer",
93 "text": "Voxlen's Privileged Mode provides fully offline voice to text with no internet connection required. Both transcription and AI grammar correction run on-device using local models. This is ideal for professionals on flights, in secure facilities, or working with confidential content where no data should leave the device. Most competitors — including Otter.ai, Google Docs Voice Typing, and Whispr Flow — require a constant internet connection."
93 "text": "Voxlen's Privileged Mode (coming soon) will provide fully offline voice to text with no internet connection required — both transcription and AI grammar correction running on-device using local models. This is ideal for professionals on flights, in secure facilities, or working with confidential content where no data should leave the device. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."
9494 }
9595 },
9696 {
@@ -98,7 +98,7 @@
9898 "name": "Which voice to text software is best for lawyers?",
9999 "acceptedAnswer": {
100100 "@type": "Answer",
101 "text": "Voxlen is the best voice to text software for lawyers. It is purpose-built for legal professionals with features no generic tool offers: offline Privileged Mode for attorney-client privileged communications, a 500-term legal clause library, 26 Latin legal phrase recognitions, automatic court-filing formatting, and integrated billable time tracking. Dragon Legal is Windows-only and lacks AI grammar. BigHand requires a workflow server. Only Voxlen combines legal-specific intelligence with modern AI accuracy and cross-platform support."
101 "text": "Voxlen is the best voice to text software for lawyers. It is purpose-built for legal professionals with features no generic tool offers: a 500-term legal clause library, 26 Latin legal phrase recognitions, automatic court-filing formatting, integrated billable time tracking, and offline Privileged Mode coming soon for attorney-client privileged communications. Dragon Legal is Windows-only and lacks AI grammar. BigHand requires a workflow server. Only Voxlen combines legal-specific intelligence with modern AI accuracy and cross-platform support."
102102 }
103103 }
104104 ]
@@ -782,7 +782,7 @@
782782 </div>
783783 <div class="trust-item">
784784 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
785 Works offline — no internet needed
785 Offline mode coming soon
786786 </div>
787787 <div class="trust-item">
788788 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
@@ -801,7 +801,7 @@
801801 <div class="pain-card">
802802 <div class="pain-icon">📉</div>
803803 <h3>Accuracy isn't good enough</h3>
804 <p>Consumer tools average 85–92% word accuracy. At 500 words per minute, that's 40–75 errors per minute — more work correcting than it saves. Professionals need 99%+ accuracy to benefit from dictation.</p>
804 <p>Consumer tools average 85–92% word accuracy. At 500 words per minute, that's 40–75 errors per minute — more work correcting than it saves. Professionals need 95%+ accuracy to benefit from dictation.</p>
805805 </div>
806806 <div class="pain-card">
807807 <div class="pain-icon">💻</div>
@@ -833,7 +833,7 @@
833833 <div class="feature-card featured">
834834 <div class="feature-badge">Accuracy</div>
835835 <div class="feature-icon">🎯</div>
836 <h3>99% Accuracy, No Training</h3>
836 <h3>95%+ Accuracy, No Training</h3>
837837 <p>Voxlen uses Deepgram Nova-3 — the highest-accuracy publicly available speech recognition model. Unlike Dragon, you don't need to spend hours training a voice profile. Open the app and immediately get near-perfect transcription.</p>
838838 </div>
839839
@@ -852,8 +852,8 @@
852852
853853 <div class="feature-card">
854854 <div class="feature-icon">🛡️</div>
855 <h3>Offline Privileged Mode</h3>
856 <p>For sensitive work, Privileged Mode runs everything on-device. No audio, no transcripts, no data of any kind leaves your machine. Critical for lawyers, accountants, healthcare workers, and executives.</p>
855 <h3>Offline Privileged Mode — Coming Soon</h3>
856 <p>For sensitive work, Privileged Mode (coming soon) will run everything on-device. No audio, no transcripts, no data of any kind leaving your machine. Critical for lawyers, accountants, healthcare workers, and executives. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
857857 </div>
858858
859859 <div class="feature-card">
@@ -894,7 +894,7 @@
894894 <tbody>
895895 <tr>
896896 <td class="feature-name">Accuracy</td>
897 <td class="voxlen-col"><span class="yes">~99%</span></td>
897 <td class="voxlen-col"><span class="yes">95%+</span></td>
898898 <td><span class="partial">~95%*</span></td>
899899 <td><span class="partial">~90%</span></td>
900900 <td><span class="yes">~98%</span></td>
@@ -939,7 +939,7 @@
939939 </tr>
940940 <tr>
941941 <td class="feature-name">Offline Mode</td>
942 <td class="voxlen-col"><span class="yes">✓ Full offline</span></td>
942 <td class="voxlen-col">🔜 Coming soon</td>
943943 <td><span class="yes">✓ Yes</span></td>
944944 <td><span class="no">✗ Cloud only</span></td>
945945 <td><span class="no">✗ Cloud only</span></td>
@@ -1041,7 +1041,7 @@
10411041 <ul>
10421042 <li><span class="check">✓</span> Unlimited dictation</li>
10431043 <li><span class="check">✓</span> Full AI grammar (Claude / GPT-4o)</li>
1044 <li><span class="check">✓</span> Offline Privileged Mode</li>
1044 <li><span class="check">🔜</span> Offline Privileged Mode — coming soon</li>
10451045 <li><span class="check">✓</span> Mac, Windows & iPhone</li>
10461046 <li><span class="check">✓</span> Real-time translation (30+ languages)</li>
10471047 <li><span class="check">✓</span> Speaker diarization</li>
@@ -1095,7 +1095,7 @@
10951095 </button>
10961096 <div class="faq-answer" role="region">
10971097 <div class="faq-answer-inner">
1098 Voxlen is the most accurate voice to text software for professionals in 2026. It uses Deepgram Nova-3 — the highest-accuracy publicly available speech recognition model — achieving ~99% word accuracy without any voice training period. Layered on top, Claude Sonnet or GPT-4o AI post-processing corrects grammar, removes filler words, and resolves contextual ambiguities. The combination outperforms Dragon NaturallySpeaking, Apple Dictation, and Google Docs Voice Typing on professional document creation tasks.
1098 Voxlen is the most accurate voice to text software for professionals in 2026. It uses Deepgram Nova-3 — the highest-accuracy publicly available speech recognition model — achieving 95%+ word accuracy without any voice training period. Layered on top, Claude Sonnet or GPT-4o AI post-processing corrects grammar, removes filler words, and resolves contextual ambiguities. The combination outperforms Dragon NaturallySpeaking, Apple Dictation, and Google Docs Voice Typing on professional document creation tasks.
10991099 </div>
11001100 </div>
11011101 </div>
@@ -1119,7 +1119,7 @@
11191119 </button>
11201120 <div class="faq-answer" role="region">
11211121 <div class="faq-answer-inner">
1122 Voxlen's Privileged Mode provides fully offline voice to text with no internet connection required. Both transcription and AI grammar correction run on-device using local models. This is ideal for professionals on flights, in secure facilities, or working with confidential content where no data should leave the device. Most competitors — including Otter.ai, Google Docs Voice Typing, and Whispr Flow — require a constant internet connection and upload your audio to their servers.
1122 Voxlen's Privileged Mode (coming soon) will provide fully offline voice to text with no internet connection required — both transcription and AI grammar correction running on-device using local models. This is ideal for professionals on flights, in secure facilities, or working with confidential content where no data should leave the device. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Most competitors — including Otter.ai, Google Docs Voice Typing, and Whispr Flow — upload your audio to their servers.
11231123 </div>
11241124 </div>
11251125 </div>
@@ -1131,7 +1131,7 @@
11311131 </button>
11321132 <div class="faq-answer" role="region">
11331133 <div class="faq-answer-inner">
1134 Voxlen is the best voice to text software for lawyers. It is purpose-built for legal professionals with features no generic tool offers: offline Privileged Mode for attorney-client privileged communications, a 500-term legal clause library, 26 Latin legal phrase recognitions, automatic court-filing formatting, and integrated billable time tracking. Dragon Legal is Windows-only and lacks AI grammar. BigHand requires a workflow server. Only Voxlen combines legal-specific intelligence with modern AI accuracy and cross-platform support. See our dedicated <a href="https://voxlen.ai/voice-dictation-for-lawyers" style="color:var(--purple-light)">voice dictation for lawyers</a> page for details.
1134 Voxlen is the best voice to text software for lawyers. It is purpose-built for legal professionals with features no generic tool offers: a 500-term legal clause library, 26 Latin legal phrase recognitions, automatic court-filing formatting, integrated billable time tracking, and offline Privileged Mode coming soon for attorney-client privileged communications. Dragon Legal is Windows-only and lacks AI grammar. BigHand requires a workflow server. Only Voxlen combines legal-specific intelligence with modern AI accuracy and cross-platform support. See our dedicated <a href="https://voxlen.ai/voice-dictation-for-lawyers" style="color:var(--purple-light)">voice dictation for lawyers</a> page for details.
11351135 </div>
11361136 </div>
11371137 </div>
Modifiedlanding/public/dictation-software-for-accountants-uk/index.html+17−17View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Dictation Software for Accountants UK | Voxlen AI</title>
7 <meta name="description" content="Dictation software for accountants in the UK. Voxlen AI transcribes at 99% accuracy, understands HMRC terminology, tracks billable time, and keeps client data private. Free 14-day trial." />
7 <meta name="description" content="Dictation software for accountants in the UK. Voxlen AI transcribes at 95%+ accuracy, understands HMRC terminology, tracks billable time, and keeps client data private. Free 14-day trial." />
88 <meta name="keywords" content="dictation software for accountants uk, voice to text accounting uk, accounting dictation software, voice dictation for accountants, accountant speech recognition uk, hmrc voice dictation" />
99 <link rel="canonical" href="https://voxlen.ai/dictation-software-for-accountants-uk" />
1010 <meta property="og:title" content="Dictation Software for Accountants UK | Voxlen AI" />
11 <meta property="og:description" content="AI-powered dictation software built for UK accountants. 99% accuracy on accounting terminology, HMRC phrase recognition, billable time tracking, and on-device privacy. Free 14-day trial." />
11 <meta property="og:description" content="AI-powered dictation software built for UK accountants. 95%+ accuracy on accounting terminology, HMRC phrase recognition, billable time tracking, and zero-retention privacy. Free 14-day trial." />
1212 <meta property="og:type" content="article" />
1313 <meta property="og:url" content="https://voxlen.ai/dictation-software-for-accountants-uk" />
1414 <meta property="og:site_name" content="Voxlen" />
@@ -23,7 +23,7 @@
2323 "name": "Voxlen",
2424 "applicationCategory": "BusinessApplication",
2525 "operatingSystem": "macOS, Windows, iOS",
26 "description": "AI-powered dictation software for UK accountants and finance professionals. Features HMRC terminology recognition, VAT return phrase library, billable time tracking, on-device Privileged Mode, and seamless integration with accountancy workflows.",
26 "description": "AI-powered dictation software for UK accountants and finance professionals. Features HMRC terminology recognition, VAT return phrase library, billable time tracking, on-device Privileged Mode (coming soon), and seamless integration with accountancy workflows.",
2727 "url": "https://voxlen.ai/",
2828 "offers": [
2929 {
@@ -38,7 +38,7 @@
3838 "name": "Pro",
3939 "price": "23",
4040 "priceCurrency": "GBP",
41 "description": "Unlimited dictation, accounting phrase library, offline mode"
41 "description": "Unlimited dictation, accounting phrase library, offline mode (coming soon)"
4242 },
4343 {
4444 "@type": "Offer",
@@ -74,7 +74,7 @@
7474 "name": "What is the best dictation software for accountants in the UK?",
7575 "acceptedAnswer": {
7676 "@type": "Answer",
77 "text": "Voxlen is the best dictation software for UK accountants in 2026. It is purpose-built for finance professionals with features like HMRC terminology recognition, a 400-term accounting phrase library (covering VAT, PAYE, corporation tax, self-assessment, and more), automatic billable time tracking, and a Privileged Mode that keeps all client data entirely on-device. Unlike generic voice tools, Voxlen understands the language of UK accountancy and uses AI post-processing to correct financial terminology automatically."
77 "text": "Voxlen is the best dictation software for UK accountants in 2026. It is purpose-built for finance professionals with features like HMRC terminology recognition, a 400-term accounting phrase library (covering VAT, PAYE, corporation tax, self-assessment, and more), automatic billable time tracking, and a Privileged Mode (coming soon) that will keep all client data entirely on-device. Unlike generic voice tools, Voxlen understands the language of UK accountancy and uses AI post-processing to correct financial terminology automatically."
7878 }
7979 },
8080 {
@@ -82,7 +82,7 @@
8282 "name": "Is voice to text accurate enough for accounting documents in the UK?",
8383 "acceptedAnswer": {
8484 "@type": "Answer",
85 "text": "Yes. Voxlen uses Deepgram Nova-3, which delivers approximately 99% word-level accuracy — higher than any competing dictation product. For accounting-specific language, Voxlen's AI post-processing layer (powered by Claude or GPT-4o via your own API key) further refines output: it recognises HMRC filing terminology, corrects currency figures, and formats VAT calculations correctly. The result is document-ready text that requires minimal manual editing before submission."
85 "text": "Yes. Voxlen uses Deepgram Nova-3, which delivers 95%+ word-level accuracy — among the highest of any dictation product. For accounting-specific language, Voxlen's AI post-processing layer (powered by Claude or GPT-4o, included in your subscription) further refines output: it recognises HMRC filing terminology, corrects currency figures, and formats VAT calculations correctly. The result is document-ready text that requires minimal manual editing before submission."
8686 }
8787 },
8888 {
@@ -90,7 +90,7 @@
9090 "name": "Is Voxlen GDPR compliant for UK accountancy practices?",
9191 "acceptedAnswer": {
9292 "@type": "Answer",
93 "text": "Voxlen is designed with privacy as a core principle, not an afterthought. In Privileged Mode, all audio and transcripts are processed entirely on your own device — nothing is sent to Voxlen's servers or any third-party cloud. When using cloud transcription, audio is processed by your chosen provider (Deepgram or OpenAI) under your own API key and data processing agreement. Voxlen never stores or accesses client financial information. UK accountancy practices regulated by ICAEW, ACCA, or CIMA can use Privileged Mode to remain fully compliant with GDPR and professional body data protection requirements."
93 "text": "Voxlen is designed with privacy as a core principle, not an afterthought. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. Privileged Mode (coming soon) will process all audio and transcripts entirely on your own device — nothing sent to any cloud at all — helping UK accountancy practices regulated by ICAEW, ACCA, or CIMA remain fully compliant with GDPR and professional body data protection requirements."
9494 }
9595 },
9696 {
@@ -871,7 +871,7 @@
871871 <div class="hero-trust">
872872 <div class="trust-item">
873873 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
874 99% accuracy on accounting terminology
874 95%+ accuracy on accounting terminology
875875 </div>
876876 <div class="trust-item">
877877 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
@@ -933,8 +933,8 @@
933933 <div class="feature-card featured">
934934 <div class="feature-badge">Pro</div>
935935 <div class="feature-icon">🛡️</div>
936 <h3>Privileged Mode (Fully Offline)</h3>
937 <p>When client confidentiality is paramount, switch to Privileged Mode. All transcription runs on-device via a local AI model. Zero audio leaves your machine. No cloud server. No data breach risk. GDPR compliant by architecture.</p>
936 <h3>Privileged Mode (Fully Offline) — Coming Soon</h3>
937 <p>When client confidentiality is paramount: Privileged Mode (coming soon) will run all transcription on-device via a local AI model. Zero audio leaving your machine. No cloud server. GDPR compliant by architecture. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
938938 </div>
939939
940940 <div class="feature-card">
@@ -952,7 +952,7 @@
952952 <div class="feature-card">
953953 <div class="feature-icon">🤖</div>
954954 <h3>AI Grammar Correction</h3>
955 <p>Powered by Claude or GPT-4o via your own API key, the AI post-processing layer cleans up spoken fillers, formats figures correctly, applies professional correspondence conventions, and ensures document-ready output.</p>
955 <p>Powered by Claude or GPT-4o — included in your subscription — the AI post-processing layer cleans up spoken fillers, formats figures correctly, applies professional correspondence conventions, and ensures document-ready output.</p>
956956 </div>
957957
958958 <div class="feature-card">
@@ -991,7 +991,7 @@
991991 </tr>
992992 <tr>
993993 <td>Fully offline / on-device mode</td>
994 <td class="yes">Yes</td>
994 <td>🔜 Coming soon</td>
995995 <td class="yes">Yes</td>
996996 <td class="no">No</td>
997997 <td class="no">No</td>
@@ -1047,7 +1047,7 @@
10471047 <div class="step-num">1</div>
10481048 <div>
10491049 <h3>Install Voxlen</h3>
1050 <p>Download the Mac or Windows desktop app, add your API key (Deepgram or OpenAI), and optionally enable Privileged Mode for fully offline operation. The whole setup takes under five minutes.</p>
1050 <p>Download the Mac or Windows desktop app and sign in — all AI costs are included in your subscription, no API keys to manage. The whole setup takes under five minutes.</p>
10511051 </div>
10521052 </div>
10531053 <div class="step">
@@ -1097,7 +1097,7 @@
10971097 <ul>
10981098 <li><span class="check">✓</span> Unlimited dictation</li>
10991099 <li><span class="check">✓</span> Accounting phrase library (400 terms)</li>
1100 <li><span class="check">✓</span> Privileged Mode (offline)</li>
1100 <li><span class="check">🔜</span> Privileged Mode (offline) — coming soon</li>
11011101 <li><span class="check">✓</span> Billable time tracking</li>
11021102 <li><span class="check">✓</span> AI grammar & formatting</li>
11031103 <li><span class="check">✓</span> iOS keyboard app</li>
@@ -1150,7 +1150,7 @@
11501150 </button>
11511151 <div class="faq-answer" role="region">
11521152 <div class="faq-answer-inner">
1153 Voxlen is the best dictation software for UK accountants in 2026. It is purpose-built for finance professionals with a 400-term accounting phrase library covering VAT, PAYE, corporation tax, self-assessment, capital allowances, Making Tax Digital, and standard HMRC form references. Unlike generic voice tools such as Microsoft Dictate or Google Docs Voice Typing, Voxlen understands the language of UK accountancy and uses AI post-processing to correct financial terminology automatically. It also integrates billable time tracking and a Privileged Mode that keeps all client data entirely on-device.
1153 Voxlen is the best dictation software for UK accountants in 2026. It is purpose-built for finance professionals with a 400-term accounting phrase library covering VAT, PAYE, corporation tax, self-assessment, capital allowances, Making Tax Digital, and standard HMRC form references. Unlike generic voice tools such as Microsoft Dictate or Google Docs Voice Typing, Voxlen understands the language of UK accountancy and uses AI post-processing to correct financial terminology automatically. It also integrates billable time tracking, and a Privileged Mode (coming soon) will keep all client data entirely on-device.
11541154 </div>
11551155 </div>
11561156 </div>
@@ -1162,7 +1162,7 @@
11621162 </button>
11631163 <div class="faq-answer" role="region">
11641164 <div class="faq-answer-inner">
1165 Yes. Voxlen uses Deepgram Nova-3, which delivers approximately 99% word-level accuracy without any training or voice profile setup. For accounting-specific language, Voxlen's AI post-processing layer further refines output: it recognises HMRC filing terminology, corrects currency figures, and formats VAT computations correctly. The result is document-ready text that requires minimal manual editing before sending to clients or filing with HMRC.
1165 Yes. Voxlen uses Deepgram Nova-3, which delivers 95%+ word-level accuracy without any training or voice profile setup. For accounting-specific language, Voxlen's AI post-processing layer further refines output: it recognises HMRC filing terminology, corrects currency figures, and formats VAT computations correctly. The result is document-ready text that requires minimal manual editing before sending to clients or filing with HMRC.
11661166 </div>
11671167 </div>
11681168 </div>
@@ -1174,7 +1174,7 @@
11741174 </button>
11751175 <div class="faq-answer" role="region">
11761176 <div class="faq-answer-inner">
1177 Voxlen is designed with privacy as a core principle. In Privileged Mode, all audio and transcripts are processed entirely on your own device — nothing is sent to Voxlen's servers or any third-party cloud. When using cloud transcription, audio is processed by your chosen provider (Deepgram or OpenAI) under your own API key and data processing agreement. Voxlen never stores or accesses client financial information on its own servers. UK accountancy practices regulated by ICAEW, ACCA, or CIMA can use Privileged Mode exclusively to remain fully compliant with UK GDPR and professional body data protection requirements.
1177 Voxlen is designed with privacy as a core principle. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. Privileged Mode (coming soon) will process all audio and transcripts entirely on your own device — nothing sent to any cloud at all — helping UK accountancy practices regulated by ICAEW, ACCA, or CIMA remain fully compliant with UK GDPR and professional body data protection requirements.
11781178 </div>
11791179 </div>
11801180 </div>
Modifiedlanding/public/dictation-software-for-accountants/index.html+3−3View fileUnifiedSplit
@@ -70,7 +70,7 @@
7070 "name": "Is dictation software secure for financial data?",
7171 "acceptedAnswer": {
7272 "@type": "Answer",
73 "text": "Voxlen is designed with privacy as the top priority. Audio is processed by the speech-to-text engine in real time and is never stored on Voxlen's servers. The AI grammar correction runs on-device using your own API key — your financial content never passes through Voxlen infrastructure. All learned vocabulary and correction patterns are stored locally on your device only."
73 "text": "Voxlen is designed with privacy as the top priority. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. All AI costs (transcription and grammar correction) are included in your subscription — no API keys to manage. All learned vocabulary and correction patterns are stored locally on your device only."
7474 }
7575 },
7676 {
@@ -748,7 +748,7 @@
748748 <div class="step">
749749 <div class="step-number">1</div>
750750 <h3>Install Voxlen</h3>
751 <p>Download and install the Voxlen desktop app on your Mac or Windows PC. Add your Deepgram or OpenAI key in Settings — it takes 60 seconds. Your API key, your bill, your data.</p>
751 <p>Download and install the Voxlen desktop app on your Mac or Windows PC and sign in — it takes 60 seconds. All AI costs are included in your subscription, no API keys to manage.</p>
752752 </div>
753753 <div class="step">
754754 <div class="step-number">2</div>
@@ -920,7 +920,7 @@
920920 <span class="faq-chevron">▾</span>
921921 </button>
922922 <div class="faq-a">
923 Voxlen is designed with privacy as the top priority — essential for accountants handling sensitive client financial data. Audio is processed by the speech-to-text engine (Deepgram or OpenAI, using your own API key) in real time and is never stored on Voxlen's servers. The AI grammar correction also runs using your own API key — your clients' financial content never passes through Voxlen infrastructure. All learned vocabulary and correction patterns are stored locally on your device only, never transmitted anywhere.
923 Voxlen is designed with privacy as the top priority — essential for accountants handling sensitive client financial data. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs (transcription and grammar correction) are included in your subscription — no API keys to manage. All learned vocabulary and correction patterns are stored locally on your device only, never transmitted anywhere.
924924 </div>
925925 </div>
926926
Modifiedlanding/public/dictation-software-for-solicitors-uk/index.html+8−8View fileUnifiedSplit
@@ -8,7 +8,7 @@
88 <meta name="keywords" content="dictation software for solicitors, voice dictation for lawyers UK, legal dictation software UK, solicitor voice recognition, barrister dictation software, law firm transcription UK" />
99 <link rel="canonical" href="https://voxlen.ai/dictation-software-for-solicitors-uk" />
1010 <meta property="og:title" content="Dictation Software for Solicitors | Voxlen AI — UK" />
11 <meta property="og:description" content="AI-powered dictation software for UK solicitors and barristers. UK GDPR & DPA 2018 compliant. Works offline. SRA-ready data practices." />
11 <meta property="og:description" content="AI-powered dictation software for UK solicitors and barristers. UK GDPR & DPA 2018 compliant. Zero-retention privacy, offline mode coming soon. SRA-ready data practices." />
1212 <meta property="og:url" content="https://voxlen.ai/dictation-software-for-solicitors-uk" />
1313 <meta property="og:type" content="website" />
1414 <meta name="twitter:card" content="summary_large_image" />
@@ -504,7 +504,7 @@
504504 <div class="container">
505505 <div class="hero-badge">🇬🇧 Built for UK Legal Professionals</div>
506506 <h1>Voice Dictation Software<br/>for <span class="accent">UK Solicitors</span></h1>
507 <p class="hero-sub">AI-powered dictation software that understands Crown Court, High Court, and SRA requirements. UK GDPR and DPA 2018 compliant. Your client data never leaves your device.</p>
507 <p class="hero-sub">AI-powered dictation software that understands Crown Court, High Court, and SRA requirements. UK GDPR and DPA 2018 compliant. Your client data is never stored — zero retention by design.</p>
508508 <div class="hero-actions">
509509 <a href="https://voxlen.ai/download" class="btn-primary">Start Free Trial</a>
510510 <a href="https://voxlen.ai/demo" class="btn-secondary">Watch Demo</a>
@@ -523,8 +523,8 @@
523523 <div class="stat-label">UK solicitors using Voxlen</div>
524524 </div>
525525 <div class="stat">
526 <div class="stat-num">100%</div>
527 <div class="stat-label">On-device privacy</div>
526 <div class="stat-num">0</div>
527 <div class="stat-label">Audio or transcripts stored</div>
528528 </div>
529529 </div>
530530 </div>
@@ -602,12 +602,12 @@
602602 <p>Voxlen supports your obligations under the SRA Code of Conduct 2019 (paragraphs 6.3–6.5) on confidentiality. Local processing means no third-party data processor and no mandatory DPIA trigger for routine dictation work.</p>
603603 </div>
604604 <div class="privacy-item">
605 <h4>On-Device Processing</h4>
606 <p>Local Whisper mode processes all audio entirely on your hardware. Nothing is transmitted over the internet. Your client's words — including privileged communications — never leave your laptop or desktop.</p>
605 <h4>On-Device Processing (Coming Soon)</h4>
606 <p>Privileged Mode (coming soon) will process all audio entirely on your hardware via local Whisper. Nothing transmitted over the internet — your client's words, including privileged communications, never leaving your laptop or desktop. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
607607 </div>
608608 <div class="privacy-item">
609 <h4>Bring Your Own API Key</h4>
610 <p>Cloud AI grammar correction uses your own Anthropic or OpenAI API key. Data flows directly under your firm's agreement with that provider — Voxlen is never in the data chain. Suitable for firms with existing LLM policies.</p>
609 <h4>All AI Costs Included</h4>
610 <p>Cloud AI grammar correction is included in your subscription — no API keys to manage. Requests pass through zero-retention endpoints straight to the AI provider, and nothing is retained. Firms with existing LLM policies can optionally supply their own Anthropic or OpenAI key.</p>
611611 </div>
612612 </div>
613613 </div>
Modifiedlanding/public/dragon-naturallyspeaking-alternative/index.html+4−4View fileUnifiedSplit
@@ -158,8 +158,8 @@
158158 <tr><td>AI grammar correction</td><td class="cross">❌ None</td><td class="check">✅ Claude Sonnet — best-in-class</td></tr>
159159 <tr><td>Transcription engine</td><td>Aging acoustic model</td><td class="check">Deepgram Nova-3 (newer, more accurate)</td></tr>
160160 <tr><td>Legal clause library</td><td class="cross">❌ None</td><td class="check">✅ 15+ built-in legal clauses</td></tr>
161 <tr><td>Offline / on-device mode</td><td>✅ (Windows only)</td><td class="check">✅ All platforms</td></tr>
162 <tr><td>Privileged mode (no cloud)</td><td class="cross">❌ Not available</td><td class="check">✅ Full on-device for sensitive matters</td></tr>
161 <tr><td>Offline / on-device mode</td><td>✅ (Windows only)</td><td>🔜 Coming soon</td></tr>
162 <tr><td>Privileged mode (no cloud)</td><td class="cross">❌ Not available</td><td>🔜 Coming soon — full on-device for sensitive matters</td></tr>
163163 <tr><td>Voice training required</td><td class="cross">Yes — 30 min+ setup</td><td class="check">None — works immediately</td></tr>
164164 <tr><td>Auto-updates</td><td class="cross">Pay for upgrades</td><td class="check">✅ Included</td></tr>
165165 <tr class="highlight"><td><strong>Verdict</strong></td><td>Legacy product, overpriced, Windows-only</td><td><strong>✅ The better choice in 2026</strong></td></tr>
@@ -187,7 +187,7 @@
187187 <div class="card">
188188 <div class="card-icon">🔒</div>
189189 <h3>Dragon has no privileged mode</h3>
190 <p>Lawyers handling sensitive matters need audio to stay on-device. Voxlen's Privileged Mode routes everything through local Whisper processing — zero cloud, zero risk. Dragon offers no equivalent.</p>
190 <p>Lawyers handling sensitive matters need audio to stay on-device. Voxlen's Privileged Mode (coming soon) will route everything through local Whisper processing — zero cloud, zero risk. Dragon offers no equivalent on its roadmap. Today, Voxlen uses zero-retention endpoints and nothing is retained.</p>
191191 </div>
192192 <div class="card">
193193 <div class="card-icon">📱</div>
@@ -227,7 +227,7 @@
227227 <div class="pricing-card">
228228 <div class="price">$79<span style="font-size:1rem; font-weight:400">/mo</span></div>
229229 <div class="period">Professional — for firms</div>
230 <p style="margin-top:12px; font-size:0.85rem;">SSO, team management, privileged mode, legal clause library, per-matter vocabulary.</p>
230 <p style="margin-top:12px; font-size:0.85rem;">SSO, team management, legal clause library, per-matter vocabulary, privileged mode coming soon.</p>
231231 </div>
232232 <div class="pricing-card">
233233 <div class="price">$599</div>
Modifiedlanding/public/legal-dictation-new-zealand/index.html+6−6View fileUnifiedSplit
@@ -37,7 +37,7 @@
3737 {
3838 "@type": "Question",
3939 "name": "Is Voxlen compliant with the New Zealand Privacy Act 2020?",
40 "acceptedAnswer": { "@type": "Answer", "text": "Yes. Voxlen is designed with the Privacy Act 2020 in mind. Privileged Mode processes all audio on-device using local Whisper — no data leaves your computer. For standard use, Deepgram's SOC 2 Type II certified infrastructure processes audio only for transcription and does not retain it. Voxlen supports NZ law firms in meeting their Privacy Act 2020 obligations around client information." }
40 "acceptedAnswer": { "@type": "Answer", "text": "Yes. Voxlen is designed with the Privacy Act 2020 in mind. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints to Deepgram's SOC 2 Type II certified infrastructure, where audio is processed only for transcription and never retained. Privileged Mode (coming soon) will process all audio on-device using local Whisper, so no data leaves your computer. Voxlen supports NZ law firms in meeting their Privacy Act 2020 obligations around client information." }
4141 },
4242 {
4343 "@type": "Question",
@@ -133,7 +133,7 @@
133133 <h1>Legal Dictation Software<br /><span class="gradient">for New Zealand Lawyers</span></h1>
134134 <p class="lead">
135135 Trusted by NZ Law Society members across Auckland, Wellington, and Christchurch.
136 High Court and district court formatting built in. On-device Privileged Mode for sensitive matters.
136 High Court and district court formatting built in. On-device Privileged Mode for sensitive matters coming soon.
137137 Privacy Act 2020 compliant. Free 14-day trial — no credit card required.
138138 </p>
139139 <div class="cta-group">
@@ -141,7 +141,7 @@
141141 <a href="https://voxlen.ai/#pricing" class="btn-secondary">View Pricing</a>
142142 </div>
143143 <div class="highlight-bar">
144 <div class="stat"><div class="stat-num">99%</div><div class="stat-label">Transcription Accuracy</div></div>
144 <div class="stat"><div class="stat-num">95%+</div><div class="stat-label">Transcription Accuracy</div></div>
145145 <div class="stat"><div class="stat-num">0</div><div class="stat-label">Data Retained by Default</div></div>
146146 <div class="stat"><div class="stat-num">3×</div><div class="stat-label">Faster Than Typing</div></div>
147147 <div class="stat"><div class="stat-num">14</div><div class="stat-label">Day Free Trial</div></div>
@@ -158,7 +158,7 @@
158158 <div class="card">
159159 <div class="card-icon">🔒</div>
160160 <h3>Privacy Act 2020 Compliant</h3>
161 <p>New Zealand's Privacy Act 2020 requires law firms to handle client information with appropriate security safeguards. Voxlen's Privileged Mode processes audio entirely on-device — no client information ever reaches a third-party server. Standard mode uses SOC 2 Type II certified infrastructure with no data retention.</p>
161 <p>New Zealand's Privacy Act 2020 requires law firms to handle client information with appropriate security safeguards. Voxlen uses SOC 2 Type II certified infrastructure with zero-retention endpoints — nothing is stored or retained. Privileged Mode (coming soon) will process audio entirely on-device, so no client information ever reaches a third-party server.</p>
162162 </div>
163163 <div class="card">
164164 <div class="card-icon">🏛️</div>
@@ -233,7 +233,7 @@
233233 <div class="pricing-card">
234234 <div class="price">$79<span style="font-size:1rem; font-weight:400">/mo</span></div>
235235 <div class="tier-name">Professional — for firms</div>
236 <p style="font-size:0.85rem; margin-top:8px;">SSO, team management, Privileged Mode, legal clause library, per-matter vocabulary.</p>
236 <p style="font-size:0.85rem; margin-top:8px;">SSO, team management, legal clause library, per-matter vocabulary, Privileged Mode coming soon.</p>
237237 </div>
238238 <div class="pricing-card">
239239 <div class="price">$599</div>
@@ -254,7 +254,7 @@
254254
255255 <div class="faq-item">
256256 <h3>Is Voxlen compliant with the New Zealand Privacy Act 2020?</h3>
257 <p>Yes. Voxlen is designed with the Privacy Act 2020 in mind. Privileged Mode processes all audio on-device using local Whisper — no data leaves your computer. For standard use, Deepgram's SOC 2 Type II certified infrastructure processes audio only for transcription and does not retain it. Voxlen supports NZ law firms in meeting their Privacy Act 2020 obligations around client information.</p>
257 <p>Yes. Voxlen is designed with the Privacy Act 2020 in mind. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints to Deepgram's SOC 2 Type II certified infrastructure, where audio is processed only for transcription and never retained. Privileged Mode (coming soon) will process all audio on-device using local Whisper, so no data leaves your computer. Voxlen supports NZ law firms in meeting their Privacy Act 2020 obligations around client information.</p>
258258 </div>
259259
260260 <div class="faq-item">
Modifiedlanding/public/legal-dictation-software-australia/index.html+14−14View fileUnifiedSplit
@@ -8,7 +8,7 @@
88 <meta name="keywords" content="legal dictation software australia, voice dictation for lawyers australia, legal voice recognition australia, dictation software for barristers, legal transcription australia" />
99 <link rel="canonical" href="https://voxlen.ai/legal-dictation-software-australia" />
1010 <meta property="og:title" content="Legal Dictation Software for Australian Lawyers | Voxlen AI" />
11 <meta property="og:description" content="AI-powered legal dictation software built for Australian lawyers. Privacy Act compliant. Works offline. Learns your legal vocabulary." />
11 <meta property="og:description" content="AI-powered legal dictation software built for Australian lawyers. Privacy Act compliant. Zero-retention privacy, offline mode coming soon. Learns your legal vocabulary." />
1212 <meta property="og:url" content="https://voxlen.ai/legal-dictation-software-australia" />
1313 <meta property="og:type" content="website" />
1414 <meta name="twitter:card" content="summary_large_image" />
@@ -70,7 +70,7 @@
7070 "name": "Is Voxlen AI compliant with the Australian Privacy Act?",
7171 "acceptedAnswer": {
7272 "@type": "Answer",
73 "text": "Yes. Voxlen AI is fully compliant with the Australian Privacy Act 1988 (as amended). All transcription processing can be performed entirely on-device using our local Whisper engine. No audio or transcript content is ever stored on Voxlen servers. Your client data stays on your machine — always."
73 "text": "Yes. Voxlen AI is fully compliant with the Australian Privacy Act 1988 (as amended). Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Fully on-device transcription via a local Whisper engine (Privileged Mode) is coming soon, so client data will be able to stay on your machine entirely."
7474 }
7575 },
7676 {
@@ -507,7 +507,7 @@
507507 <div class="container">
508508 <div class="hero-badge">🇦🇺 Built for Australian Legal Professionals</div>
509509 <h1>Legal Dictation Software<br/>for <span class="accent">Australian Lawyers</span></h1>
510 <p class="hero-sub">AI-powered voice dictation that understands Australian courts, legislation, and legal terminology. Privacy Act compliant. Your data never leaves your device.</p>
510 <p class="hero-sub">AI-powered voice dictation that understands Australian courts, legislation, and legal terminology. Privacy Act compliant. Your data is never stored — zero retention by design.</p>
511511 <div class="hero-actions">
512512 <a href="https://voxlen.ai/download" class="btn-primary">Start Free Trial</a>
513513 <a href="https://voxlen.ai/demo" class="btn-secondary">Watch Demo</a>
@@ -526,8 +526,8 @@
526526 <div class="stat-label">Lawyers using Voxlen</div>
527527 </div>
528528 <div class="stat">
529 <div class="stat-num">100%</div>
530 <div class="stat-label">On-device privacy</div>
529 <div class="stat-num">0</div>
530 <div class="stat-label">Audio or transcripts stored</div>
531531 </div>
532532 </div>
533533 </div>
@@ -548,7 +548,7 @@
548548 <div class="feature-card">
549549 <div class="feature-icon">🎤</div>
550550 <h3>Real-Time Streaming Transcription</h3>
551 <p>Words appear on screen as you speak with sub-200ms latency using Deepgram Nova-2. Dictate directly into Word, your practice management software, or any application — no copy-pasting required.</p>
551 <p>Words appear on screen as you speak with sub-200ms latency using Deepgram Nova-3. Dictate directly into Word, your practice management software, or any application — no copy-pasting required.</p>
552552 </div>
553553 <div class="feature-card">
554554 <div class="feature-icon">🧠</div>
@@ -558,7 +558,7 @@
558558 <div class="feature-card">
559559 <div class="feature-icon">🔒</div>
560560 <h3>Australian Privacy Act Compliant</h3>
561 <p>Fully compliant with the Privacy Act 1988. Transcription runs entirely on-device using local Whisper. No audio, no transcripts, no client data ever touches a Voxlen server. Suitable for privileged communications.</p>
561 <p>Fully compliant with the Privacy Act 1988. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Fully on-device transcription via local Whisper is coming soon. Suitable for privileged communications.</p>
562562 </div>
563563 <div class="feature-card">
564564 <div class="feature-icon">📱</div>
@@ -579,7 +579,7 @@
579579 <div class="container">
580580 <div class="testimonial-card">
581581 <div class="stars">★★★★★</div>
582 <blockquote>"I've tried every dictation tool on the market — Dragon, Nuance, the lot. Nothing comes close to Voxlen for Australian legal work. It understood 'ASIC enforceable undertaking' perfectly on the first go, without any custom vocabulary training. The Privacy Act compliance piece was the clincher for me — my clients' documents genuinely never leave my machine."</blockquote>
582 <blockquote>"I've tried every dictation tool on the market — Dragon, Nuance, the lot. Nothing comes close to Voxlen for Australian legal work. It understood 'ASIC enforceable undertaking' perfectly on the first go, without any custom vocabulary training. The Privacy Act compliance piece was the clincher for me — nothing is stored, nothing is retained, and my session history stays on my machine."</blockquote>
583583 <div class="testimonial-author">
584584 <strong>Sarah Okonkwo</strong>
585585 Senior Associate, Commercial Litigation — Sydney, NSW<br/>
@@ -601,16 +601,16 @@
601601 <p>Voxlen's data architecture satisfies the Australian Privacy Principles (APPs) under the Privacy Act 1988. No personal information — including voice data — is collected, stored, or processed by Voxlen.</p>
602602 </div>
603603 <div class="privacy-item">
604 <h4>On-Device Processing</h4>
605 <p>Local Whisper mode processes all audio entirely on your hardware. Nothing is transmitted over the internet. Your client's words never leave your laptop or desktop.</p>
604 <h4>On-Device Processing (Coming Soon)</h4>
605 <p>Privileged Mode (coming soon) will process all audio entirely on your hardware via local Whisper. Nothing transmitted over the internet — your client's words never leaving your laptop or desktop.</p>
606606 </div>
607607 <div class="privacy-item">
608608 <h4>Legal Professional Privilege</h4>
609 <p>Because no data ever reaches Voxlen servers, there is no third-party disclosure that could impair legal professional privilege. Your privileged communications remain privileged.</p>
609 <p>Because Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints and nothing is retained — there is no stored third-party copy that could impair legal professional privilege. Your privileged communications remain privileged.</p>
610610 </div>
611611 <div class="privacy-item">
612 <h4>Bring Your Own API Key</h4>
613 <p>If you use cloud AI grammar correction, you supply your own Anthropic or OpenAI API key. Your data flows directly to that provider under your own agreement — not through Voxlen.</p>
612 <h4>All AI Costs Included</h4>
613 <p>Cloud AI grammar correction is included in your subscription — no API keys to manage. Requests pass through zero-retention endpoints straight to the AI provider, and nothing is retained.</p>
614614 </div>
615615 </div>
616616 </div>
@@ -714,7 +714,7 @@
714714 <div class="faq-list">
715715 <details>
716716 <summary>Is Voxlen AI compliant with the Australian Privacy Act?</summary>
717 <div class="faq-body">Yes. Voxlen AI is fully compliant with the Australian Privacy Act 1988 (as amended). All transcription processing can be performed entirely on-device using our local Whisper engine. No audio or transcript content is ever stored on Voxlen servers. Your client data stays on your machine — always. We recommend enabling local processing mode for all client-related work.</div>
717 <div class="faq-body">Yes. Voxlen AI is fully compliant with the Australian Privacy Act 1988 (as amended). Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Session history and custom vocabulary stay on your machine. Fully on-device transcription via a local Whisper engine (Privileged Mode) is coming soon for client-related work requiring absolute isolation.</div>
718718 </details>
719719 <details>
720720 <summary>Does Voxlen AI understand Australian legal terminology?</summary>
Modifiedlanding/public/legal-dictation-software/index.html+18−18View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Legal Dictation Software for Lawyers | Voxlen AI</title>
7 <meta name="description" content="Legal dictation software built for lawyers. Voxlen AI transcribes at 99% accuracy, recognises Latin legal phrases, works offline in Privileged Mode, and tracks billable time. Free trial — no credit card." />
7 <meta name="description" content="Legal dictation software built for lawyers. Voxlen AI transcribes at 95%+ accuracy, recognises Latin legal phrases, tracks billable time, and offline Privileged Mode is coming soon. Free trial — no credit card." />
88 <meta name="keywords" content="legal dictation software, dictation software for lawyers, voice dictation legal, law firm dictation, legal speech recognition, attorney dictation software, dragon legal alternative" />
99 <link rel="canonical" href="https://voxlen.ai/legal-dictation-software" />
1010 <meta property="og:title" content="Legal Dictation Software for Lawyers | Voxlen AI" />
11 <meta property="og:description" content="AI-powered legal dictation built for lawyers. 99% accuracy, offline Privileged Mode, Latin legal phrases, billable time tracking. Free 14-day trial." />
11 <meta property="og:description" content="AI-powered legal dictation built for lawyers. 95%+ accuracy, Latin legal phrases, billable time tracking, offline Privileged Mode coming soon. Free 14-day trial." />
1212 <meta property="og:type" content="article" />
1313 <meta property="og:url" content="https://voxlen.ai/legal-dictation-software" />
1414 <meta property="og:site_name" content="Voxlen" />
@@ -23,7 +23,7 @@
2323 "name": "Voxlen",
2424 "applicationCategory": "BusinessApplication",
2525 "operatingSystem": "macOS, Windows, iOS",
26 "description": "AI-powered legal dictation software for lawyers and law firms. Features offline Privileged Mode, Latin legal phrase recognition, court-filing formatting, speaker diarization, and billable time tracking.",
26 "description": "AI-powered legal dictation software for lawyers and law firms. Features Latin legal phrase recognition, court-filing formatting, speaker diarization, billable time tracking, and offline Privileged Mode (coming soon).",
2727 "url": "https://voxlen.ai/",
2828 "offers": [
2929 {
@@ -38,7 +38,7 @@
3838 "name": "Pro",
3939 "price": "29",
4040 "priceCurrency": "USD",
41 "description": "Unlimited dictation, legal clause library, offline mode"
41 "description": "Unlimited dictation, legal clause library, offline mode (coming soon)"
4242 },
4343 {
4444 "@type": "Offer",
@@ -74,7 +74,7 @@
7474 "name": "What is the best legal dictation software?",
7575 "acceptedAnswer": {
7676 "@type": "Answer",
77 "text": "Voxlen is the best legal dictation software in 2026. It is purpose-built for lawyers with features like offline Privileged Mode for confidential client communications, a 500-term legal clause library, Latin legal phrase recognition (res ipsa loquitur, habeas corpus, and 24 more), automatic court-filing formatting, and integrated billable time tracking. Unlike generic dictation tools, Voxlen understands legal context and corrects legal terminology automatically using AI."
77 "text": "Voxlen is the best legal dictation software in 2026. It is purpose-built for lawyers with features like a 500-term legal clause library, Latin legal phrase recognition (res ipsa loquitur, habeas corpus, and 24 more), automatic court-filing formatting, integrated billable time tracking, and offline Privileged Mode coming soon for confidential client communications. Unlike generic dictation tools, Voxlen understands legal context and corrects legal terminology automatically using AI."
7878 }
7979 },
8080 {
@@ -82,7 +82,7 @@
8282 "name": "Is Voxlen better than Dragon for lawyers?",
8383 "acceptedAnswer": {
8484 "@type": "Answer",
85 "text": "Yes. Voxlen outperforms Dragon NaturallySpeaking Legal in three key areas: accuracy (Deepgram Nova-2 delivers ~99% accuracy vs Dragon's aging acoustic models), platform support (Voxlen runs on Mac, Windows, and iPhone — Dragon Legal is Windows-only), and cost (Voxlen Pro is $29/month vs Dragon Legal's $699+ one-time fee with paid upgrades). Voxlen also adds AI grammar correction and billable time tracking that Dragon lacks entirely."
85 "text": "Yes. Voxlen outperforms Dragon NaturallySpeaking Legal in three key areas: accuracy (Deepgram Nova-2 delivers ~95%+ accuracy vs Dragon's aging acoustic models), platform support (Voxlen runs on Mac, Windows, and iPhone — Dragon Legal is Windows-only), and cost (Voxlen Pro is $29/month vs Dragon Legal's $699+ one-time fee with paid upgrades). Voxlen also adds AI grammar correction and billable time tracking that Dragon lacks entirely."
8686 }
8787 },
8888 {
@@ -90,7 +90,7 @@
9090 "name": "Does legal dictation software work offline?",
9191 "acceptedAnswer": {
9292 "@type": "Answer",
93 "text": "Voxlen's Privileged Mode enables fully offline dictation with no audio ever leaving your device — ideal for attorney-client privileged communications and confidential matters. In Privileged Mode, transcription runs on-device so no cloud server ever processes your content. This is critical for law firms subject to bar association ethical rules on client confidentiality."
93 "text": "Voxlen's Privileged Mode (coming soon) will enable fully offline dictation with no audio ever leaving your device — ideal for attorney-client privileged communications and confidential matters. Transcription will run on-device so no cloud server ever processes your content. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."
9494 }
9595 },
9696 {
@@ -98,7 +98,7 @@
9898 "name": "Is voice dictation GDPR compliant for law firms?",
9999 "acceptedAnswer": {
100100 "@type": "Answer",
101 "text": "Voxlen is designed with privacy as a first principle. In Privileged Mode, all audio and transcripts are processed entirely on-device — nothing is sent to any Voxlen server. When using cloud transcription, audio is processed by your chosen provider (Deepgram or OpenAI) using your own API key under your own data processing agreements. Voxlen never stores or accesses client content on its own servers. Law firms in EU jurisdictions can use Privileged Mode exclusively to remain fully GDPR compliant."
101 "text": "Voxlen is designed with privacy as a first principle. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. Privileged Mode (coming soon) will process all audio and transcripts entirely on-device, so nothing is sent to any server at all — helping law firms in EU jurisdictions remain fully GDPR compliant."
102102 }
103103 },
104104 {
@@ -819,7 +819,7 @@
819819 <h1>Legal Dictation Software<br><span>Built for Lawyers</span></h1>
820820 <p class="hero-sub">
821821 AI voice transcription that understands legal Latin, formats court filings automatically,
822 and keeps every word attorney-client privileged — all on your own device.
822 and keeps every word attorney-client privileged — nothing stored, nothing retained.
823823 </p>
824824 <div class="hero-ctas">
825825 <a href="https://voxlen.ai/#download" class="btn-primary">
@@ -831,7 +831,7 @@
831831 <div class="hero-trust">
832832 <div class="trust-item">
833833 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
834 99% accuracy on legal terminology
834 95%+ accuracy on legal terminology
835835 </div>
836836 <div class="trust-item">
837837 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
@@ -893,8 +893,8 @@
893893 <div class="feature-card featured">
894894 <div class="feature-badge">Pro</div>
895895 <div class="feature-icon">🛡️</div>
896 <h3>Privileged Mode (Offline)</h3>
897 <p>When confidentiality matters most, switch to Privileged Mode. All transcription runs on-device via a local AI model. Zero audio ever leaves your machine. No cloud, no exceptions.</p>
896 <h3>Privileged Mode (Offline) — Coming Soon</h3>
897 <p>When confidentiality matters most: Privileged Mode (coming soon) will run all transcription on-device via a local AI model. Zero audio ever leaving your machine. No cloud, no exceptions. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
898898 </div>
899899
900900 <div class="feature-card">
@@ -936,7 +936,7 @@
936936 <div class="step-num">1</div>
937937 <div>
938938 <h3>Install Voxlen</h3>
939 <p>Download the Mac or Windows app, enter your API key (Deepgram or OpenAI), and optionally enable Privileged Mode for fully offline operation. Takes under 3 minutes.</p>
939 <p>Download the Mac or Windows app and sign in — all AI costs are included in your subscription, no API keys to manage. Takes under 3 minutes.</p>
940940 </div>
941941 </div>
942942 <div class="step">
@@ -986,7 +986,7 @@
986986 <ul>
987987 <li><span class="check">✓</span> Unlimited dictation</li>
988988 <li><span class="check">✓</span> Legal clause library (500 terms)</li>
989 <li><span class="check">✓</span> Privileged Mode (offline)</li>
989 <li><span class="check">🔜</span> Privileged Mode (offline) — coming soon</li>
990990 <li><span class="check">✓</span> Legal formatting templates</li>
991991 <li><span class="check">✓</span> Latin legal phrases</li>
992992 <li><span class="check">✓</span> Billable time tracking</li>
@@ -1041,7 +1041,7 @@
10411041 </button>
10421042 <div class="faq-answer" role="region">
10431043 <div class="faq-answer-inner">
1044 Voxlen is the best legal dictation software in 2026. It is purpose-built for lawyers with features no generic tool offers: offline Privileged Mode for confidential client communications, a 500-term legal clause library, Latin legal phrase recognition (<em>res ipsa loquitur, habeas corpus,</em> and 24 more), automatic court-filing formatting, and integrated billable time tracking. Unlike consumer voice tools, Voxlen understands legal context and uses AI post-processing to correct legal terminology automatically.
1044 Voxlen is the best legal dictation software in 2026. It is purpose-built for lawyers with features no generic tool offers: a 500-term legal clause library, Latin legal phrase recognition (<em>res ipsa loquitur, habeas corpus,</em> and 24 more), automatic court-filing formatting, integrated billable time tracking, and offline Privileged Mode coming soon for confidential client communications. Unlike consumer voice tools, Voxlen understands legal context and uses AI post-processing to correct legal terminology automatically.
10451045 </div>
10461046 </div>
10471047 </div>
@@ -1053,7 +1053,7 @@
10531053 </button>
10541054 <div class="faq-answer" role="region">
10551055 <div class="faq-answer-inner">
1056 Yes. Voxlen outperforms Dragon NaturallySpeaking Legal in three critical areas. First, accuracy: Voxlen uses Deepgram Nova-2, delivering ~99% word accuracy without a training period, while Dragon relies on older acoustic models that require hours of voice profile training. Second, platform support: Voxlen runs on Mac, Windows, and iPhone — Dragon Legal is Windows-only and has no Mac version since 2018. Third, cost: Voxlen Pro is $29/month vs Dragon Legal's $699+ one-time fee with paid upgrades. Voxlen also adds AI grammar correction and billable time tracking that Dragon lacks entirely.
1056 Yes. Voxlen outperforms Dragon NaturallySpeaking Legal in three critical areas. First, accuracy: Voxlen uses Deepgram Nova-2, delivering 95%+ word accuracy without a training period, while Dragon relies on older acoustic models that require hours of voice profile training. Second, platform support: Voxlen runs on Mac, Windows, and iPhone — Dragon Legal is Windows-only and has no Mac version since 2018. Third, cost: Voxlen Pro is $29/month vs Dragon Legal's $699+ one-time fee with paid upgrades. Voxlen also adds AI grammar correction and billable time tracking that Dragon lacks entirely.
10571057 </div>
10581058 </div>
10591059 </div>
@@ -1065,7 +1065,7 @@
10651065 </button>
10661066 <div class="faq-answer" role="region">
10671067 <div class="faq-answer-inner">
1068 Voxlen's Privileged Mode enables fully offline dictation with no audio ever leaving your device — ideal for attorney-client privileged communications and confidential matters. In Privileged Mode, transcription runs entirely on-device so no cloud server ever processes your content. This is critical for law firms subject to bar association ethical rules on client confidentiality, and for counsel working on particularly sensitive matters such as criminal defence, M&A transactions, or family law cases.
1068 Voxlen's Privileged Mode (coming soon) will enable fully offline dictation with no audio ever leaving your device — ideal for attorney-client privileged communications and confidential matters. Transcription will run entirely on-device so no cloud server ever processes your content — critical for law firms subject to bar association ethical rules on client confidentiality, and for counsel working on particularly sensitive matters such as criminal defence, M&A transactions, or family law cases. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained.
10691069 </div>
10701070 </div>
10711071 </div>
@@ -1077,7 +1077,7 @@
10771077 </button>
10781078 <div class="faq-answer" role="region">
10791079 <div class="faq-answer-inner">
1080 Voxlen is designed with privacy as a first principle. In Privileged Mode, all audio and transcripts are processed entirely on-device — nothing is sent to any Voxlen server. When using cloud transcription, audio is processed by your chosen provider (Deepgram or OpenAI) using your own API key under your own data processing agreements. Voxlen itself never stores or accesses client content on its own servers. Law firms in EU jurisdictions can use Privileged Mode exclusively to remain fully GDPR compliant and satisfy obligations under relevant bar association data protection guidance.
1080 Voxlen is designed with privacy as a first principle. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. Privileged Mode (coming soon) will process all audio and transcripts entirely on-device, so nothing is sent to any server at all — helping law firms in EU jurisdictions remain fully GDPR compliant and satisfy obligations under relevant bar association data protection guidance.
10811081 </div>
10821082 </div>
10831083 </div>
Modifiedlanding/public/legal-voice-dictation-canada/index.html+9−9View fileUnifiedSplit
@@ -37,7 +37,7 @@
3737 {
3838 "@type": "Question",
3939 "name": "Is Voxlen compliant with PIPEDA for Canadian law firms?",
40 "acceptedAnswer": { "@type": "Answer", "text": "Yes. Voxlen is designed with Canadian privacy law in mind. Privileged Mode processes all audio entirely on-device using local Whisper — nothing ever leaves your computer. For standard use, Voxlen uses Deepgram's SOC 2 Type II certified infrastructure, with data processed only for transcription and never retained. This supports PIPEDA compliance for Canadian legal practices." }
40 "acceptedAnswer": { "@type": "Answer", "text": "Yes. Voxlen is designed with Canadian privacy law in mind. Voxlen uses Deepgram's SOC 2 Type II certified infrastructure through zero-retention endpoints — Voxlen never stores your audio or transcripts, data is processed only for transcription, and nothing is retained. Privileged Mode (coming soon) will process all audio entirely on-device using local Whisper, so nothing ever leaves your computer. This supports PIPEDA compliance for Canadian legal practices." }
4141 },
4242 {
4343 "@type": "Question",
@@ -134,7 +134,7 @@
134134 <h1>Legal Voice Dictation<br /><span class="gradient">for Canadian Lawyers</span></h1>
135135 <p class="lead">
136136 Trusted by Bay Street firms, Law Society of Ontario members, and articling students coast to coast.
137 Bilingual English/French support. Privileged Mode for sensitive matters. PIPEDA-friendly by design.
137 Bilingual English/French support. Privileged Mode for sensitive matters coming soon. PIPEDA-friendly by design.
138138 Free 14-day trial — no credit card required.
139139 </p>
140140 <div class="cta-group">
@@ -142,9 +142,9 @@
142142 <a href="https://voxlen.ai/#pricing" class="btn-secondary">View Pricing</a>
143143 </div>
144144 <div class="highlight-bar">
145 <div class="stat"><div class="stat-num">99%</div><div class="stat-label">Transcription Accuracy</div></div>
145 <div class="stat"><div class="stat-num">95%+</div><div class="stat-label">Transcription Accuracy</div></div>
146146 <div class="stat"><div class="stat-num">2</div><div class="stat-label">Languages (EN + FR)</div></div>
147 <div class="stat"><div class="stat-num">0</div><div class="stat-label">Cloud for Privileged Matters</div></div>
147 <div class="stat"><div class="stat-num">0</div><div class="stat-label">Audio or Transcripts Stored</div></div>
148148 <div class="stat"><div class="stat-num">3×</div><div class="stat-label">Faster Than Typing</div></div>
149149 </div>
150150 </div>
@@ -158,8 +158,8 @@
158158 <div class="cards">
159159 <div class="card">
160160 <div class="card-icon">🔒</div>
161 <h3>Privileged Mode — Zero Cloud</h3>
162 <p>For matters where confidentiality is absolute, Voxlen's Privileged Mode processes all audio entirely on-device using local Whisper. No audio ever leaves your computer. Fully consistent with your professional obligations under Law Society of Ontario and Law Society of BC guidelines on cloud technology use.</p>
161 <h3>Privileged Mode — Zero Cloud (Coming Soon)</h3>
162 <p>For matters where confidentiality is absolute, Voxlen's Privileged Mode (coming soon) will process all audio entirely on-device using local Whisper — no audio ever leaving your computer. Designed to be fully consistent with your professional obligations under Law Society of Ontario and Law Society of BC guidelines on cloud technology use. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
163163 </div>
164164 <div class="card">
165165 <div class="card-icon">🇫🇷</div>
@@ -184,7 +184,7 @@
184184 <div class="card">
185185 <div class="card-icon">📋</div>
186186 <h3>PIPEDA-Friendly by Design</h3>
187 <p>Canada's <em>Personal Information Protection and Electronic Documents Act</em> (PIPEDA) requires appropriate safeguards for personal information. Voxlen processes transcription data through SOC 2 Type II certified infrastructure and offers full on-device processing in Privileged Mode — supporting your firm's PIPEDA compliance posture.</p>
187 <p>Canada's <em>Personal Information Protection and Electronic Documents Act</em> (PIPEDA) requires appropriate safeguards for personal information. Voxlen processes transcription data through SOC 2 Type II certified infrastructure on zero-retention endpoints — nothing is stored or retained — and full on-device processing in Privileged Mode is coming soon, supporting your firm's PIPEDA compliance posture.</p>
188188 </div>
189189 </div>
190190 </div>
@@ -234,7 +234,7 @@
234234 <div class="pricing-card">
235235 <div class="price">$79<span style="font-size:1rem; font-weight:400">/mo</span></div>
236236 <div class="tier-name">Professional — for firms</div>
237 <p style="font-size:0.85rem; margin-top:8px;">SSO, team management, Privileged Mode, legal clause library, per-matter vocabulary.</p>
237 <p style="font-size:0.85rem; margin-top:8px;">SSO, team management, legal clause library, per-matter vocabulary, Privileged Mode coming soon.</p>
238238 </div>
239239 <div class="pricing-card">
240240 <div class="price">$599</div>
@@ -255,7 +255,7 @@
255255
256256 <div class="faq-item">
257257 <h3>Is Voxlen compliant with PIPEDA for Canadian law firms?</h3>
258 <p>Yes. Voxlen is designed with Canadian privacy law in mind. Privileged Mode processes all audio entirely on-device using local Whisper — nothing ever leaves your computer. For standard use, Voxlen uses Deepgram's SOC 2 Type II certified infrastructure, with data processed only for transcription and never retained. This supports PIPEDA compliance for Canadian legal practices.</p>
258 <p>Yes. Voxlen is designed with Canadian privacy law in mind. Voxlen uses Deepgram's SOC 2 Type II certified infrastructure through zero-retention endpoints — Voxlen never stores your audio or transcripts, data is processed only for transcription, and nothing is retained. Privileged Mode (coming soon) will process all audio entirely on-device using local Whisper, so nothing ever leaves your computer. This supports PIPEDA compliance for Canadian legal practices.</p>
259259 </div>
260260
261261 <div class="faq-item">
Modifiedlanding/public/voice-dictation-android/index.html+5−5View fileUnifiedSplit
@@ -58,7 +58,7 @@
5858 {
5959 "@type": "Question",
6060 "name": "Does Android voice dictation work offline?",
61 "acceptedAnswer": {"@type": "Answer", "text": "Yes. Voxlen's Privileged Mode on the Professional plan uses on-device Whisper transcription — no audio leaves your device. This is critical for lawyers and accountants handling sensitive client information on their Android phone."}
61 "acceptedAnswer": {"@type": "Answer", "text": "Offline dictation is coming soon. Voxlen's Privileged Mode (coming soon, on the Professional plan) will use on-device Whisper transcription so no audio leaves your device — critical for lawyers and accountants handling sensitive client information on their Android phone. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."}
6262 }
6363 ]
6464 }
@@ -184,8 +184,8 @@
184184 </div>
185185 <div class="feature-card">
186186 <div class="feature-icon">🔒</div>
187 <h3>Privileged Mode</h3>
188 <p>On-device Whisper transcription for sensitive matters — no audio leaves your Android device. Required for privileged client communications.</p>
187 <h3>Privileged Mode — Coming Soon</h3>
188 <p>Privileged Mode (coming soon) will bring on-device Whisper transcription for sensitive matters — no audio leaving your Android device. Built for privileged client communications.</p>
189189 </div>
190190 <div class="feature-card">
191191 <div class="feature-icon">💰</div>
@@ -233,7 +233,7 @@
233233 <div class="plan-desc">For law firms and accounting teams.</div>
234234 <ul>
235235 <li>Everything in Pro</li>
236 <li>Privileged Mode (offline)</li>
236 <li>Privileged Mode (offline) — coming soon</li>
237237 <li>SSO / team management</li>
238238 <li>Priority support</li>
239239 </ul>
@@ -272,7 +272,7 @@
272272 </div>
273273 <div class="faq-item">
274274 <h3>Does Android voice dictation work offline?</h3>
275 <p>Yes. Voxlen's Privileged Mode on the Professional plan uses on-device Whisper transcription — no audio leaves your device. Critical for lawyers and accountants handling sensitive client information on their Android phone.</p>
275 <p>Offline dictation is coming soon. Voxlen's Privileged Mode (coming soon, on the Professional plan) will use on-device Whisper transcription so no audio leaves your device — critical for lawyers and accountants handling sensitive client information on their Android phone. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained.</p>
276276 </div>
277277 </div>
278278 </section>
Modifiedlanding/public/voice-dictation-for-lawyers/index.html+13−13View fileUnifiedSplit
@@ -23,7 +23,7 @@
2323 "name": "Voxlen",
2424 "applicationCategory": "BusinessApplication",
2525 "operatingSystem": "macOS, Windows, iOS",
26 "description": "Voice dictation software purpose-built for lawyers. Features a legal clause library, Latin legal phrase recognition, offline Privileged Mode for attorney-client privilege, court-filing formatting, GDPR compliance, and billable time tracking.",
26 "description": "Voice dictation software purpose-built for lawyers. Features a legal clause library, Latin legal phrase recognition, zero-retention privacy for attorney-client privilege (offline Privileged Mode coming soon), court-filing formatting, GDPR compliance, and billable time tracking.",
2727 "url": "https://voxlen.ai/",
2828 "offers": [
2929 {
@@ -38,7 +38,7 @@
3838 "name": "Pro",
3939 "price": "29",
4040 "priceCurrency": "USD",
41 "description": "Unlimited dictation, legal clause library, Privileged Mode, billable time tracking"
41 "description": "Unlimited dictation, legal clause library, billable time tracking, Privileged Mode (coming soon)"
4242 },
4343 {
4444 "@type": "Offer",
@@ -74,7 +74,7 @@
7474 "name": "Is Voxlen GDPR compliant for law firms?",
7575 "acceptedAnswer": {
7676 "@type": "Answer",
77 "text": "Yes. Voxlen is designed with privacy as a foundational principle, not an afterthought. In Privileged Mode, all audio and transcripts are processed entirely on-device — nothing is sent to any Voxlen server or any third-party server. When using cloud transcription, audio is processed by your chosen provider (Deepgram or OpenAI) using your own API key under your own data processing agreements. Voxlen itself never stores or accesses client content. Law firms in EU jurisdictions can use Privileged Mode exclusively to remain fully GDPR compliant and satisfy bar association guidance on data protection obligations."
77 "text": "Yes. Voxlen is designed with privacy as a foundational principle, not an afterthought. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. Privileged Mode (coming soon) will process all audio and transcripts entirely on-device, so nothing is sent to any server at all — helping law firms in EU jurisdictions remain fully GDPR compliant and satisfy bar association guidance on data protection obligations."
7878 }
7979 },
8080 {
@@ -98,7 +98,7 @@
9898 "name": "Can I use Voxlen for privileged client communications?",
9999 "acceptedAnswer": {
100100 "@type": "Answer",
101 "text": "Yes, and it is specifically designed for this use case. Privileged Mode enables fully offline dictation with zero audio or text leaving your device — making it safe for attorney-client privileged communications, grand jury matters, M&A transactions, and any matter where absolute confidentiality is required. In Privileged Mode, transcription runs on a local AI model with no external network calls. Nothing is stored on Voxlen servers. Nothing is sent to any cloud service. The privilege never breaks."
101 "text": "Yes. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Session history and custom vocabulary stay on your device only. Privileged Mode (coming soon) will go further: fully offline dictation with zero audio or text leaving your device, with transcription running on a local AI model with no external network calls — designed for attorney-client privileged communications, grand jury matters, M&A transactions, and any matter where absolute confidentiality is required."
102102 }
103103 }
104104 ]
@@ -710,7 +710,7 @@
710710 </div>
711711 <div class="trust-item">
712712 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
713 Privileged Mode — offline, zero cloud
713 Privileged Mode — offline, zero cloud (coming soon)
714714 </div>
715715 <div class="trust-item">
716716 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
@@ -761,8 +761,8 @@
761761 <div class="feature-card featured">
762762 <div class="feature-badge">Pro</div>
763763 <div class="feature-icon">🛡️</div>
764 <h3>Privileged Mode (Offline)</h3>
765 <p>The most important feature for any legal dictation tool. Privileged Mode runs all transcription and AI processing entirely on-device — no audio, no transcript, nothing leaves your machine. Designed for attorney-client privileged communications, grand jury matters, and any work requiring absolute confidentiality.</p>
764 <h3>Privileged Mode (Offline) — Coming Soon</h3>
765 <p>The most important feature on our roadmap for any legal dictation tool. Privileged Mode (coming soon) will run all transcription and AI processing entirely on-device — no audio, no transcript, nothing leaving your machine. Designed for attorney-client privileged communications, grand jury matters, and any work requiring absolute confidentiality. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
766766 </div>
767767
768768 <div class="feature-card featured">
@@ -858,7 +858,7 @@
858858 </tr>
859859 <tr>
860860 <td class="feature-name">Fully Offline Mode</td>
861 <td class="voxlen-col"><span class="yes">✓ Privileged Mode</span></td>
861 <td class="voxlen-col">🔜 Coming soon</td>
862862 <td><span class="yes">✓ Yes</span></td>
863863 <td><span class="no">✗ Cloud required</span></td>
864864 <td><span class="no">✗ Cloud required</span></td>
@@ -918,7 +918,7 @@
918918 <div class="step-num">1</div>
919919 <div>
920920 <h3>Install & Configure</h3>
921 <p>Download the Mac or Windows app, enter your API key (Deepgram or OpenAI), and optionally enable Privileged Mode for fully offline operation. Takes under 3 minutes. No voice training period required — unlike Dragon, which can take hours.</p>
921 <p>Download the Mac or Windows app and sign in — all AI costs are included in your subscription, no API keys to manage. Takes under 3 minutes. No voice training period required — unlike Dragon, which can take hours.</p>
922922 </div>
923923 </div>
924924 <div class="step">
@@ -932,7 +932,7 @@
932932 <div class="step-num">3</div>
933933 <div>
934934 <h3>AI Polishes the Output</h3>
935 <p>The built-in AI grammar layer — powered by Claude or GPT-4o via your own API key — cleans up spoken fillers, applies legal formatting, inserts correct punctuation, and resolves legal terminology. The result is document-ready text. Billable time is automatically logged.</p>
935 <p>The built-in AI grammar layer — powered by Claude or GPT-4o, included in your subscription — cleans up spoken fillers, applies legal formatting, inserts correct punctuation, and resolves legal terminology. The result is document-ready text. Billable time is automatically logged.</p>
936936 </div>
937937 </div>
938938 </div>
@@ -968,7 +968,7 @@
968968 <ul>
969969 <li><span class="check">✓</span> Unlimited dictation</li>
970970 <li><span class="check">✓</span> Legal clause library (500 terms)</li>
971 <li><span class="check">✓</span> Privileged Mode (fully offline)</li>
971 <li><span class="check">🔜</span> Privileged Mode (fully offline) — coming soon</li>
972972 <li><span class="check">✓</span> Legal formatting templates</li>
973973 <li><span class="check">✓</span> 26 Latin legal phrases</li>
974974 <li><span class="check">✓</span> Billable time tracking</li>
@@ -1023,7 +1023,7 @@
10231023 </button>
10241024 <div class="faq-answer" role="region">
10251025 <div class="faq-answer-inner">
1026 Yes. Voxlen is designed with privacy as a foundational principle. In Privileged Mode, all audio and transcripts are processed entirely on-device — nothing is sent to any Voxlen server or any third-party server. When using cloud transcription, audio is processed by your chosen provider (Deepgram or OpenAI) under your own API key and your own data processing agreements. Voxlen itself never stores or accesses client content. Law firms in EU jurisdictions can use Privileged Mode exclusively to remain fully GDPR compliant and satisfy bar association guidance on data protection obligations.
1026 Yes. Voxlen is designed with privacy as a foundational principle. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers (Deepgram, Anthropic, OpenAI), and nothing is retained. All AI costs are included in your subscription, with no API keys to manage. Privileged Mode (coming soon) will process all audio and transcripts entirely on-device, so nothing is sent to any server at all — helping law firms in EU jurisdictions remain fully GDPR compliant and satisfy bar association guidance on data protection obligations.
10271027 </div>
10281028 </div>
10291029 </div>
@@ -1059,7 +1059,7 @@
10591059 </button>
10601060 <div class="faq-answer" role="region">
10611061 <div class="faq-answer-inner">
1062 Yes — and this is specifically what Privileged Mode is designed for. In Privileged Mode, all transcription and AI processing runs on-device with zero external network calls. No audio leaves your device. No transcript is transmitted to any server. No data is stored by Voxlen. The mode is designed for attorney-client privileged communications, grand jury matters, M&A transactions, criminal defence work, and any matter where absolute confidentiality is required. When you engage Privileged Mode, the privilege never breaks.
1062 Yes. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Session history and custom vocabulary stay on your device only. Privileged Mode (coming soon) will go further: all transcription and AI processing running on-device with zero external network calls — no audio leaving your device, no transcript transmitted to any server. It is designed for attorney-client privileged communications, grand jury matters, M&A transactions, criminal defence work, and any matter where absolute confidentiality is required.
10631063 </div>
10641064 </div>
10651065 </div>
Modifiedlanding/public/voice-dictation-iphone/index.html+7−7View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Voice Dictation for iPhone & iPad | AI Keyboard — Voxlen</title>
7 <meta name="description" content="Voxlen adds AI voice dictation to every app on your iPhone and iPad via a custom keyboard extension. Legal clause library, AI grammar correction, and offline mode. Free trial." />
7 <meta name="description" content="Voxlen adds AI voice dictation to every app on your iPhone and iPad via a custom keyboard extension. Legal clause library, AI grammar correction, and offline mode (coming soon). Free trial." />
88 <meta name="keywords" content="voice dictation iphone, dictation app iphone, voice to text iphone, ipad dictation software, ai keyboard iphone, voice dictation for lawyers iphone" />
99 <link rel="canonical" href="https://voxlen.ai/voice-dictation-iphone" />
1010 <meta property="og:title" content="Voice Dictation for iPhone & iPad | Voxlen AI" />
11 <meta property="og:description" content="AI voice dictation keyboard for iPhone and iPad. Works in every app — email, notes, documents, legal software. Includes clause library and offline mode." />
11 <meta property="og:description" content="AI voice dictation keyboard for iPhone and iPad. Works in every app — email, notes, documents, legal software. Includes clause library — offline mode coming soon." />
1212 <meta property="og:type" content="website" />
1313 <meta property="og:url" content="https://voxlen.ai/voice-dictation-iphone" />
1414 <meta property="og:image" content="https://voxlen.ai/og-image.png" />
@@ -48,7 +48,7 @@
4848 {
4949 "@type": "Question",
5050 "name": "Is there an offline voice dictation mode for iPhone?",
51 "acceptedAnswer": {"@type": "Answer", "text": "Yes. Voxlen's Privileged Mode uses on-device Whisper transcription — audio never leaves your iPhone. This is essential for lawyers handling client-privileged information or confidential financial data. Available on the Professional plan."}
51 "acceptedAnswer": {"@type": "Answer", "text": "Offline dictation is coming soon. Voxlen's Privileged Mode (coming soon) will use on-device Whisper transcription so audio never leaves your iPhone — essential for lawyers handling client-privileged information or confidential financial data. It will be available on the Professional plan. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."}
5252 },
5353 {
5454 "@type": "Question",
@@ -186,8 +186,8 @@
186186 </div>
187187 <div class="feature-card">
188188 <div class="feature-icon">🔒</div>
189 <h3>Privileged Mode (Offline)</h3>
190 <p>Enable offline mode for sensitive matters — audio is transcribed on-device using Whisper and never sent to any server. Essential for privileged communications.</p>
189 <h3>Privileged Mode (Offline) — Coming Soon</h3>
190 <p>Offline mode (coming soon) will transcribe audio on-device for sensitive matters, with nothing sent to any server — built for privileged communications.</p>
191191 </div>
192192 <div class="feature-card">
193193 <div class="feature-icon">🤖</div>
@@ -240,7 +240,7 @@
240240 <div class="plan-desc">For law firms and accounting teams.</div>
241241 <ul>
242242 <li>Everything in Pro</li>
243 <li>Privileged Mode (offline)</li>
243 <li>Privileged Mode (offline) — coming soon</li>
244244 <li>SSO / team management</li>
245245 <li>Priority support</li>
246246 <li>Custom clause library</li>
@@ -272,7 +272,7 @@
272272 </div>
273273 <div class="faq-item">
274274 <h3>Is there an offline voice dictation mode for iPhone?</h3>
275 <p>Yes. Voxlen's Privileged Mode uses on-device Whisper transcription — audio never leaves your iPhone. This is essential for lawyers handling client-privileged information or confidential financial data. Available on the Professional plan.</p>
275 <p>Offline dictation is coming soon. Voxlen's Privileged Mode (coming soon) will use on-device Whisper transcription so audio never leaves your iPhone — essential for lawyers handling client-privileged information or confidential financial data. It will be available on the Professional plan. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained.</p>
276276 </div>
277277 <div class="faq-item">
278278 <h3>Can I use iPhone voice dictation for legal documents?</h3>
Modifiedlanding/public/voice-dictation-mac/index.html+5−5View fileUnifiedSplit
@@ -90,7 +90,7 @@
9090 "name": "Is my dictation data private?",
9191 "acceptedAnswer": {
9292 "@type": "Answer",
93 "text": "Voxlen is designed for professionals such as lawyers and accountants who require strict confidentiality. All vocabulary learning and usage patterns are stored on-device only. Your dictated content is never sent to Voxlen servers."
93 "text": "Voxlen is designed for professionals such as lawyers and accountants who require strict confidentiality. All vocabulary learning and usage patterns are stored on-device only. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."
9494 }
9595 },
9696 {
@@ -570,12 +570,12 @@
570570 <div class="feature-card">
571571 <div class="feature-icon">🧠</div>
572572 <h3>AI grammar correction</h3>
573 <p>Powered by Claude and GPT-4o-mini via your own API keys. Spoken words are automatically corrected for grammar and punctuation — so your draft comes out polished.</p>
573 <p>Powered by Claude and GPT-4o-mini — included in your subscription, no API keys to manage. Spoken words are automatically corrected for grammar and punctuation — so your draft comes out polished.</p>
574574 </div>
575575 <div class="feature-card">
576576 <div class="feature-icon">🔒</div>
577577 <h3>Privacy-first design</h3>
578 <p>Your dictated content never touches Voxlen servers. Critical for lawyers and accountants. All learning happens locally on your Mac — confidentiality by architecture.</p>
578 <p>Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Critical for lawyers and accountants. All learning happens locally on your Mac — confidentiality by architecture.</p>
579579 </div>
580580 <div class="feature-card">
581581 <div class="feature-icon">📈</div>
@@ -629,7 +629,7 @@
629629 </tr>
630630 <tr>
631631 <td>Privacy — no cloud storage of content</td>
632 <td class="col-voxlen"><span class="check">✓</span> On-device only</td>
632 <td class="col-voxlen"><span class="check">✓</span> Zero retention</td>
633633 <td class="col-dragon">Nuance cloud</td>
634634 </tr>
635635 <tr>
@@ -734,7 +734,7 @@
734734 </details>
735735 <details>
736736 <summary>Is my dictation data private?</summary>
737 <div class="faq-answer">Voxlen is designed for professionals such as lawyers and accountants who require strict confidentiality. All vocabulary learning and usage patterns are stored on-device only — your Mac, never our servers. Your dictated content is never uploaded to or stored by Voxlen.</div>
737 <div class="faq-answer">Voxlen is designed for professionals such as lawyers and accountants who require strict confidentiality. All vocabulary learning and usage patterns are stored on-device only — your Mac, never our servers. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained.</div>
738738 </details>
739739 <details>
740740 <summary>What macOS versions does Voxlen support?</summary>
Modifiedlanding/public/voice-dictation-windows/index.html+3−3View fileUnifiedSplit
@@ -565,12 +565,12 @@
565565 <div class="feature-card">
566566 <div class="feature-icon">🧠</div>
567567 <h3>AI grammar correction</h3>
568 <p>Powered by Claude and GPT-4o-mini via your own API keys. Spoken words are automatically corrected for grammar, punctuation, and capitalization — so your draft comes out polished from the first word.</p>
568 <p>Powered by Claude and GPT-4o-mini — included in your subscription, no API keys to manage. Spoken words are automatically corrected for grammar, punctuation, and capitalization — so your draft comes out polished from the first word.</p>
569569 </div>
570570 <div class="feature-card">
571571 <div class="feature-icon">🔒</div>
572572 <h3>Privacy-first — no cloud content</h3>
573 <p>Your dictated content is never sent to or stored on Voxlen servers. Essential for lawyers handling privileged communications and accountants managing confidential financial data. Privacy by architecture.</p>
573 <p>Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Essential for lawyers handling privileged communications and accountants managing confidential financial data. Privacy by architecture.</p>
574574 </div>
575575 <div class="feature-card">
576576 <div class="feature-icon">📈</div>
@@ -624,7 +624,7 @@
624624 </tr>
625625 <tr>
626626 <td>No cloud storage of your content</td>
627 <td class="col-voxlen"><span class="check">✓</span> On-device only</td>
627 <td class="col-voxlen"><span class="check">✓</span> Zero retention</td>
628628 <td class="col-dragon">Nuance / Microsoft cloud</td>
629629 </tr>
630630 <tr>
Modifiedlanding/public/voice-to-text-for-medical/index.html+17−17View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Voice to Text Medical Dictation Software | Voxlen AI</title>
7 <meta name="description" content="Medical dictation software for doctors, nurses, and healthcare professionals. Voxlen AI transcribes at 99% accuracy, understands clinical terminology, keeps patient data private. Free 14-day trial." />
7 <meta name="description" content="Medical dictation software for doctors, nurses, and healthcare professionals. Voxlen AI transcribes at 95%+ accuracy, understands clinical terminology, keeps patient data private. Free 14-day trial." />
88 <meta name="keywords" content="voice to text medical, medical dictation software, clinical dictation, doctor dictation software, healthcare voice recognition, medical speech to text, clinical documentation software" />
99 <link rel="canonical" href="https://voxlen.ai/voice-to-text-for-medical" />
1010 <meta property="og:title" content="Voice to Text Medical Dictation Software | Voxlen AI" />
11 <meta property="og:description" content="AI-powered medical dictation software for clinicians. 99% accuracy on clinical terminology, HIPAA-ready on-device mode, patient record dictation, and structured clinical note formatting. Free 14-day trial." />
11 <meta property="og:description" content="AI-powered medical dictation software for clinicians. 95%+ accuracy on clinical terminology, zero-retention privacy (HIPAA-ready on-device mode coming soon), patient record dictation, and structured clinical note formatting. Free 14-day trial." />
1212 <meta property="og:type" content="article" />
1313 <meta property="og:url" content="https://voxlen.ai/voice-to-text-for-medical" />
1414 <meta property="og:site_name" content="Voxlen" />
@@ -23,7 +23,7 @@
2323 "name": "Voxlen",
2424 "applicationCategory": "MedicalApplication",
2525 "operatingSystem": "macOS, Windows, iOS",
26 "description": "AI-powered medical dictation software for doctors, nurses, and healthcare professionals. Features clinical terminology recognition, SOAP note formatting, on-device Privileged Mode for patient data privacy, and structured clinical documentation templates.",
26 "description": "AI-powered medical dictation software for doctors, nurses, and healthcare professionals. Features clinical terminology recognition, SOAP note formatting, structured clinical documentation templates, and on-device Privileged Mode (coming soon) for patient data privacy.",
2727 "url": "https://voxlen.ai/",
2828 "offers": [
2929 {
@@ -38,7 +38,7 @@
3838 "name": "Pro",
3939 "price": "29",
4040 "priceCurrency": "USD",
41 "description": "Unlimited dictation, clinical phrase library, offline mode"
41 "description": "Unlimited dictation, clinical phrase library, offline mode (coming soon)"
4242 },
4343 {
4444 "@type": "Offer",
@@ -74,7 +74,7 @@
7474 "name": "What is the best voice to text software for medical professionals?",
7575 "acceptedAnswer": {
7676 "@type": "Answer",
77 "text": "Voxlen is the best voice-to-text software for medical professionals in 2026. It uses Deepgram Nova-3 for approximately 99% word-level accuracy on clinical terminology, including drug names, anatomical terms, diagnostic codes, and procedural nomenclature. A built-in clinical phrase library covers over 500 medical terms across general practice, surgery, radiology, and psychiatry. The Privileged Mode processes all audio on-device with no data leaving the machine — critical for HIPAA and NHS data governance compliance."
77 "text": "Voxlen is the best voice-to-text software for medical professionals in 2026. It uses Deepgram Nova-3 for 95%+ word-level accuracy on clinical terminology, including drug names, anatomical terms, diagnostic codes, and procedural nomenclature. A built-in clinical phrase library covers over 500 medical terms across general practice, surgery, radiology, and psychiatry. Privileged Mode (coming soon) will process all audio on-device with no data leaving the machine — critical for HIPAA and NHS data governance compliance. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."
7878 }
7979 },
8080 {
@@ -82,7 +82,7 @@
8282 "name": "Is medical dictation software HIPAA compliant?",
8383 "acceptedAnswer": {
8484 "@type": "Answer",
85 "text": "Voxlen's Privileged Mode is designed to support HIPAA compliance requirements. In Privileged Mode, all audio and transcripts are processed entirely on-device — no patient-identifiable information is transmitted to any cloud server. Voxlen itself never receives, stores, or processes Protected Health Information (PHI). When clinicians in US healthcare settings need to meet HIPAA safe harbour requirements, Privileged Mode provides the strongest available privacy guarantee: physical isolation of PHI to the practitioner's own device."
85 "text": "Voxlen's Privileged Mode (coming soon) is designed to support HIPAA compliance requirements. It will process all audio and transcripts entirely on-device — no patient-identifiable information transmitted to any cloud server — providing the strongest available privacy guarantee: physical isolation of PHI to the practitioner's own device. Today, Voxlen never stores audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained."
8686 }
8787 },
8888 {
@@ -106,7 +106,7 @@
106106 "name": "How accurate is Voxlen on medical terminology and drug names?",
107107 "acceptedAnswer": {
108108 "@type": "Answer",
109 "text": "Voxlen achieves approximately 99% word-level accuracy using Deepgram Nova-3, which is trained on a broad corpus including medical audio. The AI post-processing layer (Claude or GPT-4o, running via your own API key) performs a second-pass correction specifically for clinical context: it recognises generic and brand-name drug names, disambiguates similar-sounding clinical terms, corrects dosage figures, and applies standard medical abbreviations correctly. Drug name accuracy in testing exceeds that of Dragon Medical One at a fraction of the cost."
109 "text": "Voxlen achieves 95%+ word-level accuracy using Deepgram Nova-3, which is trained on a broad corpus including medical audio. The AI post-processing layer (Claude or GPT-4o, included in your subscription) performs a second-pass correction specifically for clinical context: it recognises generic and brand-name drug names, disambiguates similar-sounding clinical terms, corrects dosage figures, and applies standard medical abbreviations correctly. Drug name accuracy in testing exceeds that of Dragon Medical One at a fraction of the cost."
110110 }
111111 }
112112 ]
@@ -868,11 +868,11 @@
868868 <div class="hero-trust">
869869 <div class="trust-item">
870870 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
871 99% accuracy on clinical terminology
871 95%+ accuracy on clinical terminology
872872 </div>
873873 <div class="trust-item">
874874 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
875 HIPAA-ready on-device mode
875 HIPAA-ready on-device mode coming soon
876876 </div>
877877 <div class="trust-item">
878878 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
@@ -930,8 +930,8 @@
930930 <div class="feature-card featured">
931931 <div class="feature-badge">Pro</div>
932932 <div class="feature-icon">🛡️</div>
933 <h3>Privileged Mode (Fully Offline)</h3>
934 <p>All transcription runs on-device with no patient data ever leaving your machine. Designed to support HIPAA safe harbour, NHS DSP Toolkit compliance, and GDPR requirements. Zero cloud transmission of Protected Health Information.</p>
933 <h3>Privileged Mode (Fully Offline) — Coming Soon</h3>
934 <p>Privileged Mode (coming soon) will run all transcription on-device with no patient data ever leaving your machine. Designed to support HIPAA safe harbour, NHS DSP Toolkit compliance, and GDPR requirements. Today, all requests pass through zero-retention endpoints and nothing is retained.</p>
935935 </div>
936936
937937 <div class="feature-card">
@@ -988,7 +988,7 @@
988988 </tr>
989989 <tr>
990990 <td>Fully offline / on-device mode</td>
991 <td class="yes">Yes</td>
991 <td>🔜 Coming soon</td>
992992 <td class="yes">Yes</td>
993993 <td class="no">No</td>
994994 <td class="no">No</td>
@@ -1044,7 +1044,7 @@
10441044 <div class="step-num">1</div>
10451045 <div>
10461046 <h3>Install Voxlen</h3>
1047 <p>Download the Mac or Windows desktop app, add your API key (Deepgram or OpenAI), and optionally enable Privileged Mode for fully on-device operation. No training period and no voice profile required. Setup takes under five minutes.</p>
1047 <p>Download the Mac or Windows desktop app and sign in — all AI costs are included in your subscription, no API keys to manage. No training period and no voice profile required. Setup takes under five minutes.</p>
10481048 </div>
10491049 </div>
10501050 <div class="step">
@@ -1094,7 +1094,7 @@
10941094 <ul>
10951095 <li><span class="check">✓</span> Unlimited dictation</li>
10961096 <li><span class="check">✓</span> Clinical phrase library (500+ terms)</li>
1097 <li><span class="check">✓</span> Privileged Mode (offline)</li>
1097 <li><span class="check">🔜</span> Privileged Mode (offline) — coming soon</li>
10981098 <li><span class="check">✓</span> SOAP note & clinical templates</li>
10991099 <li><span class="check">✓</span> Speaker diarization</li>
11001100 <li><span class="check">✓</span> iOS keyboard app</li>
@@ -1147,7 +1147,7 @@
11471147 </button>
11481148 <div class="faq-answer" role="region">
11491149 <div class="faq-answer-inner">
1150 Voxlen is the best voice-to-text software for medical professionals in 2026. It uses Deepgram Nova-3 for approximately 99% word-level accuracy on clinical terminology, including drug names, anatomical terms, diagnostic codes, and procedural nomenclature. The built-in clinical phrase library covers over 500 medical terms. Privileged Mode processes all audio on-device with no patient data leaving the machine — critical for HIPAA, NHS Data Security and Protection Toolkit, and GDPR compliance. At $29/month, it costs less than a third of Dragon Medical One.
1150 Voxlen is the best voice-to-text software for medical professionals in 2026. It uses Deepgram Nova-3 for 95%+ word-level accuracy on clinical terminology, including drug names, anatomical terms, diagnostic codes, and procedural nomenclature. The built-in clinical phrase library covers over 500 medical terms. Privileged Mode (coming soon) will process all audio on-device with no patient data leaving the machine — critical for HIPAA, NHS Data Security and Protection Toolkit, and GDPR compliance. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. At $29/month, it costs less than a third of Dragon Medical One.
11511151 </div>
11521152 </div>
11531153 </div>
@@ -1159,7 +1159,7 @@
11591159 </button>
11601160 <div class="faq-answer" role="region">
11611161 <div class="faq-answer-inner">
1162 Voxlen's Privileged Mode is designed to support HIPAA compliance requirements. In Privileged Mode, all audio and transcripts are processed entirely on-device — no Protected Health Information is transmitted to any cloud server. Voxlen itself never receives, stores, or processes PHI. When clinicians in US healthcare settings need to satisfy HIPAA safe harbour requirements, Privileged Mode provides the strongest available privacy guarantee: complete physical isolation of PHI to the practitioner's own device. Practices should review their specific compliance obligations with their privacy officer before deployment.
1162 Voxlen's Privileged Mode (coming soon) is designed to support HIPAA compliance requirements. It will process all audio and transcripts entirely on-device — no Protected Health Information transmitted to any cloud server — providing the strongest available privacy guarantee: complete physical isolation of PHI to the practitioner's own device. Today, Voxlen never stores audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Practices should review their specific compliance obligations with their privacy officer before deployment.
11631163 </div>
11641164 </div>
11651165 </div>
@@ -1195,7 +1195,7 @@
11951195 </button>
11961196 <div class="faq-answer" role="region">
11971197 <div class="faq-answer-inner">
1198 Voxlen achieves approximately 99% word-level accuracy using Deepgram Nova-3, which is trained on a broad corpus including medical and professional audio. The AI post-processing layer (Claude or GPT-4o, via your own API key) performs a second-pass correction specifically for clinical context: it recognises generic and brand-name drug names, disambiguates similar-sounding clinical terms (such as ileum vs ilium, or hypertension vs hypotension in context), corrects dosage figures, and applies standard medical abbreviations correctly. No voice training or acoustic model tuning is required — accuracy is high from the first dictation.
1198 Voxlen achieves 95%+ word-level accuracy using Deepgram Nova-3, which is trained on a broad corpus including medical and professional audio. The AI post-processing layer (Claude or GPT-4o, included in your subscription) performs a second-pass correction specifically for clinical context: it recognises generic and brand-name drug names, disambiguates similar-sounding clinical terms (such as ileum vs ilium, or hypertension vs hypotension in context), corrects dosage figures, and applies standard medical abbreviations correctly. No voice training or acoustic model tuning is required — accuracy is high from the first dictation.
11991199 </div>
12001200 </div>
12011201 </div>
Modifiedlanding/public/voxlen-vs-dragon/index.html+4−4View fileUnifiedSplit
@@ -31,7 +31,7 @@
3131 {
3232 "@type": "Question",
3333 "name": "How does Voxlen compare to Dragon Legal?",
34 "acceptedAnswer": {"@type": "Answer", "text": "Voxlen matches Dragon Legal on legal vocabulary and formatting, and exceeds it on: AI grammar correction (Claude AI), Mac support (Dragon Legal is Windows-only), mobile apps (Dragon has no iOS/Android keyboard), offline privacy mode, and price. Dragon Legal costs $500–$900; Voxlen Pro is $29/month."}
34 "acceptedAnswer": {"@type": "Answer", "text": "Voxlen matches Dragon Legal on legal vocabulary and formatting, and exceeds it on: AI grammar correction (Claude AI), Mac support (Dragon Legal is Windows-only), mobile apps (Dragon has no iOS/Android keyboard), zero-retention privacy (offline privacy mode coming soon), and price. Dragon Legal costs $500–$900; Voxlen Pro is $29/month."}
3535 },
3636 {
3737 "@type": "Question",
@@ -126,11 +126,11 @@
126126 <tr><td>Windows support</td><td class="yes">✓ Windows 10/11</td><td class="yes">✓ Windows only</td></tr>
127127 <tr><td>iPhone / iPad</td><td class="yes">✓ Keyboard extension</td><td class="no">✗ No</td></tr>
128128 <tr><td>Android / Samsung</td><td class="yes">✓ Keyboard extension</td><td class="no">✗ No</td></tr>
129 <tr><td>Transcription engine</td><td class="yes">Deepgram Nova-3 (99%+ accuracy)</td><td class="partial">Dragon engine (requires voice training)</td></tr>
129 <tr><td>Transcription engine</td><td class="yes">Deepgram Nova-3 (95%+ accuracy)</td><td class="partial">Dragon engine (requires voice training)</td></tr>
130130 <tr><td>Voice training required</td><td class="yes">✓ None — works immediately</td><td class="no">✗ 5–15 min training required</td></tr>
131131 <tr><td>AI grammar correction</td><td class="yes">✓ Claude AI (context-aware)</td><td class="no">✗ None</td></tr>
132132 <tr><td>Legal clause library</td><td class="yes">✓ 15+ pre-built clauses</td><td class="partial">⚠ Custom commands only</td></tr>
133 <tr><td>Offline / privileged mode</td><td class="yes">✓ On-device Whisper</td><td class="yes">✓ Fully local processing</td></tr>
133 <tr><td>Offline / privileged mode</td><td>🔜 Coming soon</td><td class="yes">✓ Fully local processing</td></tr>
134134 <tr><td>Latin legal phrases (26)</td><td class="yes">✓ Built-in recognition</td><td class="partial">⚠ Requires manual training</td></tr>
135135 <tr><td>Speaker diarization</td><td class="yes">✓ Multi-speaker support</td><td class="no">✗ Single speaker only</td></tr>
136136 <tr><td>Price</td><td class="yes">$29/mo or $599 lifetime</td><td class="no">$300–$900 upfront</td></tr>
@@ -184,7 +184,7 @@
184184 </div>
185185 <div class="faq-item">
186186 <h3>How does Voxlen compare to Dragon Legal?</h3>
187 <p>Voxlen matches Dragon Legal on legal vocabulary and formatting, and exceeds it on: AI grammar correction, Mac support, mobile apps (Dragon has no iOS/Android), offline privacy mode, and price. Dragon Legal costs $500–$900; Voxlen Pro is $29/month.</p>
187 <p>Voxlen matches Dragon Legal on legal vocabulary and formatting, and exceeds it on: AI grammar correction, Mac support, mobile apps (Dragon has no iOS/Android), zero-retention privacy (offline privacy mode coming soon), and price. Dragon Legal costs $500–$900; Voxlen Pro is $29/month.</p>
188188 </div>
189189 <div class="faq-item">
190190 <h3>Does Voxlen require voice training like Dragon?</h3>
Modifiedlanding/public/voxlen-vs-otter/index.html+7−7View fileUnifiedSplit
@@ -4,7 +4,7 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Voxlen vs Otter.ai — Which is Better for Lawyers & Accountants?</title>
7 <meta name="description" content="Detailed comparison of Voxlen vs Otter.ai for legal and accounting professionals. See why Voxlen wins on privacy, legal features, text injection, and offline mode." />
7 <meta name="description" content="Detailed comparison of Voxlen vs Otter.ai for legal and accounting professionals. See why Voxlen wins on privacy, legal features, text injection, and offline mode (coming soon)." />
88 <meta name="keywords" content="voxlen vs otter, otter ai alternative, otter ai for lawyers, best dictation software for lawyers, voice dictation comparison" />
99 <link rel="canonical" href="https://voxlen.ai/voxlen-vs-otter" />
1010 <meta property="og:title" content="Voxlen vs Otter.ai — Comparison for Legal Professionals" />
@@ -21,7 +21,7 @@
2121 {
2222 "@type": "Question",
2323 "name": "Is Voxlen better than Otter.ai for lawyers?",
24 "acceptedAnswer": {"@type": "Answer", "text": "Yes, for several reasons. Voxlen injects text directly into any app (real-time dictation), while Otter.ai is primarily a meeting recorder and transcription tool — it does not type into your documents. Voxlen includes a legal clause library, Privileged Mode for offline processing, and legal-specific formatting. Otter.ai has none of these features. For active dictation while drafting documents, Voxlen is the clear winner."}
24 "acceptedAnswer": {"@type": "Answer", "text": "Yes, for several reasons. Voxlen injects text directly into any app (real-time dictation), while Otter.ai is primarily a meeting recorder and transcription tool — it does not type into your documents. Voxlen includes a legal clause library, legal-specific formatting, and Privileged Mode coming soon for offline processing. Otter.ai has none of these features. For active dictation while drafting documents, Voxlen is the clear winner."}
2525 },
2626 {
2727 "@type": "Question",
@@ -36,7 +36,7 @@
3636 {
3737 "@type": "Question",
3838 "name": "Is Otter.ai GDPR compliant for law firms?",
39 "acceptedAnswer": {"@type": "Answer", "text": "Otter.ai stores all transcripts in its cloud. For law firms handling privileged client communications, this creates confidentiality risks. Voxlen's Privileged Mode transcribes entirely on-device — audio and text never leave your machine, making it the safer choice for privileged matters."}
39 "acceptedAnswer": {"@type": "Answer", "text": "Otter.ai stores all transcripts in its cloud. For law firms handling privileged client communications, this creates confidentiality risks. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Privileged Mode (coming soon) will transcribe entirely on-device, so audio and text never leave your machine — making Voxlen the safer choice for privileged matters."}
4040 },
4141 {
4242 "@type": "Question",
@@ -147,7 +147,7 @@
147147 <tr><td>iPhone keyboard</td><td class="yes">✓ Yes</td><td class="no">✗ No</td></tr>
148148 <tr><td>Android keyboard</td><td class="yes">✓ Yes</td><td class="no">✗ No</td></tr>
149149 <tr><td>Legal clause library</td><td class="yes">✓ 15+ clauses</td><td class="no">✗ No</td></tr>
150 <tr><td>Offline / privileged mode</td><td class="yes">✓ On-device Whisper</td><td class="no">✗ Cloud only</td></tr>
150 <tr><td>Offline / privileged mode</td><td>🔜 Coming soon</td><td class="no">✗ Cloud only</td></tr>
151151 <tr><td>AI grammar correction</td><td class="yes">✓ Claude AI</td><td class="partial">⚠ Basic cleanup only</td></tr>
152152 <tr><td>Legal formatting (citations, filings)</td><td class="yes">✓ Yes</td><td class="no">✗ No</td></tr>
153153 <tr><td>Meeting transcription</td><td class="partial">⚠ Via speaker diarization</td><td class="yes">✓ Core feature</td></tr>
@@ -181,7 +181,7 @@
181181 <div class="faq-list">
182182 <div class="faq-item">
183183 <h3>Is Voxlen better than Otter.ai for lawyers?</h3>
184 <p>Yes, for active dictation. Voxlen injects text directly into any app in real time, includes a legal clause library, supports offline privileged mode, and formats legal documents. Otter.ai is a meeting recorder — it doesn't type into your documents.</p>
184 <p>Yes, for active dictation. Voxlen injects text directly into any app in real time, includes a legal clause library, formats legal documents, and offline Privileged Mode is coming soon. Otter.ai is a meeting recorder — it doesn't type into your documents.</p>
185185 </div>
186186 <div class="faq-item">
187187 <h3>What is the difference between Voxlen and Otter.ai?</h3>
@@ -193,11 +193,11 @@
193193 </div>
194194 <div class="faq-item">
195195 <h3>Is Otter.ai GDPR compliant for law firms?</h3>
196 <p>Otter.ai stores all transcripts in its cloud. For law firms handling privileged client communications, this creates confidentiality risks. Voxlen's Privileged Mode transcribes entirely on-device — no audio or text leaves your machine.</p>
196 <p>Otter.ai stores all transcripts in its cloud. For law firms handling privileged client communications, this creates confidentiality risks. Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained. Privileged Mode (coming soon) will transcribe entirely on-device, so no audio or text leaves your machine.</p>
197197 </div>
198198 <div class="faq-item">
199199 <h3>Which is cheaper — Voxlen or Otter.ai?</h3>
200 <p>Otter.ai Pro is $16.99/month for meeting transcription only. Voxlen Pro is $29/month but includes real-time dictation, text injection into any app, legal clause library, AI grammar correction, offline mode, and cross-platform support. For professional dictation, Voxlen provides far more value.</p>
200 <p>Otter.ai Pro is $16.99/month for meeting transcription only. Voxlen Pro is $29/month but includes real-time dictation, text injection into any app, legal clause library, AI grammar correction, and cross-platform support (offline mode coming soon). For professional dictation, Voxlen provides far more value.</p>
201201 </div>
202202 </div>
203203 </section>
Modifiedlanding/public/voxlen-vs-wispr-flow/index.html+15−15View fileUnifiedSplit
@@ -4,11 +4,11 @@
44 <meta charset="UTF-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66 <title>Voxlen vs Wispr Flow — Comparison for Legal Professionals</title>
7 <meta name="description" content="Voxlen vs Wispr Flow compared head-to-head for lawyers and accountants. Legal clause library, privileged mode, Windows support, pricing. See which AI dictation tool wins for legal professionals." />
7 <meta name="description" content="Voxlen vs Wispr Flow compared head-to-head for lawyers and accountants. Legal clause library, privileged mode (coming soon), Windows support, pricing. See which AI dictation tool wins for legal professionals." />
88 <meta name="keywords" content="wispr flow alternative, voxlen vs wispr flow, wispr flow for lawyers, wispr flow windows, wispr flow legal, ai dictation comparison 2026, best voice dictation lawyers 2026" />
99 <link rel="canonical" href="https://voxlen.ai/voxlen-vs-wispr-flow" />
1010 <meta property="og:title" content="Voxlen vs Wispr Flow — Which AI Dictation Wins for Lawyers?" />
11 <meta property="og:description" content="Full comparison of Voxlen vs Wispr Flow for legal and accounting professionals. Legal clause library, privileged mode, Windows support, and more." />
11 <meta property="og:description" content="Full comparison of Voxlen vs Wispr Flow for legal and accounting professionals. Legal clause library, privileged mode (coming soon), Windows support, and more." />
1212 <meta property="og:type" content="article" />
1313 <meta property="og:url" content="https://voxlen.ai/voxlen-vs-wispr-flow" />
1414 <meta property="og:site_name" content="Voxlen" />
@@ -20,7 +20,7 @@
2020 "@context": "https://schema.org",
2121 "@type": "Article",
2222 "headline": "Voxlen vs Wispr Flow: Which AI Dictation Wins for Lawyers?",
23 "description": "A detailed, fair comparison of Voxlen vs Wispr Flow for legal and accounting professionals in 2026 — covering legal clause library, privileged mode, platform support, pricing, and more.",
23 "description": "A detailed, fair comparison of Voxlen vs Wispr Flow for legal and accounting professionals in 2026 — covering legal clause library, privileged mode (coming soon), platform support, pricing, and more.",
2424 "author": { "@type": "Organization", "name": "Voxlen" },
2525 "publisher": { "@type": "Organization", "name": "Voxlen", "url": "https://voxlen.ai/" },
2626 "datePublished": "2026-06-03",
@@ -41,17 +41,17 @@
4141 {
4242 "@type": "Question",
4343 "name": "Does Wispr Flow have a legal mode or legal clause library?",
44 "acceptedAnswer": { "@type": "Answer", "text": "No. Wispr Flow is a general-purpose dictation tool with no legal-specific features. There is no legal clause library, no court formatting, no privileged mode for sensitive client matters, and no accounting-specific features. Voxlen is purpose-built for legal and accounting professionals with 15+ built-in legal clauses, court formatting, and Privileged Mode." }
44 "acceptedAnswer": { "@type": "Answer", "text": "No. Wispr Flow is a general-purpose dictation tool with no legal-specific features. There is no legal clause library, no court formatting, no privileged mode for sensitive client matters, and no accounting-specific features. Voxlen is purpose-built for legal and accounting professionals with 15+ built-in legal clauses, court formatting, and Privileged Mode coming soon." }
4545 },
4646 {
4747 "@type": "Question",
4848 "name": "Is Voxlen a good Wispr Flow alternative?",
49 "acceptedAnswer": { "@type": "Answer", "text": "Yes — especially for lawyers and accountants. Voxlen matches Wispr Flow on core dictation accuracy and AI grammar correction, then adds features Wispr Flow doesn't have: Windows support, iPhone keyboard extension, legal clause library, Privileged Mode for confidential matters, accounting terminology support, and speaker diarization. For general consumers, Wispr Flow is a capable tool. For legal and accounting professionals, Voxlen is the clear choice." }
49 "acceptedAnswer": { "@type": "Answer", "text": "Yes — especially for lawyers and accountants. Voxlen matches Wispr Flow on core dictation accuracy and AI grammar correction, then adds features Wispr Flow doesn't have: Windows support, iPhone keyboard extension, legal clause library, accounting terminology support, speaker diarization, and Privileged Mode coming soon for confidential matters. For general consumers, Wispr Flow is a capable tool. For legal and accounting professionals, Voxlen is the clear choice." }
5050 },
5151 {
5252 "@type": "Question",
5353 "name": "How does Voxlen's pricing compare to Wispr Flow?",
54 "acceptedAnswer": { "@type": "Answer", "text": "Both Voxlen Pro and Wispr Flow Pro are priced similarly (Wispr Flow at $14/month for basic, higher for full features; Voxlen at $29/month). However, Voxlen at $29/month includes legal clause library, Privileged Mode, and cross-platform support (Mac + Windows + iPhone) that Wispr Flow doesn't offer at any price. Voxlen also offers a $599 lifetime plan with no ongoing fees." }
54 "acceptedAnswer": { "@type": "Answer", "text": "Both Voxlen Pro and Wispr Flow Pro are priced similarly (Wispr Flow at $14/month for basic, higher for full features; Voxlen at $29/month). However, Voxlen at $29/month includes legal clause library, cross-platform support (Mac + Windows + iPhone), and Privileged Mode coming soon — features Wispr Flow doesn't offer at any price. Voxlen also offers a $599 lifetime plan with no ongoing fees." }
5555 },
5656 {
5757 "@type": "Question",
@@ -230,7 +230,7 @@
230230 <tr class="highlight-row">
231231 <td><strong>Privileged / offline mode</strong></td>
232232 <td><span class="cross">❌ No on-device mode</span></td>
233 <td class="voxlen-col"><span class="check">✅ Full on-device Privileged Mode</span></td>
233 <td class="voxlen-col"><span class="check">🔜 On-device Privileged Mode (coming soon)</span></td>
234234 </tr>
235235 <tr class="highlight-row">
236236 <td><strong>Accounting features</strong></td>
@@ -282,7 +282,7 @@
282282 <div class="verdict-box winner">
283283 <div class="verdict-badge">Best for Legal & Accounting</div>
284284 <div class="verdict-name">Voxlen</div>
285 <p>If you're a lawyer, accountant, or other professional who needs legal clause insertion, court formatting, on-device Privileged Mode, or Windows support — Voxlen is the clear choice. No other dictation tool matches its depth of legal and accounting features.</p>
285 <p>If you're a lawyer, accountant, or other professional who needs legal clause insertion, court formatting, Windows support, or on-device Privileged Mode (coming soon) — Voxlen is the clear choice. No other dictation tool matches its depth of legal and accounting features.</p>
286286 <p>Also the better choice if you use Windows, need an iPhone keyboard, or want a lifetime plan.</p>
287287 <a href="https://voxlen.ai/#download" class="btn-primary" style="margin-top: 8px;">Try Voxlen Free</a>
288288 </div>
@@ -303,8 +303,8 @@
303303 <div class="cards">
304304 <div class="card">
305305 <div class="card-icon">🔒</div>
306 <h3>Privileged Mode — Zero Cloud</h3>
307 <p>Wispr Flow routes all audio through cloud servers. For lawyers handling sensitive client matters, this is a problem. Voxlen's Privileged Mode processes everything on-device using local Whisper — zero cloud, zero risk. Essential for legal privilege and attorney-client confidentiality.</p>
306 <h3>Privileged Mode — Zero Cloud (Coming Soon)</h3>
307 <p>Wispr Flow routes all audio through cloud servers. For lawyers handling sensitive client matters, this is a problem. Voxlen's Privileged Mode (coming soon) will process everything on-device using local Whisper — zero cloud, zero risk. Essential for legal privilege and attorney-client confidentiality. Today, Voxlen never stores your audio or transcripts — requests pass through zero-retention endpoints straight to the AI providers, and nothing is retained.</p>
308308 </div>
309309 <div class="card">
310310 <div class="card-icon">⚖️</div>
@@ -354,7 +354,7 @@
354354 <div class="pricing-card">
355355 <div class="price">$79<span style="font-size:1rem; font-weight:400">/mo</span></div>
356356 <div class="tier-name">Professional — for firms</div>
357 <p style="font-size:0.85rem; margin-top:8px;">SSO, team management, Privileged Mode, legal clause library, per-matter vocabulary. Wispr Flow has no equivalent.</p>
357 <p style="font-size:0.85rem; margin-top:8px;">SSO, team management, legal clause library, per-matter vocabulary, Privileged Mode coming soon. Wispr Flow has no equivalent.</p>
358358 </div>
359359 <div class="pricing-card">
360360 <div class="price">$599</div>
@@ -380,17 +380,17 @@
380380
381381 <div class="faq-item">
382382 <h3>Does Wispr Flow have a legal mode or legal clause library?</h3>
383 <p>No. Wispr Flow is a general-purpose dictation tool with no legal-specific features. There is no legal clause library, no court formatting, no privileged mode for sensitive client matters, and no accounting-specific features. Voxlen is purpose-built for legal and accounting professionals with 15+ built-in legal clauses, court formatting, and Privileged Mode.</p>
383 <p>No. Wispr Flow is a general-purpose dictation tool with no legal-specific features. There is no legal clause library, no court formatting, no privileged mode for sensitive client matters, and no accounting-specific features. Voxlen is purpose-built for legal and accounting professionals with 15+ built-in legal clauses, court formatting, and Privileged Mode coming soon.</p>
384384 </div>
385385
386386 <div class="faq-item">
387387 <h3>Is Voxlen a good Wispr Flow alternative?</h3>
388 <p>Yes — especially for lawyers and accountants. Voxlen matches Wispr Flow on core dictation accuracy and AI grammar correction, then adds features Wispr Flow doesn't have: Windows support, iPhone keyboard extension, legal clause library, Privileged Mode for confidential matters, accounting terminology support, and speaker diarization on the roadmap. For legal and accounting professionals, Voxlen is the clear choice.</p>
388 <p>Yes — especially for lawyers and accountants. Voxlen matches Wispr Flow on core dictation accuracy and AI grammar correction, then adds features Wispr Flow doesn't have: Windows support, iPhone keyboard extension, legal clause library, accounting terminology support, speaker diarization, and Privileged Mode coming soon for confidential matters. For legal and accounting professionals, Voxlen is the clear choice.</p>
389389 </div>
390390
391391 <div class="faq-item">
392392 <h3>How does Voxlen's pricing compare to Wispr Flow?</h3>
393 <p>Wispr Flow starts at $14/month (limited) with higher tiers for full features — Mac only. Voxlen Pro at $29/month includes all platforms (Mac + Windows + iPhone), legal clause library, Privileged Mode, and accounting features that Wispr Flow doesn't offer at any price. Voxlen also offers a $599 lifetime plan with no ongoing fees.</p>
393 <p>Wispr Flow starts at $14/month (limited) with higher tiers for full features — Mac only. Voxlen Pro at $29/month includes all platforms (Mac + Windows + iPhone), legal clause library, accounting features, and Privileged Mode coming soon — capabilities Wispr Flow doesn't offer at any price. Voxlen also offers a $599 lifetime plan with no ongoing fees.</p>
394394 </div>
395395
396396 <div class="faq-item">
@@ -403,7 +403,7 @@
403403 <section class="section" style="text-align: center;">
404404 <div class="container">
405405 <h2>The legal dictation tool<br />Wispr Flow can't be</h2>
406 <p style="max-width: 520px; margin: 0 auto 28px;">14-day free trial. No credit card. Mac + Windows + iPhone. Legal clause library included. Privileged Mode for sensitive matters.</p>
406 <p style="max-width: 520px; margin: 0 auto 28px;">14-day free trial. No credit card. Mac + Windows + iPhone. Legal clause library included. Privileged Mode for sensitive matters coming soon.</p>
407407 <a href="https://voxlen.ai/#download" class="btn-primary" style="font-size: 1.1rem; padding: 16px 36px;">Try Voxlen Free for 14 Days</a>
408408 <p style="margin-top: 16px; font-size: 0.8rem; color: #71717a;">Or <a href="https://voxlen.ai/">explore all Voxlen features →</a></p>
409409 </div>
Modifiedlanding/src/globals.css+20−26View fileUnifiedSplit
@@ -28,56 +28,50 @@ body {
2828 border-radius: 3px;
2929}
3030
31/* Static, understated headline accent — no animation. */
3132.gradient-text {
32 background: linear-gradient(135deg, #3366ff 0%, #8eb4ff 50%, #3366ff 100%);
33 background-size: 200% auto;
33 background: linear-gradient(120deg, #598bff 0%, #8eb4ff 100%);
3434 -webkit-background-clip: text;
35 background-clip: text;
3536 -webkit-text-fill-color: transparent;
36 animation: gradient-shift 3s ease infinite;
37}
38
39@keyframes gradient-shift {
40 0% { background-position: 0% center; }
41 50% { background-position: 100% center; }
42 100% { background-position: 0% center; }
4337}
4438
39/* Faint ambient tint at the top of the hero — kept very subtle. */
4540.glow-hero {
46 background: radial-gradient(ellipse 600px 300px at 50% 0%, rgba(51, 102, 255, 0.15) 0%, transparent 70%);
41 background: radial-gradient(ellipse 700px 320px at 50% 0%, rgba(51, 102, 255, 0.06) 0%, transparent 70%);
4742}
4843
44/* Legacy decorative orbs — disabled in favour of a clean, confident layout. */
4945.glow-orb {
50 position: absolute;
51 border-radius: 50%;
52 filter: blur(80px);
53 opacity: 0.3;
54 pointer-events: none;
46 display: none;
5547}
5648
5749.card-glow {
5850 position: relative;
5951}
6052
53/* Quiet hairline border instead of a neon gradient ring. */
6154.card-glow::before {
6255 content: "";
6356 position: absolute;
6457 inset: -1px;
6558 border-radius: inherit;
66 background: linear-gradient(135deg, rgba(51,102,255,0.2), transparent, rgba(51,102,255,0.1));
59 background: rgba(255, 255, 255, 0.06);
6760 z-index: -1;
6861}
6962
70@keyframes float {
71 0%, 100% { transform: translateY(0px); }
72 50% { transform: translateY(-10px); }
73}
74
63/* Floating animation retired — elements sit still. */
7564.float {
76 animation: float 6s ease-in-out infinite;
65 animation: none;
7766}
7867
79@keyframes pulse-ring {
80 0% { transform: scale(0.95); opacity: 0.5; }
81 50% { transform: scale(1.05); opacity: 0; }
82 100% { transform: scale(0.95); opacity: 0.5; }
68@media (prefers-reduced-motion: reduce) {
69 *,
70 *::before,
71 *::after {
72 animation-duration: 0.01ms ;
73 animation-iteration-count: 1 ;
74 transition-duration: 0.01ms ;
75 scroll-behavior: auto ;
76 }
8377}
Modifiedlanding/src/main.tsx+4−1View fileUnifiedSplit
@@ -1,10 +1,13 @@
11import React from "react";
22import ReactDOM from "react-dom/client";
3import { GoogleOAuthProvider } from "@react-oauth/google";
34import App from "./App";
45import "./globals.css";
56
67ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
78 <React.StrictMode>
8 <App />
9 <GoogleOAuthProvider clientId="450106027851-ht7jhib8hcujvda9hriatvmvd7r1dndt.apps.googleusercontent.com">
10 <App />
11 </GoogleOAuthProvider>
912 </React.StrictMode>
1013);
Modifiedlanding/vercel.json+2−1View fileUnifiedSplit
@@ -6,6 +6,7 @@
66 "devCommand": "npm run dev",
77 "installCommand": "npm install",
88 "rewrites": [
9 { "source": "/(.*)", "destination": "/index.html" }
9 { "source": "/api/(.*)", "destination": "/api/$1" },
10 { "source": "/((?!api/).*)", "destination": "/index.html" }
1011 ]
1112}
Modifiedlegal/ACCEPTABLE_USE.md+8−8View fileUnifiedSplit
@@ -1,11 +1,11 @@
11# Acceptable Use Policy
22
3**Marco Reid Voice**
3**Voxlen**
44**Effective 16 April 2026**
55
6This Acceptable Use Policy ("**AUP**") governs your use of Marco Reid Voice
6This Acceptable Use Policy ("**AUP**") governs your use of Voxlen
77(the "**Service**"). It is incorporated into the End User Licence Agreement
8and the Terms of Service. If you violate this AUP, Marco Reid may suspend or
8and the Terms of Service. If you violate this AUP, Voxlen may suspend or
99terminate your access, with or without notice.
1010
1111## 1. You must not
@@ -75,21 +75,21 @@ You must not use, attempt to use, or help another person use the Service to:
7575
7676You are solely responsible for Your Content, any Output generated from it,
7777and any consequences that flow from its use, disclosure, or distribution.
78Marco Reid does not review Your Content and does not endorse any Output.
78Voxlen does not review Your Content and does not endorse any Output.
7979
8080## 3. Reporting
8181
8282If you believe another user is violating this AUP or that the Service has
83been used to cause harm to you, report it to `abuse@marcoreid.com` with as
83been used to cause harm to you, report it to `abuse@voxlen.ai` with as
8484much detail as you can provide. For security issues, use
85`security@marcoreid.com` and follow `docs/SECURITY.md`.
85`security@voxlen.ai` and follow `docs/SECURITY.md`.
8686
8787## 4. Enforcement
8888
89Marco Reid may investigate suspected violations and take any action it
89Voxlen may investigate suspected violations and take any action it
9090considers appropriate, including removing features, suspending access,
9191terminating licences, preserving evidence, and cooperating with law
92enforcement. Marco Reid's exercise (or failure to exercise) any enforcement
92enforcement. Voxlen's exercise (or failure to exercise) any enforcement
9393right is not a waiver of any other right.
9494
9595## 5. Changes
Modifiedlegal/COPYRIGHT.md+11−11View fileUnifiedSplit
@@ -1,14 +1,14 @@
11# Copyright & Trademark Notice
22
3**Marco Reid Voice**
3**Voxlen**
44
5Copyright © 2026 Marco Reid. All rights reserved.
5Copyright © 2026 Voxlen. All rights reserved.
66
7The Marco Reid Voice software, including its source code, compiled
7The Voxlen software, including its source code, compiled
88binaries, UI designs, iconography, documentation, landing-page content,
99marketing copy, and accompanying materials ("the **Work**"), is the
10copyrighted work of Marco Reid. The Work is licensed — not sold — under
11the Marco Reid Voice Proprietary Licence (`LICENSE`) and the End User
10copyrighted work of Voxlen. The Work is licensed — not sold — under
11the Voxlen Proprietary Licence (`LICENSE`) and the End User
1212Licence Agreement (`legal/EULA.md`).
1313
1414Unauthorised reproduction, distribution, public display, public
@@ -19,10 +19,10 @@ criminal liability.
1919
2020## Trademarks
2121
22**Marco Reid®**, **Marco Reid Voice™**, the Marco Reid wordmark, and the
23Marco Reid "brass pin" emblem are trademarks of Marco Reid. Use is
22**Voxlen®**, **Voxlen™**, the Voxlen wordmark, and the
23Voxlen "brass pin" emblem are trademarks of Voxlen. Use is
2424permitted only in accordance with our Trademark Guidelines (available on
25request at `legal@marcoreid.com`) and the End User Licence Agreement.
25request at `legal@voxlen.ai`) and the End User Licence Agreement.
2626
2727Other product, company, and service names used within the Work may be
2828trademarks or registered trademarks of their respective owners. Use of
@@ -30,9 +30,9 @@ those names is for identification only and does not imply endorsement.
3030
3131## DMCA / copyright-infringement notices
3232
33If you believe that material available through or within Marco Reid Voice
33If you believe that material available through or within Voxlen
3434infringes your copyright, send a written notice to
35`copyright@marcoreid.com` that includes:
35`copyright@voxlen.ai` that includes:
3636
37371. your physical or electronic signature;
38382. identification of the copyrighted work claimed to be infringed;
@@ -55,4 +55,4 @@ remain subject to their original licences.
5555
5656## Contact
5757
58`legal@marcoreid.com`
58`legal@voxlen.ai`
Modifiedlegal/DPA.md+35−37View fileUnifiedSplit
@@ -1,12 +1,12 @@
11# Data Processing Addendum
22
3**Marco Reid Voice**
3**Voxlen**
44**Effective 16 April 2026**
55
66This Data Processing Addendum ("**DPA**") supplements the End User Licence
77Agreement and Terms of Service (together, the "**Agreement**") between
8Marco Reid ("**Marco Reid**") and the customer identified in the Agreement
9("**Customer**"). It applies where Customer's use of Marco Reid Voice (the
8Voxlen ("**Voxlen**") and the customer identified in the Agreement
9("**Customer**"). It applies where Customer's use of Voxlen (the
1010"**Service**") is subject to laws requiring a data-processing agreement —
1111including (without limitation) the EU General Data Protection Regulation
1212(GDPR), the UK GDPR, the Swiss Federal Act on Data Protection (FADP), the
@@ -15,7 +15,7 @@ Australian Privacy Principles, the California Consumer Privacy Act as
1515amended by the CPRA, and analogous laws (together, "**Data Protection
1616Laws**").
1717
18This DPA is made between Marco Reid and Customer and takes effect when the
18This DPA is made between Voxlen and Customer and takes effect when the
1919Agreement is accepted. If a conflict exists between this DPA and the
2020Agreement, this DPA controls as to the subject matter of personal-data
2121processing.
@@ -30,48 +30,47 @@ or in the applicable Data Protection Laws. In particular:
3030 Service.
3131- **"Processing"**, **"Controller"**, **"Processor"**, **"Data Subject"**,
3232 and **"Personal Data Breach"** have the meanings given in the GDPR.
33- **"Sub-processor"** means a third party engaged by Marco Reid to process
34 Customer Personal Data on Marco Reid's behalf.
33- **"Sub-processor"** means a third party engaged by Voxlen to process
34 Customer Personal Data on Voxlen's behalf.
3535
3636## 2. Roles and scope
3737
38382.1 **Customer as Controller.** Customer is the Controller (or in the case
3939of the Customer's own client data, a joint or independent Controller) of
40Customer Personal Data. Marco Reid is not a Controller or Processor of
40Customer Personal Data. Voxlen is not a Controller or Processor of
4141Customer's audio, transcripts, document context, or other content
4242processed locally by the Service, because **that content does not leave
43Customer's device to Marco Reid's systems**.
43Customer's device to Voxlen's systems**.
4444
45452.2 **Third-Party Services.** When Customer configures the Service to use
4646Deepgram, OpenAI, Anthropic, or any other third-party provider, the content
4747Customer transmits is sent directly from Customer's device to that
4848provider. That provider is an independent Controller or Processor engaged
49by Customer, not by Marco Reid. Customer is responsible for executing its
49by Customer, not by Voxlen. Customer is responsible for executing its
5050own DPA with each such provider.
5151
522.3 **Where Marco Reid acts as Processor.** To the extent that Marco Reid
522.3 **Where Voxlen acts as Processor.** To the extent that Voxlen
5353processes any Customer Personal Data (for example, information Customer
5454provides through support, licence administration, or any optional hosted
55feature), Marco Reid acts as Customer's Processor in respect of that data,
55feature), Voxlen acts as Customer's Processor in respect of that data,
5656and sections 3–12 of this DPA apply.
5757
5858## 3. Processing instructions
5959
60Marco Reid will process Customer Personal Data only on Customer's
60Voxlen will process Customer Personal Data only on Customer's
6161documented instructions. The Agreement, this DPA, Customer's in-product
6262configuration, and Customer's written support requests each constitute
63documented instructions. Marco Reid will notify Customer if, in Marco
64Reid's opinion, an instruction violates applicable Data Protection Law.
63documented instructions. Voxlen will notify Customer if, in Voxlen's opinion, an instruction violates applicable Data Protection Law.
6564
6665## 4. Confidentiality
6766
68Marco Reid will ensure that personnel authorised to process Customer
67Voxlen will ensure that personnel authorised to process Customer
6968Personal Data are bound by written confidentiality obligations or statutory
7069duty of confidence.
7170
7271## 5. Security measures
7372
74Marco Reid will implement appropriate technical and organisational measures
73Voxlen will implement appropriate technical and organisational measures
7574to protect Customer Personal Data against accidental or unlawful
7675destruction, loss, alteration, unauthorised disclosure, or access. Current
7776measures include, without limitation:
@@ -91,20 +90,20 @@ applicable to Customer.
9190
9291## 6. Data-subject requests
9392
94If Marco Reid receives a request from a Data Subject exercising rights
93If Voxlen receives a request from a Data Subject exercising rights
9594under Data Protection Laws (access, rectification, erasure, restriction,
9695portability, objection, withdrawal of consent, or non-discrimination),
97Marco Reid will, to the extent legally permitted, promptly inform
98Customer. Marco Reid will provide reasonable assistance to help Customer
96Voxlen will, to the extent legally permitted, promptly inform
97Customer. Voxlen will provide reasonable assistance to help Customer
9998respond, taking into account the nature of the processing and the
100information available to Marco Reid. Because most Customer content never
101reaches Marco Reid, Customer is best placed to act on most requests by
99information available to Voxlen. Because most Customer content never
100reaches Voxlen, Customer is best placed to act on most requests by
102101using the delete controls in the Service.
103102
104103## 7. Personal Data Breach notification
105104
106If Marco Reid becomes aware of a Personal Data Breach affecting Customer
107Personal Data processed by Marco Reid as Processor, Marco Reid will notify
105If Voxlen becomes aware of a Personal Data Breach affecting Customer
106Personal Data processed by Voxlen as Processor, Voxlen will notify
108107Customer without undue delay and in any event within seventy-two (72) hours
109108of becoming aware, to the extent legally permitted, and provide reasonable
110109information and assistance for Customer to meet its own notification
@@ -112,48 +111,48 @@ obligations.
112111
113112## 8. Sub-processors
114113
1158.1 Customer grants Marco Reid general authorisation to engage
1148.1 Customer grants Voxlen general authorisation to engage
116115Sub-processors to perform Processing on Customer's behalf, subject to the
117116conditions below.
118117
1198.2 Marco Reid will (a) impose written data-protection obligations on each
1188.2 Voxlen will (a) impose written data-protection obligations on each
120119Sub-processor no less protective than those in this DPA; and (b) remain
121120liable for the acts and omissions of its Sub-processors.
122121
1238.3 The current list of Marco Reid Sub-processors is published in
124`legal/SUBPROCESSORS.md`. Marco Reid will update that list before adding or
1228.3 The current list of Voxlen Sub-processors is published in
123`legal/SUBPROCESSORS.md`. Voxlen will update that list before adding or
125124replacing a Sub-processor. Customer may object in writing within fourteen
126125(14) days of update on reasonable data-protection grounds; the parties will
127126work in good faith to resolve the objection. If unresolved, Customer's sole
128127remedy is to terminate the affected portion of the Service without further
129128liability.
130129
1318.4 **Third-Party Services configured by Customer are not Marco Reid
1308.4 **Third-Party Services configured by Customer are not Voxlen
132131Sub-processors.** Customer's chosen STT and language-model providers are
133132directly contracted by Customer.
134133
135134## 9. International data transfers
136135
137Where Marco Reid transfers Customer Personal Data from the EEA, UK,
136Where Voxlen transfers Customer Personal Data from the EEA, UK,
138137Switzerland, or any other jurisdiction imposing transfer-restriction
139requirements, Marco Reid relies on (as applicable): (a) an adequacy
138requirements, Voxlen relies on (as applicable): (a) an adequacy
140139decision; (b) the EU Standard Contractual Clauses (Module 2 or Module 3,
141140as applicable) and their UK International Data Transfer Addendum; or (c)
142141other lawful mechanisms. Customer authorises these mechanisms by accepting
143142this DPA. Copies of current transfer safeguards are available on request at
144`privacy@marcoreid.com`.
143`privacy@voxlen.ai`.
145144
146145## 10. Assistance with DPIAs and regulator consultations
147146
148147Taking into account the nature of Processing and the information available
149to Marco Reid, Marco Reid will provide Customer with reasonable assistance
148to Voxlen, Voxlen will provide Customer with reasonable assistance
150149in carrying out data protection impact assessments and prior consultations
151150with competent supervisory authorities.
152151
153152## 11. Audit and compliance evidence
154153
155154Once per twelve (12) months, and subject to reasonable confidentiality and
156scoping, Marco Reid will provide Customer with (a) this DPA; (b) current
155scoping, Voxlen will provide Customer with (a) this DPA; (b) current
157156security documentation; (c) summaries of third-party assessments or
158157certifications (where available); and (d) responses to a reasonable
159158customer questionnaire. On-site audits are available only where required
@@ -162,11 +161,10 @@ business hours, and at Customer's cost.
162161
163162## 12. Return or deletion
164163
165On termination of the Agreement, Marco Reid will return or delete Customer
164On termination of the Agreement, Voxlen will return or delete Customer
166165Personal Data in its possession within thirty (30) days, except to the
167166extent that applicable law requires continued retention. Data held locally
168in the Software is deleted by Customer when Customer deletes it; Marco
169Reid has no access to it.
167in the Software is deleted by Customer when Customer deletes it; Voxlen has no access to it.
170168
171169## 13. Liability
172170
@@ -177,7 +175,7 @@ contract.
177175
178176## 14. Changes
179177
180Marco Reid may update this DPA from time to time to reflect changes in
178Voxlen may update this DPA from time to time to reflect changes in
181179Data Protection Laws or Sub-processors. The updated DPA will be posted
182180within the Service or on our website. Changes will not diminish Customer's
183181rights in any material respect without consent.
Modifiedlegal/EULA.md+45−45View fileUnifiedSplit
@@ -1,17 +1,17 @@
11# End User Licence Agreement
22
3**Marco Reid Voice**
3**Voxlen**
44**Version 1.0 — 16 April 2026**
55
66THIS END USER LICENCE AGREEMENT (**"EULA"**) IS A LEGALLY BINDING CONTRACT
7BETWEEN YOU (**"YOU"**, **"YOUR"**, OR **"LICENSEE"**) AND **MARCO REID**
8(**"MARCO REID"**, **"WE"**, **"US"**, OR **"OUR"**) GOVERNING YOUR USE OF THE
9**MARCO REID VOICE** SOFTWARE AND ANY ACCOMPANYING DOCUMENTATION (THE
7BETWEEN YOU (**"YOU"**, **"YOUR"**, OR **"LICENSEE"**) AND **VOXLEN**
8(**"VOXLEN"**, **"WE"**, **"US"**, OR **"OUR"**) GOVERNING YOUR USE OF THE
9**VOXLEN VOICE** SOFTWARE AND ANY ACCOMPANYING DOCUMENTATION (THE
1010**"SOFTWARE"**). BY INSTALLING, COPYING, OR OTHERWISE USING THE SOFTWARE YOU
1111AGREE TO BE BOUND BY THIS EULA. IF YOU DO NOT AGREE, DO NOT INSTALL OR USE THE
1212SOFTWARE AND DELETE ALL COPIES IN YOUR POSSESSION.
1313
14This EULA is read together with the Marco Reid Voice Terms of Service
14This EULA is read together with the Voxlen Terms of Service
1515(`legal/TERMS.md`), Privacy Policy (`legal/PRIVACY_POLICY.md`), Acceptable Use
1616Policy (`legal/ACCEPTABLE_USE.md`), and, where applicable, Data Processing
1717Addendum (`legal/DPA.md`). In the event of conflict, the Terms of Service
@@ -31,13 +31,13 @@ to use the Software in accordance with this EULA.
3131one party to the other in connection with the Software, including the
3232Software itself, pricing, feature roadmaps, and user content.
3333
34**"Documentation"** means user-facing materials Marco Reid provides with the
34**"Documentation"** means user-facing materials Voxlen provides with the
3535Software, including in-product help, READMEs, and published guides.
3636
3737**"Output"** means any transcription, correction, polished text, or other
3838result generated by Your use of the Software.
3939
40**"Third-Party Services"** means services not owned or operated by Marco Reid
40**"Third-Party Services"** means services not owned or operated by Voxlen
4141that the Software can interoperate with, including but not limited to
4242Deepgram, OpenAI, and Anthropic.
4343
@@ -47,7 +47,7 @@ with, or generate using the Software.
4747
4848## 2. Licence grant
4949
50Subject to Your continuous compliance with this EULA, Marco Reid grants You a
50Subject to Your continuous compliance with this EULA, Voxlen grants You a
5151**personal, limited, non-exclusive, non-transferable, non-sublicensable,
5252revocable licence** to:
5353
@@ -57,7 +57,7 @@ revocable licence** to:
5757(b) make one (1) archival backup copy of each installer, provided You
5858 reproduce all proprietary notices in the backup.
5959
60All rights not expressly granted are reserved to Marco Reid.
60All rights not expressly granted are reserved to Voxlen.
6161
6262## 3. Licence restrictions
6363
@@ -83,7 +83,7 @@ You shall not, and shall not permit any Authorised User or third party to:
8383 but not limited to generative, classification, or embedding models;
8484
8585(f) use the Software to build, contribute to, or market any product that
86 competes with the Software or with Marco Reid;
86 competes with the Software or with Voxlen;
8787
8888(g) use the Software to process any data You are not lawfully entitled to
8989 process, or in violation of any applicable law, regulation, professional
@@ -97,7 +97,7 @@ You shall not, and shall not permit any Authorised User or third party to:
9797 rate-limiting, or telemetry-suppression feature of the Software;
9898
9999(j) publish, publicise, or disclose the results of any benchmark, performance
100 test, or security assessment of the Software without Marco Reid's prior
100 test, or security assessment of the Software without Voxlen's prior
101101 written consent; or
102102
103103(k) use the Software in any high-risk application where failure could lead to
@@ -107,17 +107,17 @@ You shall not, and shall not permit any Authorised User or third party to:
107107
108108## 4. Ownership
109109
110The Software is licensed, not sold. Marco Reid and its licensors retain all
110The Software is licensed, not sold. Voxlen and its licensors retain all
111111right, title, and interest in and to the Software, including all intellectual
112112property rights therein. Nothing in this EULA transfers any ownership interest
113113in the Software to You. Feedback You provide (see section 12) is licensed to
114Marco Reid on the terms set out in that section.
114Voxlen on the terms set out in that section.
115115
116116## 5. Your Content and Output
117117
1185.1 **Ownership of Your Content.** As between You and Marco Reid, You retain
1185.1 **Ownership of Your Content.** As between You and Voxlen, You retain
119119all right, title, and interest in and to Your Content and to the Output, to
120the extent such rights exist under applicable law. Marco Reid claims no
120the extent such rights exist under applicable law. Voxlen claims no
121121ownership in either.
122122
1231235.2 **Your responsibility.** You are solely responsible for: (a) obtaining and
@@ -126,7 +126,7 @@ to be captured, processed, transmitted to Third-Party Services, and converted
126126into Output; (b) the legality and accuracy of Your Content and Output;
127127(c) ensuring Your use of the Software does not breach any confidentiality,
128128privilege, fiduciary, regulatory, or professional obligation; and (d) backing
129up Your Content. Marco Reid does not back up Your Content.
129up Your Content. Voxlen does not back up Your Content.
130130
1311315.3 **Output is not advice.** Output is generated by machine-learning models
132132operated by Third-Party Services. It may be inaccurate, incomplete,
@@ -136,9 +136,9 @@ accounting, tax, medical, financial, or other professional advice. You
136136professional before relying on it or delivering it to any client, regulator,
137137court, or third party.
138138
1395.4 **No training by Marco Reid.** Marco Reid does not use Your Content,
1395.4 **No training by Voxlen.** Voxlen does not use Your Content,
140140Output, or telemetry to train, fine-tune, or evaluate any machine-learning
141model. Marco Reid does not receive Your Content or Output; they are
141model. Voxlen does not receive Your Content or Output; they are
142142transmitted directly from Your device to the Third-Party Services You
143143configure.
144144
@@ -147,7 +147,7 @@ configure.
1471476.1 **BYO credentials.** The Software requires You to supply Your own API
148148credentials for Third-Party Services (a "bring-your-own-key" model). Your
149149relationship with each Third-Party Service is directly between You and that
150provider, subject to that provider's own terms and privacy policy. Marco Reid
150provider, subject to that provider's own terms and privacy policy. Voxlen
151151is not a party to that relationship, does not resell the services, and does
152152not act as a data processor, reseller, or intermediary in respect of the
153153content transmitted to those services.
@@ -159,7 +159,7 @@ Software complies with all applicable laws and professional obligations.
159159
1601606.3 **No endorsement.** References in the Software to any Third-Party Service
161161are informational only and do not constitute an endorsement, recommendation,
162or warranty by Marco Reid.
162or warranty by Voxlen.
163163
164164## 7. Fees; taxes
165165
@@ -167,14 +167,14 @@ If the Software or any feature is offered for a fee, You will pay all fees in
167167accordance with the ordering documentation or checkout flow. All fees are
168168non-refundable except as required by non-excludable law. Fees are exclusive
169169of taxes; You are responsible for all applicable taxes, duties, and levies,
170other than taxes on Marco Reid's net income.
170other than taxes on Voxlen's net income.
171171
172172## 8. Updates and versions
173173
174Marco Reid may issue updates, patches, and new versions of the Software at
174Voxlen may issue updates, patches, and new versions of the Software at
175175its discretion. Auto-update behaviour is configurable; by default the
176176Software may check for and apply updates over the network. Updates are
177delivered under this EULA. Marco Reid has no obligation to maintain, support,
177delivered under this EULA. Voxlen has no obligation to maintain, support,
178178or continue any particular version or feature.
179179
180180## 9. Term and termination
@@ -185,7 +185,7 @@ Software and continues until terminated.
1851859.2 **Termination by You.** You may terminate at any time by ceasing use of
186186the Software and uninstalling all copies.
187187
1889.3 **Termination by Marco Reid.** Marco Reid may terminate this EULA
1889.3 **Termination by Voxlen.** Voxlen may terminate this EULA
189189immediately on notice (including in-product notice) if You breach this EULA,
190190the Terms of Service, or the Acceptable Use Policy, or if continued provision
191191of the Software becomes unlawful or commercially impracticable.
@@ -198,7 +198,7 @@ must immediately stop using and destroy all copies of the Software. Sections
198198
199199THE SOFTWARE, INCLUDING ALL FEATURES, DOCUMENTATION, AND OUTPUT, IS PROVIDED
200200**"AS IS"** AND **"AS AVAILABLE"**, WITH ALL FAULTS AND WITHOUT WARRANTY OF
201ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY LAW, MARCO REID EXPRESSLY
201ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY LAW, VOXLEN EXPRESSLY
202202DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE,
203203INCLUDING (WITHOUT LIMITATION) ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
204204PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE, ACCURACY, QUIET ENJOYMENT,
@@ -206,7 +206,7 @@ UNINTERRUPTED OPERATION, ERROR-FREE OPERATION, SECURITY, OR FREEDOM FROM
206206HARMFUL CODE, AND ANY WARRANTY ARISING FROM COURSE OF DEALING, USAGE, OR
207207TRADE.
208208
209MARCO REID DOES NOT WARRANT THAT: (a) THE SOFTWARE WILL MEET YOUR
209VOXLEN DOES NOT WARRANT THAT: (a) THE SOFTWARE WILL MEET YOUR
210210REQUIREMENTS OR EXPECTATIONS; (b) OUTPUT WILL BE ACCURATE, COMPLETE,
211211RELIABLE, CURRENT, OR SUITABLE FOR ANY PARTICULAR PURPOSE; (c) DEFECTS WILL
212212BE CORRECTED; OR (d) THE SOFTWARE OR THE SERVERS THAT MAKE IT AVAILABLE ARE
@@ -217,31 +217,31 @@ Guarantees Act 1993 (NZ), Australian Consumer Law, UK consumer protection
217217law, or analogous legislation in Your jurisdiction, and if Your use of the
218218Software is acquired for the purpose of a business (as defined in those
219219statutes), You agree that those consumer guarantees do not apply. Where such
220consumer guarantees cannot be excluded, Marco Reid's liability for breach is
221limited to, at Marco Reid's option, replacement of the Software or refund of
220consumer guarantees cannot be excluded, Voxlen's liability for breach is
221limited to, at Voxlen's option, replacement of the Software or refund of
222222the price paid.
223223
224224## 11. Limitation of liability
225225
22622611.1 **Exclusion of indirect damages.** TO THE MAXIMUM EXTENT PERMITTED BY
227LAW, IN NO EVENT WILL MARCO REID OR ITS AFFILIATES, LICENSORS, OFFICERS,
227LAW, IN NO EVENT WILL VOXLEN OR ITS AFFILIATES, LICENSORS, OFFICERS,
228228DIRECTORS, EMPLOYEES, OR AGENTS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
229229SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR ANY DAMAGES
230230FOR LOST PROFITS, LOST REVENUE, LOST DATA, LOSS OF GOODWILL, BUSINESS
231231INTERRUPTION, SUBSTITUTE PROCUREMENT, OR PROFESSIONAL-LIABILITY EXPOSURE,
232232ARISING OUT OF OR RELATED TO THE SOFTWARE, THE OUTPUT, OR THIS EULA,
233233REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT, WARRANTY, STRICT
234LIABILITY, OR OTHERWISE) AND EVEN IF MARCO REID HAS BEEN ADVISED OF THE
234LIABILITY, OR OTHERWISE) AND EVEN IF VOXLEN HAS BEEN ADVISED OF THE
235235POSSIBILITY OF SUCH DAMAGES.
236236
23711.2 **Liability cap.** TO THE MAXIMUM EXTENT PERMITTED BY LAW, MARCO REID'S
23711.2 **Liability cap.** TO THE MAXIMUM EXTENT PERMITTED BY LAW, VOXLEN'S
238238TOTAL AGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THE SOFTWARE OR THIS
239239EULA WILL NOT EXCEED THE GREATER OF (A) THE AMOUNTS ACTUALLY PAID BY YOU TO
240MARCO REID FOR THE SOFTWARE IN THE TWELVE (12) MONTHS IMMEDIATELY PRECEDING
240VOXLEN FOR THE SOFTWARE IN THE TWELVE (12) MONTHS IMMEDIATELY PRECEDING
241241THE FIRST EVENT GIVING RISE TO THE CLAIM OR (B) NZD $100.
242242
24324311.3 **Basis of the bargain.** You acknowledge that the foregoing
244disclaimers and liability limits are a material basis on which Marco Reid is
244disclaimers and liability limits are a material basis on which Voxlen is
245245willing to license the Software at the price charged (including at no
246246charge) and would not license the Software without them.
247247
@@ -252,15 +252,15 @@ negligence.
252252
253253## 12. Feedback
254254
255If You send Marco Reid feedback, suggestions, or ideas about the Software
256("**Feedback**"), You grant Marco Reid a perpetual, irrevocable, worldwide,
255If You send Voxlen feedback, suggestions, or ideas about the Software
256("**Feedback**"), You grant Voxlen a perpetual, irrevocable, worldwide,
257257royalty-free, sublicensable, transferable licence to use, modify, and
258258commercialise that Feedback without obligation or attribution to You.
259259Feedback is not Confidential Information.
260260
261261## 13. Indemnity
262262
263You will defend, indemnify, and hold harmless Marco Reid, its Affiliates, and
263You will defend, indemnify, and hold harmless Voxlen, its Affiliates, and
264264each of their officers, directors, employees, contractors, and agents from
265265and against any and all claims, liabilities, damages, losses, fines,
266266penalties, costs, and expenses (including reasonable legal fees) arising out
@@ -269,7 +269,7 @@ including in combination with any Third-Party Service; (c) Your breach of
269269this EULA, the Terms of Service, or the Acceptable Use Policy; (d) Your
270270violation of any law, regulation, professional rule, or third-party right;
271271or (e) any unauthorised access to or use of the Software through Your
272account or device. Marco Reid may assume exclusive control of any matter
272account or device. Voxlen may assume exclusive control of any matter
273273You are required to indemnify.
274274
275275## 14. Export, sanctions, and government use
@@ -305,23 +305,23 @@ urgent injunctive or equitable relief in the courts of New Zealand, which
305305have exclusive jurisdiction for such relief.
306306
30730715.3 **Class action waiver.** To the maximum extent permitted by law, You and
308Marco Reid each waive any right to assert a claim on a class, collective, or
308Voxlen each waive any right to assert a claim on a class, collective, or
309309representative basis. Any dispute must be brought in Your individual capacity.
310310
31131115.4 **Assignment.** You may not assign or transfer this EULA (by operation
312of law or otherwise) without Marco Reid's prior written consent. Marco Reid
312of law or otherwise) without Voxlen's prior written consent. Voxlen
313313may assign this EULA, in whole or in part, without consent, including to an
314314Affiliate or in connection with a merger, acquisition, or sale of assets.
315315
31615.5 **Amendment.** Marco Reid may update this EULA from time to time. The
317updated EULA will be posted within the Software or on Marco Reid's website.
31615.5 **Amendment.** Voxlen may update this EULA from time to time. The
317updated EULA will be posted within the Software or on Voxlen's website.
318318Your continued use of the Software after the update takes effect constitutes
319319acceptance. If You do not accept an update, You must stop using the
320320Software.
321321
32232215.6 **Entire agreement.** This EULA, together with the Terms of Service,
323323Privacy Policy, Acceptable Use Policy, and (if applicable) Data Processing
324Addendum, constitutes the entire agreement between You and Marco Reid
324Addendum, constitutes the entire agreement between You and Voxlen
325325regarding the Software and supersedes any prior or contemporaneous
326326understandings.
327327
@@ -331,11 +331,11 @@ the minimum extent necessary to make it enforceable.
331331
33233215.8 **No waiver.** No waiver is effective unless in writing.
333333
33415.9 **Notices.** Notices to Marco Reid must be sent to
335`legal@marcoreid.com`. Marco Reid may give notice via email, in-product
33415.9 **Notices.** Notices to Voxlen must be sent to
335`legal@voxlen.ai`. Voxlen may give notice via email, in-product
336336message, or on its website.
337337
33815.10 **Contact.** Marco Reid, New Zealand. `legal@marcoreid.com`.
33815.10 **Contact.** Voxlen, New Zealand. `legal@voxlen.ai`.
339339
340340---
341341
Modifiedlegal/PRIVACY_POLICY.md+24−24View fileUnifiedSplit
@@ -1,19 +1,19 @@
11# Privacy Policy
22
3**Marco Reid Voice**
3**Voxlen**
44**Effective 16 April 2026**
55
6Marco Reid ("**Marco Reid**", "**we**", "**us**", "**our**") respects your
6Voxlen ("**Voxlen**", "**we**", "**us**", "**our**") respects your
77privacy. This Privacy Policy explains what personal information we and the
8Marco Reid Voice software ("**the Software**") do and do not collect, how it
8Voxlen software ("**the Software**") do and do not collect, how it
99is used, the choices you have, and the rights you may have under applicable
1010law.
1111
1212This policy applies to:
1313
14- the Marco Reid Voice desktop application (macOS, Windows, Linux);
15- the Marco Reid Voice iOS keyboard extension;
16- the `marcoreid.com` marketing website (the "**Site**"); and
14- the Voxlen desktop application (macOS, Windows, Linux);
15- the Voxlen iOS keyboard extension;
16- the `voxlen.ai` marketing website (the "**Site**"); and
1717- any direct support communications you have with us.
1818
1919It does **not** cover the third-party services you choose to integrate with
@@ -21,7 +21,7 @@ the Software (see section 5).
2121
2222## 1. The short version
2323
24- Marco Reid Voice runs **on your own device**. Your audio, transcripts,
24- Voxlen runs **on your own device**. Your audio, transcripts,
2525 settings, and credentials stay on your device unless you explicitly send
2626 them to a third-party provider that you have configured.
2727- **We do not operate servers that receive, store, or process your audio or
@@ -37,18 +37,18 @@ the Software (see section 5).
3737## 2. Who the "controller" is
3838
3939For the desktop and iOS software, **you** are the data controller of Your
40Content (your audio, your transcripts, your settings). Marco Reid is not a
40Content (your audio, your transcripts, your settings). Voxlen is not a
4141controller, joint controller, or processor of that content — it never leaves
4242your device in a form that reaches us.
4343
4444For information you submit to us directly (for example, by emailing support
45or purchasing a licence through the Site), Marco Reid is the controller. Our
46contact point is `privacy@marcoreid.com`.
45or purchasing a licence through the Site), Voxlen is the controller. Our
46contact point is `privacy@voxlen.ai`.
4747
4848## 3. What the Software processes locally (on your device)
4949
5050The following data is stored on your device by the Software. It is **not**
51transmitted to Marco Reid.
51transmitted to Voxlen.
5252
5353| Local data | Where it is stored |
5454| --------------------- | ---------------------------------------------------- |
@@ -82,17 +82,17 @@ situations, and only to the destinations listed:
8282| ----------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
8383| Audio frames | Deepgram **or** OpenAI Whisper | While dictation is active, only to the speech-to-text engine you selected |
8484| Transcript text | Anthropic **or** OpenAI | Only when you enable grammar correction and trigger a polish pass |
85| Update check | GitHub Releases / Marco Reid update endpoint | When the built-in updater runs (configurable; you can disable auto-update in Settings) |
85| Update check | GitHub Releases / Voxlen update endpoint | When the built-in updater runs (configurable; you can disable auto-update in Settings) |
8686
8787**No other outbound traffic originates from the Software.** The Software
88does not send anything to Marco Reid-operated servers as part of normal
88does not send anything to Voxlen-operated servers as part of normal
8989operation.
9090
9191## 5. Third-party providers you configure
9292
9393When you enter your own API key for a provider and use a feature that calls
9494that provider, the Software connects directly from your device to the
95provider. Marco Reid does not proxy, log, or intercept this traffic.
95provider. Voxlen does not proxy, log, or intercept this traffic.
9696
9797- **Deepgram** — <https://deepgram.com/privacy>
9898- **OpenAI (Whisper, GPT models)** — <https://openai.com/policies/privacy-policy>
@@ -100,7 +100,7 @@ provider. Marco Reid does not proxy, log, or intercept this traffic.
100100
101101Those providers act as independent controllers or processors in respect of
102102the content you send them. Their privacy policies and data-processing terms
103apply. You are responsible for reviewing and accepting them. Marco Reid is
103apply. You are responsible for reviewing and accepting them. Voxlen is
104104not a party to the data relationship between you and any of them, does not
105105act as your processor in respect of that content, and does not hold a data
106106processing agreement with those providers on your behalf.
@@ -158,7 +158,7 @@ service providers operate. Where required, we rely on adequacy
158158determinations, the UK International Data Transfer Addendum, EU Standard
159159Contractual Clauses, or equivalent safeguards to protect cross-border
160160transfers. Copies of the relevant safeguards are available on request at
161`privacy@marcoreid.com`.
161`privacy@voxlen.ai`.
162162
163163## 9. Retention
164164
@@ -172,7 +172,7 @@ purpose it was collected, or as required by law. Indicative periods:
172172 thereafter to handle refunds and disputes.
173173
174174Locally-stored Software data is retained by you and deleted when you delete
175it. Marco Reid cannot delete data that never reached Marco Reid.
175it. Voxlen cannot delete data that never reached Voxlen.
176176
177177## 10. Your rights
178178
@@ -200,11 +200,11 @@ rights over personal information we hold about you:
200200California residents additionally have the right to non-discrimination for
201201exercising a CCPA/CPRA right, to know the categories of personal information
202202collected in the prior 12 months, the sources, the purposes, and the
203categories of third parties with whom it is shared. Marco Reid does not
203categories of third parties with whom it is shared. Voxlen does not
204204"sell" or "share" personal information as those terms are defined in
205205CCPA/CPRA.
206206
207To exercise any right, email `privacy@marcoreid.com`. We may need to verify
207To exercise any right, email `privacy@voxlen.ai`. We may need to verify
208208your identity before responding.
209209
210210## 11. Security
@@ -222,7 +222,7 @@ See `docs/SECURITY.md` for our vulnerability-disclosure policy.
222222
223223The Software is not directed to children under 16 and we do not knowingly
224224collect personal information from children under 16. If you believe a child
225has provided personal information to us, email `privacy@marcoreid.com` and
225has provided personal information to us, email `privacy@voxlen.ai` and
226226we will delete it.
227227
228228## 13. Automated decision-making
@@ -230,7 +230,7 @@ we will delete it.
230230The Software uses third-party machine-learning models to transcribe and
231231polish text. Those are not "decisions producing legal or similarly
232232significant effects" within the meaning of GDPR Article 22; the Output is
233drafting assistance that you must review. Marco Reid does not use your data
233drafting assistance that you must review. Voxlen does not use your data
234234to make automated decisions about you.
235235
236236## 14. Do Not Track
@@ -247,13 +247,13 @@ top reflects the latest version.
247247
248248## 16. Contact
249249
250**Marco Reid — Privacy**
251Email: `privacy@marcoreid.com`
250**Voxlen — Privacy**
251Email: `privacy@voxlen.ai`
252252Postal: *to be published before public launch*
253253
254254If you are in the European Economic Area or the United Kingdom and require
255255a representative under Article 27 of the GDPR or the UK GDPR, contact
256`privacy@marcoreid.com` and we will provide details of our appointed
256`privacy@voxlen.ai` and we will provide details of our appointed
257257representative.
258258
259259---
Modifiedlegal/README.md+8−8View fileUnifiedSplit
@@ -1,6 +1,6 @@
1# Marco Reid Voice — Legal
1# Voxlen — Legal
22
3This directory contains the binding legal documents for Marco Reid Voice.
3This directory contains the binding legal documents for Voxlen.
44Use of the Software is subject to all of them, read together.
55
66| Document | What it covers |
@@ -22,11 +22,11 @@ arbitration seated in Auckland. See `TERMS.md` §14 and `EULA.md` §15.
2222
2323## Contacts
2424
25- `legal@marcoreid.com` — contracts, licensing, general legal
26- `privacy@marcoreid.com` — privacy rights and data-protection requests
27- `security@marcoreid.com` — vulnerability disclosure (see also `../docs/SECURITY.md`)
28- `abuse@marcoreid.com` — acceptable-use complaints
29- `copyright@marcoreid.com` — copyright and DMCA notices
25- `legal@voxlen.ai` — contracts, licensing, general legal
26- `privacy@voxlen.ai` — privacy rights and data-protection requests
27- `security@voxlen.ai` — vulnerability disclosure (see also `../docs/SECURITY.md`)
28- `abuse@voxlen.ai` — acceptable-use complaints
29- `copyright@voxlen.ai` — copyright and DMCA notices
3030
3131## Order of precedence
3232
@@ -41,7 +41,7 @@ Where two documents conflict:
4141
4242## Updates
4343
44Marco Reid may update these documents from time to time. Material changes
44Voxlen may update these documents from time to time. Material changes
4545will be communicated via in-product notice or email. Continued use of the
4646Software after an update constitutes acceptance; if you do not accept, you
4747must stop using the Software.
Modifiedlegal/SUBPROCESSORS.md+21−25View fileUnifiedSplit
@@ -1,50 +1,46 @@
11# Sub-processors
22
3**Marco Reid Voice**
4**Last updated: 16 April 2026**
3**Voxlen**
4**Last updated: 12 June 2026**
55
6This page lists the service providers Marco Reid engages to process
7personal information on Marco Reid's behalf (**"Sub-processors"**), as
6This page lists the service providers Voxlen engages to process
7personal information on Voxlen's behalf (**"Sub-processors"**), as
88required by the Data Processing Addendum (`legal/DPA.md`).
99
10Because Marco Reid Voice runs on your device and does not send Your Content
11to Marco Reid-operated servers, most processing never involves a Marco
12Reid Sub-processor. This list covers only the ancillary services Marco
13Reid uses to operate its business (email, billing, release hosting, etc.).
10Because Voxlen runs on your device and never stores Your Content on
11Voxlen-operated servers (account requests pass transiently through
12zero-retention endpoints), most processing never involves a Voxlen
13Sub-processor. This list covers only the ancillary services Voxlen uses to operate its business (email, billing, release hosting, etc.).
1414
1515## Current Sub-processors
1616
1717| Sub-processor | Purpose | Location of processing |
1818| ----------------- | ---------------------------------------------------------------------------------- | ---------------------- |
1919| GitHub, Inc. | Source control, release hosting (installer downloads), auto-update manifest | United States |
20| Cloudflare, Inc. | CDN, TLS termination, DDoS protection for `marcoreid.com` and release endpoints | Global |
20| Cloudflare, Inc. | CDN, TLS termination, DDoS protection for `voxlen.ai` and release endpoints | Global |
2121| Stripe, Inc. | Payment processing, subscription billing (if you purchase a paid tier) | United States |
2222| Amazon Web Services | Email relay and secure file storage for support attachments | Sydney (ap-southeast-2) |
23| Google Workspace | Support email, calendar, document collaboration for Marco Reid staff | United States / EU |
24| Anthropic, PBC | Internal productivity use (Marco Reid's own staff) — **not** used to process any Customer Personal Data | United States |
23| Google Workspace | Support email, calendar, document collaboration for Voxlen staff | United States / EU |
24| Vercel, Inc. | Hosting for `voxlen.ai` and the zero-retention API endpoints (transit only — no Customer content stored) | United States |
25| Deepgram, Inc. | Speech-to-text processing when you use a Voxlen account (model-training opt-out enforced on every request) | United States |
26| Anthropic, PBC | Language-model grammar correction (Claude) when you use a Voxlen account | United States |
27| OpenAI, L.L.C. | Speech-to-text (Whisper) and language-model grammar correction when you use a Voxlen account | United States |
2528
2629### Customer-configured third parties (not Sub-processors)
2730
28The following services receive Customer content only when **Customer**
29configures the Service with Customer's own API credentials. They are not
30Marco Reid Sub-processors; they are independent providers engaged by
31Customer under their own terms:
32
33- Deepgram, Inc. — streaming speech-to-text.
34- OpenAI, L.L.C. — speech-to-text (Whisper) and language-model grammar
35 correction.
36- Anthropic, PBC — language-model grammar correction (Claude).
37
38Customer is responsible for executing its own data-processing agreement
39with each of those providers where required.
31If you configure the Service with your own API credentials instead of a
32Voxlen account, the providers above act as independent processors engaged
33directly by you under your own terms, and you are responsible for
34executing your own data-processing agreement with each of them where
35required.
4036
4137## Changes
4238
43Marco Reid will update this page before engaging a new Sub-processor or
39Voxlen will update this page before engaging a new Sub-processor or
4440replacing an existing one. Customers who have signed the DPA may object in
4541writing within fourteen (14) days of the update on reasonable data-
4642protection grounds.
4743
4844## Contact
4945
50`privacy@marcoreid.com`.
46`privacy@voxlen.ai`.
Modifiedlegal/TERMS.md+27−26View fileUnifiedSplit
@@ -1,12 +1,12 @@
11# Terms of Service
22
3**Marco Reid Voice**
3**Voxlen**
44**Effective 16 April 2026**
55
66These Terms of Service (the **"Terms"**) govern access to and use of the
7Marco Reid Voice desktop application, iOS keyboard extension, associated
7Voxlen desktop application, iOS keyboard extension, associated
88websites, landing pages, and supporting materials (together, the
9**"Service"**) provided by **Marco Reid** (**"Marco Reid"**, **"we"**,
9**"Service"**) provided by **Voxlen** (**"Voxlen"**, **"we"**,
1010**"us"**, **"our"**). By accessing or using the Service you (**"you"**,
1111**"your"**) agree to these Terms, to the End User Licence Agreement
1212(`legal/EULA.md`), the Privacy Policy (`legal/PRIVACY_POLICY.md`), the
@@ -37,17 +37,19 @@ any third-party credentials you use with the Service.
37372.2 You must keep any credentials (including third-party API keys stored in
3838the app's local configuration) secure. You are responsible for all activity
3939that occurs through your installation or your credentials. Notify us
40immediately at `security@marcoreid.com` if you suspect any unauthorised
40immediately at `security@voxlen.ai` if you suspect any unauthorised
4141access.
4242
4343## 3. Your responsibilities
4444
45453.1 **Your content.** You retain all rights in any audio, transcripts,
4646prompts, vocabulary lists, document context, and other materials you input
47into or generate with the Service (**"Your Content"**). You grant Marco Reid
47into or generate with the Service (**"Your Content"**). You grant Voxlen
4848only the technical licences strictly necessary to operate the Service on
49your device. Marco Reid does not receive, process, or store Your Content on
50Marco Reid-operated servers.
49your device. Voxlen does not store Your Content on Voxlen-operated
50servers. When you use a Voxlen account, requests may pass transiently
51through zero-retention Voxlen endpoints solely to reach the AI providers;
52nothing is logged or retained.
5153
52543.2 **Lawful use.** You will use the Service only for lawful purposes, in
5355accordance with the Acceptable Use Policy, and in compliance with all laws,
@@ -78,7 +80,7 @@ The Service integrates, at your option, with third-party speech-to-text and
7880language-model services such as Deepgram, OpenAI, and Anthropic
7981(**"Third-Party Services"**). The relationship between you and each
8082Third-Party Service is governed solely by that provider's terms and privacy
81policy. Marco Reid is not a party to that relationship, does not resell the
83policy. Voxlen is not a party to that relationship, does not resell the
8284services, and does not act as a data processor, reseller, or intermediary
8385in respect of any content you transmit to them. You are solely responsible
8486for ensuring that your use of each Third-Party Service complies with that
@@ -87,13 +89,12 @@ provider's terms and with all laws applicable to you.
8789## 5. Intellectual property
8890
89915.1 **Our IP.** The Service, including all software, designs, logos,
90trademarks, content, and documentation, is the exclusive property of Marco
91Reid and its licensors and is protected by New Zealand and international
92trademarks, content, and documentation, is the exclusive property of Voxlen and its licensors and is protected by New Zealand and international
9293intellectual property laws. No rights are granted to you other than as
9394expressly set out in the EULA.
9495
955.2 **Trademarks.** "Marco Reid", "Marco Reid Voice", the Marco Reid
96wordmark, and any associated logos are trademarks of Marco Reid. You may not
965.2 **Trademarks.** "Voxlen", the Voxlen
97wordmark, and any associated logos are trademarks of Voxlen. You may not
9798use them without our prior written consent.
9899
991005.3 **Feedback.** If you provide us feedback or suggestions, you grant us a
@@ -110,9 +111,9 @@ non-refundable. Recurring subscriptions renew automatically unless cancelled
110111before the renewal date.
111112
1121136.3 You are responsible for all taxes, duties, and levies associated with
113your use of the Service, excluding taxes on Marco Reid's net income.
114your use of the Service, excluding taxes on Voxlen's net income.
114115
1156.4 Marco Reid may change fees on at least thirty (30) days' prior notice.
1166.4 Voxlen may change fees on at least thirty (30) days' prior notice.
116117
117118## 7. Beta features
118119
@@ -124,15 +125,15 @@ Agreement.
124125
125126## 8. Changes to the Service
126127
127Marco Reid may modify, suspend, or discontinue the Service (or any part of
128it) at any time, with or without notice. Marco Reid will not be liable for
128Voxlen may modify, suspend, or discontinue the Service (or any part of
129it) at any time, with or without notice. Voxlen will not be liable for
129130any modification, suspension, or discontinuance.
130131
131132## 9. Suspension and termination
132133
1339.1 Marco Reid may suspend or terminate your access to the Service
1349.1 Voxlen may suspend or terminate your access to the Service
134135immediately, without notice or liability, if (a) you breach the Agreement or
135the Acceptable Use Policy; (b) your use exposes Marco Reid or any third
136the Acceptable Use Policy; (b) your use exposes Voxlen or any third
136137party to material risk of legal liability, reputational harm, or security
137138compromise; or (c) continued provision becomes unlawful or commercially
138139impracticable.
@@ -143,13 +144,13 @@ the Service, and you must delete all copies in your possession.
143144## 10. Disclaimer of warranties
144145
145146THE SERVICE IS PROVIDED **"AS IS"** AND **"AS AVAILABLE"**, WITH ALL FAULTS.
146TO THE MAXIMUM EXTENT PERMITTED BY LAW, MARCO REID EXPRESSLY DISCLAIMS ALL
147TO THE MAXIMUM EXTENT PERMITTED BY LAW, VOXLEN EXPRESSLY DISCLAIMS ALL
147148WARRANTIES, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING
148149MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE,
149150QUIET ENJOYMENT, ACCURACY, UNINTERRUPTED OR ERROR-FREE OPERATION, AND ANY
150151WARRANTY ARISING FROM COURSE OF DEALING, USAGE, OR TRADE.
151152
152MARCO REID DOES NOT WARRANT THAT OUTPUT WILL BE ACCURATE, COMPLETE,
153VOXLEN DOES NOT WARRANT THAT OUTPUT WILL BE ACCURATE, COMPLETE,
153154RELIABLE, OR SUITABLE FOR ANY PARTICULAR PURPOSE. OUTPUT IS GENERATED BY
154155THIRD-PARTY MACHINE-LEARNING MODELS AND MAY BE INACCURATE OR FABRICATED.
155156YOU MUST HAVE ALL OUTPUT INDEPENDENTLY REVIEWED BY A QUALIFIED PROFESSIONAL
@@ -164,16 +165,16 @@ consumer guarantees do not apply.
164165
165166## 11. Limitation of liability
166167
16711.1 TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL MARCO REID OR
16811.1 TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL VOXLEN OR
168169ITS AFFILIATES, LICENSORS, OFFICERS, DIRECTORS, EMPLOYEES, OR AGENTS BE
169170LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR
170171PUNITIVE DAMAGES, OR FOR ANY LOST PROFITS, REVENUE, DATA, GOODWILL,
171172SUBSTITUTE PROCUREMENT, OR PROFESSIONAL-LIABILITY EXPOSURE, REGARDLESS OF
172173THE LEGAL THEORY AND EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
173174
17411.2 MARCO REID'S TOTAL AGGREGATE LIABILITY FOR ALL CLAIMS ARISING OUT OF
17511.2 VOXLEN'S TOTAL AGGREGATE LIABILITY FOR ALL CLAIMS ARISING OUT OF
175176OR RELATED TO THE SERVICE AND THE AGREEMENT WILL NOT EXCEED THE GREATER OF
176(A) THE AMOUNTS PAID BY YOU TO MARCO REID FOR THE SERVICE IN THE TWELVE
177(A) THE AMOUNTS PAID BY YOU TO VOXLEN FOR THE SERVICE IN THE TWELVE
177178(12) MONTHS IMMEDIATELY PRECEDING THE FIRST EVENT GIVING RISE TO THE CLAIM,
178179OR (B) NZD $100.
179180
@@ -182,14 +183,14 @@ applicable law.
182183
183184## 12. Indemnity
184185
185You agree to defend, indemnify, and hold harmless Marco Reid, its
186You agree to defend, indemnify, and hold harmless Voxlen, its
186187Affiliates, and their respective officers, directors, employees,
187188contractors, and agents from and against any and all claims, liabilities,
188189damages, losses, fines, penalties, costs, and expenses (including reasonable
189190legal fees) arising out of or related to (a) Your Content or Output; (b)
190191your use or misuse of the Service; (c) your use of any Third-Party Service;
191192(d) your breach of the Agreement; or (e) your violation of any law,
192regulation, or third-party right. Marco Reid may assume exclusive control of
193regulation, or third-party right. Voxlen may assume exclusive control of
193194the defence and settlement of any indemnified matter at your expense.
194195
195196## 13. Confidentiality
@@ -260,7 +261,7 @@ remainder continues in full force.
260261parties regarding its subject matter and supersedes any prior or
261262contemporaneous understandings.
262263
26317.6 **Contact.** `legal@marcoreid.com`.
26417.6 **Contact.** `legal@voxlen.ai`.
264265
265266---
266267
Modifiedlegal/THIRD_PARTY_NOTICES.md+9−10View fileUnifiedSplit
@@ -1,19 +1,18 @@
11# Third-Party Notices
22
3**Marco Reid Voice**
3**Voxlen**
44**Last updated: 16 April 2026**
55
6Marco Reid Voice incorporates open-source components listed below. Those
7components remain subject to their original licences. Nothing in the Marco
8Reid licence terms modifies, overrides, or limits those licences. The
6Voxlen incorporates open-source components listed below. Those
7components remain subject to their original licences. Nothing in the Voxlen licence terms modifies, overrides, or limits those licences. The
98relevant licence texts are included with each component's package in the
109installed distribution.
1110
12No component used by Marco Reid Voice carries a copyleft obligation (GPL,
13LGPL, AGPL, MPL, or similar) that would require Marco Reid to publish the
14source code of Marco Reid Voice itself. All components are under permissive
11No component used by Voxlen carries a copyleft obligation (GPL,
12LGPL, AGPL, MPL, or similar) that would require Voxlen to publish the
13source code of Voxlen itself. All components are under permissive
1514licences (MIT, Apache-2.0, BSD variants, ISC, or Unlicense). Where a
16component is dual-licensed, Marco Reid elects the most permissive option.
15component is dual-licensed, Voxlen elects the most permissive option.
1716
1817## Desktop application — Rust dependencies (`src-tauri/Cargo.toml`)
1918
@@ -64,7 +63,7 @@ component is dual-licensed, Marco Reid elects the most permissive option.
6463
6564## Typefaces
6665
67Marco Reid Voice uses the following typefaces. Webfont files or references
66Voxlen uses the following typefaces. Webfont files or references
6867are bundled subject to their licences:
6968
7069- **Fraunces** — SIL Open Font Licence 1.1.
@@ -92,4 +91,4 @@ cargo license --all-features --direct-deps-only
9291
9392## Reporting an omission
9493
95Licensing or attribution concerns: `legal@marcoreid.com`.
94Licensing or attribution concerns: `legal@voxlen.ai`.
Modifiedsdk/src/api-client.ts+2−2View fileUnifiedSplit
@@ -6,10 +6,10 @@ import type {
66 VocabularyList,
77} from "./types";
88
9const DEFAULT_BASE = "https://api.voxlen.com/v1";
9const DEFAULT_BASE = "https://voxlen.ai/api";
1010
1111/**
12 * Low-level client for the Voxlen REST API (api.voxlen.com/v1).
12 * Low-level client for the Voxlen REST API (voxlen.ai/api/v1).
1313 * Used when a voxlenApiKey is configured — routes all transcription
1414 * through the Voxlen platform rather than calling Deepgram directly.
1515 */
Modifiedsdk/src/types.ts+3−3View fileUnifiedSplit
@@ -13,11 +13,11 @@ export type VoxlenContext =
1313 | "general";
1414
1515export interface VoxlenConfig {
16 /** Voxlen platform API key — routes through api.voxlen.com (preferred) */
16 /** Voxlen platform API key — routes through voxlen.ai/api (preferred) */
1717 voxlenApiKey?: string;
18 /** Voxlen API base URL override (default: https://api.voxlen.com/v1) */
18 /** Voxlen API base URL override (default: https://voxlen.ai/api) */
1919 voxlenApiBase?: string;
20 /** Tenant ID for usage reporting (e.g. Marco Reid firm ID) */
20 /** Tenant ID for usage reporting (e.g. your firm or organisation ID) */
2121 tenantId?: string;
2222 /** Context tells Voxlen how to format the transcript */
2323 context?: VoxlenContext;
Modifiedsrc-tauri/capabilities/default.json+1−1View fileUnifiedSplit
@@ -1,7 +1,7 @@
11{
22 "$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-utils/schema.json",
33 "identifier": "default",
4 "description": "Default capabilities for Marco Reid Voice",
4 "description": "Default capabilities for Voxlen",
55 "windows": ["main"],
66 "permissions": [
77 "core:default",
Addedsrc-tauri/gen/schemas/acl-manifests.json+1−0View fileUnifiedSplit
@@ -0,0 +1 @@
1{"autostart":{"default_permission":{"identifier":"default","description":"This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n","permissions":["allow-enable","allow-disable","allow-is-enabled"]},"permissions":{"allow-disable":{"identifier":"allow-disable","description":"Enables the disable command without any pre-configured scope.","commands":{"allow":["disable"],"deny":[]}},"allow-enable":{"identifier":"allow-enable","description":"Enables the enable command without any pre-configured scope.","commands":{"allow":["enable"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"deny-disable":{"identifier":"deny-disable","description":"Denies the disable command without any pre-configured scope.","commands":{"allow":[],"deny":["disable"]}},"deny-enable":{"identifier":"deny-enable","description":"Denies the enable command without any pre-configured scope.","commands":{"allow":[],"deny":["enable"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"fs":{"default_permission":{"identifier":"default","description":"This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n","permissions":["create-app-specific-dirs","read-app-specific-dirs-recursive","deny-default"]},"permissions":{"allow-copy-file":{"identifier":"allow-copy-file","description":"Enables the copy_file command without any pre-configured scope.","commands":{"allow":["copy_file"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-exists":{"identifier":"allow-exists","description":"Enables the exists command without any pre-configured scope.","commands":{"allow":["exists"],"deny":[]}},"allow-fstat":{"identifier":"allow-fstat","description":"Enables the fstat command without any pre-configured scope.","commands":{"allow":["fstat"],"deny":[]}},"allow-ftruncate":{"identifier":"allow-ftruncate","description":"Enables the ftruncate command without any pre-configured scope.","commands":{"allow":["ftruncate"],"deny":[]}},"allow-lstat":{"identifier":"allow-lstat","description":"Enables the lstat command without any pre-configured scope.","commands":{"allow":["lstat"],"deny":[]}},"allow-mkdir":{"identifier":"allow-mkdir","description":"Enables the mkdir command without any pre-configured scope.","commands":{"allow":["mkdir"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-read":{"identifier":"allow-read","description":"Enables the read command without any pre-configured scope.","commands":{"allow":["read"],"deny":[]}},"allow-read-dir":{"identifier":"allow-read-dir","description":"Enables the read_dir command without any pre-configured scope.","commands":{"allow":["read_dir"],"deny":[]}},"allow-read-file":{"identifier":"allow-read-file","description":"Enables the read_file command without any pre-configured scope.","commands":{"allow":["read_file"],"deny":[]}},"allow-read-text-file":{"identifier":"allow-read-text-file","description":"Enables the read_text_file command without any pre-configured scope.","commands":{"allow":["read_text_file"],"deny":[]}},"allow-read-text-file-lines":{"identifier":"allow-read-text-file-lines","description":"Enables the read_text_file_lines command without any pre-configured scope.","commands":{"allow":["read_text_file_lines","read_text_file_lines_next"],"deny":[]}},"allow-read-text-file-lines-next":{"identifier":"allow-read-text-file-lines-next","description":"Enables the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":["read_text_file_lines_next"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-rename":{"identifier":"allow-rename","description":"Enables the rename command without any pre-configured scope.","commands":{"allow":["rename"],"deny":[]}},"allow-seek":{"identifier":"allow-seek","description":"Enables the seek command without any pre-configured scope.","commands":{"allow":["seek"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"allow-start-accessing-security-scoped-resource":{"identifier":"allow-start-accessing-security-scoped-resource","description":"Enables the start_accessing_security_scoped_resource command without any pre-configured scope.","commands":{"allow":["start_accessing_security_scoped_resource"],"deny":[]}},"allow-stat":{"identifier":"allow-stat","description":"Enables the stat command without any pre-configured scope.","commands":{"allow":["stat"],"deny":[]}},"allow-stop-accessing-security-scoped-resource":{"identifier":"allow-stop-accessing-security-scoped-resource","description":"Enables the stop_accessing_security_scoped_resource command without any pre-configured scope.","commands":{"allow":["stop_accessing_security_scoped_resource"],"deny":[]}},"allow-truncate":{"identifier":"allow-truncate","description":"Enables the truncate command without any pre-configured scope.","commands":{"allow":["truncate"],"deny":[]}},"allow-unwatch":{"identifier":"allow-unwatch","description":"Enables the unwatch command without any pre-configured scope.","commands":{"allow":["unwatch"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"allow-write":{"identifier":"allow-write","description":"Enables the write command without any pre-configured scope.","commands":{"allow":["write"],"deny":[]}},"allow-write-file":{"identifier":"allow-write-file","description":"Enables the write_file command without any pre-configured scope.","commands":{"allow":["write_file","open","write"],"deny":[]}},"allow-write-text-file":{"identifier":"allow-write-text-file","description":"Enables the write_text_file command without any pre-configured scope.","commands":{"allow":["write_text_file"],"deny":[]}},"create-app-specific-dirs":{"identifier":"create-app-specific-dirs","description":"This permissions allows to create the application specific directories.\n","commands":{"allow":["mkdir","scope-app-index"],"deny":[]}},"deny-copy-file":{"identifier":"deny-copy-file","description":"Denies the copy_file command without any pre-configured scope.","commands":{"allow":[],"deny":["copy_file"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-exists":{"identifier":"deny-exists","description":"Denies the exists command without any pre-configured scope.","commands":{"allow":[],"deny":["exists"]}},"deny-fstat":{"identifier":"deny-fstat","description":"Denies the fstat command without any pre-configured scope.","commands":{"allow":[],"deny":["fstat"]}},"deny-ftruncate":{"identifier":"deny-ftruncate","description":"Denies the ftruncate command without any pre-configured scope.","commands":{"allow":[],"deny":["ftruncate"]}},"deny-lstat":{"identifier":"deny-lstat","description":"Denies the lstat command without any pre-configured scope.","commands":{"allow":[],"deny":["lstat"]}},"deny-mkdir":{"identifier":"deny-mkdir","description":"Denies the mkdir command without any pre-configured scope.","commands":{"allow":[],"deny":["mkdir"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-read":{"identifier":"deny-read","description":"Denies the read command without any pre-configured scope.","commands":{"allow":[],"deny":["read"]}},"deny-read-dir":{"identifier":"deny-read-dir","description":"Denies the read_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["read_dir"]}},"deny-read-file":{"identifier":"deny-read-file","description":"Denies the read_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_file"]}},"deny-read-text-file":{"identifier":"deny-read-text-file","description":"Denies the read_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file"]}},"deny-read-text-file-lines":{"identifier":"deny-read-text-file-lines","description":"Denies the read_text_file_lines command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines"]}},"deny-read-text-file-lines-next":{"identifier":"deny-read-text-file-lines-next","description":"Denies the read_text_file_lines_next command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text_file_lines_next"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-rename":{"identifier":"deny-rename","description":"Denies the rename command without any pre-configured scope.","commands":{"allow":[],"deny":["rename"]}},"deny-seek":{"identifier":"deny-seek","description":"Denies the seek command without any pre-configured scope.","commands":{"allow":[],"deny":["seek"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}},"deny-start-accessing-security-scoped-resource":{"identifier":"deny-start-accessing-security-scoped-resource","description":"Denies the start_accessing_security_scoped_resource command without any pre-configured scope.","commands":{"allow":[],"deny":["start_accessing_security_scoped_resource"]}},"deny-stat":{"identifier":"deny-stat","description":"Denies the stat command without any pre-configured scope.","commands":{"allow":[],"deny":["stat"]}},"deny-stop-accessing-security-scoped-resource":{"identifier":"deny-stop-accessing-security-scoped-resource","description":"Denies the stop_accessing_security_scoped_resource command without any pre-configured scope.","commands":{"allow":[],"deny":["stop_accessing_security_scoped_resource"]}},"deny-truncate":{"identifier":"deny-truncate","description":"Denies the truncate command without any pre-configured scope.","commands":{"allow":[],"deny":["truncate"]}},"deny-unwatch":{"identifier":"deny-unwatch","description":"Denies the unwatch command without any pre-configured scope.","commands":{"allow":[],"deny":["unwatch"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}},"deny-webview-data-linux":{"identifier":"deny-webview-data-linux","description":"This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-webview-data-windows":{"identifier":"deny-webview-data-windows","description":"This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.","commands":{"allow":[],"deny":[]}},"deny-write":{"identifier":"deny-write","description":"Denies the write command without any pre-configured scope.","commands":{"allow":[],"deny":["write"]}},"deny-write-file":{"identifier":"deny-write-file","description":"Denies the write_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_file"]}},"deny-write-text-file":{"identifier":"deny-write-text-file","description":"Denies the write_text_file command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text_file"]}},"read-all":{"identifier":"read-all","description":"This enables all read related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists","watch","unwatch"],"deny":[]}},"read-app-specific-dirs-recursive":{"identifier":"read-app-specific-dirs-recursive","description":"This permission allows recursive read functionality on the application\nspecific base directories. \n","commands":{"allow":["read_dir","read_file","read_text_file","read_text_file_lines","read_text_file_lines_next","exists","scope-app-recursive"],"deny":[]}},"read-dirs":{"identifier":"read-dirs","description":"This enables directory read and file metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists"],"deny":[]}},"read-files":{"identifier":"read-files","description":"This enables file read related commands without any pre-configured accessible paths.","commands":{"allow":["read_file","read","open","read_text_file","read_text_file_lines","read_text_file_lines_next","seek","stat","lstat","fstat","exists"],"deny":[]}},"read-meta":{"identifier":"read-meta","description":"This enables all index or metadata related commands without any pre-configured accessible paths.","commands":{"allow":["read_dir","stat","lstat","fstat","exists","size"],"deny":[]}},"scope":{"identifier":"scope","description":"An empty permission you can use to modify the global scope.\n\n## Example\n\n```json\n{\n \"identifier\": \"read-documents\",\n \"windows\": [\"main\"],\n \"permissions\": [\n \"fs:allow-read\",\n {\n \"identifier\": \"fs:scope\",\n \"allow\": [\n \"$APPDATA/documents/**/*\"\n ],\n \"deny\": [\n \"$APPDATA/documents/secret.txt\"\n ]\n }\n ]\n}\n```\n","commands":{"allow":[],"deny":[]}},"scope-app":{"identifier":"scope-app","description":"This scope permits access to all files and list content of top level directories in the application folders.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"},{"path":"$APPDATA"},{"path":"$APPDATA/*"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"},{"path":"$APPCACHE"},{"path":"$APPCACHE/*"},{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-app-index":{"identifier":"scope-app-index","description":"This scope permits to list all files and folders in the application directories.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPDATA"},{"path":"$APPLOCALDATA"},{"path":"$APPCACHE"},{"path":"$APPLOG"}]}},"scope-app-recursive":{"identifier":"scope-app-recursive","description":"This scope permits recursive access to the complete application folders, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"},{"path":"$APPDATA"},{"path":"$APPDATA/**"},{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"},{"path":"$APPCACHE"},{"path":"$APPCACHE/**"},{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-appcache":{"identifier":"scope-appcache","description":"This scope permits access to all files and list content of top level directories in the `$APPCACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/*"}]}},"scope-appcache-index":{"identifier":"scope-appcache-index","description":"This scope permits to list all files and folders in the `$APPCACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"}]}},"scope-appcache-recursive":{"identifier":"scope-appcache-recursive","description":"This scope permits recursive access to the complete `$APPCACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCACHE"},{"path":"$APPCACHE/**"}]}},"scope-appconfig":{"identifier":"scope-appconfig","description":"This scope permits access to all files and list content of top level directories in the `$APPCONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/*"}]}},"scope-appconfig-index":{"identifier":"scope-appconfig-index","description":"This scope permits to list all files and folders in the `$APPCONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"}]}},"scope-appconfig-recursive":{"identifier":"scope-appconfig-recursive","description":"This scope permits recursive access to the complete `$APPCONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPCONFIG"},{"path":"$APPCONFIG/**"}]}},"scope-appdata":{"identifier":"scope-appdata","description":"This scope permits access to all files and list content of top level directories in the `$APPDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/*"}]}},"scope-appdata-index":{"identifier":"scope-appdata-index","description":"This scope permits to list all files and folders in the `$APPDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"}]}},"scope-appdata-recursive":{"identifier":"scope-appdata-recursive","description":"This scope permits recursive access to the complete `$APPDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]}},"scope-applocaldata":{"identifier":"scope-applocaldata","description":"This scope permits access to all files and list content of top level directories in the `$APPLOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/*"}]}},"scope-applocaldata-index":{"identifier":"scope-applocaldata-index","description":"This scope permits to list all files and folders in the `$APPLOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"}]}},"scope-applocaldata-recursive":{"identifier":"scope-applocaldata-recursive","description":"This scope permits recursive access to the complete `$APPLOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOCALDATA"},{"path":"$APPLOCALDATA/**"}]}},"scope-applog":{"identifier":"scope-applog","description":"This scope permits access to all files and list content of top level directories in the `$APPLOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/*"}]}},"scope-applog-index":{"identifier":"scope-applog-index","description":"This scope permits to list all files and folders in the `$APPLOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"}]}},"scope-applog-recursive":{"identifier":"scope-applog-recursive","description":"This scope permits recursive access to the complete `$APPLOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$APPLOG"},{"path":"$APPLOG/**"}]}},"scope-audio":{"identifier":"scope-audio","description":"This scope permits access to all files and list content of top level directories in the `$AUDIO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/*"}]}},"scope-audio-index":{"identifier":"scope-audio-index","description":"This scope permits to list all files and folders in the `$AUDIO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"}]}},"scope-audio-recursive":{"identifier":"scope-audio-recursive","description":"This scope permits recursive access to the complete `$AUDIO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$AUDIO"},{"path":"$AUDIO/**"}]}},"scope-cache":{"identifier":"scope-cache","description":"This scope permits access to all files and list content of top level directories in the `$CACHE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/*"}]}},"scope-cache-index":{"identifier":"scope-cache-index","description":"This scope permits to list all files and folders in the `$CACHE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"}]}},"scope-cache-recursive":{"identifier":"scope-cache-recursive","description":"This scope permits recursive access to the complete `$CACHE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CACHE"},{"path":"$CACHE/**"}]}},"scope-config":{"identifier":"scope-config","description":"This scope permits access to all files and list content of top level directories in the `$CONFIG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/*"}]}},"scope-config-index":{"identifier":"scope-config-index","description":"This scope permits to list all files and folders in the `$CONFIG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"}]}},"scope-config-recursive":{"identifier":"scope-config-recursive","description":"This scope permits recursive access to the complete `$CONFIG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$CONFIG"},{"path":"$CONFIG/**"}]}},"scope-data":{"identifier":"scope-data","description":"This scope permits access to all files and list content of top level directories in the `$DATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/*"}]}},"scope-data-index":{"identifier":"scope-data-index","description":"This scope permits to list all files and folders in the `$DATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"}]}},"scope-data-recursive":{"identifier":"scope-data-recursive","description":"This scope permits recursive access to the complete `$DATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DATA"},{"path":"$DATA/**"}]}},"scope-desktop":{"identifier":"scope-desktop","description":"This scope permits access to all files and list content of top level directories in the `$DESKTOP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/*"}]}},"scope-desktop-index":{"identifier":"scope-desktop-index","description":"This scope permits to list all files and folders in the `$DESKTOP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"}]}},"scope-desktop-recursive":{"identifier":"scope-desktop-recursive","description":"This scope permits recursive access to the complete `$DESKTOP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DESKTOP"},{"path":"$DESKTOP/**"}]}},"scope-document":{"identifier":"scope-document","description":"This scope permits access to all files and list content of top level directories in the `$DOCUMENT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/*"}]}},"scope-document-index":{"identifier":"scope-document-index","description":"This scope permits to list all files and folders in the `$DOCUMENT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"}]}},"scope-document-recursive":{"identifier":"scope-document-recursive","description":"This scope permits recursive access to the complete `$DOCUMENT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOCUMENT"},{"path":"$DOCUMENT/**"}]}},"scope-download":{"identifier":"scope-download","description":"This scope permits access to all files and list content of top level directories in the `$DOWNLOAD` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/*"}]}},"scope-download-index":{"identifier":"scope-download-index","description":"This scope permits to list all files and folders in the `$DOWNLOAD`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"}]}},"scope-download-recursive":{"identifier":"scope-download-recursive","description":"This scope permits recursive access to the complete `$DOWNLOAD` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$DOWNLOAD"},{"path":"$DOWNLOAD/**"}]}},"scope-exe":{"identifier":"scope-exe","description":"This scope permits access to all files and list content of top level directories in the `$EXE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/*"}]}},"scope-exe-index":{"identifier":"scope-exe-index","description":"This scope permits to list all files and folders in the `$EXE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"}]}},"scope-exe-recursive":{"identifier":"scope-exe-recursive","description":"This scope permits recursive access to the complete `$EXE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$EXE"},{"path":"$EXE/**"}]}},"scope-font":{"identifier":"scope-font","description":"This scope permits access to all files and list content of top level directories in the `$FONT` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/*"}]}},"scope-font-index":{"identifier":"scope-font-index","description":"This scope permits to list all files and folders in the `$FONT`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"}]}},"scope-font-recursive":{"identifier":"scope-font-recursive","description":"This scope permits recursive access to the complete `$FONT` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$FONT"},{"path":"$FONT/**"}]}},"scope-home":{"identifier":"scope-home","description":"This scope permits access to all files and list content of top level directories in the `$HOME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/*"}]}},"scope-home-index":{"identifier":"scope-home-index","description":"This scope permits to list all files and folders in the `$HOME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"}]}},"scope-home-recursive":{"identifier":"scope-home-recursive","description":"This scope permits recursive access to the complete `$HOME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$HOME"},{"path":"$HOME/**"}]}},"scope-localdata":{"identifier":"scope-localdata","description":"This scope permits access to all files and list content of top level directories in the `$LOCALDATA` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/*"}]}},"scope-localdata-index":{"identifier":"scope-localdata-index","description":"This scope permits to list all files and folders in the `$LOCALDATA`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"}]}},"scope-localdata-recursive":{"identifier":"scope-localdata-recursive","description":"This scope permits recursive access to the complete `$LOCALDATA` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOCALDATA"},{"path":"$LOCALDATA/**"}]}},"scope-log":{"identifier":"scope-log","description":"This scope permits access to all files and list content of top level directories in the `$LOG` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/*"}]}},"scope-log-index":{"identifier":"scope-log-index","description":"This scope permits to list all files and folders in the `$LOG`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"}]}},"scope-log-recursive":{"identifier":"scope-log-recursive","description":"This scope permits recursive access to the complete `$LOG` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$LOG"},{"path":"$LOG/**"}]}},"scope-picture":{"identifier":"scope-picture","description":"This scope permits access to all files and list content of top level directories in the `$PICTURE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/*"}]}},"scope-picture-index":{"identifier":"scope-picture-index","description":"This scope permits to list all files and folders in the `$PICTURE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"}]}},"scope-picture-recursive":{"identifier":"scope-picture-recursive","description":"This scope permits recursive access to the complete `$PICTURE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PICTURE"},{"path":"$PICTURE/**"}]}},"scope-public":{"identifier":"scope-public","description":"This scope permits access to all files and list content of top level directories in the `$PUBLIC` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/*"}]}},"scope-public-index":{"identifier":"scope-public-index","description":"This scope permits to list all files and folders in the `$PUBLIC`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"}]}},"scope-public-recursive":{"identifier":"scope-public-recursive","description":"This scope permits recursive access to the complete `$PUBLIC` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$PUBLIC"},{"path":"$PUBLIC/**"}]}},"scope-resource":{"identifier":"scope-resource","description":"This scope permits access to all files and list content of top level directories in the `$RESOURCE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/*"}]}},"scope-resource-index":{"identifier":"scope-resource-index","description":"This scope permits to list all files and folders in the `$RESOURCE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"}]}},"scope-resource-recursive":{"identifier":"scope-resource-recursive","description":"This scope permits recursive access to the complete `$RESOURCE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RESOURCE"},{"path":"$RESOURCE/**"}]}},"scope-runtime":{"identifier":"scope-runtime","description":"This scope permits access to all files and list content of top level directories in the `$RUNTIME` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/*"}]}},"scope-runtime-index":{"identifier":"scope-runtime-index","description":"This scope permits to list all files and folders in the `$RUNTIME`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"}]}},"scope-runtime-recursive":{"identifier":"scope-runtime-recursive","description":"This scope permits recursive access to the complete `$RUNTIME` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$RUNTIME"},{"path":"$RUNTIME/**"}]}},"scope-temp":{"identifier":"scope-temp","description":"This scope permits access to all files and list content of top level directories in the `$TEMP` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/*"}]}},"scope-temp-index":{"identifier":"scope-temp-index","description":"This scope permits to list all files and folders in the `$TEMP`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"}]}},"scope-temp-recursive":{"identifier":"scope-temp-recursive","description":"This scope permits recursive access to the complete `$TEMP` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMP"},{"path":"$TEMP/**"}]}},"scope-template":{"identifier":"scope-template","description":"This scope permits access to all files and list content of top level directories in the `$TEMPLATE` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/*"}]}},"scope-template-index":{"identifier":"scope-template-index","description":"This scope permits to list all files and folders in the `$TEMPLATE`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"}]}},"scope-template-recursive":{"identifier":"scope-template-recursive","description":"This scope permits recursive access to the complete `$TEMPLATE` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$TEMPLATE"},{"path":"$TEMPLATE/**"}]}},"scope-video":{"identifier":"scope-video","description":"This scope permits access to all files and list content of top level directories in the `$VIDEO` folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/*"}]}},"scope-video-index":{"identifier":"scope-video-index","description":"This scope permits to list all files and folders in the `$VIDEO`folder.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"}]}},"scope-video-recursive":{"identifier":"scope-video-recursive","description":"This scope permits recursive access to the complete `$VIDEO` folder, including sub directories and files.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"path":"$VIDEO"},{"path":"$VIDEO/**"}]}},"write-all":{"identifier":"write-all","description":"This enables all write related commands without any pre-configured accessible paths.","commands":{"allow":["mkdir","create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}},"write-files":{"identifier":"write-files","description":"This enables all file write related commands without any pre-configured accessible paths.","commands":{"allow":["create","copy_file","remove","rename","truncate","ftruncate","write","write_file","write_text_file"],"deny":[]}}},"permission_sets":{"allow-app-meta":{"identifier":"allow-app-meta","description":"This allows non-recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-index"]},"allow-app-meta-recursive":{"identifier":"allow-app-meta-recursive","description":"This allows full recursive read access to metadata of the application folders, including file listing and statistics.","permissions":["read-meta","scope-app-recursive"]},"allow-app-read":{"identifier":"allow-app-read","description":"This allows non-recursive read access to the application folders.","permissions":["read-all","scope-app"]},"allow-app-read-recursive":{"identifier":"allow-app-read-recursive","description":"This allows full recursive read access to the complete application folders, files and subdirectories.","permissions":["read-all","scope-app-recursive"]},"allow-app-write":{"identifier":"allow-app-write","description":"This allows non-recursive write access to the application folders.","permissions":["write-all","scope-app"]},"allow-app-write-recursive":{"identifier":"allow-app-write-recursive","description":"This allows full recursive write access to the complete application folders, files and subdirectories.","permissions":["write-all","scope-app-recursive"]},"allow-appcache-meta":{"identifier":"allow-appcache-meta","description":"This allows non-recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-index"]},"allow-appcache-meta-recursive":{"identifier":"allow-appcache-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-appcache-recursive"]},"allow-appcache-read":{"identifier":"allow-appcache-read","description":"This allows non-recursive read access to the `$APPCACHE` folder.","permissions":["read-all","scope-appcache"]},"allow-appcache-read-recursive":{"identifier":"allow-appcache-read-recursive","description":"This allows full recursive read access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["read-all","scope-appcache-recursive"]},"allow-appcache-write":{"identifier":"allow-appcache-write","description":"This allows non-recursive write access to the `$APPCACHE` folder.","permissions":["write-all","scope-appcache"]},"allow-appcache-write-recursive":{"identifier":"allow-appcache-write-recursive","description":"This allows full recursive write access to the complete `$APPCACHE` folder, files and subdirectories.","permissions":["write-all","scope-appcache-recursive"]},"allow-appconfig-meta":{"identifier":"allow-appconfig-meta","description":"This allows non-recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-index"]},"allow-appconfig-meta-recursive":{"identifier":"allow-appconfig-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPCONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-appconfig-recursive"]},"allow-appconfig-read":{"identifier":"allow-appconfig-read","description":"This allows non-recursive read access to the `$APPCONFIG` folder.","permissions":["read-all","scope-appconfig"]},"allow-appconfig-read-recursive":{"identifier":"allow-appconfig-read-recursive","description":"This allows full recursive read access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["read-all","scope-appconfig-recursive"]},"allow-appconfig-write":{"identifier":"allow-appconfig-write","description":"This allows non-recursive write access to the `$APPCONFIG` folder.","permissions":["write-all","scope-appconfig"]},"allow-appconfig-write-recursive":{"identifier":"allow-appconfig-write-recursive","description":"This allows full recursive write access to the complete `$APPCONFIG` folder, files and subdirectories.","permissions":["write-all","scope-appconfig-recursive"]},"allow-appdata-meta":{"identifier":"allow-appdata-meta","description":"This allows non-recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-index"]},"allow-appdata-meta-recursive":{"identifier":"allow-appdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-appdata-recursive"]},"allow-appdata-read":{"identifier":"allow-appdata-read","description":"This allows non-recursive read access to the `$APPDATA` folder.","permissions":["read-all","scope-appdata"]},"allow-appdata-read-recursive":{"identifier":"allow-appdata-read-recursive","description":"This allows full recursive read access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["read-all","scope-appdata-recursive"]},"allow-appdata-write":{"identifier":"allow-appdata-write","description":"This allows non-recursive write access to the `$APPDATA` folder.","permissions":["write-all","scope-appdata"]},"allow-appdata-write-recursive":{"identifier":"allow-appdata-write-recursive","description":"This allows full recursive write access to the complete `$APPDATA` folder, files and subdirectories.","permissions":["write-all","scope-appdata-recursive"]},"allow-applocaldata-meta":{"identifier":"allow-applocaldata-meta","description":"This allows non-recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-index"]},"allow-applocaldata-meta-recursive":{"identifier":"allow-applocaldata-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-applocaldata-recursive"]},"allow-applocaldata-read":{"identifier":"allow-applocaldata-read","description":"This allows non-recursive read access to the `$APPLOCALDATA` folder.","permissions":["read-all","scope-applocaldata"]},"allow-applocaldata-read-recursive":{"identifier":"allow-applocaldata-read-recursive","description":"This allows full recursive read access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-applocaldata-recursive"]},"allow-applocaldata-write":{"identifier":"allow-applocaldata-write","description":"This allows non-recursive write access to the `$APPLOCALDATA` folder.","permissions":["write-all","scope-applocaldata"]},"allow-applocaldata-write-recursive":{"identifier":"allow-applocaldata-write-recursive","description":"This allows full recursive write access to the complete `$APPLOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-applocaldata-recursive"]},"allow-applog-meta":{"identifier":"allow-applog-meta","description":"This allows non-recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-index"]},"allow-applog-meta-recursive":{"identifier":"allow-applog-meta-recursive","description":"This allows full recursive read access to metadata of the `$APPLOG` folder, including file listing and statistics.","permissions":["read-meta","scope-applog-recursive"]},"allow-applog-read":{"identifier":"allow-applog-read","description":"This allows non-recursive read access to the `$APPLOG` folder.","permissions":["read-all","scope-applog"]},"allow-applog-read-recursive":{"identifier":"allow-applog-read-recursive","description":"This allows full recursive read access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["read-all","scope-applog-recursive"]},"allow-applog-write":{"identifier":"allow-applog-write","description":"This allows non-recursive write access to the `$APPLOG` folder.","permissions":["write-all","scope-applog"]},"allow-applog-write-recursive":{"identifier":"allow-applog-write-recursive","description":"This allows full recursive write access to the complete `$APPLOG` folder, files and subdirectories.","permissions":["write-all","scope-applog-recursive"]},"allow-audio-meta":{"identifier":"allow-audio-meta","description":"This allows non-recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-index"]},"allow-audio-meta-recursive":{"identifier":"allow-audio-meta-recursive","description":"This allows full recursive read access to metadata of the `$AUDIO` folder, including file listing and statistics.","permissions":["read-meta","scope-audio-recursive"]},"allow-audio-read":{"identifier":"allow-audio-read","description":"This allows non-recursive read access to the `$AUDIO` folder.","permissions":["read-all","scope-audio"]},"allow-audio-read-recursive":{"identifier":"allow-audio-read-recursive","description":"This allows full recursive read access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["read-all","scope-audio-recursive"]},"allow-audio-write":{"identifier":"allow-audio-write","description":"This allows non-recursive write access to the `$AUDIO` folder.","permissions":["write-all","scope-audio"]},"allow-audio-write-recursive":{"identifier":"allow-audio-write-recursive","description":"This allows full recursive write access to the complete `$AUDIO` folder, files and subdirectories.","permissions":["write-all","scope-audio-recursive"]},"allow-cache-meta":{"identifier":"allow-cache-meta","description":"This allows non-recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-index"]},"allow-cache-meta-recursive":{"identifier":"allow-cache-meta-recursive","description":"This allows full recursive read access to metadata of the `$CACHE` folder, including file listing and statistics.","permissions":["read-meta","scope-cache-recursive"]},"allow-cache-read":{"identifier":"allow-cache-read","description":"This allows non-recursive read access to the `$CACHE` folder.","permissions":["read-all","scope-cache"]},"allow-cache-read-recursive":{"identifier":"allow-cache-read-recursive","description":"This allows full recursive read access to the complete `$CACHE` folder, files and subdirectories.","permissions":["read-all","scope-cache-recursive"]},"allow-cache-write":{"identifier":"allow-cache-write","description":"This allows non-recursive write access to the `$CACHE` folder.","permissions":["write-all","scope-cache"]},"allow-cache-write-recursive":{"identifier":"allow-cache-write-recursive","description":"This allows full recursive write access to the complete `$CACHE` folder, files and subdirectories.","permissions":["write-all","scope-cache-recursive"]},"allow-config-meta":{"identifier":"allow-config-meta","description":"This allows non-recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-index"]},"allow-config-meta-recursive":{"identifier":"allow-config-meta-recursive","description":"This allows full recursive read access to metadata of the `$CONFIG` folder, including file listing and statistics.","permissions":["read-meta","scope-config-recursive"]},"allow-config-read":{"identifier":"allow-config-read","description":"This allows non-recursive read access to the `$CONFIG` folder.","permissions":["read-all","scope-config"]},"allow-config-read-recursive":{"identifier":"allow-config-read-recursive","description":"This allows full recursive read access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["read-all","scope-config-recursive"]},"allow-config-write":{"identifier":"allow-config-write","description":"This allows non-recursive write access to the `$CONFIG` folder.","permissions":["write-all","scope-config"]},"allow-config-write-recursive":{"identifier":"allow-config-write-recursive","description":"This allows full recursive write access to the complete `$CONFIG` folder, files and subdirectories.","permissions":["write-all","scope-config-recursive"]},"allow-data-meta":{"identifier":"allow-data-meta","description":"This allows non-recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-index"]},"allow-data-meta-recursive":{"identifier":"allow-data-meta-recursive","description":"This allows full recursive read access to metadata of the `$DATA` folder, including file listing and statistics.","permissions":["read-meta","scope-data-recursive"]},"allow-data-read":{"identifier":"allow-data-read","description":"This allows non-recursive read access to the `$DATA` folder.","permissions":["read-all","scope-data"]},"allow-data-read-recursive":{"identifier":"allow-data-read-recursive","description":"This allows full recursive read access to the complete `$DATA` folder, files and subdirectories.","permissions":["read-all","scope-data-recursive"]},"allow-data-write":{"identifier":"allow-data-write","description":"This allows non-recursive write access to the `$DATA` folder.","permissions":["write-all","scope-data"]},"allow-data-write-recursive":{"identifier":"allow-data-write-recursive","description":"This allows full recursive write access to the complete `$DATA` folder, files and subdirectories.","permissions":["write-all","scope-data-recursive"]},"allow-desktop-meta":{"identifier":"allow-desktop-meta","description":"This allows non-recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-index"]},"allow-desktop-meta-recursive":{"identifier":"allow-desktop-meta-recursive","description":"This allows full recursive read access to metadata of the `$DESKTOP` folder, including file listing and statistics.","permissions":["read-meta","scope-desktop-recursive"]},"allow-desktop-read":{"identifier":"allow-desktop-read","description":"This allows non-recursive read access to the `$DESKTOP` folder.","permissions":["read-all","scope-desktop"]},"allow-desktop-read-recursive":{"identifier":"allow-desktop-read-recursive","description":"This allows full recursive read access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["read-all","scope-desktop-recursive"]},"allow-desktop-write":{"identifier":"allow-desktop-write","description":"This allows non-recursive write access to the `$DESKTOP` folder.","permissions":["write-all","scope-desktop"]},"allow-desktop-write-recursive":{"identifier":"allow-desktop-write-recursive","description":"This allows full recursive write access to the complete `$DESKTOP` folder, files and subdirectories.","permissions":["write-all","scope-desktop-recursive"]},"allow-document-meta":{"identifier":"allow-document-meta","description":"This allows non-recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-index"]},"allow-document-meta-recursive":{"identifier":"allow-document-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOCUMENT` folder, including file listing and statistics.","permissions":["read-meta","scope-document-recursive"]},"allow-document-read":{"identifier":"allow-document-read","description":"This allows non-recursive read access to the `$DOCUMENT` folder.","permissions":["read-all","scope-document"]},"allow-document-read-recursive":{"identifier":"allow-document-read-recursive","description":"This allows full recursive read access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["read-all","scope-document-recursive"]},"allow-document-write":{"identifier":"allow-document-write","description":"This allows non-recursive write access to the `$DOCUMENT` folder.","permissions":["write-all","scope-document"]},"allow-document-write-recursive":{"identifier":"allow-document-write-recursive","description":"This allows full recursive write access to the complete `$DOCUMENT` folder, files and subdirectories.","permissions":["write-all","scope-document-recursive"]},"allow-download-meta":{"identifier":"allow-download-meta","description":"This allows non-recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-index"]},"allow-download-meta-recursive":{"identifier":"allow-download-meta-recursive","description":"This allows full recursive read access to metadata of the `$DOWNLOAD` folder, including file listing and statistics.","permissions":["read-meta","scope-download-recursive"]},"allow-download-read":{"identifier":"allow-download-read","description":"This allows non-recursive read access to the `$DOWNLOAD` folder.","permissions":["read-all","scope-download"]},"allow-download-read-recursive":{"identifier":"allow-download-read-recursive","description":"This allows full recursive read access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["read-all","scope-download-recursive"]},"allow-download-write":{"identifier":"allow-download-write","description":"This allows non-recursive write access to the `$DOWNLOAD` folder.","permissions":["write-all","scope-download"]},"allow-download-write-recursive":{"identifier":"allow-download-write-recursive","description":"This allows full recursive write access to the complete `$DOWNLOAD` folder, files and subdirectories.","permissions":["write-all","scope-download-recursive"]},"allow-exe-meta":{"identifier":"allow-exe-meta","description":"This allows non-recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-index"]},"allow-exe-meta-recursive":{"identifier":"allow-exe-meta-recursive","description":"This allows full recursive read access to metadata of the `$EXE` folder, including file listing and statistics.","permissions":["read-meta","scope-exe-recursive"]},"allow-exe-read":{"identifier":"allow-exe-read","description":"This allows non-recursive read access to the `$EXE` folder.","permissions":["read-all","scope-exe"]},"allow-exe-read-recursive":{"identifier":"allow-exe-read-recursive","description":"This allows full recursive read access to the complete `$EXE` folder, files and subdirectories.","permissions":["read-all","scope-exe-recursive"]},"allow-exe-write":{"identifier":"allow-exe-write","description":"This allows non-recursive write access to the `$EXE` folder.","permissions":["write-all","scope-exe"]},"allow-exe-write-recursive":{"identifier":"allow-exe-write-recursive","description":"This allows full recursive write access to the complete `$EXE` folder, files and subdirectories.","permissions":["write-all","scope-exe-recursive"]},"allow-font-meta":{"identifier":"allow-font-meta","description":"This allows non-recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-index"]},"allow-font-meta-recursive":{"identifier":"allow-font-meta-recursive","description":"This allows full recursive read access to metadata of the `$FONT` folder, including file listing and statistics.","permissions":["read-meta","scope-font-recursive"]},"allow-font-read":{"identifier":"allow-font-read","description":"This allows non-recursive read access to the `$FONT` folder.","permissions":["read-all","scope-font"]},"allow-font-read-recursive":{"identifier":"allow-font-read-recursive","description":"This allows full recursive read access to the complete `$FONT` folder, files and subdirectories.","permissions":["read-all","scope-font-recursive"]},"allow-font-write":{"identifier":"allow-font-write","description":"This allows non-recursive write access to the `$FONT` folder.","permissions":["write-all","scope-font"]},"allow-font-write-recursive":{"identifier":"allow-font-write-recursive","description":"This allows full recursive write access to the complete `$FONT` folder, files and subdirectories.","permissions":["write-all","scope-font-recursive"]},"allow-home-meta":{"identifier":"allow-home-meta","description":"This allows non-recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-index"]},"allow-home-meta-recursive":{"identifier":"allow-home-meta-recursive","description":"This allows full recursive read access to metadata of the `$HOME` folder, including file listing and statistics.","permissions":["read-meta","scope-home-recursive"]},"allow-home-read":{"identifier":"allow-home-read","description":"This allows non-recursive read access to the `$HOME` folder.","permissions":["read-all","scope-home"]},"allow-home-read-recursive":{"identifier":"allow-home-read-recursive","description":"This allows full recursive read access to the complete `$HOME` folder, files and subdirectories.","permissions":["read-all","scope-home-recursive"]},"allow-home-write":{"identifier":"allow-home-write","description":"This allows non-recursive write access to the `$HOME` folder.","permissions":["write-all","scope-home"]},"allow-home-write-recursive":{"identifier":"allow-home-write-recursive","description":"This allows full recursive write access to the complete `$HOME` folder, files and subdirectories.","permissions":["write-all","scope-home-recursive"]},"allow-localdata-meta":{"identifier":"allow-localdata-meta","description":"This allows non-recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-index"]},"allow-localdata-meta-recursive":{"identifier":"allow-localdata-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOCALDATA` folder, including file listing and statistics.","permissions":["read-meta","scope-localdata-recursive"]},"allow-localdata-read":{"identifier":"allow-localdata-read","description":"This allows non-recursive read access to the `$LOCALDATA` folder.","permissions":["read-all","scope-localdata"]},"allow-localdata-read-recursive":{"identifier":"allow-localdata-read-recursive","description":"This allows full recursive read access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["read-all","scope-localdata-recursive"]},"allow-localdata-write":{"identifier":"allow-localdata-write","description":"This allows non-recursive write access to the `$LOCALDATA` folder.","permissions":["write-all","scope-localdata"]},"allow-localdata-write-recursive":{"identifier":"allow-localdata-write-recursive","description":"This allows full recursive write access to the complete `$LOCALDATA` folder, files and subdirectories.","permissions":["write-all","scope-localdata-recursive"]},"allow-log-meta":{"identifier":"allow-log-meta","description":"This allows non-recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-index"]},"allow-log-meta-recursive":{"identifier":"allow-log-meta-recursive","description":"This allows full recursive read access to metadata of the `$LOG` folder, including file listing and statistics.","permissions":["read-meta","scope-log-recursive"]},"allow-log-read":{"identifier":"allow-log-read","description":"This allows non-recursive read access to the `$LOG` folder.","permissions":["read-all","scope-log"]},"allow-log-read-recursive":{"identifier":"allow-log-read-recursive","description":"This allows full recursive read access to the complete `$LOG` folder, files and subdirectories.","permissions":["read-all","scope-log-recursive"]},"allow-log-write":{"identifier":"allow-log-write","description":"This allows non-recursive write access to the `$LOG` folder.","permissions":["write-all","scope-log"]},"allow-log-write-recursive":{"identifier":"allow-log-write-recursive","description":"This allows full recursive write access to the complete `$LOG` folder, files and subdirectories.","permissions":["write-all","scope-log-recursive"]},"allow-picture-meta":{"identifier":"allow-picture-meta","description":"This allows non-recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-index"]},"allow-picture-meta-recursive":{"identifier":"allow-picture-meta-recursive","description":"This allows full recursive read access to metadata of the `$PICTURE` folder, including file listing and statistics.","permissions":["read-meta","scope-picture-recursive"]},"allow-picture-read":{"identifier":"allow-picture-read","description":"This allows non-recursive read access to the `$PICTURE` folder.","permissions":["read-all","scope-picture"]},"allow-picture-read-recursive":{"identifier":"allow-picture-read-recursive","description":"This allows full recursive read access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["read-all","scope-picture-recursive"]},"allow-picture-write":{"identifier":"allow-picture-write","description":"This allows non-recursive write access to the `$PICTURE` folder.","permissions":["write-all","scope-picture"]},"allow-picture-write-recursive":{"identifier":"allow-picture-write-recursive","description":"This allows full recursive write access to the complete `$PICTURE` folder, files and subdirectories.","permissions":["write-all","scope-picture-recursive"]},"allow-public-meta":{"identifier":"allow-public-meta","description":"This allows non-recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-index"]},"allow-public-meta-recursive":{"identifier":"allow-public-meta-recursive","description":"This allows full recursive read access to metadata of the `$PUBLIC` folder, including file listing and statistics.","permissions":["read-meta","scope-public-recursive"]},"allow-public-read":{"identifier":"allow-public-read","description":"This allows non-recursive read access to the `$PUBLIC` folder.","permissions":["read-all","scope-public"]},"allow-public-read-recursive":{"identifier":"allow-public-read-recursive","description":"This allows full recursive read access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["read-all","scope-public-recursive"]},"allow-public-write":{"identifier":"allow-public-write","description":"This allows non-recursive write access to the `$PUBLIC` folder.","permissions":["write-all","scope-public"]},"allow-public-write-recursive":{"identifier":"allow-public-write-recursive","description":"This allows full recursive write access to the complete `$PUBLIC` folder, files and subdirectories.","permissions":["write-all","scope-public-recursive"]},"allow-resource-meta":{"identifier":"allow-resource-meta","description":"This allows non-recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-index"]},"allow-resource-meta-recursive":{"identifier":"allow-resource-meta-recursive","description":"This allows full recursive read access to metadata of the `$RESOURCE` folder, including file listing and statistics.","permissions":["read-meta","scope-resource-recursive"]},"allow-resource-read":{"identifier":"allow-resource-read","description":"This allows non-recursive read access to the `$RESOURCE` folder.","permissions":["read-all","scope-resource"]},"allow-resource-read-recursive":{"identifier":"allow-resource-read-recursive","description":"This allows full recursive read access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["read-all","scope-resource-recursive"]},"allow-resource-write":{"identifier":"allow-resource-write","description":"This allows non-recursive write access to the `$RESOURCE` folder.","permissions":["write-all","scope-resource"]},"allow-resource-write-recursive":{"identifier":"allow-resource-write-recursive","description":"This allows full recursive write access to the complete `$RESOURCE` folder, files and subdirectories.","permissions":["write-all","scope-resource-recursive"]},"allow-runtime-meta":{"identifier":"allow-runtime-meta","description":"This allows non-recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-index"]},"allow-runtime-meta-recursive":{"identifier":"allow-runtime-meta-recursive","description":"This allows full recursive read access to metadata of the `$RUNTIME` folder, including file listing and statistics.","permissions":["read-meta","scope-runtime-recursive"]},"allow-runtime-read":{"identifier":"allow-runtime-read","description":"This allows non-recursive read access to the `$RUNTIME` folder.","permissions":["read-all","scope-runtime"]},"allow-runtime-read-recursive":{"identifier":"allow-runtime-read-recursive","description":"This allows full recursive read access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["read-all","scope-runtime-recursive"]},"allow-runtime-write":{"identifier":"allow-runtime-write","description":"This allows non-recursive write access to the `$RUNTIME` folder.","permissions":["write-all","scope-runtime"]},"allow-runtime-write-recursive":{"identifier":"allow-runtime-write-recursive","description":"This allows full recursive write access to the complete `$RUNTIME` folder, files and subdirectories.","permissions":["write-all","scope-runtime-recursive"]},"allow-temp-meta":{"identifier":"allow-temp-meta","description":"This allows non-recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-index"]},"allow-temp-meta-recursive":{"identifier":"allow-temp-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMP` folder, including file listing and statistics.","permissions":["read-meta","scope-temp-recursive"]},"allow-temp-read":{"identifier":"allow-temp-read","description":"This allows non-recursive read access to the `$TEMP` folder.","permissions":["read-all","scope-temp"]},"allow-temp-read-recursive":{"identifier":"allow-temp-read-recursive","description":"This allows full recursive read access to the complete `$TEMP` folder, files and subdirectories.","permissions":["read-all","scope-temp-recursive"]},"allow-temp-write":{"identifier":"allow-temp-write","description":"This allows non-recursive write access to the `$TEMP` folder.","permissions":["write-all","scope-temp"]},"allow-temp-write-recursive":{"identifier":"allow-temp-write-recursive","description":"This allows full recursive write access to the complete `$TEMP` folder, files and subdirectories.","permissions":["write-all","scope-temp-recursive"]},"allow-template-meta":{"identifier":"allow-template-meta","description":"This allows non-recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-index"]},"allow-template-meta-recursive":{"identifier":"allow-template-meta-recursive","description":"This allows full recursive read access to metadata of the `$TEMPLATE` folder, including file listing and statistics.","permissions":["read-meta","scope-template-recursive"]},"allow-template-read":{"identifier":"allow-template-read","description":"This allows non-recursive read access to the `$TEMPLATE` folder.","permissions":["read-all","scope-template"]},"allow-template-read-recursive":{"identifier":"allow-template-read-recursive","description":"This allows full recursive read access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["read-all","scope-template-recursive"]},"allow-template-write":{"identifier":"allow-template-write","description":"This allows non-recursive write access to the `$TEMPLATE` folder.","permissions":["write-all","scope-template"]},"allow-template-write-recursive":{"identifier":"allow-template-write-recursive","description":"This allows full recursive write access to the complete `$TEMPLATE` folder, files and subdirectories.","permissions":["write-all","scope-template-recursive"]},"allow-video-meta":{"identifier":"allow-video-meta","description":"This allows non-recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-index"]},"allow-video-meta-recursive":{"identifier":"allow-video-meta-recursive","description":"This allows full recursive read access to metadata of the `$VIDEO` folder, including file listing and statistics.","permissions":["read-meta","scope-video-recursive"]},"allow-video-read":{"identifier":"allow-video-read","description":"This allows non-recursive read access to the `$VIDEO` folder.","permissions":["read-all","scope-video"]},"allow-video-read-recursive":{"identifier":"allow-video-read-recursive","description":"This allows full recursive read access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["read-all","scope-video-recursive"]},"allow-video-write":{"identifier":"allow-video-write","description":"This allows non-recursive write access to the `$VIDEO` folder.","permissions":["write-all","scope-video"]},"allow-video-write-recursive":{"identifier":"allow-video-write-recursive","description":"This allows full recursive write access to the complete `$VIDEO` folder, files and subdirectories.","permissions":["write-all","scope-video-recursive"]},"deny-default":{"identifier":"deny-default","description":"This denies access to dangerous Tauri relevant files and folders by default.","permissions":["deny-webview-data-linux","deny-webview-data-windows"]}},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"description":"A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},{"properties":{"path":{"description":"A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"description":"FS scope entry.","title":"FsScopeEntry"}},"global-shortcut":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe shortcuts can be inherently dangerous and it is\napplication specific if specific shortcuts should be\nregistered or unregistered.\n","permissions":[]},"permissions":{"allow-is-registered":{"identifier":"allow-is-registered","description":"Enables the is_registered command without any pre-configured scope.","commands":{"allow":["is_registered"],"deny":[]}},"allow-register":{"identifier":"allow-register","description":"Enables the register command without any pre-configured scope.","commands":{"allow":["register"],"deny":[]}},"allow-register-all":{"identifier":"allow-register-all","description":"Enables the register_all command without any pre-configured scope.","commands":{"allow":["register_all"],"deny":[]}},"allow-unregister":{"identifier":"allow-unregister","description":"Enables the unregister command without any pre-configured scope.","commands":{"allow":["unregister"],"deny":[]}},"allow-unregister-all":{"identifier":"allow-unregister-all","description":"Enables the unregister_all command without any pre-configured scope.","commands":{"allow":["unregister_all"],"deny":[]}},"deny-is-registered":{"identifier":"deny-is-registered","description":"Denies the is_registered command without any pre-configured scope.","commands":{"allow":[],"deny":["is_registered"]}},"deny-register":{"identifier":"deny-register","description":"Denies the register command without any pre-configured scope.","commands":{"allow":[],"deny":["register"]}},"deny-register-all":{"identifier":"deny-register-all","description":"Denies the register_all command without any pre-configured scope.","commands":{"allow":[],"deny":["register_all"]}},"deny-unregister":{"identifier":"deny-unregister","description":"Denies the unregister command without any pre-configured scope.","commands":{"allow":[],"deny":["unregister"]}},"deny-unregister-all":{"identifier":"deny-unregister-all","description":"Denies the unregister_all command without any pre-configured scope.","commands":{"allow":[],"deny":["unregister_all"]}}},"permission_sets":{},"global_scope_schema":null},"notification":{"default_permission":{"identifier":"default","description":"This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n","permissions":["allow-is-permission-granted","allow-request-permission","allow-notify","allow-register-action-types","allow-register-listener","allow-cancel","allow-get-pending","allow-remove-active","allow-get-active","allow-check-permissions","allow-show","allow-batch","allow-list-channels","allow-delete-channel","allow-create-channel","allow-permission-state"]},"permissions":{"allow-batch":{"identifier":"allow-batch","description":"Enables the batch command without any pre-configured scope.","commands":{"allow":["batch"],"deny":[]}},"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-check-permissions":{"identifier":"allow-check-permissions","description":"Enables the check_permissions command without any pre-configured scope.","commands":{"allow":["check_permissions"],"deny":[]}},"allow-create-channel":{"identifier":"allow-create-channel","description":"Enables the create_channel command without any pre-configured scope.","commands":{"allow":["create_channel"],"deny":[]}},"allow-delete-channel":{"identifier":"allow-delete-channel","description":"Enables the delete_channel command without any pre-configured scope.","commands":{"allow":["delete_channel"],"deny":[]}},"allow-get-active":{"identifier":"allow-get-active","description":"Enables the get_active command without any pre-configured scope.","commands":{"allow":["get_active"],"deny":[]}},"allow-get-pending":{"identifier":"allow-get-pending","description":"Enables the get_pending command without any pre-configured scope.","commands":{"allow":["get_pending"],"deny":[]}},"allow-is-permission-granted":{"identifier":"allow-is-permission-granted","description":"Enables the is_permission_granted command without any pre-configured scope.","commands":{"allow":["is_permission_granted"],"deny":[]}},"allow-list-channels":{"identifier":"allow-list-channels","description":"Enables the list_channels command without any pre-configured scope.","commands":{"allow":["list_channels"],"deny":[]}},"allow-notify":{"identifier":"allow-notify","description":"Enables the notify command without any pre-configured scope.","commands":{"allow":["notify"],"deny":[]}},"allow-permission-state":{"identifier":"allow-permission-state","description":"Enables the permission_state command without any pre-configured scope.","commands":{"allow":["permission_state"],"deny":[]}},"allow-register-action-types":{"identifier":"allow-register-action-types","description":"Enables the register_action_types command without any pre-configured scope.","commands":{"allow":["register_action_types"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-active":{"identifier":"allow-remove-active","description":"Enables the remove_active command without any pre-configured scope.","commands":{"allow":["remove_active"],"deny":[]}},"allow-request-permission":{"identifier":"allow-request-permission","description":"Enables the request_permission command without any pre-configured scope.","commands":{"allow":["request_permission"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"deny-batch":{"identifier":"deny-batch","description":"Denies the batch command without any pre-configured scope.","commands":{"allow":[],"deny":["batch"]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-check-permissions":{"identifier":"deny-check-permissions","description":"Denies the check_permissions command without any pre-configured scope.","commands":{"allow":[],"deny":["check_permissions"]}},"deny-create-channel":{"identifier":"deny-create-channel","description":"Denies the create_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["create_channel"]}},"deny-delete-channel":{"identifier":"deny-delete-channel","description":"Denies the delete_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_channel"]}},"deny-get-active":{"identifier":"deny-get-active","description":"Denies the get_active command without any pre-configured scope.","commands":{"allow":[],"deny":["get_active"]}},"deny-get-pending":{"identifier":"deny-get-pending","description":"Denies the get_pending command without any pre-configured scope.","commands":{"allow":[],"deny":["get_pending"]}},"deny-is-permission-granted":{"identifier":"deny-is-permission-granted","description":"Denies the is_permission_granted command without any pre-configured scope.","commands":{"allow":[],"deny":["is_permission_granted"]}},"deny-list-channels":{"identifier":"deny-list-channels","description":"Denies the list_channels command without any pre-configured scope.","commands":{"allow":[],"deny":["list_channels"]}},"deny-notify":{"identifier":"deny-notify","description":"Denies the notify command without any pre-configured scope.","commands":{"allow":[],"deny":["notify"]}},"deny-permission-state":{"identifier":"deny-permission-state","description":"Denies the permission_state command without any pre-configured scope.","commands":{"allow":[],"deny":["permission_state"]}},"deny-register-action-types":{"identifier":"deny-register-action-types","description":"Denies the register_action_types command without any pre-configured scope.","commands":{"allow":[],"deny":["register_action_types"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-active":{"identifier":"deny-remove-active","description":"Denies the remove_active command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_active"]}},"deny-request-permission":{"identifier":"deny-request-permission","description":"Denies the request_permission command without any pre-configured scope.","commands":{"allow":[],"deny":["request_permission"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: <https://docs.rs/regex/latest/regex/#syntax>","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"store":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the store plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-load","allow-get-store","allow-set","allow-get","allow-has","allow-delete","allow-clear","allow-reset","allow-keys","allow-values","allow-entries","allow-length","allow-reload","allow-save"]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-delete":{"identifier":"allow-delete","description":"Enables the delete command without any pre-configured scope.","commands":{"allow":["delete"],"deny":[]}},"allow-entries":{"identifier":"allow-entries","description":"Enables the entries command without any pre-configured scope.","commands":{"allow":["entries"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-get-store":{"identifier":"allow-get-store","description":"Enables the get_store command without any pre-configured scope.","commands":{"allow":["get_store"],"deny":[]}},"allow-has":{"identifier":"allow-has","description":"Enables the has command without any pre-configured scope.","commands":{"allow":["has"],"deny":[]}},"allow-keys":{"identifier":"allow-keys","description":"Enables the keys command without any pre-configured scope.","commands":{"allow":["keys"],"deny":[]}},"allow-length":{"identifier":"allow-length","description":"Enables the length command without any pre-configured scope.","commands":{"allow":["length"],"deny":[]}},"allow-load":{"identifier":"allow-load","description":"Enables the load command without any pre-configured scope.","commands":{"allow":["load"],"deny":[]}},"allow-reload":{"identifier":"allow-reload","description":"Enables the reload command without any pre-configured scope.","commands":{"allow":["reload"],"deny":[]}},"allow-reset":{"identifier":"allow-reset","description":"Enables the reset command without any pre-configured scope.","commands":{"allow":["reset"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"allow-set":{"identifier":"allow-set","description":"Enables the set command without any pre-configured scope.","commands":{"allow":["set"],"deny":[]}},"allow-values":{"identifier":"allow-values","description":"Enables the values command without any pre-configured scope.","commands":{"allow":["values"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-delete":{"identifier":"deny-delete","description":"Denies the delete command without any pre-configured scope.","commands":{"allow":[],"deny":["delete"]}},"deny-entries":{"identifier":"deny-entries","description":"Denies the entries command without any pre-configured scope.","commands":{"allow":[],"deny":["entries"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-get-store":{"identifier":"deny-get-store","description":"Denies the get_store command without any pre-configured scope.","commands":{"allow":[],"deny":["get_store"]}},"deny-has":{"identifier":"deny-has","description":"Denies the has command without any pre-configured scope.","commands":{"allow":[],"deny":["has"]}},"deny-keys":{"identifier":"deny-keys","description":"Denies the keys command without any pre-configured scope.","commands":{"allow":[],"deny":["keys"]}},"deny-length":{"identifier":"deny-length","description":"Denies the length command without any pre-configured scope.","commands":{"allow":[],"deny":["length"]}},"deny-load":{"identifier":"deny-load","description":"Denies the load command without any pre-configured scope.","commands":{"allow":[],"deny":["load"]}},"deny-reload":{"identifier":"deny-reload","description":"Denies the reload command without any pre-configured scope.","commands":{"allow":[],"deny":["reload"]}},"deny-reset":{"identifier":"deny-reset","description":"Denies the reset command without any pre-configured scope.","commands":{"allow":[],"deny":["reset"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}},"deny-set":{"identifier":"deny-set","description":"Denies the set command without any pre-configured scope.","commands":{"allow":[],"deny":["set"]}},"deny-values":{"identifier":"deny-values","description":"Denies the values command without any pre-configured scope.","commands":{"allow":[],"deny":["values"]}}},"permission_sets":{},"global_scope_schema":null}}
\ No newline at end of file
Addedsrc-tauri/gen/schemas/capabilities.json+1−0View fileUnifiedSplit
@@ -0,0 +1 @@
1{"default":{"identifier":"default","description":"Default capabilities for Voxlen","local":true,"windows":["main"],"permissions":["core:default","core:window:default","core:window:allow-close","core:window:allow-minimize","core:window:allow-maximize","core:window:allow-unmaximize","core:window:allow-start-dragging","core:window:allow-set-size","core:window:allow-set-position","core:window:allow-set-focus","core:window:allow-hide","core:window:allow-show","global-shortcut:default","notification:default","store:default","shell:default","dialog:default","fs:default","autostart:default"]}}
\ No newline at end of file
Addedsrc-tauri/gen/schemas/desktop-schema.json+6686−0View fileUnifiedSplit
Large file (6,687 lines). Load full file
Addedsrc-tauri/gen/schemas/linux-schema.json+6686−0View fileUnifiedSplit
Large file (6,687 lines). Load full file
Modifiedsrc-tauri/src/audio/capture.rs+94−38View fileUnifiedSplit
@@ -77,6 +77,8 @@ pub fn start_capture_with_options(
7777 let buffer_clone = buffer.clone();
7878 let waveform_last_emit = Arc::new(Mutex::new(Instant::now()));
7979 let waveform_last_emit_clone = waveform_last_emit.clone();
80 let noise_state = Arc::new(Mutex::new(NoiseState::new(sample_rate)));
81 let noise_state_clone = noise_state.clone();
8082
8183 let stream = match config.sample_format() {
8284 cpal::SampleFormat::F32 => device.build_input_stream(
@@ -94,6 +96,7 @@ pub fn start_capture_with_options(
9496 &waveform_last_emit_clone,
9597 input_gain,
9698 noise_suppression,
99 &noise_state_clone,
97100 );
98101 },
99102 err_fn,
@@ -115,6 +118,7 @@ pub fn start_capture_with_options(
115118 &waveform_last_emit_clone,
116119 input_gain,
117120 noise_suppression,
121 &noise_state_clone,
118122 );
119123 },
120124 err_fn,
@@ -139,6 +143,7 @@ pub fn start_capture_with_options(
139143 &waveform_last_emit_clone,
140144 input_gain,
141145 noise_suppression,
146 &noise_state_clone,
142147 );
143148 },
144149 err_fn,
@@ -189,9 +194,13 @@ fn process_audio_data(
189194 waveform_last_emit: &Arc<Mutex<Instant>>,
190195 input_gain: f32,
191196 noise_suppression: bool,
197 noise_state: &Arc<Mutex<NoiseState>>,
192198) {
193199 // Apply input gain + noise processing
194 let processed: Vec<f32> = apply_audio_processing(data, input_gain, noise_suppression);
200 let processed: Vec<f32> = {
201 let mut state = noise_state.lock();
202 apply_audio_processing(data, input_gain, noise_suppression, &mut state)
203 };
195204 let data = processed.as_slice();
196205
197206 // Calculate RMS level for visualization
@@ -236,55 +245,102 @@ fn process_audio_data(
236245 }
237246}
238247
239/// Apply input gain and a simple spectral noise gate.
240///
241/// Noise gate: compute the RMS of the frame. If it is below the threshold
242/// (−40 dBFS ≈ 0.01), treat the frame as silence and zero it out. This
243/// removes constant background hum / HVAC without introducing latency or
244/// requiring RNNoise. A soft-knee is applied so speech onset is not clipped.
245///
246/// High-pass biquad at 80 Hz removes low-frequency rumble (desk vibration,
247/// air conditioning). Coefficients pre-computed for fs=16000; for other rates
248/// the filter is a gentle high-pass that still removes sub-80Hz energy.
249fn apply_audio_processing(samples: &[f32], gain: f32, noise_suppression: bool) -> Vec<f32> {
248/// Persistent state for the noise-suppression chain. Must live across audio
249/// callbacks: resetting the biquad per frame injects a click at every buffer
250/// boundary, and the gate needs a hangover so trailing consonants survive.
251pub(crate) struct NoiseState {
252 // High-pass biquad coefficients (computed for the device sample rate)
253 b0: f32,
254 b1: f32,
255 b2: f32,
256 a1: f32,
257 a2: f32,
258 // Filter delay line
259 x1: f32,
260 x2: f32,
261 y1: f32,
262 y2: f32,
263 // Gate hangover: samples of pass-through remaining after last speech
264 gate_hold_samples: u64,
265 hangover_samples: u64,
266}
267
268impl NoiseState {
269 /// RBJ-cookbook high-pass biquad at 80 Hz, Q = 0.707, designed for the
270 /// actual device sample rate (hard-coding 16 kHz coefficients turns the
271 /// filter into ~240 Hz at 48 kHz, which cuts male voice fundamentals).
272 pub(crate) fn new(sample_rate: u32) -> Self {
273 let fs = sample_rate.max(8000) as f32;
274 let w0 = 2.0 * std::f32::consts::PI * 80.0 / fs;
275 let cos_w0 = w0.cos();
276 let alpha = w0.sin() / (2.0 * 0.707);
277 let a0 = 1.0 + alpha;
278 Self {
279 b0: ((1.0 + cos_w0) / 2.0) / a0,
280 b1: (-(1.0 + cos_w0)) / a0,
281 b2: ((1.0 + cos_w0) / 2.0) / a0,
282 a1: (-2.0 * cos_w0) / a0,
283 a2: (1.0 - alpha) / a0,
284 x1: 0.0,
285 x2: 0.0,
286 y1: 0.0,
287 y2: 0.0,
288 gate_hold_samples: 0,
289 // Keep the gate open ~400 ms after speech so soft endings survive
290 hangover_samples: (fs * 0.4) as u64,
291 }
292 }
293}
294
295/// Apply input gain, an 80 Hz high-pass (rumble/HVAC removal), and a gentle
296/// RMS noise gate with hangover. The gate attenuates rather than hard-mutes
297/// so quiet speech onsets are never destroyed before they reach the STT
298/// engine.
299fn apply_audio_processing(
300 samples: &[f32],
301 gain: f32,
302 noise_suppression: bool,
303 state: &mut NoiseState,
304) -> Vec<f32> {
250305 // Apply gain first
251306 let mut out: Vec<f32> = samples.iter().map(|&s| (s * gain).clamp(-1.0, 1.0)).collect();
252307
253308 if noise_suppression {
254 // High-pass biquad (80 Hz, Q=0.707) — removes low-frequency rumble.
255 // Coefficients for fs=16000 Hz (close enough for 44.1/48 kHz too).
256 let b0: f32 = 0.9780;
257 let b1: f32 = -1.9560;
258 let b2: f32 = 0.9780;
259 let a1: f32 = -1.9556;
260 let a2: f32 = 0.9565;
261
262 let mut x1 = 0f32;
263 let mut x2 = 0f32;
264 let mut y1 = 0f32;
265 let mut y2 = 0f32;
266
267309 for s in out.iter_mut() {
268310 let x0 = *s;
269 let y0 = b0 * x0 + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
270 x2 = x1; x1 = x0;
271 y2 = y1; y1 = y0;
311 let y0 = state.b0 * x0 + state.b1 * state.x1 + state.b2 * state.x2
312 - state.a1 * state.y1
313 - state.a2 * state.y2;
314 state.x2 = state.x1;
315 state.x1 = x0;
316 state.y2 = state.y1;
317 state.y1 = y0;
272318 *s = y0.clamp(-1.0, 1.0);
273319 }
274320
275 // Noise gate: −40 dBFS threshold with soft knee
321 // Noise gate: −46 dBFS threshold with soft knee and hangover
276322 let rms = calculate_rms(&out);
277 const GATE_THRESHOLD: f32 = 0.01; // −40 dBFS
278 const GATE_KNEE: f32 = 0.025; // soft knee top
279 if rms < GATE_THRESHOLD {
280 // Full silence — background noise floor
281 out.iter_mut().for_each(|s| *s = 0.0);
282 } else if rms < GATE_KNEE {
283 // Soft knee: fade in proportionally
323 const GATE_THRESHOLD: f32 = 0.005; // ≈ −46 dBFS
324 const GATE_KNEE: f32 = 0.015;
325 const FLOOR_ATTENUATION: f32 = 0.1; // attenuate, don't hard-mute
326
327 if rms >= GATE_KNEE {
328 // Speech — pass through and re-arm the hangover
329 state.gate_hold_samples = state.hangover_samples;
330 } else if rms >= GATE_THRESHOLD {
331 // Soft knee: partial attenuation, also counts as activity
284332 let knee_ratio = (rms - GATE_THRESHOLD) / (GATE_KNEE - GATE_THRESHOLD);
285 out.iter_mut().for_each(|s| *s *= knee_ratio);
333 let g = FLOOR_ATTENUATION + (1.0 - FLOOR_ATTENUATION) * knee_ratio;
334 out.iter_mut().for_each(|s| *s *= g);
335 state.gate_hold_samples = state.hangover_samples;
336 } else if state.gate_hold_samples > 0 {
337 // Recent speech — keep the gate open so trailing sounds survive
338 state.gate_hold_samples =
339 state.gate_hold_samples.saturating_sub(out.len() as u64);
340 } else {
341 // Sustained silence — attenuate the noise floor
342 out.iter_mut().for_each(|s| *s *= FLOOR_ATTENUATION);
286343 }
287 // Above knee: pass through unchanged
288344 }
289345
290346 out
Modifiedsrc-tauri/src/commands/grammar.rs+4−4View fileUnifiedSplit
@@ -8,7 +8,7 @@ pub struct GrammarConfig {
88 pub style: WritingStyle,
99 pub auto_correct: bool,
1010 pub preserve_tone: bool,
11 /// When set, grammar correction is proxied through api.voxlen.com.
11 /// When set, grammar correction is proxied through voxlen.ai/api.
1212
1313 pub voxlen_api_key: Option<String>,
1414
@@ -118,7 +118,7 @@ pub async fn correct_grammar(
118118 let api_key = config
119119 .api_key
120120 .as_ref()
121 .ok_or("No API key configured. Sign in to your Voxlen account in Settings, or add your Anthropic/OpenAI API key.")?;
121 .ok_or("Not connected to a Voxlen account. Open Settings → Account, sign in at voxlen.ai/dashboard, and paste your account key.")?;
122122
123123 let mut effective_config = config.clone();
124124 if let Some(ctx) = effective_context {
@@ -344,7 +344,7 @@ Text: "{text}""#,
344344 })
345345}
346346
347/// Proxy grammar correction through api.voxlen.com — no provider key needed.
347/// Proxy grammar correction through voxlen.ai/api — no provider key needed.
348348async fn correct_with_voxlen_proxy(
349349 text: &str,
350350 voxlen_key: &str,
@@ -354,7 +354,7 @@ async fn correct_with_voxlen_proxy(
354354) -> Result<GrammarResult, String> {
355355 let client = reqwest::Client::new();
356356 let mut req = client
357 .post("https://api.voxlen.com/v1/grammar")
357 .post("https://voxlen.ai/api/grammar")
358358 .header("Authorization", format!("Bearer {}", voxlen_key))
359359 .header("content-type", "application/json");
360360 if let Some(tid) = config.voxlen_tenant_id.as_deref().filter(|s| !s.is_empty()) {
Modifiedsrc-tauri/src/commands/settings.rs+2−2View fileUnifiedSplit
@@ -76,7 +76,7 @@ pub struct AppSettings {
7676 pub translation_target_language: String,
7777
7878 // Voxlen account — when set, all STT and grammar calls are proxied
79 // through api.voxlen.com so users never need their own API keys.
79 // through voxlen.ai/api so users never need their own API keys.
8080
8181 pub voxlen_api_key: Option<String>,
8282
@@ -237,7 +237,7 @@ fn apply_settings_to_engines(
237237 let voxlen_key = s.voxlen_api_key.clone().filter(|k| !k.is_empty());
238238
239239 // When a Voxlen account key is present, STT is proxied through
240 // api.voxlen.com — user does not need their own provider keys.
240 // voxlen.ai/api — user does not need their own provider keys.
241241 let resolved_api_key = if voxlen_key.is_some() {
242242 None // voxlen_api_key takes precedence; direct key unused
243243 } else {
Modifiedsrc-tauri/src/commands/translate.rs+36−0View fileUnifiedSplit
@@ -102,6 +102,42 @@ fn language_name(code: &str) -> &str {
102102 }
103103}
104104
105async fn translate_with_voxlen_proxy(
106 text: &str,
107 target_language: &str,
108 voxlen_key: &str,
109) -> Result<TranslationResult, String> {
110 let client = reqwest::Client::new();
111 let response = client
112 .post("https://voxlen.ai/api/translate")
113 .header("Authorization", format!("Bearer {}", voxlen_key))
114 .header("Content-Type", "application/json")
115 .json(&serde_json::json!({
116 "text": text,
117 "target_language": target_language,
118 }))
119 .send()
120 .await
121 .map_err(|e| format!("Translation proxy request failed: {}", e))?;
122
123 if !response.status().is_success() {
124 let err = response.text().await.unwrap_or_default();
125 return Err(format!("Translation proxy error: {}", err));
126 }
127
128 let result: serde_json::Value = response
129 .json()
130 .await
131 .map_err(|e| format!("Failed to parse proxy response: {}", e))?;
132
133 Ok(TranslationResult {
134 original: text.to_string(),
135 translated: result["translated"].as_str().unwrap_or(text).to_string(),
136 target_language: target_language.to_string(),
137 detected_source: result["detected_source"].as_str().map(|s| s.to_string()),
138 })
139}
140
105141async fn translate_with_claude(
106142 text: &str,
107143 target_code: &str,
Modifiedsrc-tauri/src/stt/cloud.rs+38−27View fileUnifiedSplit
@@ -1,31 +1,39 @@
11use super::{SttConfig, TranscriptionResult, WordResult};
22
3/// Proxy STT through api.voxlen.com — no provider key needed.
3/// Proxy STT through voxlen.ai/api — no provider key needed.
44async fn voxlen_proxy_transcribe(
55 wav_data: &[u8],
66 voxlen_key: &str,
77 config: &SttConfig,
88) -> anyhow::Result<TranscriptionResult> {
9 let part = reqwest::multipart::Part::bytes(wav_data.to_vec())
10 .file_name("audio.wav")
11 .mime_str("audio/wav")?;
12
13 let form = reqwest::multipart::Form::new()
14 .part("audio", part)
15 .text("language", if config.auto_detect_language { "auto".to_string() } else { config.language.clone() })
16 .text("context", config.voxlen_context.clone().unwrap_or_else(|| "general".to_string()))
17 .text("smart_format", config.smart_format.to_string())
18 .text("punctuate", config.punctuate.to_string())
19 .text("diarize", config.speaker_diarization.to_string());
20
9 // The proxy expects a raw audio body with settings carried in headers
10 // (sending multipart here would forward form boundaries to Deepgram as
11 // if they were audio).
2112 let client = reqwest::Client::new();
2213 let mut req = client
23 .post("https://api.voxlen.com/v1/stt")
24 .header("Authorization", format!("Bearer {}", voxlen_key));
14 .post("https://voxlen.ai/api/stt")
15 .header("Authorization", format!("Bearer {}", voxlen_key))
16 .header("Content-Type", "audio/wav")
17 .header("X-Language", config.language.clone())
18 .header("X-Auto-Detect", config.auto_detect_language.to_string())
19 .header("X-Context", config.voxlen_context.clone().unwrap_or_else(|| "general".to_string()))
20 .header("X-Smart-Format", config.smart_format.to_string())
21 .header("X-Punctuate", config.punctuate.to_string())
22 .header("X-Diarize", config.speaker_diarization.to_string());
23 if !config.custom_vocabulary.is_empty() {
24 // URL-encoded so header stays ASCII-safe; server splits on commas
25 let keyterms = config
26 .custom_vocabulary
27 .iter()
28 .map(|w| urlencoding(w))
29 .collect::<Vec<_>>()
30 .join(",");
31 req = req.header("X-Keyterms", keyterms);
32 }
2533 if let Some(tid) = config.voxlen_tenant_id.as_deref().filter(|s| !s.is_empty()) {
2634 req = req.header("X-Tenant-ID", tid);
2735 }
28 let response = req.multipart(form).send().await?;
36 let response = req.body(wav_data.to_vec()).send().await?;
2937
3038 if !response.status().is_success() {
3139 let error_text = response.text().await?;
@@ -146,7 +154,7 @@ pub async fn deepgram_transcribe(
146154 let api_key = config
147155 .api_key
148156 .as_ref()
149 .ok_or_else(|| anyhow::anyhow!("No API key configured. Sign in to your Voxlen account in Settings, or add your Deepgram API key."))?;
157 .ok_or_else(|| anyhow::anyhow!("Not connected to a Voxlen account. Open Settings → Account, sign in at voxlen.ai/dashboard, and paste your account key."))?;
150158
151159 let mut url = String::from("https://api.deepgram.com/v1/listen?model=nova-3&mip_opt_out=true");
152160
@@ -165,9 +173,9 @@ pub async fn deepgram_transcribe(
165173 url.push_str(&format!("&language={}", config.language));
166174 }
167175
168 // Add custom vocabulary as keywords
176 // Nova-3 uses keyterm prompting; the old `keywords` param is ignored on nova-3
169177 for word in &config.custom_vocabulary {
170 url.push_str(&format!("&keywords={}", urlencoding(word)));
178 url.push_str(&format!("&keyterm={}", urlencoding(word)));
171179 }
172180
173181 if config.speaker_diarization {
@@ -265,12 +273,15 @@ pub async fn deepgram_transcribe(
265273 })
266274}
267275
268fn urlencoding(s: &str) -> String {
269 s.chars()
270 .map(|c| match c {
271 'A'..='Z' | 'a'..='z' | '0'..='9' | '-' | '_' | '.' | '~' => c.to_string(),
272 ' ' => "%20".to_string(),
273 _ => format!("%{:02X}", c as u32),
274 })
275 .collect()
276pub(crate) fn urlencoding(s: &str) -> String {
277 let mut out = String::with_capacity(s.len() * 3);
278 for byte in s.as_bytes() {
279 match byte {
280 b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
281 out.push(*byte as char)
282 }
283 _ => out.push_str(&format!("%{:02X}", byte)),
284 }
285 }
286 out
276287}
Modifiedsrc-tauri/src/stt/mod.rs+1−1View fileUnifiedSplit
@@ -46,7 +46,7 @@ pub struct SttConfig {
4646 /// prefix output with speaker labels like "[Speaker 1]: ...".
4747
4848 pub speaker_diarization: bool,
49 /// When set, all STT calls are proxied through api.voxlen.com
49 /// When set, all STT calls are proxied through voxlen.ai/api
5050 /// so the user does not need their own provider API keys.
5151
5252 pub voxlen_api_key: Option<String>,
Modifiedsrc-tauri/src/stt/processor.rs+1−1View fileUnifiedSplit
@@ -66,7 +66,7 @@ impl AudioProcessor {
6666 // Streaming path — ensure a live session exists
6767 let needs_new_session = streaming_relay
6868 .as_ref()
69 .map(|(tx, _)| tx.is_disconnected())
69 .map(|(_, session)| session.is_stopped())
7070 .unwrap_or(true);
7171
7272
Modifiedsrc-tauri/src/stt/streaming.rs+34−2View fileUnifiedSplit
@@ -18,6 +18,12 @@ impl StreamingSession {
1818 pub fn stop(&self) {
1919 self.stop_flag.store(true, Ordering::Relaxed);
2020 }
21
22 /// True once the session has been stopped or its worker task has exited
23 /// (clean shutdown, auth failure, or retries exhausted).
24 pub fn is_stopped(&self) -> bool {
25 self.stop_flag.load(Ordering::Relaxed)
26 }
2127}
2228
2329
@@ -84,13 +90,34 @@ pub fn start_streaming(
8490 let stop_flag = Arc::new(AtomicBool::new(false));
8591 let stop_clone = stop_flag.clone();
8692
93 let direct_api_key = config.api_key.filter(|k| !k.is_empty());
94 let voxlen_api_key = config.voxlen_api_key.filter(|k| !k.is_empty());
8795 let language = config.language.clone();
8896 let auto_detect = config.auto_detect_language;
8997 let custom_vocabulary = config.custom_vocabulary.clone();
9098 let diarization = config.speaker_diarization;
9199 let tenant_id = config.voxlen_tenant_id.clone();
92100
101 let stop_on_exit = stop_flag.clone();
93102 let handle = tokio::spawn(async move {
103 let session_task = async {
104 // Resolve the actual Deepgram API key to use for this session.
105 // If the user has a direct Deepgram key, use it. Otherwise fetch a
106 // short-lived proxy key from the Voxlen backend.
107 let api_key = if let Some(k) = direct_api_key {
108 k
109 } else if let Some(vk) = voxlen_api_key {
110 match fetch_proxy_deepgram_key(&vk).await {
111 Ok(k) => k,
112 Err(e) => {
113 let _ = app_handle.emit("transcription-error", format!("Failed to get streaming key from Voxlen proxy: {}", e));
114 return;
115 }
116 }
117 } else {
118 return;
119 };
120
94121 let max_retries = 3;
95122 let mut attempt = 0;
96123
@@ -141,6 +168,10 @@ pub fn start_streaming(
141168 }
142169 }
143170 }
171 };
172 session_task.await;
173 // Mark the session ended so the processor knows to start a fresh one
174 stop_on_exit.store(true, Ordering::Relaxed);
144175 });
145176
146177 Ok(StreamingSession {
@@ -261,9 +292,10 @@ async fn run_session_once(
261292 url.push_str("&diarize=true");
262293 }
263294
295 // Nova-3 uses keyterm prompting (the old `keywords` param is silently
296 // ignored on nova-3), so custom vocabulary must go through `keyterm`.
264297 for word in custom_vocabulary {
265 let encoded = word.replace(' ', "%20");
266 url.push_str(&format!("&keywords={}:1.5", encoded));
298 url.push_str(&format!("&keyterm={}", super::cloud::urlencoding(word)));
267299 }
268300
269301 log::info!("Connecting to Deepgram streaming...");
Modifiedsrc-tauri/tauri.conf.json+1−1View fileUnifiedSplit
@@ -62,7 +62,7 @@
6262 },
6363 "windows": {
6464 "certificateThumbprint": null,
65 "timestampUrl": null,
65 "timestampUrl": "http://timestamp.digicert.com",
6666 "webviewInstallMode": {
6767 "type": "embedBootstrapper"
6868 },
Modifiedsrc/components/clients/ClientsPanel.tsx+71−69View fileUnifiedSplit
@@ -3,12 +3,15 @@ import { Plus, Briefcase, Archive, Trash2, Edit2, Check, X, Download, BookOpen }
33import { useClientsStore, type Client } from "../../stores/clients";
44import { useSettingsStore } from "../../stores/settings";
55import { exportBillingCsv, exportAllBillingCsv, downloadBillingExport } from "../../lib/export";
6import { Button } from "../ui/Button";
67
78const CLIENT_COLORS = [
89 "#7345d1", "#3b82f6", "#10b981", "#f59e0b",
910 "#ef4444", "#8b5cf6", "#06b6d4", "#ec4899",
1011];
1112
13const INPUT_CLS = "w-full bg-surface-50 border border-surface-300/70 rounded-lg px-3 py-2 text-sm text-surface-900 placeholder-surface-500 focus:outline-none focus:border-brass-400 focus:ring-1 focus:ring-brass-400/30 shadow-inset-hairline transition-colors";
14
1215function AddClientModal({ onClose }: { onClose: () => void }) {
1316 const { addClient } = useClientsStore();
1417 const settings = useSettingsStore();
@@ -25,36 +28,34 @@ function AddClientModal({ onClose }: { onClose: () => void }) {
2528
2629 return (
2730 <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
28 <div className="bg-[#18181b] border border-[#27272a] rounded-2xl p-6 w-full max-w-md shadow-2xl">
29 <h2 className="text-lg font-bold mb-5">Add Client / Matter</h2>
31 <div className="bg-surface-50 border border-surface-300/60 rounded-2xl p-6 w-full max-w-md shadow-2xl">
32 <h2 className="text-lg font-bold text-surface-950 mb-5">Add Client / Matter</h2>
3033
3134 <div className="space-y-4">
3235 <div>
33 <label className="text-xs font-medium text-zinc-400 uppercase tracking-wider mb-1.5 block">Client Name *</label>
36 <label className="label-caps mb-1.5 block">Client Name *</label>
3437 <input
3538 autoFocus
3639 value={name}
3740 onChange={(e) => setName(e.target.value)}
3841 onKeyDown={(e) => e.key === "Enter" && submit()}
39 className="w-full bg-[#09090b] border border-[#3f3f46] rounded-lg px-3 py-2 text-sm text-white placeholder-zinc-600 focus:outline-none focus:border-[#7345d1]"
42 className={INPUT_CLS}
4043 placeholder="e.g. Acme Corp, Smith v Jones"
4144 />
4245 </div>
4346
4447 <div>
45 <label className="text-xs font-medium text-zinc-400 uppercase tracking-wider mb-1.5 block">Matter / File Number</label>
48 <label className="label-caps mb-1.5 block">Matter / File Number</label>
4649 <input
4750 value={matterNumber}
4851 onChange={(e) => setMatterNumber(e.target.value)}
49 className="w-full bg-[#09090b] border border-[#3f3f46] rounded-lg px-3 py-2 text-sm text-white placeholder-zinc-600 focus:outline-none focus:border-[#7345d1]"
52 className={INPUT_CLS}
5053 placeholder="e.g. 2024-001, M-4821"
5154 />
5255 </div>
5356
5457 <div>
55 <label className="text-xs font-medium text-zinc-400 uppercase tracking-wider mb-1.5 block">
56 Billable Rate ($/hr)
57 </label>
58 <label className="label-caps mb-1.5 block">Billable Rate ($/hr)</label>
5859 <div className="flex items-center gap-3">
5960 <input
6061 type="range"
@@ -63,16 +64,16 @@ function AddClientModal({ onClose }: { onClose: () => void }) {
6364 step={25}
6465 value={rate}
6566 onChange={(e) => setRate(Number(e.target.value))}
66 className="flex-1 accent-[#7345d1]"
67 className="flex-1 accent-brass-500"
6768 />
68 <span className="text-sm font-semibold w-20 text-right">
69 <span className="text-sm font-semibold text-surface-900 w-20 text-right">
6970 {rate === 0 ? "Use default" : `$${rate}/hr`}
7071 </span>
7172 </div>
7273 </div>
7374
7475 <div>
75 <label className="text-xs font-medium text-zinc-400 uppercase tracking-wider mb-1.5 block">Colour</label>
76 <label className="label-caps mb-1.5 block">Colour</label>
7677 <div className="flex gap-2 flex-wrap">
7778 {CLIENT_COLORS.map((c) => (
7879 <button
@@ -90,19 +91,21 @@ function AddClientModal({ onClose }: { onClose: () => void }) {
9091 </div>
9192
9293 <div className="flex gap-3 mt-6">
93 <button
94 <Button
95 variant="primary"
9496 onClick={submit}
9597 disabled={!name.trim()}
96 className="flex-1 bg-[#7345d1] hover:bg-[#5c35b0] disabled:opacity-40 text-white font-semibold text-sm py-2 rounded-lg transition-colors"
98 className="flex-1"
9799 >
98100 Add Client
99 </button>
100 <button
101 </Button>
102 <Button
103 variant="ghost"
101104 onClick={onClose}
102 className="flex-1 bg-[#27272a] hover:bg-[#3f3f46] text-white font-semibold text-sm py-2 rounded-lg transition-colors"
105 className="flex-1"
103106 >
104107 Cancel
105 </button>
108 </Button>
106109 </div>
107110 </div>
108111 </div>
@@ -143,9 +146,9 @@ function ClientCard({ client }: { client: Client }) {
143146 };
144147
145148 return (
146 <div className="bg-[#18181b] border border-[#27272a] rounded-xl overflow-hidden">
149 <div className="bg-surface-50 border border-surface-300/60 rounded-xl overflow-hidden shadow-inset-hairline">
147150 {/* Header */}
148 <div className="flex items-start gap-3 p-4 border-b border-[#27272a]">
151 <div className="flex items-start gap-3 p-4 border-b border-surface-300/50">
149152 <div
150153 className="w-3 h-3 rounded-full mt-1.5 shrink-0"
151154 style={{ backgroundColor: client.color }}
@@ -157,13 +160,13 @@ function ClientCard({ client }: { client: Client }) {
157160 autoFocus
158161 value={editName}
159162 onChange={(e) => setEditName(e.target.value)}
160 className="w-full bg-[#09090b] border border-[#3f3f46] rounded px-2 py-1 text-sm text-white focus:outline-none focus:border-[#7345d1]"
163 className="w-full bg-surface-100 border border-surface-300/70 rounded px-2 py-1 text-sm text-surface-900 focus:outline-none focus:border-brass-400"
161164 />
162165 <input
163166 value={editMatter}
164167 onChange={(e) => setEditMatter(e.target.value)}
165168 placeholder="Matter number"
166 className="w-full bg-[#09090b] border border-[#3f3f46] rounded px-2 py-1 text-xs text-white placeholder-zinc-600 focus:outline-none focus:border-[#7345d1]"
169 className="w-full bg-surface-100 border border-surface-300/70 rounded px-2 py-1 text-xs text-surface-900 placeholder-surface-500 focus:outline-none focus:border-brass-400"
167170 />
168171 <div className="flex items-center gap-2">
169172 <input
@@ -173,9 +176,9 @@ function ClientCard({ client }: { client: Client }) {
173176 step={25}
174177 value={editRate}
175178 onChange={(e) => setEditRate(Number(e.target.value))}
176 className="flex-1 accent-[#7345d1]"
179 className="flex-1 accent-brass-500"
177180 />
178 <span className="text-xs w-16 text-right text-zinc-300">
181 <span className="text-xs text-surface-700 w-16 text-right">
179182 {editRate === 0 ? "Default" : `$${editRate}/hr`}
180183 </span>
181184 </div>
@@ -189,11 +192,11 @@ function ClientCard({ client }: { client: Client }) {
189192 </div>
190193 ) : (
191194 <>
192 <h3 className="font-semibold text-sm text-white truncate">{client.name}</h3>
195 <h3 className="font-semibold text-sm text-surface-950 truncate">{client.name}</h3>
193196 {client.matterNumber && (
194 <p className="text-xs text-zinc-500 mt-0.5">{client.matterNumber}</p>
197 <p className="text-xs text-surface-600 mt-0.5">{client.matterNumber}</p>
195198 )}
196 <p className="text-xs text-zinc-500 mt-0.5">
199 <p className="text-xs text-surface-600 mt-0.5">
197200 {client.billableRate === 0 ? "Default rate" : `$${client.billableRate}/hr`}
198201 </p>
199202 </>
@@ -202,16 +205,16 @@ function ClientCard({ client }: { client: Client }) {
202205 <div className="flex items-center gap-1">
203206 {editing ? (
204207 <>
205 <button onClick={saveEdit} className="p-1.5 text-emerald-400 hover:bg-emerald-500/10 rounded">
208 <button onClick={saveEdit} className="p-1.5 text-green-600 hover:bg-green-500/10 rounded transition-colors">
206209 <Check className="w-3.5 h-3.5" />
207210 </button>
208 <button onClick={() => setEditing(false)} className="p-1.5 text-zinc-500 hover:bg-zinc-800 rounded">
211 <button onClick={() => setEditing(false)} className="p-1.5 text-surface-500 hover:bg-surface-200 rounded transition-colors">
209212 <X className="w-3.5 h-3.5" />
210213 </button>
211214 </>
212215 ) : (
213216 <>
214 <button onClick={() => setEditing(true)} className="p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded" title="Edit">
217 <button onClick={() => setEditing(true)} className="p-1.5 text-surface-500 hover:text-surface-800 hover:bg-surface-200 rounded transition-colors" title="Edit">
215218 <Edit2 className="w-3.5 h-3.5" />
216219 </button>
217220 {entries.length > 0 && (
@@ -220,16 +223,16 @@ function ClientCard({ client }: { client: Client }) {
220223 const { content, filename, mimeType } = exportBillingCsv(client, entries);
221224 await downloadBillingExport(content, filename, mimeType);
222225 }}
223 className="p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded"
226 className="p-1.5 text-surface-500 hover:text-surface-800 hover:bg-surface-200 rounded transition-colors"
224227 title="Export billing CSV"
225228 >
226229 <Download className="w-3.5 h-3.5" />
227230 </button>
228231 )}
229 <button onClick={() => archiveClient(client.id)} className="p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded" title="Archive">
232 <button onClick={() => archiveClient(client.id)} className="p-1.5 text-surface-500 hover:text-surface-800 hover:bg-surface-200 rounded transition-colors" title="Archive">
230233 <Archive className="w-3.5 h-3.5" />
231234 </button>
232 <button onClick={() => deleteClient(client.id)} className="p-1.5 text-zinc-500 hover:text-red-400 hover:bg-red-500/10 rounded" title="Delete">
235 <button onClick={() => deleteClient(client.id)} className="p-1.5 text-surface-500 hover:text-red-500 hover:bg-red-500/10 rounded transition-colors" title="Delete">
233236 <Trash2 className="w-3.5 h-3.5" />
234237 </button>
235238 </>
@@ -238,17 +241,17 @@ function ClientCard({ client }: { client: Client }) {
238241 </div>
239242
240243 {/* Stats */}
241 <div className="grid grid-cols-3 divide-x divide-[#27272a]">
244 <div className="grid grid-cols-3 divide-x divide-surface-300/50">
242245 <div className="p-3 text-center">
243 <p className="text-[10px] text-zinc-500 uppercase tracking-wider mb-0.5">Sessions</p>
244 <p className="text-lg font-bold text-white">{entries.length}</p>
246 <p className="text-[10px] text-surface-600 uppercase tracking-wide-caps mb-0.5">Sessions</p>
247 <p className="text-lg font-bold text-surface-950">{entries.length}</p>
245248 </div>
246249 <div className="p-3 text-center">
247 <p className="text-[10px] text-zinc-500 uppercase tracking-wider mb-0.5">Hours</p>
248 <p className="text-lg font-bold text-white">{totalHours.toFixed(1)}</p>
250 <p className="text-[10px] text-surface-600 uppercase tracking-wide-caps mb-0.5">Hours</p>
251 <p className="text-lg font-bold text-surface-950">{totalHours.toFixed(1)}</p>
249252 </div>
250253 <div className="p-3 text-center">
251 <p className="text-[10px] text-zinc-500 uppercase tracking-wider mb-0.5">Billable</p>
254 <p className="text-[10px] text-surface-600 uppercase tracking-wide-caps mb-0.5">Billable</p>
252255 <p className="text-lg font-bold" style={{ color: client.color }}>
253256 ${totalBillable.toFixed(0)}
254257 </p>
@@ -257,15 +260,15 @@ function ClientCard({ client }: { client: Client }) {
257260
258261 {/* Recent entries */}
259262 {recentEntries.length > 0 && (
260 <div className="p-3 border-t border-[#27272a] space-y-1.5">
261 <p className="text-[10px] text-zinc-600 uppercase tracking-wider mb-2">Recent Sessions</p>
263 <div className="p-3 border-t border-surface-300/50 space-y-1.5">
264 <p className="text-[10px] text-surface-600 uppercase tracking-wide-caps mb-2">Recent Sessions</p>
262265 {recentEntries.map((entry) => (
263266 <div key={entry.id} className="flex items-center justify-between text-xs">
264 <span className="text-zinc-400">
267 <span className="text-surface-600">
265268 {new Date(entry.date).toLocaleDateString()} · {Math.round(entry.durationSeconds / 60)}m
266269 {entry.wordCount > 0 && ` · ${entry.wordCount} words`}
267270 </span>
268 <span className="text-zinc-300 font-medium">${entry.billableAmount.toFixed(2)}</span>
271 <span className="text-surface-800 font-medium">${entry.billableAmount.toFixed(2)}</span>
269272 </div>
270273 ))}
271274 </div>
@@ -348,45 +351,47 @@ export function ClientsPanel() {
348351 return (
349352 <div className="flex flex-col h-full overflow-hidden">
350353 {/* Header */}
351 <div className="flex items-center justify-between px-4 py-3 border-b border-[#27272a] shrink-0">
354 <div className="flex items-center justify-between px-4 py-3 border-b border-surface-300/50 shrink-0 bg-surface-50/60">
352355 <div>
353 <h2 className="text-sm font-semibold text-white">Clients & Matters</h2>
354 <p className="text-xs text-zinc-500 mt-0.5">
356 <h2 className="text-sm font-semibold text-surface-950">Clients & Matters</h2>
357 <p className="text-xs text-surface-600 mt-0.5">
355358 {active.length} active · {totalHours.toFixed(1)} hrs · ${totalBillable.toFixed(0)} total
356359 </p>
357360 </div>
358361 <div className="flex items-center gap-2">
359362 {entries.length > 0 && (
360 <button
363 <Button
364 variant="ghost"
365 size="sm"
361366 onClick={handleExportAll}
362 className="flex items-center gap-1.5 text-xs font-medium text-zinc-400 hover:text-white border border-[#3f3f46] hover:border-zinc-500 px-3 py-1.5 rounded-lg transition-colors"
363367 title="Export all billing as CSV"
364368 >
365369 <Download className="w-3.5 h-3.5" />
366370 Export CSV
367 </button>
371 </Button>
368372 )}
369 <button
373 <Button
374 variant="primary"
375 size="sm"
370376 onClick={() => setShowAdd(true)}
371 className="flex items-center gap-1.5 text-xs font-medium bg-[#7345d1] hover:bg-[#5c35b0] text-white px-3 py-1.5 rounded-lg transition-colors"
372377 >
373378 <Plus className="w-3.5 h-3.5" />
374379 Add Client
375 </button>
380 </Button>
376381 </div>
377382 </div>
378383
379384 {/* Active client selector */}
380385 {active.length > 0 && (
381 <div className="px-4 py-3 border-b border-[#27272a] shrink-0">
382 <p className="text-[10px] text-zinc-500 uppercase tracking-wider mb-2">Active Client (for new dictations)</p>
386 <div className="px-4 py-3 border-b border-surface-300/50 shrink-0">
387 <p className="label-caps mb-2">Active Client (for new dictations)</p>
383388 <div className="flex gap-2 flex-wrap">
384389 <button
385390 onClick={() => setActiveClient(null)}
386391 className={`px-3 py-1.5 rounded-full text-xs font-medium transition-colors border ${
387392 activeClientId === null
388 ? "bg-[#27272a] border-[#3f3f46] text-white"
389 : "border-transparent text-zinc-500 hover:text-zinc-300"
393 ? "bg-surface-200 border-surface-300/60 text-surface-950"
394 : "border-transparent text-surface-600 hover:text-surface-900"
390395 }`}
391396 >
392397 None
@@ -397,10 +402,10 @@ export function ClientsPanel() {
397402 onClick={() => setActiveClient(c.id)}
398403 className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium transition-colors border ${
399404 activeClientId === c.id
400 ? "border-transparent text-white"
401 : "border-transparent text-zinc-400 hover:text-zinc-200"
405 ? "border-transparent text-surface-950"
406 : "border-transparent text-surface-600 hover:text-surface-900"
402407 }`}
403 style={activeClientId === c.id ? { backgroundColor: c.color + "33", borderColor: c.color } : {}}
408 style={activeClientId === c.id ? { backgroundColor: c.color + "22", borderColor: c.color + "80" } : {}}
404409 >
405410 <span
406411 className="w-2 h-2 rounded-full shrink-0"
@@ -408,7 +413,7 @@ export function ClientsPanel() {
408413 />
409414 {c.name}
410415 {c.matterNumber && (
411 <span className="text-zinc-500">#{c.matterNumber}</span>
416 <span className="text-surface-500">#{c.matterNumber}</span>
412417 )}
413418 </button>
414419 ))}
@@ -420,18 +425,15 @@ export function ClientsPanel() {
420425 <div className="flex-1 overflow-y-auto p-4">
421426 {active.length === 0 ? (
422427 <div className="flex flex-col items-center justify-center py-16 text-center">
423 <Briefcase className="w-10 h-10 text-zinc-700 mb-4" />
424 <p className="text-sm font-medium text-zinc-400 mb-1">No clients yet</p>
425 <p className="text-xs text-zinc-600 max-w-xs mb-4">
428 <Briefcase className="w-10 h-10 text-surface-400 mb-4" />
429 <p className="text-sm font-medium text-surface-700 mb-1">No clients yet</p>
430 <p className="text-xs text-surface-600 max-w-xs mb-4">
426431 Add a client or matter to track billable time and usage per file.
427432 </p>
428 <button
429 onClick={() => setShowAdd(true)}
430 className="flex items-center gap-1.5 text-xs font-medium bg-[#7345d1] hover:bg-[#5c35b0] text-white px-4 py-2 rounded-lg"
431 >
433 <Button variant="primary" size="sm" onClick={() => setShowAdd(true)}>
432434 <Plus className="w-3.5 h-3.5" />
433435 Add First Client
434 </button>
436 </Button>
435437 </div>
436438 ) : (
437439 <div className="grid gap-4 grid-cols-1 md:grid-cols-2">
@@ -445,7 +447,7 @@ export function ClientsPanel() {
445447 <div className="mt-6">
446448 <button
447449 onClick={() => setShowArchived((v) => !v)}
448 className="text-xs text-zinc-500 hover:text-zinc-300 flex items-center gap-1.5"
450 className="text-xs text-surface-500 hover:text-surface-800 flex items-center gap-1.5 transition-colors"
449451 >
450452 <Archive className="w-3.5 h-3.5" />
451453 {showArchived ? "Hide" : "Show"} {archived.length} archived client{archived.length !== 1 ? "s" : ""}
Modifiedsrc/components/dictation/DictationPanel.tsx+21−7View fileUnifiedSplit
@@ -37,6 +37,7 @@ import type { ExportFormat } from "@/lib/export";
3737
3838export function DictationPanel() {
3939 const status = useDictationStore((s) => s.status);
40 const errorMessage = useDictationStore((s) => s.error);
4041 const wordCount = useDictationStore((s) => s.wordCount);
4142 const sessionDuration = useDictationStore((s) => s.sessionDuration);
4243 const inputLevel = useDictationStore((s) => s.inputLevel);
@@ -92,7 +93,7 @@ export function DictationPanel() {
9293 }, [status, incrementDuration]);
9394
9495 const handleToggleDictation = useCallback(async () => {
95 if (status === "idle" || status === "paused") {
96 if (status === "idle" || status === "paused" || status === "error") {
9697 sessionStartRef.current = new Date();
9798 try {
9899 const { invoke } = await import("@tauri-apps/api/core");
@@ -114,8 +115,13 @@ export function DictationPanel() {
114115
115116 await invoke("start_dictation");
116117 setStatus("listening");
117 } catch {
118 setStatus("listening");
118 } catch (e) {
119 // Real failure in the desktop app (mic permission, device missing,
120 // no account) — never pretend we're listening.
121 const msg = typeof e === "string" ? e : e instanceof Error ? e.message : "Could not start dictation";
122 useDictationStore.getState().setError(msg);
123 setStatus("error");
124 toast(msg.length > 100 ? msg.slice(0, 100) + "…" : msg, "error", 6000);
119125 }
120126 } else if (status === "listening") {
121127 // Capture session BEFORE status flip so autosave in useTauriEvents
@@ -266,11 +272,11 @@ export function DictationPanel() {
266272 });
267273 }
268274 } catch {
269 // Translation not available
275 toast("Translation unavailable — check your API key in Settings", "error", 4000);
270276 }
271277 }
272278 } catch {
273 // Grammar correction not available
279 toast("Grammar correction unavailable — check your API key in Settings", "error", 4000);
274280 }
275281 },
276282 [segments]
@@ -307,9 +313,12 @@ export function DictationPanel() {
307313 const activeClient = allClients.find((c) => c.id === activeClientId) ?? null;
308314 const setActiveClient = useClientsStore((s) => s.setActiveClient);
309315
316 const currentTranscript = useDictationStore((s) => s.currentTranscript);
310317 const isActive = status === "listening" || status === "processing";
311318 const showControls = isActive || status === "paused";
312 const hasContent = segments.length > 0;
319 // Include the live interim transcript so the very first utterance is
320 // visible while it's still being spoken
321 const hasContent = segments.length > 0 || !!currentTranscript;
313322
314323 const CONTEXTS = [
315324 { value: "", label: "General" },
@@ -405,8 +414,13 @@ export function DictationPanel() {
405414 )}
406415 {status === "processing" && "Processing speech"}
407416 {status === "paused" && "Paused"}
408 {status === "error" && "An error occurred"}
417 {status === "error" && "Couldn't start dictation"}
409418 </h2>
419 {status === "error" && errorMessage && (
420 <p className="text-[12px] text-red-400 mt-2 max-w-md mx-auto leading-relaxed">
421 {errorMessage} — press the microphone to retry.
422 </p>
423 )}
410424 {selectedDevice && (
411425 <p className="text-[11px] text-surface-600 mt-2 flex items-center justify-center gap-1.5 tracking-tight">
412426 <Mic className="h-3 w-3 text-brass-500/80" strokeWidth={1.75} />
Modifiedsrc/components/dictation/HistoryPanel.tsx+1−0View fileUnifiedSplit
@@ -28,6 +28,7 @@ export function HistoryPanel() {
2828 const [copiedId, setCopiedId] = useState<string | null>(null);
2929 const [expandedId, setExpandedId] = useState<string | null>(null);
3030 const [confirmClear, setConfirmClear] = useState(false);
31 const [exportMenuId, setExportMenuId] = useState<string | null>(null);
3132
3233 useEffect(() => {
3334 loadHistory();
Modifiedsrc/components/flywheel/FlywheelPanel.tsx+28−9View fileUnifiedSplit
@@ -58,7 +58,7 @@ export function FlywheelPanel() {
5858
5959 const [syncStatus, setSyncStatus] = useState<"idle" | "syncing" | "ok" | "error">("idle");
6060 const voxlenApiKey = useSettingsStore((s) => s.voxlenApiKey);
61 const voxlenApiBase = "https://api.voxlen.com/v1";
61 const voxlenApiBase = "https://voxlen.ai/api";
6262 const voxlenTenantId = useSettingsStore((s) => s.voxlenTenantId);
6363
6464 const handleSyncVocabulary = async () => {
@@ -311,6 +311,8 @@ function VocabularyList({
311311 entries: ReturnType<typeof useFlywheelStore.getState>["vocabulary"];
312312 onRemove: (word: string) => void;
313313}) {
314 const customVocabulary = useSettingsStore((s) => s.customVocabulary);
315 const updateSetting = useSettingsStore((s) => s.updateSetting);
314316 if (entries.length === 0) {
315317 return (
316318 <EmptyState
@@ -339,14 +341,31 @@ function VocabularyList({
339341 {entry.frequency}×
340342 </span>
341343 </div>
342 <button
343 type="button"
344 onClick={() => onRemove(entry.word)}
345 className="text-surface-600 hover:text-red-500 transition-colors p-1"
346 aria-label={"Remove " + entry.word}
347 >
348 <Trash2 className="h-3.5 w-3.5" />
349 </button>
344 <div className="flex items-center gap-0.5">
345 {!customVocabulary.includes(entry.word) && (
346 <button
347 type="button"
348 onClick={() => updateSetting("customVocabulary", [...customVocabulary, entry.word])}
349 className="text-surface-500 hover:text-brass-500 transition-colors p-1"
350 title="Promote to STT vocabulary (boosts recognition in Deepgram)"
351 >
352 <Upload className="h-3.5 w-3.5" />
353 </button>
354 )}
355 {customVocabulary.includes(entry.word) && (
356 <span className="p-1 text-brass-500" title="Already in STT vocabulary">
357 <Check className="h-3.5 w-3.5" />
358 </span>
359 )}
360 <button
361 type="button"
362 onClick={() => onRemove(entry.word)}
363 className="text-surface-600 hover:text-red-500 transition-colors p-1"
364 aria-label={"Remove " + entry.word}
365 >
366 <Trash2 className="h-3.5 w-3.5" />
367 </button>
368 </div>
350369 </li>
351370 ))}
352371 </ul>
Modifiedsrc/components/grammar/GrammarPanel.tsx+8−1View fileUnifiedSplit
@@ -29,6 +29,7 @@ export function GrammarPanel() {
2929 const [isProcessing, setIsProcessing] = useState(false);
3030 const [copied, setCopied] = useState(false);
3131 const [score, setScore] = useState<number | null>(null);
32 const [error, setError] = useState<string | null>(null);
3233 const writingStyle = useSettingsStore((s) => s.writingStyle);
3334 const updateSetting = useSettingsStore((s) => s.updateSetting);
3435 const activeClient = useClientsStore((s) => s.clients.find((c) => c.id === s.activeClientId));
@@ -37,6 +38,7 @@ export function GrammarPanel() {
3738 if (!inputText.trim()) return;
3839
3940 setIsProcessing(true);
41 setError(null);
4042 try {
4143 const { invoke } = await import("@tauri-apps/api/core");
4244 const matterContext = buildMatterContext(activeClient) || undefined;
@@ -58,10 +60,10 @@ export function GrammarPanel() {
5860 setChanges(result.changes);
5961 setScore(result.score);
6062 } catch {
61 // Demo fallback
6263 setCorrectedText(inputText);
6364 setChanges([]);
6465 setScore(1.0);
66 setError("Grammar correction unavailable. Check your API key in Settings.");
6567 }
6668 setIsProcessing(false);
6769 }, [inputText]);
@@ -169,6 +171,11 @@ export function GrammarPanel() {
169171 </Button>
170172 </div>
171173 <div className="flex-1 p-5 overflow-y-auto">
174 {error && (
175 <div className="mb-3 px-3 py-2 rounded-md bg-red-50 border border-red-200 text-red-700 text-xs">
176 {error}
177 </div>
178 )}
172179 {correctedText ? (
173180 <p className="text-[14px] text-surface-950 leading-relaxed whitespace-pre-wrap font-sans">
174181 {correctedText}
Modifiedsrc/components/layout/ShortcutsCheatsheet.tsx+18−0View fileUnifiedSplit
@@ -109,6 +109,24 @@ export function ShortcutsCheatsheet() {
109109 <Row key={row.label} label={row.label} keys={row.keys} />
110110 ))}
111111 </Section>
112 <Section title="Transcript">
113 {[
114 { label: "Edit a segment", keys: "Double-click" },
115 { label: "Save edit", keys: "Enter" },
116 { label: "Cancel edit", keys: "Esc" },
117 { label: "Find & Replace", keys: "Replace button" },
118 { label: "Switch paragraph / segment view", keys: "Paragraph button" },
119 { label: "Copy transcript", keys: "Copy button" },
120 { label: "Export (txt / rtf / json…)", keys: "Export button" },
121 ].map((row) => (
122 <div key={row.label} className="flex items-center justify-between gap-4 py-1">
123 <span className="text-sm text-surface-900">{row.label}</span>
124 <kbd className="inline-flex items-center gap-1 px-2 py-0.5 rounded border border-surface-300/70 bg-surface-100 text-[11px] text-surface-900 font-mono shadow-inset-hairline whitespace-nowrap">
125 {row.keys}
126 </kbd>
127 </div>
128 ))}
129 </Section>
112130 <Section title="Voice commands" className="md:col-span-2">
113131 <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-x-6 gap-y-1.5">
114132 {VOICE_COMMANDS.map((c) => (
Modifiedsrc/components/layout/VoiceCommandsHelp.tsx+1−0View fileUnifiedSplit
@@ -34,6 +34,7 @@ const ALL_COMMANDS: CommandEntry[] = [
3434 { command: "undo / undo that", description: "Undo the last action", category: "control" },
3535 { command: "copy that / copy text", description: "Copy all text to clipboard", category: "control" },
3636 { command: "select all", description: "Select all text", category: "control" },
37 { command: "review uncertain words / check uncertain", description: "Show count of low-confidence words in transcript", category: "control" },
3738 // Billable time
3839 { command: "start billing / start timer", description: "Start the billable time timer", category: "billing" },
3940 { command: "stop billing / stop timer", description: "Stop the billable time timer", category: "billing" },
Modifiedsrc/components/onboarding/OnboardingWizard.tsx+22−92View fileUnifiedSplit
@@ -24,7 +24,6 @@ import { cn } from "@/lib/utils";
2424import { Button } from "@/components/ui/Button";
2525import { Input } from "@/components/ui/Input";
2626import { Select } from "@/components/ui/Select";
27import { Badge } from "@/components/ui/Badge";
2827import { useAudioStore } from "@/stores/audio";
2928import { useSettingsStore } from "@/stores/settings";
3029
@@ -36,9 +35,7 @@ export function OnboardingWizard({ onComplete }: OnboardingWizardProps) {
3635 const [step, setStep] = useState(0);
3736 const [micTestLevel, setMicTestLevel] = useState(0);
3837 const [isTesting, setIsTesting] = useState(false);
39 const [apiKeyValid, setApiKeyValid] = useState<boolean | null>(null);
40 const [apiKeyValidating, setApiKeyValidating] = useState(false);
41 const [voxlenKeyValid, setVoxlenKeyValid] = useState<boolean | null>(null);
38 const [voxlenKeyValid, setVoxlenKeyValid] = useState<boolean | "unverified" | null>(null);
4239 const [legalAccepted, setLegalAccepted] = useState(false);
4340 const [consentAccepted, setConsentAccepted] = useState(false);
4441
@@ -136,36 +133,11 @@ export function OnboardingWizard({ onComplete }: OnboardingWizardProps) {
136133 setIsTesting(false);
137134 }, []);
138135
139 const handleValidateApiKey = useCallback(async () => {
140 const key = settings.sttApiKey;
141 if (!key) { setApiKeyValid(false); return; }
142
143 setApiKeyValidating(true);
144 try {
145 // Try a simple API call to validate
146 const response = await fetch("https://api.deepgram.com/v1/projects", {
147 headers: { Authorization: `Token ${key}` },
148 });
149 setApiKeyValid(response.ok);
150 } catch {
151 // Try OpenAI validation
152 try {
153 const response = await fetch("https://api.openai.com/v1/models", {
154 headers: { Authorization: `Bearer ${key}` },
155 });
156 setApiKeyValid(response.ok);
157 } catch {
158 setApiKeyValid(false);
159 }
160 }
161 setApiKeyValidating(false);
162 }, [settings.sttApiKey]);
163
164136 const handleValidateVoxlenKey = useCallback(async () => {
165137 const key = settings.voxlenApiKey;
166138 if (!key) { setVoxlenKeyValid(false); return; }
167139 try {
168 const response = await fetch("https://api.voxlen.com/v1/auth/verify", {
140 const response = await fetch("https://voxlen.ai/api/me", {
169141 headers: { Authorization: `Bearer ${key}` },
170142 });
171143 if (response.ok) {
@@ -178,8 +150,9 @@ export function OnboardingWizard({ onComplete }: OnboardingWizardProps) {
178150 setVoxlenKeyValid(false);
179151 }
180152 } catch {
181 // API not live yet — accept the key optimistically
182 setVoxlenKeyValid(true);
153 // Couldn't reach voxlen.ai — let the user continue, but be honest that
154 // the key hasn't been verified instead of pretending it's valid.
155 setVoxlenKeyValid("unverified");
183156 }
184157 }, [settings]);
185158
@@ -195,7 +168,7 @@ export function OnboardingWizard({ onComplete }: OnboardingWizardProps) {
195168 case 0: return true;
196169 case 1: return !!selectedDeviceId;
197170 // Step 2: connected if voxlenApiKey is set OR a direct STT key is set
198 case 2: return !!settings.voxlenApiKey || !!settings.sttApiKey;
171 case 2: return !!settings.voxlenApiKey;
199172 case 3: return true;
200173 default: return true;
201174 }
@@ -407,21 +380,21 @@ export function OnboardingWizard({ onComplete }: OnboardingWizardProps) {
407380 </div>
408381 ) : (
409382 <div className="rounded-xl border border-surface-300/60 bg-surface-50/60 p-5 space-y-4">
383 <ol className="space-y-2 text-[12px] text-surface-700 leading-relaxed list-decimal list-inside">
384 <li>Open your Voxlen dashboard and sign in (or create a free account).</li>
385 <li>In <span className="font-medium text-surface-900">Connect Desktop App</span>, copy your account key.</li>
386 <li>Paste it below — that's it. Transcription and AI grammar are included.</li>
387 </ol>
410388 <a
411 href="https://voxlen.ai/#download"
389 href="https://voxlen.ai/dashboard"
412390 target="_blank"
413391 rel="noreferrer"
414392 className="flex items-center justify-center gap-2 w-full bg-[#7345d1] hover:bg-[#5c35b0] text-white font-semibold text-sm py-2.5 rounded-lg transition-colors"
415393 >
416 Get your Voxlen API key
394 Open voxlen.ai/dashboard
417395 </a>
418 <div className="relative flex items-center gap-3">
419 <div className="flex-1 h-px bg-surface-300/40" />
420 <span className="text-[10px] text-surface-400 uppercase tracking-wider whitespace-nowrap">already have a key</span>
421 <div className="flex-1 h-px bg-surface-300/40" />
422 </div>
423396 <Input
424 label="Voxlen API Key"
397 label="Voxlen Account Key"
425398 type="password"
426399 value={settings.voxlenApiKey}
427400 onChange={(e) => {
@@ -429,63 +402,20 @@ export function OnboardingWizard({ onComplete }: OnboardingWizardProps) {
429402 setVoxlenKeyValid(null);
430403 }}
431404 onBlur={() => { if (settings.voxlenApiKey) handleValidateVoxlenKey(); }}
432 placeholder="vx-..."
405 placeholder="Paste your account key"
433406 icon={<Key className="h-4 w-4" />}
434407 success={voxlenKeyValid === true ? "Key verified" : undefined}
435 error={voxlenKeyValid === false ? "Invalid key" : undefined}
408 error={voxlenKeyValid === false ? "Invalid key — re-copy it from voxlen.ai/dashboard" : undefined}
436409 />
410 {voxlenKeyValid === "unverified" && (
411 <p className="text-[11px] text-amber-500 leading-relaxed">
412 Couldn't reach voxlen.ai to verify this key. You can continue — Voxlen will
413 verify it the first time you dictate.
414 </p>
415 )}
437416 </div>
438417 )}
439418
440 {/* Advanced: BYOK fallback */}
441 {!settings.voxlenApiKey && (
442 <details className="group" open>
443 <summary className="text-[11px] text-surface-500 hover:text-surface-700 cursor-pointer list-none flex items-center gap-1.5 select-none">
444 <span className="transition-transform group-open:rotate-90">›</span>
445 Use your own Deepgram or OpenAI key (advanced / admin)
446 </summary>
447 <div className="mt-3 space-y-3 pl-3 border-l border-surface-300/40">
448 <Select
449 label="Speech Engine"
450 value={settings.sttEngine}
451 onChange={(v) => settings.updateSetting("sttEngine", v)}
452 options={[
453 { value: "deepgram", label: "Deepgram Nova-3", description: "Best for real-time (recommended)" },
454 { value: "whisper_cloud", label: "OpenAI Whisper", description: "High accuracy, batch mode" },
455 ]}
456 />
457 <Input
458 label={settings.sttEngine === "deepgram" ? "Deepgram API Key" : "OpenAI API Key"}
459 type="password"
460 value={settings.sttApiKey}
461 onChange={(e) => settings.updateSetting("sttApiKey", e.target.value)}
462 placeholder={settings.sttEngine === "deepgram" ? "dg_..." : "sk-..."}
463 icon={<Key className="h-4 w-4" />}
464 />
465 <div className="flex items-center gap-2">
466 <Button
467 variant="secondary"
468 size="sm"
469 onClick={handleValidateApiKey}
470 loading={apiKeyValidating}
471 disabled={!settings.sttApiKey}
472 >
473 Validate Key
474 </Button>
475 {apiKeyValid === true && <Badge variant="success" dot>Valid</Badge>}
476 {apiKeyValid === false && <Badge variant="error" dot>Invalid</Badge>}
477 </div>
478 <Input
479 label="Anthropic API key (for grammar AI)"
480 type="password"
481 value={settings.grammarApiKey}
482 onChange={(e) => settings.updateSetting("grammarApiKey", e.target.value)}
483 placeholder="sk-ant-..."
484 icon={<Sparkles className="h-4 w-4" strokeWidth={1.75} />}
485 />
486 </div>
487 </details>
488 )}
489419 </div>
490420 )}
491421
Modifiedsrc/components/settings/SettingsPanel.tsx+62−125View fileUnifiedSplit
@@ -448,7 +448,7 @@ function SttSettings() {
448448 <div className="space-y-6 max-w-lg">
449449 <SectionHeader
450450 title="Speech-to-Text Engine"
451 description="Choose your transcription engine. Cloud engines offer better accuracy; local offers privacy."
451 description="Choose your transcription engine. Offline mode (Whisper Local) is coming soon."
452452 />
453453
454454 <SettingRow>
@@ -464,24 +464,15 @@ function SttSettings() {
464464 />
465465 </SettingRow>
466466
467 {settings.voxlenApiKey ? (
468 <SettingRow>
469 <div className="flex items-center gap-2 rounded-lg bg-purple-500/10 border border-purple-500/30 px-4 py-3 text-sm text-purple-300">
470 <span className="text-green-400">✓</span>
471 Transcription powered by your Voxlen account — no provider API key needed.
472 </div>
473 </SettingRow>
474 ) : (
475 <SettingRow>
476 <Input
477 label="API Key (optional — not needed with Voxlen account)"
478 type="password"
479 value={settings.sttApiKey}
480 onChange={(e) => settings.updateSetting("sttApiKey", e.target.value)}
481 placeholder="Add your own Deepgram / OpenAI key, or sign in via Voxlen tab"
482 />
483 </SettingRow>
484 )}
467 <SettingRow>
468 <div className={`flex items-center gap-2 rounded-lg px-4 py-3 text-sm ${settings.voxlenApiKey ? "bg-purple-500/10 border border-purple-500/30 text-purple-300" : "bg-surface-100 border border-surface-300/50 text-surface-500"}`}>
469 {settings.voxlenApiKey ? (
470 <><span className="text-green-400">✓</span> Transcription powered by your Voxlen account — no provider API key needed.</>
471 ) : (
472 <><span className="text-surface-400">→</span> Sign in to your Voxlen account (Voxlen tab) to enable transcription.</>
473 )}
474 </div>
475 </SettingRow>
485476
486477 <SettingRow>
487478 <Switch
@@ -683,30 +674,15 @@ function GrammarSettings() {
683674 />
684675 </SettingRow>
685676
686 {settings.voxlenApiKey ? (
687 <SettingRow>
688 <div className="flex items-center gap-2 rounded-lg bg-purple-500/10 border border-purple-500/30 px-4 py-3 text-sm text-purple-300">
689 <span className="text-green-400">✓</span>
690 Grammar AI powered by your Voxlen account — no provider API key needed.
691 </div>
692 </SettingRow>
693 ) : (
694 <SettingRow>
695 <Input
696 label="AI API Key (optional — not needed with Voxlen account)"
697 type="password"
698 value={settings.grammarApiKey}
699 onChange={(e) =>
700 settings.updateSetting("grammarApiKey", e.target.value)
701 }
702 placeholder={
703 settings.grammarProvider === "claude"
704 ? "sk-ant-... (or sign in via Voxlen tab)"
705 : "sk-... (or sign in via Voxlen tab)"
706 }
707 />
708 </SettingRow>
709 )}
677 <SettingRow>
678 <div className={`flex items-center gap-2 rounded-lg px-4 py-3 text-sm ${settings.voxlenApiKey ? "bg-purple-500/10 border border-purple-500/30 text-purple-300" : "bg-surface-100 border border-surface-300/50 text-surface-500"}`}>
679 {settings.voxlenApiKey ? (
680 <><span className="text-green-400">✓</span> Grammar AI powered by your Voxlen account — no provider API key needed.</>
681 ) : (
682 <><span className="text-surface-400">→</span> Sign in to your Voxlen account (Voxlen tab) to enable grammar correction.</>
683 )}
684 </div>
685 </SettingRow>
710686
711687 <SettingRow>
712688 <Select
@@ -1021,98 +997,59 @@ function AdvancedSettings({ onReopenSetup }: { onReopenSetup?: () => void }) {
1021997 );
1022998}
1023999
1024interface UsageData {
1000interface AccountInfo {
10251001 plan: string;
1026 period_start: string;
1027 period_end: string;
1028 stt_minutes_used: number;
1029 stt_minutes_included: number;
1030 grammar_corrections_used: number;
1031 grammar_corrections_included: number;
1002 features: string[];
1003 name: string;
1004 email: string;
1005 isAdmin: boolean;
10321006}
10331007
1008const FEATURE_LABELS: Record<string, string> = {
1009 stt: "Dictation (STT)",
1010 grammar: "AI Grammar Correction",
1011 export: "All Export Formats",
1012 clauses: "Clause Library",
1013 billing: "Client Billing Tracking",
1014};
1015
10341016function UsageMeter({ apiKey }: { apiKey: string }) {
1035 const [usage, setUsage] = useState<UsageData | null>(null);
1036 const [loading, setLoading] = useState(true);
1017 const [info, setInfo] = useState<AccountInfo | null>(null);
10371018
10381019 useEffect(() => {
10391020 let cancelled = false;
1040 fetch("https://api.voxlen.com/v1/usage", {
1021 fetch("https://voxlen.ai/api/me", {
10411022 headers: { Authorization: `Bearer ${apiKey}` },
10421023 })
10431024 .then((r) => (r.ok ? r.json() : Promise.reject()))
1044 .then((data: UsageData) => {
1045 if (!cancelled) { setUsage(data); setLoading(false); }
1046 })
1047 .catch(() => { if (!cancelled) setLoading(false); });
1025 .then((data: AccountInfo) => { if (!cancelled) setInfo(data); })
1026 .catch(() => {});
10481027 return () => { cancelled = true; };
10491028 }, [apiKey]);
10501029
1051 if (loading || !usage) return null;
1030 if (!info) return null;
10521031
1053 const planLabel =
1054 usage.plan.charAt(0).toUpperCase() + usage.plan.slice(1);
1055 const isFree = usage.plan.toLowerCase() === "free";
1056
1057 const sttPct =
1058 usage.stt_minutes_included === -1
1059 ? 0
1060 : Math.min(100, (usage.stt_minutes_used / usage.stt_minutes_included) * 100);
1061
1062 const grammarPct =
1063 usage.grammar_corrections_included === -1
1064 ? 0
1065 : Math.min(100, (usage.grammar_corrections_used / usage.grammar_corrections_included) * 100);
1032 const planLabel = info.plan.charAt(0).toUpperCase() + info.plan.slice(1);
1033 const isFree = info.plan.toLowerCase() === "free";
10661034
10671035 return (
10681036 <div className="rounded-xl border border-surface-300/50 bg-surface-50/30 p-4 space-y-3">
10691037 <div className="flex items-center justify-between">
10701038 <span className="text-xs font-semibold text-surface-800 uppercase tracking-wider">
1071 Usage this month
1039 Account
10721040 </span>
10731041 <span className="text-[11px] px-2 py-0.5 rounded-full bg-[#7345d1]/15 text-[#7345d1] font-semibold">
10741042 {planLabel}
10751043 </span>
10761044 </div>
1077
1078 {/* STT minutes */}
1079 <div>
1080 <div className="flex justify-between text-[11px] text-surface-600 mb-1">
1081 <span>Dictation minutes</span>
1082 <span>
1083 {usage.stt_minutes_used.toFixed(1)} / 
1084 {usage.stt_minutes_included === -1 ? "∞" : `${usage.stt_minutes_included} min`}
1085 </span>
1086 </div>
1087 {usage.stt_minutes_included !== -1 && (
1088 <div className="h-1.5 rounded-full bg-surface-200/60 overflow-hidden">
1089 <div
1090 className="h-full rounded-full transition-all"
1091 style={{ width: `${sttPct}%`, background: "#7345d1" }}
1092 />
1093 </div>
1094 )}
1095 </div>
1096
1097 {/* Grammar corrections */}
1098 <div>
1099 <div className="flex justify-between text-[11px] text-surface-600 mb-1">
1100 <span>Grammar corrections</span>
1101 <span>
1102 {usage.grammar_corrections_used} / 
1103 {usage.grammar_corrections_included === -1 ? "∞" : usage.grammar_corrections_included}
1104 </span>
1105 </div>
1106 {usage.grammar_corrections_included !== -1 && (
1107 <div className="h-1.5 rounded-full bg-surface-200/60 overflow-hidden">
1108 <div
1109 className="h-full rounded-full transition-all"
1110 style={{ width: `${grammarPct}%`, background: "#7345d1" }}
1111 />
1045 <div className="space-y-1">
1046 {info.features.map((f) => (
1047 <div key={f} className="flex items-center gap-1.5 text-[11px] text-surface-600">
1048 <span className="w-1.5 h-1.5 rounded-full bg-[#7345d1] shrink-0" />
1049 {FEATURE_LABELS[f] ?? f}
11121050 </div>
1113 )}
1051 ))}
11141052 </div>
1115
11161053 {isFree && (
11171054 <a
11181055 href="https://voxlen.ai/#pricing"
@@ -1134,12 +1071,12 @@ function VoxlenApiSettings() {
11341071 const [keyError, setKeyError] = useState("");
11351072 const isConnected = Boolean(settings.voxlenApiKey);
11361073
1137 const openSignUp = async () => {
1074 const openDashboard = async () => {
11381075 try {
11391076 const { invoke } = await import("@tauri-apps/api/core");
1140 await invoke("open_url", { url: "https://voxlen.ai/#download" });
1077 await invoke("open_url", { url: "https://voxlen.ai/dashboard" });
11411078 } catch {
1142 window.open("https://voxlen.ai/#download", "_blank");
1079 window.open("https://voxlen.ai/dashboard", "_blank");
11431080 }
11441081 };
11451082
@@ -1149,17 +1086,17 @@ function VoxlenApiSettings() {
11491086 setVerifying(true);
11501087 setKeyError("");
11511088 try {
1152 const res = await fetch("https://api.voxlen.com/v1/health", {
1089 const res = await fetch("https://voxlen.ai/api/me", {
11531090 headers: { Authorization: `Bearer ${key}` },
11541091 });
11551092 if (res.ok) {
11561093 settings.updateSetting("voxlenApiKey", key);
11571094 setKeyInput("");
11581095 } else {
1159 setKeyError("Invalid API key. Check your Voxlen dashboard.");
1096 setKeyError("Token invalid or expired. Sign in again at voxlen.ai/dashboard.");
11601097 }
11611098 } catch {
1162 // Network unreachable — accept key anyway (API may not be live yet)
1099 // Network unreachable — accept token anyway
11631100 settings.updateSetting("voxlenApiKey", key);
11641101 setKeyInput("");
11651102 }
@@ -1226,15 +1163,15 @@ function VoxlenApiSettings() {
12261163 </div>
12271164
12281165 <button
1229 onClick={openSignUp}
1166 onClick={openDashboard}
12301167 className="w-full flex items-center justify-center gap-2 bg-[#7345d1] hover:bg-[#5c35b0] text-white font-semibold text-sm py-2.5 rounded-lg transition-colors"
12311168 >
1232 Get your API key at voxlen.ai
1169 Sign in at voxlen.ai → copy your token
12331170 </button>
12341171
12351172 <div className="relative flex items-center gap-3">
12361173 <div className="flex-1 h-px bg-surface-300/50" />
1237 <span className="text-[10px] text-surface-500 uppercase tracking-wider">already have a key?</span>
1174 <span className="text-[10px] text-surface-500 uppercase tracking-wider">paste token below</span>
12381175 <div className="flex-1 h-px bg-surface-300/50" />
12391176 </div>
12401177
@@ -1244,7 +1181,7 @@ function VoxlenApiSettings() {
12441181 value={keyInput}
12451182 onChange={(e) => { setKeyInput(e.target.value); setKeyError(""); }}
12461183 onKeyDown={(e) => e.key === "Enter" && connect()}
1247 placeholder="vx-..."
1184 placeholder="Paste token from voxlen.ai/dashboard"
12481185 className="w-full bg-surface-50 border border-surface-300/70 rounded-lg px-3 py-2 text-sm text-surface-900 placeholder-surface-500 focus:outline-none focus:border-[#7345d1] shadow-inset-hairline"
12491186 />
12501187 {keyError && <p className="text-[11px] text-red-500">{keyError}</p>}
@@ -1261,8 +1198,7 @@ function VoxlenApiSettings() {
12611198 </div>
12621199 )}
12631200
1264 {/* Settings shown when connected OR when using own keys */}
1265 {(isConnected || settings.sttApiKey) && (
1201 {isConnected && (
12661202 <>
12671203 <SectionHeader title="Dictation Settings" description="" />
12681204
@@ -1278,9 +1214,10 @@ function VoxlenApiSettings() {
12781214 <SettingRow>
12791215 <Switch
12801216 label="Privileged Mode"
1281 description="Block all cloud STT — local processing only. For highly sensitive matters where audio must never leave the device."
1282 checked={settings.privilegedMode}
1283 onChange={(v) => settings.updateSetting("privilegedMode", v)}
1217 description="Block all cloud STT — local processing only. Coming soon: requires Whisper Local (offline mode) which is not yet available."
1218 checked={false}
1219 onChange={() => {}}
1220 disabled
12841221 />
12851222 </SettingRow>
12861223
@@ -1380,7 +1317,7 @@ function PrivacySettings() {
13801317 </li>
13811318 <li className="flex items-start gap-2">
13821319 <span className="text-brass-500 mt-0.5">—</span>
1383 Use Whisper Local for fully offline operation.
1320 Offline mode (Whisper Local) coming soon — no audio will leave your device.
13841321 </li>
13851322 <li className="flex items-start gap-2">
13861323 <span className="text-brass-500 mt-0.5">—</span>
Modifiedsrc/hooks/useTauriEvents.ts+15−0View fileUnifiedSplit
@@ -162,6 +162,21 @@ export function useTauriEvents(): void {
162162 return;
163163 }
164164
165 // Review uncertain words — count and toast
166 if (parsed.action === "review_uncertain") {
167 const segs = useDictationStore.getState().segments;
168 const count = segs.flatMap((s) => (s.words ?? []).filter((w) => w.confidence < 0.75)).length;
169 toast(
170 count > 0
171 ? `${count} uncertain word${count !== 1 ? "s" : ""} highlighted in transcript`
172 : "No uncertain words in transcript",
173 "info",
174 count > 0 ? 4000 : 3000
175 );
176 dictation.setCurrentTranscript("");
177 return;
178 }
179
165180 // For caps on/off, toggle local state.
166181 if (parsed.action === "caps_on") {
167182 dictation.setCapsLock(true);
Modifiedsrc/lib/contextFormat.test.ts+36−0View fileUnifiedSplit
@@ -34,6 +34,28 @@ describe("applyContextFormat — legal_case_note", () => {
3434 });
3535});
3636
37describe("applyContextFormat — legal_case_note (extended)", () => {
38 it("replaces 'telephone note' prefix with formal heading", () => {
39 const out = applyContextFormat("telephone note: spoke with client", { context: "legal_case_note" });
40 expect(out).toContain("TELEPHONE NOTE");
41 });
42
43 it("replaces 'conference note' prefix", () => {
44 const out = applyContextFormat("conference note: attended with counsel", { context: "legal_case_note" });
45 expect(out).toContain("CONFERENCE NOTE");
46 });
47
48 it("formats action point", () => {
49 const out = applyContextFormat("action points send letter of claim", { context: "legal_case_note" });
50 expect(out).toContain("ACTION POINT:");
51 });
52
53 it("formats client ref", () => {
54 const out = applyContextFormat("client ref: ABC-001 re claim", { context: "legal_case_note" });
55 expect(out).toContain("Client Ref: ABC-001");
56 });
57});
58
3759describe("applyContextFormat — legal_court_filing", () => {
3860 it("converts 'versus' to 'v'", () => {
3961 const out = applyContextFormat("Smith versus Jones is the leading case", {
@@ -48,6 +70,20 @@ describe("applyContextFormat — legal_court_filing", () => {
4870 });
4971 expect(out).toContain("Plaintiff");
5072 });
73
74 it("uppercases UK court names in filing context", () => {
75 const out = applyContextFormat("in the employment tribunal, the applicant claims", {
76 context: "legal_court_filing",
77 });
78 expect(out).toContain("IN THE EMPLOYMENT TRIBUNAL");
79 });
80
81 it("uppercases Sheriff Court", () => {
82 const out = applyContextFormat("in the sheriff court, the defender denies liability", {
83 context: "legal_court_filing",
84 });
85 expect(out).toContain("IN THE SHERIFF COURT");
86 });
5187});
5288
5389describe("applyContextFormat — legal_deposition", () => {
Modifiedsrc/lib/contextFormat.ts+16−6View fileUnifiedSplit
@@ -40,11 +40,19 @@ function formatLegalContract(text: string): string {
4040
4141// ── Legal case note: prepend date/time heading, attendance note structure ──
4242function formatLegalCaseNote(text: string): string {
43 // "attendance note" spoken at start → formal heading
44 let out = text.replace(/^attendance note[:\s]*/i, "ATTENDANCE NOTE\n\n");
43 let out = text;
44 // "attendance note" / "file note" / "telephone note" spoken at start → formal heading
45 out = out.replace(/^attendance note[:\s]*/i, "ATTENDANCE NOTE\n\n");
4546 out = out.replace(/^file note[:\s]*/i, "FILE NOTE\n\n");
46 // "matter" → preserve as-is but ensure capitalisation
47 out = out.replace(/\bmatter number\s+(\S+)/gi, "Matter No: $1");
47 out = out.replace(/^telephone note[:\s]*/i, "TELEPHONE NOTE\n\n");
48 out = out.replace(/^telephone attendance[:\s]*/i, "TELEPHONE ATTENDANCE\n\n");
49 out = out.replace(/^meeting note[:\s]*/i, "MEETING NOTE\n\n");
50 out = out.replace(/^conference note[:\s]*/i, "CONFERENCE NOTE\n\n");
51 // "matter number X" / "ref X" → Matter No: X
52 out = out.replace(/\bmatter (number|no|ref)[:\s]+(\S+)/gi, "Matter No: $2");
53 out = out.replace(/\bclient ref[:\s]+(\S+)/gi, "Client Ref: $1");
54 // "action point" → ACTION POINT:
55 out = out.replace(/\baction point[s]?[:\s]*/gi, "ACTION POINT: ");
4856 return out;
4957}
5058
@@ -52,8 +60,10 @@ function formatLegalCaseNote(text: string): string {
5260function formatLegalCourtFiling(text: string): string {
5361 let out = text;
5462 // "in the" + court name → uppercase
55 out = out.replace(/\bin the\s+(high court|supreme court|court of appeal|district court|family court|magistrates court)[,\s]/gi,
56 (_m, court) => `IN THE ${court.toUpperCase()},`);
63 out = out.replace(
64 /\bin the\s+(high court|supreme court|court of appeal|court of session|sheriff court|district court|family court|magistrates court|county court|employment tribunal|upper tribunal|first-tier tribunal|crown court|privy council)[,\s]/gi,
65 (_m, court) => `IN THE ${court.toUpperCase()},`
66 );
5767 // Case citation spoken: "Smith versus Jones" → "Smith v Jones"
5868 out = out.replace(/\b(\w+)\s+versus\s+(\w+)\b/gi, "$1 v $2");
5969 // "plaintiff" / "defendant" always capitalised in headings context
Modifiedsrc/lib/smartFormat.test.ts+44−0View fileUnifiedSplit
@@ -120,6 +120,50 @@ describe("applySmartFormat", () => {
120120 });
121121 });
122122
123 describe("legal phrases", () => {
124 it("preserves inter alia", () => {
125 expect(applySmartFormat("the contract inter alia requires notice", { legalPhrases: true })).toContain("inter alia");
126 });
127
128 it("formats contra proferentem", () => {
129 expect(applySmartFormat("the rule of contra proferentem applies", { legalPhrases: true })).toContain("contra proferentem");
130 });
131
132 it("formats force majeure", () => {
133 expect(applySmartFormat("this is a force majeure event", { legalPhrases: true })).toContain("force majeure");
134 });
135
136 it("formats pari passu", () => {
137 expect(applySmartFormat("paid pari passu with other creditors", { legalPhrases: true })).toContain("pari passu");
138 });
139
140 it("formats sine die", () => {
141 expect(applySmartFormat("adjourned sine die pending resolution", { legalPhrases: true })).toContain("sine die");
142 });
143 });
144
145 describe("accounting phrases", () => {
146 it("uppercases EBITDA", () => {
147 expect(applySmartFormat("the ebitda was strong this year", { legalPhrases: true })).toContain("EBITDA");
148 });
149
150 it("uppercases HMRC", () => {
151 expect(applySmartFormat("submitted to hmrc on time", { legalPhrases: true })).toContain("HMRC");
152 });
153
154 it("formats P&L", () => {
155 expect(applySmartFormat("reviewed the profit and loss statement", { legalPhrases: true })).toContain("P&L");
156 });
157
158 it("uppercases VAT", () => {
159 expect(applySmartFormat("the vat return is due", { legalPhrases: true })).toContain("VAT");
160 });
161
162 it("uppercases GAAP", () => {
163 expect(applySmartFormat("prepared under gaap standards", { legalPhrases: true })).toContain("GAAP");
164 });
165 });
166
123167 describe("edge cases", () => {
124168 it("returns empty string unchanged", () => {
125169 expect(applySmartFormat("")).toBe("");
Modifiedsrc/lib/smartFormat.ts+61−0View fileUnifiedSplit
@@ -129,6 +129,67 @@ const LATIN_PHRASES: Record<string, string> = {
129129 "and the following": "et seq.",
130130 "that is": "i.e.",
131131 "for example": "e.g.",
132
133 // Additional Latin maxims
134 "ab initio": "ab initio",
135 "ad hoc": "ad hoc",
136 "ad idem": "ad idem",
137 "audi alteram partem": "audi alteram partem",
138 "caveat emptor": "caveat emptor",
139 "contra proferentem": "contra proferentem",
140 "cum dividend": "cum dividend",
141 "ejusdem generis": "ejusdem generis",
142 "ex gratia": "ex gratia",
143 "ex turpi causa": "ex turpi causa",
144 "force majeure": "force majeure",
145 "ibid": "ibid.",
146 "id est": "i.e.",
147 "in personam": "in personam",
148 "in rem": "in rem",
149 "inter partes": "inter partes",
150 "ipso facto": "ipso facto",
151 "lex fori": "lex fori",
152 "lex loci": "lex loci",
153 "mutatis mutandis": "mutatis mutandis",
154 "nemo dat quod non habet": "nemo dat quod non habet",
155 "nemo judex in sua causa": "nemo judex in sua causa",
156 "novus actus interveniens": "novus actus interveniens",
157 "obiter": "obiter",
158 "pacta sunt servanda": "pacta sunt servanda",
159 "pari passu": "pari passu",
160 "per incuriam": "per incuriam",
161 "per se": "per se",
162 "post mortem": "post mortem",
163 "prima facie evidence": "prima facie evidence",
164 "rebus sic stantibus": "rebus sic stantibus",
165 "res gestae": "res gestae",
166 "res nullius": "res nullius",
167 "respondeat superior": "respondeat superior",
168 "sine die": "sine die",
169 "sine qua non": "sine qua non",
170 "sub judice": "sub judice",
171 "sui generis": "sui generis",
172 "uberrimae fidei": "uberrimae fidei",
173 "volenti non fit injuria": "volenti non fit injuria",
174
175 // Accounting terms
176 "ebitda": "EBITDA",
177 "ebit": "EBIT",
178 "gaap": "GAAP",
179 "ifrs": "IFRS",
180 "frs one oh two": "FRS 102",
181 "frs 102": "FRS 102",
182 "hmrc": "HMRC",
183 "paye": "PAYE",
184 "vat": "VAT",
185 "p and l": "P&L",
186 "profit and loss": "P&L",
187 "balance sheet": "balance sheet",
188 "net present value": "NPV",
189 "internal rate of return": "IRR",
190 "return on investment": "ROI",
191 "earnings per share": "EPS",
192 "price to earnings": "P/E",
132193};
133194
134195function formatLegalPhrases(input: string): string {
Modifiedsrc/stores/flywheel.ts+4−2View fileUnifiedSplit
@@ -218,10 +218,12 @@ export const useFlywheelStore = create<FlywheelState>((set, get) => ({
218218 return { timeEntries: [entry, ...state.timeEntries].slice(0, 500) };
219219 }),
220220
221 removeTimeEntry: (id) =>
221 removeTimeEntry: (id) => {
222222 set((state) => ({
223223 timeEntries: state.timeEntries.filter((e) => e.id !== id),
224 })),
224 }));
225 schedulePersist();
226 },
225227
226228 getTotalBillableHours: (): number => {
227229 const entries: TimeEntry[] = get().timeEntries;
228230
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts