Commit graph

548 commits

Author SHA1 Message Date
CJ Pais
4e4bc613ed please add logs when submitting bugs 2026-02-24 17:58:23 +08:00
CJ Pais
a83228030f Add BoltAI as a sponsor! 2026-02-24 16:02:46 +08:00
CJ Pais
551ad6c414 Add BoltAI as a sponsor! 2026-02-24 15:35:46 +08:00
CJ Pais
0c8358899f
use blocking for handy keys (#881) 2026-02-23 11:18:47 +08:00
CJ Pais
a5c3f88ace
Update PR template with feature freeze notice
Added a warning about feature freeze and prioritization of bug fixes.
2026-02-20 23:42:48 +08:00
CJ Pais
74951cfca4 release v0.7.7 2026-02-20 13:25:25 +08:00
CJ Pais
4fcc974ab7 Merge branch 'main' of github.com:cjpais/Handy 2026-02-20 13:25:04 +08:00
CJ Pais
f367353752
fix handy-keys not firing when in the ui (#856) 2026-02-20 13:24:47 +08:00
CJ Pais
3e140e53b2 upgrade handy-keys 2026-02-20 13:18:51 +08:00
Phuoc Thinh Vu
15fbc47f5a
fix(nix): update bunDeps outputHash (#853) 2026-02-19 04:03:44 -08:00
CJ Pais
e624a45264 toast if exists 2026-02-19 17:26:14 +08:00
CJ Pais
2cf5effef3 add translations + fix bindings 2026-02-19 17:09:22 +08:00
Pierre Carru
b90077b228
Add "external script" paste method (#638)
* feat(linux): add "external script" paste method

* feat(i18n): external script translation for fr, de, it
2026-02-19 17:07:16 +08:00
Mathieu Dupuis
f8ee7fce7c
feat: add z.ai post-process provider (#849)
Co-authored-by: Mathieu Dupuis <mathieu.dupuis@moov.ai>
2026-02-19 16:54:36 +08:00
CJ Pais
3c0fb95185
drain audio (#838) 2026-02-19 10:32:30 +08:00
MaximilianGaedig
cbc80802cb
fix: update nix hash for dependencies (#842) 2026-02-17 22:13:10 +08:00
CJ Pais
58b95c5c95 release v0.7.6 2026-02-17 13:02:48 +08:00
Anatoliy Guskov
133c50c6d4
feat: add CLI parameters for linux (#792)
* feat: add CLI parameters for Linux (--start-hidden, --no-tray, --toggle-transcription, --debug)

Add command-line interface using clap for better Linux desktop integration:
- --start-hidden: launch without showing the main window
- --no-tray: launch without system tray icon (closing window quits app)
- --toggle-transcription: toggle recording on/off on a running instance
  via tauri_plugin_single_instance
- --debug: enable debug mode with Trace-level logging (runtime-only)

Extract toggle_transcription() from signal_handle.rs into a reusable
function shared between SIGUSR2 handler and CLI single-instance callback.

Update CLAUDE.md and README.md with CLI documentation including setup
instructions for GNOME, KDE Plasma, Sway/i3, and Hyprland.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* add cancel and post processs

* cleanup

* format

* docs

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-17 12:48:43 +08:00
Chirag Agggarwal
0cb8ab2162
feat: implement structured outputs for post-processing providers (#706)
* feat: implement structured outputs for Cerebras, OpenRouter, OpenAI, and Apple Intelligence

- Add structured output support with JSON schema in llm_client.rs
- Update actions.rs to use system prompt + user content approach
- Remove legacy ${output} variable substitution for supported providers
- Update Apple Intelligence Swift code to accept system prompts
- All providers now use consistent structured output format
- Remove duplicate check_apple_intelligence_availability function

* wip changes

* fix(structured-outputs): address PR #706 review comments

- Add settings migration to sync supports_structured_output field for existing providers
- Fix fallback behavior: structured output failures now fall through to legacy mode
- Clone api_key to prevent ownership issues in fallback path
- Clean up build_system_prompt(): remove  placeholder entirely
  (instead of replacing with 'the user's message' which reads awkwardly)
- Add warn import from log crate

* refactor(structured-outputs): apply best practice improvements

- Optimize settings migration: use single match instead of double iteration
- Add TRANSCRIPTION_FIELD constant to replace magic strings
- Keep Apple Intelligence behavior unchanged (no API fallback for privacy)

Addresses code review feedback on PR #706:
1. More efficient provider lookup in ensure_post_process_defaults()
2. Eliminates hardcoded 'transcription' string in JSON parsing
3. Maintains privacy-first approach for Apple Intelligence

* fix groq output

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-17 12:14:00 +08:00
CJ Pais
83e6f5c492
support moonshine v2 (#837)
* support moonshine v2

* format

* add translations for models
2026-02-17 11:44:10 +08:00
Ari
203ba1dbc2
feat(linux): add SIGUSR1 signal for transcribe_with_post_process (#759)
* feat(linux): add SIGUSR1 signal for transcribe_with_post_process

Register SIGUSR1 alongside SIGUSR2 in the signal handler so Linux
users can trigger transcription with post-processing via system
signals (e.g. `pkill -SIGUSR1 -x handy`). This mirrors the existing
SIGUSR2 toggle pattern and maps to the `transcribe_with_post_process`
action already present in ACTION_MAP.

Closes #758

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* readme

* format

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-16 22:41:33 +08:00
johnpyp
7fdde63460
fix: transcription lock-up race condition & add small debounce (#824)
* fix: add TranscriptionState to prevent race conditions & add debounce

* refactor(transcription): replace state machine with actor coordinator

* some cleanup

* format

* minor cleanup

* format

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-16 22:18:50 +08:00
CJ Pais
dc2077431a add back lang 2026-02-16 21:14:42 +08:00
CJ Pais
e2a8008274 push lock 2026-02-16 17:26:58 +08:00
Sami Ansari
3b88717091
fix(nix): address PR #778 review comments (#800)
- Replace patchShebangs with targeted substituteInPlace for tsc/vite
  shebangs, pointing them to bun instead of node
- Use `bun run build` instead of `${pkgs.bun}/bin/bun run build`
  since bun is already in nativeBuildInputs
- Remove nodejs from nativeBuildInputs (no longer needed)
- Add comment explaining why doCheck is disabled
2026-02-13 08:41:25 +08:00
Brandon Chen
cc477a310a
feat(i18n): add Traditional Chinese (zh-TW) locale (#796)
* feat(i18n): add Traditional Chinese (zh-TW) locale

* style(i18n): clarify zh as Simplified Chinese and format languages.ts

* tweak

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-12 18:19:28 +08:00
Phuoc Thinh Vu
336ccffcc7
fix(nix): fix ALSA mismatch, add GStreamer plugins, and repair UI environment (#787)
- Update `flake.lock` to synchronize `alsa-lib` and `glibc` versions, resolving a runtime `dlopen` crash when loading the PipeWire plugin.
  - Add `gstreamer`, `gst-plugins-base`, `good`, `bad`, and `ugly` to both `buildInputs` (package) and `devShell` to support WebKitGTK audio/video playback (resolving missing `appsink`/`autoaudiosink`).
  - Set `GST_PLUGIN_SYSTEM_PATH_1_0` in both environments so GStreamer can locate the plugins at runtime.
  - Manually set `XDG_DATA_DIRS` in `devShell` to include `gsettings-desktop-schemas` and `gtk3` schemas, fixing UI scaling, theming, and missing asset issues during development.

Co-authored-by: Thinh Vu <phuocthinhvu@gmail.com>
2026-02-11 21:34:03 +08:00
CJ Pais
43bc2373ef
Revert "feat: add portable ZIP archives for Windows releases (#753)" (#788)
This reverts commit 6f3fd9babc.
2026-02-11 21:13:32 +08:00
CJ Pais
36c29b6628 release v0.7.5 2026-02-11 20:29:33 +08:00
suuuehgi
eafc74a91e
fix: Apply DMABUF workaround on all Linux systems (#789)
The previous implementation only applied the workaround on X11 sessions,
leaving Wayland users affected by WebkitGTK DMABUF crashes. This affects
various GPU configurations (at least Intel and NVIDIA) on both X11 and Wayland.

This change applies the workaround unconditionally on Linux, ensuring
the app doesn't crash on affected systems while having minimal performance
impact.

Related: https://github.com/tauri-apps/tauri/issues/9394

Co-authored-by: suuuehgi <>
2026-02-11 20:24:30 +08:00
CJ Pais
7db91f5f92
try minimal fix (#781) 2026-02-11 19:52:42 +08:00
Phuoc Thinh Vu
b02873dab5
feat(linux): Add option to select typing tool (#760)
* feat(linux): Add option to select typing tool

 - Added a Linux-only typing tool setting shown for direct paste, with a new dropdown in advanced settings.
 - Wired new typing tool setting through settings store, bindings, and Tauri commands.
 - Added typing tool enum/defaults and selection handling in Linux clipboard direct typing.
 - Added translations for the new typing tool setting across locales.

* fix compilation on macos

* format

* only list available tools

* format

---------

Co-authored-by: Thinh Vu <phuocthinhvu@gmail.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-11 15:00:29 +08:00
CJ Pais
d70d076bdc release v0.7.4 2026-02-11 11:38:14 +08:00
CJ Pais
624579e636
Support RCtrl/etc (#782) 2026-02-11 11:37:38 +08:00
sasha
bf2a59f5ef
feat: add configurable auto-submit after transcription paste (#765)
* feat: add configurable auto-submit after transcription paste

Add an Advanced output setting that can send Enter, Ctrl+Enter, or Cmd+Enter after text insertion so Handy works smoothly with different editor and agent submit shortcuts. This keeps the behavior opt-in, persists it in settings, and adds focused Rust tests for defaults and paste auto-submit decision logic.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: simplify auto submit configuration UX

Replace the auto-submit toggle and key dropdown with a single dropdown that includes an Off state, so output behavior is clearer and faster to configure. Clarify Meta-key behavior by showing Cmd+Enter on macOS and Super+Enter on Windows/Linux, with matching localized copy.

Co-authored-by: Cursor <cursoragent@cursor.com>

* use bindings generated on macos

* and translations.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-11 10:55:31 +08:00
Shehab Tarek
6f3fd9babc
feat: add portable ZIP archives for Windows releases (#753)
* 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>
2026-02-11 10:35:43 +08:00
Sami Ansari
c34e7d584b
fix(nix): build from source instead of wrapping AppImage (#778)
* 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>
2026-02-11 08:47:39 +08:00
Bastian
9ec4f1841b
fix(linux): improve Wayland startup stability (#769)
* feat: add configurable custom audio feedback sounds

* fix(linux): improve Wayland startup stability

* add dep for layer shell

* fix(linux): avoid layer-shell init on KDE Wayland

* chore(linux): realign startup-fix branch with main baseline

* fix(linux): avoid layer-shell init on KDE Wayland

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
Co-authored-by: Bastian (BaM) <git@noxware.de>
2026-02-11 08:47:26 +08:00
CJ Pais
cba3b71b8d add dep for layer shell 2026-02-10 21:50:45 +08:00
CJ Pais
6a099fb873 release v0.7.3 2026-02-10 12:05:37 +08:00
Victor Navarro
f2c306eab6
Add show tray icon setting (#667)
* feat: add show tray icon setting

Allow hiding system tray icon via Settings > Advanced.
When hidden, closing window quits app instead of hiding.

* i8n

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-10 10:39:35 +08:00
Alex Pantechovskis
ea4b270f85
feat: add "Unload Model" in tray (#731)
* feat: add "Unload Model" in tray

* gray out "unload model" when model not loaded

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-10 09:55:46 +08:00
Phuoc Thinh Vu
14db1791d5
fix: missing dependency for flake.nix (#751)
* fix: missing dependency for flake.nix

* fix formatting

* remove bindings.ts changes

---------

Co-authored-by: Thinh Vu <phuocthinhvu@gmail.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-10 09:34:33 +08:00
Martin Kleine
647ccab7f8
fix(ci): install gtk-layer-shell runtime package for Ubuntu builds (#752)
* fix(ci): install gtk-layer-shell runtime package for Ubuntu builds

* docs: update runtime dependency table formatting.

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-10 09:31:18 +08:00
CJ Pais
f10cdd3d17 format 2026-02-09 22:07:53 +08:00
Martin Kleine
306bcb0d52
docs: clarify Linux gtk-layer-shell runtime requirements (#748) 2026-02-09 16:12:00 +08:00
Anton Sotkov
a9024d07bc
fix: bottom overlay positioned partially off-screen (#543) 2026-02-09 14:35:08 +08:00
CJ Pais
4c9c200709
Add support for SenseVoice (#745)
* Add support for sense voice.

* format
2026-02-09 12:15:42 +08:00
Anton Sotkov
82d5c759ad
Add “Processing…” overlay state when post-processing (#740)
* feat: add “Processing…” overlay state

* format

* missing translations

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-09 10:36:00 +08:00
Hoss
a4999164ae
feat(models): add opt-in custom Whisper model discovery (#622)
* feat(models): auto-discover custom Whisper models in models directory

Enable automatic discovery of custom GGML-format Whisper models (.bin files)
placed in the models directory, so users don't need to modify source code
to use their own fine-tuned models.

Backend changes:
- Add discover_custom_whisper_models() to scan for .bin files
- Generate display names from filenames (e.g., "my-model" → "My Model")
- Skip predefined model filenames to avoid duplicates
- Add 3 unit tests for discovery logic

Frontend changes:
- Split model dropdown into 3 sections: Custom, Downloaded, Downloadable
- Add collapsible section for downloadable models to reduce clutter
- Add max-height with scroll for long model lists
- Add "Custom" badge for user-provided models

* feat(models): make custom Whisper model discovery opt-in

[why] Address maintainer concern about support burden from community
models. Custom models should be a power-user feature, not enabled by
default.

[how] Add custom_models_enabled setting (default: false) in Debug
settings. Discovery only runs when enabled. Models show "Not officially
supported" messaging. Documentation updated with enable steps.

* feat(models): add is_custom field and integrate custom models with new UI

[why]
PR review requested an explicit is_custom field instead of inferring
custom status from url === null. Custom models also need proper
integration with the new models settings page from PR #478.

[how]
- Add is_custom: bool to ModelInfo struct, set true on discovered models
- Change discover_custom_whisper_models signature from &PathBuf to &Path
- Use 0.0 sentinel scores so UI hides score bars for custom models
- Add "Custom Models" section to ModelsSettings with 3-way model split
- Show "Custom" badge in ModelCard and ModelDropdown
- Hide language/translation tags when supported_languages is empty
- Remove custom models from available_models on delete instead of
  just marking as not downloaded (they have no re-download URL)
- Update tests with new fields and assertions

* chore(i18n): add custom model translation keys to all locales

[why]
Custom model feature introduces 5 new translation keys that need
to be present in all 15 non-English locales for CI to pass.

[how]
Add English placeholder values for: customModelDescription,
modelSelector.custom, settings.models.customModels,
settings.debug.customModels.label, settings.debug.customModels.description

* fix(models): keep language filter visible when no models match

[why]
The language filter was inside a conditionally rendered section
that disappeared when no downloaded models matched the selected
language, leaving the user stuck with no way to change the filter.

[how]
Always render the "Your Models" header row with the language filter,
only conditionally render the model cards below it.

* docs: fix custom models section reference in README

Model selector → Models settings page.

* fix(models): apply custom models toggle immediately without restart

[why]
Two bugs reported in PR review: (1) app breaks on restart when a
custom model was selected and the toggle is disabled — selected_model
still points to the missing model, causing "Model not found" error.
(2) Custom models remain visible in the UI after toggle-off because
the in-memory model list is never updated and no event is emitted.

[how]
- Add remove_custom_models() and add_custom_models() to ModelManager
  for runtime mutation of the available_models mutex
- On disable: reset selected_model to empty if it's a custom model,
  then remove custom models from the in-memory list
- On enable: run discover_custom_whisper_models against the mutex
- Emit model-state-changed event so the frontend refreshes immediately

* chore(i18n): remove "restart required" from custom model descriptions

Toggle now takes effect immediately, so the restart sentence
is inaccurate. Updated all 16 locales and README instructions.

* fix(models): clear stale model selection on startup

[why]
If a custom model file is deleted from disk while it's the selected
model, the app gets stuck on "Loading..." forever on next launch
because the model ID is not in available_models but
auto_select_model_if_needed only checked for empty string.

[how]
Validate that selected_model exists in available_models before
accepting it. If not found, clear the selection so auto-select
picks a valid downloaded model.

* remove toggle and clean up

* format

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
2026-02-09 10:15:45 +08:00