Hacker News

Open Source, Free Tier Capable Whispr Using Cloudflare AI

Architecture

Voice-to-text tool that captures speech, transcribes it via Whisper, and formats the output with an LLM. Press a hotkey, speak, release - formatted text lands in your clipboard and is auto-pasted into whatever you were typing in.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       PCM chunks       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚    Wails Desktop App โ”‚ โ”€โ”€WebSocketโ”€โ”€โ–ถ         โ”‚ Cloudflare Worker (Durable Obj) โ”‚
โ”‚  (Go + React WebView)โ”‚ โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€         โ”‚ Whisper STT โ†’ LLM Formatter     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                      formatted text
                                                          โ”‚
                                                          โ–ผ
                                                  Clipboard โ†’ Auto-paste

Usage Flow

  • Hold Ctrl+Cmd - focus context is captured, recording starts, overlay appears at top-center
  • Speak into your microphone (voice level meter shows input)
  • Release Ctrl+Cmd - audio streams to the cloud
  • Whisper transcribes, LLM formats, result is copied to clipboard and auto-pasted into the originating app

Project Structure

voicebox/
โ”œโ”€โ”€ main.go                    # Wails entrypoint, app menu
โ”œโ”€โ”€ app.go                     # App lifecycle, hotkey handlers, pipeline orchestration
โ”œโ”€โ”€ window_darwin.go           # macOS window management (overlay, settings, dock click)
โ”œโ”€โ”€ window_other.go            # Stub for non-macOS builds
โ”œโ”€โ”€ internal/
โ”‚   โ”œโ”€โ”€ audio/                 # PCM audio capture (malgo/miniaudio), RMS level
โ”‚   โ”œโ”€โ”€ pipeline/              # WebSocket client, streams audio + focus context to worker
โ”‚   โ”œโ”€โ”€ accessibility/         # macOS AX API: focused element context + auto-paste (Cmd+V)
โ”‚   โ”œโ”€โ”€ config/                # TOML config loading and saving
โ”‚   โ”œโ”€โ”€ hotkey/                # Global hotkey registration
โ”‚   โ”œโ”€โ”€ stt/                   # STT provider interface (stubs)
โ”‚   โ””โ”€โ”€ formatter/             # LLM formatting provider interface (stubs)
โ”œโ”€โ”€ frontend/                  # React + Tailwind overlay UI (Vite)
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ”œโ”€โ”€ App.tsx            # Routes between settings mode and overlay mode
โ”‚       โ”œโ”€โ”€ components/
โ”‚       โ”‚   โ”œโ”€โ”€ settings-form.tsx   # Config editor (react-hook-form + zod)
โ”‚       โ”‚   โ””โ”€โ”€ title-bar.tsx       # Frameless title bar with drag region
โ”‚       โ””โ”€โ”€ hooks/
โ”‚           โ”œโ”€โ”€ use-voicebox.ts     # voicebox:state / voicebox:mode / voicebox:level events
โ”‚           โ””โ”€โ”€ use-config.ts       # GetConfig / SaveConfig / GetConfigPath bindings
โ”œโ”€โ”€ worker/                    # Cloudflare Worker (TypeScript)
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ index.ts           # Router: /ws (WebSocket), /health
โ”‚   โ”‚   โ”œโ”€โ”€ session.ts         # Durable Object: audio accumulation + AI pipeline
โ”‚   โ”‚   โ”œโ”€โ”€ prompt.ts          # System prompt + user message builder
โ”‚   โ”‚   โ”œโ”€โ”€ wav.ts             # PCM-to-WAV wrapper
โ”‚   โ”‚   โ””โ”€โ”€ types.ts           # Shared types
โ”‚   โ”œโ”€โ”€ test/                  # Vitest tests
โ”‚   โ””โ”€โ”€ wrangler.jsonc         # Worker configuration
โ”œโ”€โ”€ go.mod
โ””โ”€โ”€ voicebox.toml              # User config (gitignored)

Prerequisites

  • Go 1.24+
  • Node.js + pnpm
  • Wails v2 CLI
  • A Cloudflare account with Workers AI access
  • macOS (accessibility permission required for auto-paste)

Quick Start

cd worker
pnpm install
wrangler secret put VOICEBOX_TOKEN   # set a shared secret
pnpm deploy

On first launch, VoiceBox opens a settings window. You can also create the config manually at ~/.config/voicebox/voicebox.toml:

[provider]
mode = "cloud"

[cloud]
worker_url = "https://voicebox.<your-subdomain>.workers.dev"
token = "your-shared-secret"

[audio]
sample_rate = 16000
channels = 1
chunk_size = 4096

[hotkey]
record = "ctrl+cmd"

Config is loaded from (in order): ~/.config/voicebox/voicebox.toml, next to the binary, then ./voicebox.toml.

Accessibility Permissions

Auto-paste requires macOS Accessibility access. On first use, macOS will prompt for permission, or you can grant it manually in System Settings โ†’ Privacy & Security โ†’ Accessibility.

Development & Build

wails dev      # dev mode with hot reload
wails build    # production binary

UI Windows

  • Settings (700ร—450, centered): Opens on launch, dock click, or via the Recording menu. Edit config here.
  • Overlay (160ร—48, top-center, floating): Appears during recording. Shows recording indicator with voice level meter, spinner while processing, checkmark on success.

WebSocket Protocol

Client connects to GET /ws?token=<token>. After receiving {"type":"ready"}, the client sends a configure message with audio and focus context, then streams binary PCM chunks:

Client                                 Server
  โ”‚โ”€โ”€ connect /ws?token=... โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ   โ”‚
  โ”‚โ—€โ”€โ”€ {"type":"ready"} โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚
  โ”‚โ”€โ”€ {"type":"configure", ...} โ”€โ”€โ–ถ   โ”‚
  โ”‚โ”€โ”€ [binary PCM chunk] โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ   โ”‚
  โ”‚โ”€โ”€ [binary PCM chunk] โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ   โ”‚
  โ”‚โ”€โ”€ {"type":"audio_end"} โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ   โ”‚
  โ”‚โ—€โ”€โ”€ {"type":"processing",...} โ”€โ”€   โ”‚
  โ”‚โ—€โ”€โ”€ {"type":"result",...} โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚

The configure message carries audio params and focused element context (app name, bundle ID, element role, title, placeholder, current value) used by the LLM formatter to tailor output.

AI Models

  • STT: @cf/openai/whisper-large-v3-turbo
  • Formatter: @cf/qwen/qwen3-30b-a3b-fp8

Local Fallback

  • STT: faster-whisper
  • Formatter: Ollama

Provider interfaces exist at internal/stt/ and internal/formatter/.

Audio Specifications

  • 16kHz sample rate, mono, PCM signed 16-bit LE
  • ~4096 byte chunks (~128ms each)
  • Max recording: ~25 MiB (~13 minutes)

Commands

Desktop App

wails dev           # dev server (Go + Vite hot reload)
wails build         # production build
go vet ./...        # lint Go
go test ./internal/...   # test Go

Frontend

cd frontend && pnpm install && pnpm build

Worker

cd worker
pnpm dev            # local dev server
pnpm lint           # type-check
pnpm format         # prettier
pnpm test           # vitest
pnpm deploy         # deploy to Cloudflare

Comments

No comments yet. Start the discussion.