Add a visible feature freeze section near the top of CONTRIBUTING.md
so contributors see it before starting work. Fix "GATEHRED" typo in
the PR template.
sign-binaries: false passes empty strings for TAURI_SIGNING_PRIVATE_KEY
and APPLE_CERTIFICATE, but Tauri treats a set-but-empty env var as a
signing attempt, causing all builds to fail. Use sign-binaries: true to
match pr-test-build.yml — secrets are already configured in the repo.
* test build for 0.16.0
* macos 10.15?
* format
* shorter dir for build on windows?
* Update build.yml
* move
* Update build.yml
* long path support
* clang
* try
* try
* move to ort rc12
* use ms prebuilt?
* use lower version for 1.23.1
* download my prebuilt
* Update build.yml
* Update build.yml
* fix?
* fix(nix): use dynamic linking for ort-sys 2.0.0-rc.12
ort-sys rc.12 removed pkg-config support; without ORT_PREFER_DYNAMIC_LINK
it defaults to static linking against ORT_LIB_LOCATION, which fails
because nixpkgs only provides shared libraries (.so).
* fix(nix): override onnxruntime to 1.24.2 for ort-sys rc.12 compatibility
ort 2.0.0-rc.12 enables API v24 by default, but nixpkgs only ships
onnxruntime 1.23.2 (API v23), causing a runtime panic on model load.
Use Microsoft's prebuilt binaries for onnxruntime 1.24.2 via overlay,
patched with autoPatchelfHook for NixOS compatibility.
This overlay should be removed once nixpkgs merges onnxruntime ≥ 1.24:
https://github.com/NixOS/nixpkgs/pull/499389
* updated deps for whisper
* fix(nix): sync devShell with packages for ort-sys rc.12 compatibility
- Extract shared definitions (commonNativeDeps, gstPlugins, commonEnv,
onnxruntimeOverlay) to avoid duplication between packages and devShells
- Add onnxruntime 1.24.2 overlay to devShell (was only in packages)
- Add BINDGEN_EXTRA_CLANG_ARGS to devShell so bindgen can find stdio.h
and generate correct vulkan bindings for whisper-rs-sys
- Add ORT_LIB_LOCATION and ORT_PREFER_DYNAMIC_LINK to devShell
- Replace libappindicator with libayatana-appindicator in devShell
- Add onnxruntime and vulkan-loader to devShell LD_LIBRARY_PATH
* fix missing lib in the handy blob dl
* scope lib verification
* dont run bun2nix on windows
---------
Co-authored-by: Evgeny <evgeny.khudoba@yandex.ru>
* ci: add full build and quality checks on push to main
Adds a new main-build.yml workflow that runs the full 7-platform build
matrix on every push to main, uploading artifacts for 30 days. Also
adds push-to-main triggers to code-quality, test, and nix-check
workflows. The nix full build now always runs on main pushes (not just
when nix packaging files change), catching the expensive breakage that
currently requires manual verification before each release.
* ci: fix permissions and clarify nix full-build intent
- narrow contents: write to contents: read in main-build.yml — no
release assets are uploaded here so write access is unnecessary
- update nix-check comment to reflect that the full build always runs
on push to main (not just when nix files change), matching intent
* ci: reduce PR check time from ~30 min to ~1 min
- merge lint + prettier into single code-quality workflow
- add concurrency groups to cancel stale runs on rapid pushes
- add path filters so irrelevant changes skip checks
- make full nix build opt-in via "nix" label (eval-only by default)
- add nix store caching via magic-nix-cache-action
- cache trusted-signing-cli binary on windows builds
- upgrade setup-bun from v1 to v2
* ci: add workflow path filters and expand nix build triggers
- add .github/workflows/** to path filters on code-quality and nix-check
so CI runs when workflow files themselves change
- include tauri.conf.json and build.rs in nix full-build diff check since
these can break nix sandbox builds independently of cargo builds
* fix(nix): replace manual hash management with bun2nix
Eliminate the recurring problem of Nix build hashes breaking whenever
bun dependencies change or the bun version in nixpkgs updates.
Changes:
- Add bun2nix flake input (pinned to v2.0.1) for per-package fetchurl
expressions from bun.lock, replacing the single FOD hash approach
- Use allowBuiltinFetchGit for cargo git dependencies, removing manual
outputHashes that required updates on every git dep change
- Add scripts/check-nix-deps.ts (cross-platform, runs via bun) that
auto-regenerates .nix/bun.nix when bun.lock changes, triggered by
the postinstall hook in package.json
- Update CI workflow to verify bun.nix is in sync and evaluate flake
- Remove scripts/update-nix-hashes.sh (no longer needed)
* style: format check-nix-deps.ts with prettier
* ci(nix): make nix-check job a required check
* fix(nix): address review feedback
- Fix bun2nix input pinning: use path syntax (github:owner/repo/tag)
instead of ?tag= query parameter so flake.lock records the ref
and `nix flake update` respects the pin
- Make check-nix-deps.ts exit with 0 on bun2nix failure so that
`bun install` is not blocked for non-Nix developers (CI validates
bun.nix independently)
- Fix stale reference to check-nix-deps.sh in flake.nix comment
* ci(nix): add full nix build step to CI workflow
Add `nix build .#handy -L --show-trace` after flake evaluation to
catch runtime build errors (broken dependencies, sandbox issues,
compilation failures) that flake eval alone cannot detect.
* fix(nix): update bun2nix pin from 2.0.1 to 2.0.8
bun2nix 2.0.1 has a bug in cache-entry-creator that causes
"ln: failed to create symbolic link '/p': Permission denied"
during the build. Version 2.0.8 fixes this.
* feat: add portable ZIP archives for Windows releases
Add portable (no-install) ZIP builds for Windows x64 and ARM64.
After the existing Tauri build step, a new step packages Handy.exe
and its resources/ directory into a zip archive that users can
extract and run directly without an installer.
The portable ZIPs are uploaded to GitHub Releases alongside the
existing NSIS/MSI installers, and included in CI artifact uploads.
Closes#153
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use -not instead of ! for PowerShell compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(nix): build from source instead of wrapping AppImage (#701)
Replace the AppImage-based Nix package with a native from-source build
using cargo-tauri.hook + rustPlatform.buildRustPackage. This eliminates
the recurring hash mismatch failures when releases update the binary.
- Build frontend (bun) and backend (cargo tauri) from source
- Vendor JS deps as a fixed-output derivation
- Patch libappindicator-sys for Nix store path
- Patch ferrous-opencc to skip cbindgen (upstream removed in v0.3.1+)
- Wrap binary with WEBKIT_DISABLE_DMABUF_RENDERER and LD_LIBRARY_PATH
- Delete update-flake-hash.yml workflow (no longer needed)
- devShell unchanged
* add support for arm64
---------
Co-authored-by: CJ Pais <cj@cjpais.com>
* feat: add models settings page with filtering and management
- add dedicated models settings page in sidebar
- reuse ModelCard component from onboarding for consistent UI
- add filter buttons for all/multi-language/translation models
- add model deletion with native confirmation dialog (tauri-plugin-dialog)
- consolidate model event listeners into useModels hook (Zustand store)
- remove duplicate event listeners from ModelSelector, LanguageSelector, TranslateToEnglish
- gate AccessibilityPermissions to macOS only
- add is_recommended field to model registry for featured models
- remove unused get_recommended_first_model command
- add translations for all 9 supported languages
* feat: add language filter to models settings page
adds a searchable language dropdown filter to the models page that lets users filter models by language support. when a non-english language is selected, models that don't support multiple languages (like parakeet) are hidden.
- add searchable language dropdown (right-aligned in filter row)
- filter models using supports_language_selection capability
- add allLanguages translation key to all 10 locales
* feat: add translation consistency checker script
- add scripts/check-translations.cjs to validate all language files
- script dynamically discovers languages from directory structure
- checks that all languages have same keys as english reference
- detects missing and extra keys in each language
- add check:translations npm script
- integrate into github actions lint workflow
- validates translations on every pull request
* fix: update imports and add missing translations after rebase
- replace useModels hook with useModelStore in components
- add permission error keys to all languages
- add model settings keys to cs and tr (new languages from main)
* fix: translate english placeholders in cs and tr locale files
* refactor: simplify model dropdown and migrate store to immer
- model dropdown now only shows downloaded models (no download/delete)
- convert store to immer with record types for immutability
- remove unused translation keys (welcome, downloadPrompt, etc.)
- add missing moonshine-base model fields
- sync translations after rebase
* fix: add download cancellation support and ui improvements
- add full download cancellation with Arc<AtomicBool> flags in rust backend
- add progress event throttling (100ms) to prevent ui freeze
- add cancel button to model card in settings page
- add model-deleted event listener to refresh dropdown after deletion
- remove pink background from recommended models in settings (keep badge only)
- add cancel/cancelDownload translation keys to all 14 languages
* fix: remove duplicate language/translate settings from general and advanced
settings are now only in ModelSettingsCard, not duplicated in their old locations
* fix: prevent model dropdown from being clipped by window edge
* add languages explicitly, clean up some ui
* fix: clear bottom progress bar when download is cancelled
The ModelSelector component maintains its own local state for download
progress. When a download was cancelled, the Rust backend would update
its state but never emitted an event to notify the frontend. This caused
the bottom progress bar to remain stuck showing "Downloading X%".
Added model-download-cancelled event emission in Rust and corresponding
listener in ModelSelector to clear progress state on cancellation.
* fix: align model card content to top to prevent floating elements
Changed ModelCard flex alignment from items-center to items-start so
the accuracy/speed bars stay at the top when the card expands (e.g.,
during download with progress bar visible).
* fix: prevent model deletion from interrupting active extractions
Added extracting_models HashSet to track models currently being
extracted. The update_download_status() function now skips cleanup
of .extracting directories for models that are actively extracting,
preventing a race condition where deleting one model would interrupt
another model's extraction process.
* refactor: migrate ModelCard buttons to Button component
Added two new Button variants for common patterns:
- primary-soft: soft/tinted primary buttons (used for download)
- danger-ghost: subtle destructive actions (used for delete/cancel)
Migrated all hardcoded buttons in ModelCard to use the shared Button
component for consistency and maintainability.
* feat: separate downloaded and available models into sections
Split the models list into "Your Models" and "Available to Download"
sections for clearer visual distinction between downloaded and
downloadable models.
Also adds missing translation keys to all locales:
- modelSelector.capabilities.singleLanguage
- modelSelector.capabilities.languageOnly
- settings.models.yourModels
- settings.models.availableModels
* fix: add missing translations after rebase onto main
add post-processing hotkey translations to all 15 locales and
backfill 29 missing keys for korean locale added in main.
* fix: add label to model delete button for clearer destructive state
* check translations as typescript
* format
* better text for dropdown
* wip ui tweaks
* rounded + ui tweaks
* fix download not 0% immediately, ui tweaks
* tweak name
* block for model downloading in onboarding
* small fixes
---------
Co-authored-by: CJ Pais <cj@cjpais.com>
* feat: add Playwright testing infrastructure
- Add @playwright/test dependency
- Add playwright.config.ts with Chromium setup
- Add test scripts (test, test:ui, test:headed)
- Add hello world test to verify setup works
This is the foundation for adding comprehensive E2E tests.
Tests run against the Vite dev server on port 1420.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* ci: add E2E test workflow
Runs Playwright tests on pull requests using Chromium.
Uploads test artifacts on failure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: rename e2e to playwright, fix CI test
- Rename workflow from "E2E Tests" to "Playwright"
- Rename scripts from test:e2e to test:playwright
- Fix test to not require Tauri APIs (just check server responds)
- Run prettier
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
* fix: run Rust tests in CI
Fixes#670
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: run Rust tests in CI
Adds a separate test.yml workflow to run existing Rust unit tests.
Fixes#670
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: use mock TranscriptionManager in CI tests
Swap to a mock adapter during CI to avoid compiling whisper/Vulkan.
The mock has the same interface but no heavy dependencies.
Existing tests don't exercise transcription code, so this is safe.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add Nix flake for NixOS support
Provides:
- handy-appimage: AppImage-based package (default)
- devShell: Development environment for building from source
* fix(nix): address PR feedback for flake.nix
- Remove aarch64-linux from supportedSystems (ARM64 builds not produced)
- Read version dynamically from Cargo.toml instead of hardcoding
This enables automated updates during GitHub releases
* chore(nix): add GitHub Actions workflow to auto-update AppImage hash
Adds a separate workflow triggered on release publication that:
- Fetches the released AppImage
- Computes the SRI hash using nix-prefetch-url
- Updates flake.nix with the new hash
- Commits and pushes changes directly
Includes retry logic for timing issues and defensive checks to verify
the hash was actually updated and skip commits if unchanged.
* Update flake.nix hash to resolve mismatch
Co-authored-by: pinage404 <pinage404@gmail.com>
* Update flake.nix to install dependencies automatically
Co-authored-by: pinage404 <pinage404@gmail.com>
* fix: update AppImage hash for v0.7.0
* modified description
---------
Co-authored-by: pinage404 <pinage404@gmail.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
* Add `select-none` and `cursor-default` to root to prevent selection and
hover on most items
* Lint
* refactor paths a bit
* format
---------
Co-authored-by: CJ Pais <cj@cjpais.com>
defer apple intelligence availability check from app initialization
to when the user actually tries to use the feature. accessing
SystemLanguageModel.default during early app startup causes SIGABRT
on macOS 26.x (tahoe) beta.
- remove availability check from default_post_process_providers()
- always include apple intelligence provider on macos arm64
- add checkAppleIntelligenceAvailable command for lazy checking
- show error message if apple intelligence unavailable when selected
- clear error on any dropdown selection for better UX
* feat: add fallback microphone for clamshell/desktop mode
* refactor: moved "Closed Laptop Microphone" setting to Debug
* cleanup
* run format
* add check back
---------
Co-authored-by: CJ Pais <cj@cjpais.com>