Handy

repository·main·Indexed 12 days ago

https://github.com/cjpais/handy

A free, open-source, and privacy-focused speech-to-text desktop application for offline transcription. Handy performs all processing locally using Whisper or Parakeet V3 models and Silero VAD for silence filtering, automatically pasting transcribed text into the active field. It features a CLI for remote control, GPU acceleration support, and integration with Raycast.

Tokens
23K
Snippets
81
Records
115
Agent score
92%

What's inside Handy

  1. How Handy works

    main

    Handy provides offline speech transcription through a four-step local process:

    1. Trigger: Press a configurable keyboard shortcut (or use push-to-talk mode).
    2. Record: Speak while the shortcut is active.
    3. Process: Upon release, Handy processes the audio locally using either:
      • Whisper models (Small, Medium, Turbo, or Large) with GPU acceleration support.
      • Parakeet V3 (CPU-optimized with automatic language detection).
      • Silence is filtered using Silero VAD (Voice Activity Detection).
    4. Output: The transcribed text is automatically pasted into your active text field.

    All processing happens entirely on your local machine for privacy.

  2. Add a new language translation to Handy

    main

    To add a new language to Handy, follow these steps:

    1. Create the language folder: Use the ISO 639-1 language code (e.g., de for German, ja for Japanese).
    2. Copy the source file: Copy src/i18n/locales/en/translation.json to your new folder as src/i18n/locales/[language-code]/translation.json.
    3. Translate values: Open the JSON file and translate only the values (the right side). Do not modify the keys (the left side).
    4. Register the language: Add your language metadata to src/i18n/languages.ts inside the LANGUAGE_METADATA object.
    5. Test: Run the app using bun run tauri dev, navigate to Settings → General → App Language, and select your language to verify the UI.
    # 1. Create folder
    mkdir src/i18n/locales/de
    
    # 2. Copy English source
    cp src/i18n/locales/en/translation.json src/i18n/locales/de/translation.json
    
    # 3. Run app to test
    bun run tauri dev
  3. Install Handy from source on Linux

    main

    The raw binary src-tauri/target/release/handy requires co-located resource files (tray icons, sounds, VAD model).

    Method 1: Install from the .deb bundle (Recommended) This works on any Linux distro:

    cd /tmp
    ar x /path/to/Handy/src-tauri/target/release/bundle/deb/Handy_*_amd64.deb data.tar.gz
    tar xzf data.tar.gz
    sudo cp usr/bin/handy /usr/bin/
    sudo cp -a usr/lib/. /usr/lib/
    sudo cp -r usr/share/icons/hicolor/* /usr/share/icons/hicolor/
    sudo cp usr/share/applications/Handy.desktop /usr/share/applications/

    Method 2: Manual Rebuild/Update If you rebuild the project, copy the binary and the runtime libraries:

    sudo cp src-tauri/target/release/handy /usr/bin/
    sudo mkdir -p /usr/lib/Handy
    sudo cp -a src-tauri/transcribe-libs/. /usr/lib/Handy/
    ar x /path/to/Handy/src-tauri/target/release/bundle/deb/Handy_*_amd64.deb data.tar.gz
    tar xzf data.tar.gz
    sudo cp usr/bin/handy /usr/bin/
    sudo cp -a usr/lib/. /usr/lib/
    sudo cp -r usr/share/icons/hicolor/* /usr/share/icons/hicolor/
    sudo cp usr/share/applications/Handy.desktop /usr/share/applications/
  4. Verify Handy release signatures

    main

    Handy releases are signed using the Tauri updater signature format. To verify a release manually, you need the public key from src-tauri/tauri.conf.json (under plugins.updater.pubkey) and the .sig file provided with the artifact.

    Note: Use minisign, not gpg.

    1. Save the pubkey value to handy.pub.b64.
    2. Use the following Python script to decode the keys and verify the artifact:
    # Replace with the file you downloaded
    ARTIFACT="Handy_0.8.1_amd64.AppImage"
    
    python3 - "$ARTIFACT" <<'PY'
    import base64, pathlib, sys
    
    artifact = sys.argv[1]
    
    pub = pathlib.Path("handy.pub.b64").read_text().strip()
    pathlib.Path("handy.pub").write_bytes(base64.b64decode(pub))
    
    sig = pathlib.Path(f"{artifact}.sig").read_text().strip()
    pathlib.Path(f"{artifact}.minisig}").write_bytes(base64.b64decode(sig))
    PY
    
    minisign -Vm "$ARTIFACT" \
      -p handy.pub \
      -x "$ARTIFACT.minisig"
  5. Translate translation.json values correctly

    main

    When editing translation.json, adhere to these rules to avoid breaking the application:

    • Keys vs. Values: Only translate the values. The keys are used by the code to look up strings and must remain identical to the English source.
    • Variables: Preserve all placeholders wrapped in double curly braces, such as {{error}} or {{model}}. Do not translate the text inside the braces.
    • JSON Integrity: Maintain the exact JSON structure and formatting.

    Example of correct translation:

    // English (Source)
    "downloadModel": "Failed to download model: {{error}}"
    
    // French (Correct)
    "downloadModel": "Échec du téléchargement du modèle : {{error}}"
    
    // French (Incorrect - DO NOT DO THIS)
    "downloadModel": "Échec du téléchargement du modèle : {{erreur}}"
    {
      "sidebar": {
        "general": "General",      // ← Translate this value
        "advanced": "Advanced"     // ← Translate this value
      }
    }
  6. Build and validate Handy

    main

    Use these commands to build the project or perform type checking:

    • Type Checking: Run bunx tsc --noEmit to validate TypeScript types without emitting files.
    • Frontend Build: Run bun run build to build the frontend assets.
    • Production Build: Run bun run tauri build to create a production-ready application.
    • Full Build & Validate: Run bun run build to build and validate the project.
    bunx tsc --noEmit
    bun run build
    bun run tauri build
  7. Quick Start: Clone, Install, and Run Handy

    main

    Follow these steps to set up the development environment and start running Handy:

    1. Clone the Repository
      git clone git@github.com:cjpais/Handy.git
      cd Handy
    2. Install Dependencies
      bun install
    3. Start Dev Server
      bun tauri dev
    4. Build for Production
      bun run tauri build
      This generates platform-specific bundles (deb, rpm, AppImage, dmg, or msi).
    git clone git@github.com:cjpais/Handy.git
    cd Handy
    bun install
    bun tauri dev
    bun run tauri build
  8. Platform-specific build requirements for Windows

    main

    To build on Windows, you need:

    1. Microsoft C++ Build Tools: Visual Studio 2019/2022 with C++ development tools.
    2. CMake: Must be on your PATH. Install via winget:
      winget install Kitware.CMake
    3. Vulkan SDK: Required for the Vulkan GPU backend (vulkan-shaders-gen). Install via winget:
      winget install KhronosGroup.VulkanSDK
      Note: Open a new terminal after installation to ensure VULKAN_SDK is set.

    Note on Path Limits: The build uses an NTFS junction to work around the 260-character MAX_PATH limit. If you encounter MSB3491, FTK1011, or MSB6003 errors, see the troubleshooting section.

    winget install Kitware.CMake
    winget install KhronosGroup.VulkanSDK
  9. Platform-specific build requirements for macOS

    main

    macOS General

    Install Xcode Command Line Tools using:

    xcode-select --install

    Intel Mac (x86_64)

    Prebuilt ONNX Runtime binaries are unavailable for Intel Macs. You must install onnxruntime via Homebrew and use specific environment variables to link it dynamically during development or production builds.

    Development:

    brew install onnxruntime
    ORT_LIB_LOCATION=$(brew --prefix onnxruntime)/lib ORT_PREFER_DYNAMIC_LINK=1 bun run tauri dev

    Production Build:

    ORT_LIB_LOCATION=$(brew --prefix onnxruntime)/lib ORT_PREFER_DYNAMIC_LINK=1 bun run tauri build
    ORT_LIB_LOCATION=$(brew --prefix onnxruntime)/lib ORT_PREFER_DYNAMIC_LINK=1 bun run tauri dev
  10. Run Handy in development mode

    main

    Depending on whether you want to develop the full application or just the frontend, use the following commands:

    • Full App Development: Runs the Tauri application (includes backend and frontend).
    • Frontend Only: Runs the Vite development server for the frontend.

    Note for macOS users: If you encounter CMake issues, use the CMAKE_POLICY_VERSION_MINIMUM environment variable.

    # Full app development
    bun run tauri dev
    
    # macOS with cmake fix
    CMAKE_POLICY_VERSION_MINIMUM=3.5 bun run tauri dev
    
    # Frontend only (Vite)
    bun run dev