{"slug": "show-hn-pasteface-record-transcribe-and-copy-speech-locally-in-your-terminal", "title": "Show HN: Pasteface - Record, transcribe and copy speech locally in your terminal", "summary": "Developer blairjordan released Pasteface, an open-source terminal application that records, transcribes, and copies speech locally using whisper.cpp or OpenAI's transcription API. Pasteface installs via a Rust toolchain and FFmpeg on Linux and macOS, organizes recordings into named transcript tabs, and transcribes earlier chunks while recording continues; Windows is not currently supported.", "body_md": "Record, transcribe, and copy speech from your terminal.\n\nOrganize recordings into named transcript tabs, keep recording while earlier chunks transcribe, and copy the results to your clipboard. Transcribe on your machine with whisper.cpp or use OpenAI’s transcription API.\n\nInstall a current stable Rust toolchain and FFmpeg. Local transcription also requires a separate whisper.cpp executable and model; see [Transcription settings](#transcription-settings).\n\nInstall the native dependencies for the default build, which includes the tray:\n\n```\n# Arch / Manjaro\nsudo pacman -S --needed base-devel pkgconf alsa-lib gtk3 xdotool libayatana-appindicator ffmpeg\n\n# Debian / Ubuntu\nsudo apt install build-essential pkg-config libasound2-dev libgtk-3-dev \\\n  libxdo-dev libayatana-appindicator3-dev libwayland-dev libxkbcommon-dev ffmpeg\n```\n\nClone and install:\n\n```\ngit clone https://github.com/blairjordan/pasteface.git\ncd pasteface\n./scripts/install-linux.sh\n```\n\nThe installer builds Pasteface and installs the executable in `~/.local/bin` and a desktop launcher in `~/.local/share/applications`. Ensure `~/.local/bin` is on your `PATH`.\n\nThe tray requires a StatusNotifier/AppIndicator host. On i3, `snixembed` can bridge it to an enabled i3bar tray. Recording and the terminal interface also work without a tray host.\n\nInstall the Xcode command-line tools, Rust, and FFmpeg:\n\n```\nxcode-select --install\nbrew install ffmpeg\ngit clone https://github.com/blairjordan/pasteface.git\ncd pasteface\n./scripts/bundle-macos.sh\nopen target/Pasteface.app\n```\n\nThe script creates an ad-hoc signed application bundle that opens the TUI in Terminal. Grant microphone access when prompted; Terminal may also need microphone permission. This is a source build, not a notarized release. macOS compilation is covered by CI; microphone, menu-bar, and permission behavior still need testing on a Mac.\n\n```\ncargo build --release --locked\n./target/release/pasteface\n\n# Omit the tray and its GTK dependencies.\ncargo build --release --locked --no-default-features\n```\n\nThe tray-free build still requires the platform audio libraries and FFmpeg. Linux and macOS are the target platforms; Windows is not currently supported.\n\nRun `pasteface` to open the terminal interface and start the tray companion.\n\n| Key | Action | \n|---|---|\n| **Space** | Start or stop recording; stopping enqueues the chunk | \n| **C** | Copy the selected tab’s transcript | \n| **E** | Export the selected tab to a .txt file | \n| **Ctrl+C** | Copy only the latest completed chunk | \n| **X** | Clear the selected tab’s recordings and transcript after confirmation | \n| **S** | Open settings, including microphone selection | \n| **Tab / Shift+Tab** | Switch transcript tabs | \n| **+** | Create a transcript tab | \n| **F2** | Rename the selected tab | \n| **↑ / ↓** | Scroll the transcript | \n| **Esc** | Cancel active transcription and all queued chunks | \n| **Q** | Close the terminal interface | \n\nClick **+** to create a named transcript tab. New recordings append to the selected tab; recording a chunk never creates a tab. Click a tab to switch transcripts, or click a queue block to open its owning tab. Tabs also support **[ / ]** navigation. Right-click a tab and choose **Rename**, or press **F2**, to give it a persistent name. **Close tab** in the same menu hides the tab while retaining its transcript and audio. Use **Reopen** beside **+** to restore closed tabs.\n\nClick the footer controls to record, copy, clear, cancel, or open settings. Settings and the microphone picker support clicks and the mouse wheel. Scroll over the transcript with the wheel. Drag across transcript text to highlight and copy it; hold **Shift** while dragging to use native terminal selection instead.\n\nPress **E**, or right-click a tab and choose **Export…**, to save its completed transcript as plain UTF-8 text. Edit the suggested path and press **Enter** to save. Relative paths use the terminal’s working directory; ~/ is supported. Existing files are never overwritten.\n\nThe microphone meter responds to your voice while recording. Queue blocks show each chunk's duration and whether it is queued, transcribing, completed, failed, or canceled.\n\nCancel preserves existing text and recorded audio. It does not stop a recording in progress. Clear is available once recording and transcription have stopped, and does not erase the system clipboard. In a picker or settings dialog, **Esc** closes the dialog instead.\n\nThe terminal and tray control the same background recorder. Closing either interface leaves the recorder running. To reopen the terminal, run `pasteface` again or choose **Open terminal** from the tray menu. The tray circle changes with recording and transcription status.\n\n```\npasteface tui --no-tray  # Terminal interface without starting the tray\npasteface tray           # Tray interface only\npasteface start\npasteface stop           # Enqueue the recording and return immediately\npasteface toggle\npasteface cancel         # Abort active transcription and cancel the queue\npasteface copy\npasteface clear\npasteface status         # JSON state, including transcript and chunk status\npasteface devices\npasteface doctor\npasteface shutdown       # Stop an idle recorder\n```\n\n`pasteface retry` retries the oldest failed chunk. No global shortcuts are registered; a window manager or other automation can invoke the CLI commands.\n\nTo restart the terminal interface, press **Q** and run `pasteface`. To restart the recorder, first finish or cancel its work, run `pasteface shutdown`, then reopen the app.\n\nPress **S** to choose a provider, configure the local executable and model, or enter an OpenAI API key. Settings are saved separately from recorded audio. Provider changes apply to subsequent transcription jobs; an active job keeps the settings with which it started.\n\nLocal transcription processes audio on your machine. Install an executable and model using the [whisper.cpp instructions](https://github.com/ggml-org/whisper.cpp), then set their paths in Pasteface. The default paths are:\n\n```\n~/.local/lib/whisper.cpp/build/bin/whisper-cli\n~/.local/lib/whisper.cpp/models/ggml-large-v3-turbo-q5_0.bin\n```\n\nAcceleration is a runtime setting:\n\n| Mode | Behavior | \n|---|---|\n| **Auto** | Let the configured whisper.cpp executable choose its available backend | \n| **CPU** | Disable GPU inference for the configured executable | \n| **Vulkan** | Use a separately installed Vulkan-capable whisper.cpp executable | \n\nPasteface does not bundle Whisper models, Vulkan drivers, or a GPU runtime. Vulkan support belongs to the external whisper.cpp installation, so changing it does not require rebuilding Pasteface. Select the appropriate executable in settings and install the Vulkan driver for your GPU. A CPU-only executable does not gain GPU support by selecting Vulkan.\n\nAdvanced backend environment overrides, such as `GGML_VK_VISIBLE_DEVICES`, can be set in the `environment` object in `transcription.json`. Supported prefixes are `GGML_`, `VK_`, and `MESA_`.\n\nSelect **OpenAI** in settings and enter your API key in the masked field, or set `OPENAI_API_KEY` before starting the recorder. The default model is **`gpt-transcribe`**; the model name is editable.\n\nWhen selected, this provider sends completed recordings to OpenAI's audio transcription endpoint. API usage is billed to your OpenAI account. Local mode does not upload audio. Recordings must fit the API's 25 MB file limit after conversion; use shorter chunks for longer sessions.\n\nKeys entered in the app are stored in a separate `secrets.json` file with owner-only permissions (`0600`). They are not included in status responses or transcript files. A saved key takes precedence over the `OPENAI_API_KEY` environment variable.\n\nSee the official [file transcription guide](https://developers.openai.com/api/docs/guides/speech-to-text) and [`gpt-transcribe` model documentation](https://developers.openai.com/api/docs/models/gpt-transcribe).\n\nCapture uses the selected microphone's native sample rate. After stopping, FFmpeg converts the recording to mono 16 kHz PCM. Each chunk is transcribed as a complete recording. Text appears when the chunk finishes; live partial transcripts are not currently displayed.\n\nState is stored in a private application directory: normally `~/.local/state/pasteface` on Linux or the platform application-data directory on macOS. It contains `transcription.json`, the optional `secrets.json`, recorded chunks, processing logs, and the combined transcript.\n\nEach recording has its own directory. One worker drains the queue in order while microphone capture remains available. There is no fixed chunk-count limit; recordings use available disk space. Queued work survives recorder restarts, and a failed chunk retains its audio without blocking later chunks. Canceled chunks remain canceled after a restart.\n\n| Environment variable | Purpose | \n|---|---|\n| `WHISPER_BINARY` | Override the configured whisper.cpp executable path | \n| `WHISPER_MODEL` | Override the configured local model path | \n| `OPENAI_API_KEY` | OpenAI key fallback when no key is saved | \n| `AUDIO_DEVICE` | Override the saved microphone selection | \n| `TERMINAL` | Terminal executable for the tray's **Open terminal** action on Linux | \n| `PASTEFACE_AUTO_COPY=0` | Disable automatic clipboard updates | \n| `PASTEFACE_REDUCED_MOTION=1` | Disable the recording shimmer | \n| `PASTEFACE_STATE_DIR` | Override the application state directory | \n\nEnvironment variables are read by the recorder process. Restart an idle recorder after changing them. Desktop launchers inherit the graphical session's environment, which may differ from a terminal's.\n\nSee [CONTRIBUTING.md](https://github.com/blairjordan/pasteface/blob/main/CONTRIBUTING.md) and [AGENTS.md](https://github.com/blairjordan/pasteface/blob/main/AGENTS.md). All commits must follow Conventional Commits.\n\n```\ncargo fmt --check\ncargo clippy --all-targets -- -D warnings\ncargo test\ncargo check --no-default-features\n```\n\nTests use isolated recording fixtures and mock HTTP responses. They do not record from your microphone or upload your audio to OpenAI.", "url": "https://wpnews.pro/news/show-hn-pasteface-record-transcribe-and-copy-speech-locally-in-your-terminal", "canonical_source": "https://github.com/blairjordan/pasteface", "published_at": "2026-10-15 23:59:51+00:00", "updated_at": "2026-10-16 00:28:32.047001+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "natural-language-processing"], "entities": ["Pasteface", "blairjordan", "whisper.cpp", "OpenAI", "Rust", "FFmpeg", "GitHub", "macOS"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-pasteface-record-transcribe-and-copy-speech-locally-in-your-terminal", "markdown": "https://wpnews.pro/news/show-hn-pasteface-record-transcribe-and-copy-speech-locally-in-your-terminal.md", "text": "https://wpnews.pro/news/show-hn-pasteface-record-transcribe-and-copy-speech-locally-in-your-terminal.txt", "jsonld": "https://wpnews.pro/news/show-hn-pasteface-record-transcribe-and-copy-speech-locally-in-your-terminal.jsonld"}}