Skip to content

Add transcription hook#930

Open
AlexanderYastrebov wants to merge 1 commit intocjpais:mainfrom
AlexanderYastrebov:transcription-hook
Open

Add transcription hook#930
AlexanderYastrebov wants to merge 1 commit intocjpais:mainfrom
AlexanderYastrebov:transcription-hook

Conversation

@AlexanderYastrebov
Copy link

@AlexanderYastrebov AlexanderYastrebov commented Mar 1, 2026

Before Submitting This PR

Please confirm you have done the following:

If this is a feature or change that was previously closed/rejected:

  • I have explained in the description below why this should be reconsidered
  • I have gathered community feedback (link to discussion below)

Human Written Description

Add support for transcription hook - an executable script in app's data directory.

If transcription_hook file exists, Handy runs it passing transcription text via stdin and
uses script stdout as a transcription result.

This approach is a flexible extension point for advanced users
(which nowadays means with access to coding LLM) akin to git hooks.

Here are some possible scenarios:

  • simple transcription modifications
  • a pipeline involving LLM processing, language detection and translation
  • custom paste method (as Handy does nothing if transcription is empty)
  • conditional processing based on the active application waiting for the input
  • quote clipboard content and append transcription

Related Issues/Discussions

See related:

Community Feedback

Testing

Build and ran Handy with both example scripts.

Screenshots/Videos (if applicable)

AI Assistance

  • No AI was used in this PR
  • AI was used (please describe below)

If AI was used:

  • Tools used: Copilot with Claude Sonnet 4.5
  • How extensively: Handle Command stdin in Rust and compose hook example that uses Apple Script.

@AlexanderYastrebov
Copy link
Author

A couple more examples from discussions to keep README small:

Example quoting clipboard content and appending transcription:

#!/bin/bash
clipboard=$(pbpaste)
if [ -n "$clipboard" ]; then
    echo "> $clipboard"
    echo
fi
cat

Example expanding voice commands to actual commands and emoji shortcuts:

#!/usr/bin/env python3
import sys

text = sys.stdin.read()

# Command expansions and emoji shortcuts
replacements = {
    # Commands
    "run unit tests": "pnpm run tests",
    "run tests": "pnpm run tests",
    "run dev": "pnpm run dev",
    "run build": "pnpm run build",
    "git status": "git status",
    "git commit": "git commit",
    # Emojis
    "grin emoji": ":grin:",
    "smile emoji": ":smile:",
    "thumbs up emoji": ":thumbsup:",
    "heart emoji": ":heart:",
    "fire emoji": ":fire:",
    "rocket emoji": ":rocket:",
    "eyes emoji": ":eyes:",
    "party emoji": ":tada:",
}

# Strip punctuation for lookup
lookup_text = text.strip().lower().rstrip('.,!?;:')
sys.stdout.write(replacements.get(lookup_text, text))

@AlexanderYastrebov
Copy link
Author

AlexanderYastrebov commented Mar 1, 2026

As a possible future extension I have the following idea: Handy supports multiple hotkeys and the hotkey used to capture transcription is passed to the script via environment variable or an argument - this way script may perform different actions based on the hotkey.

}
};

let transcription_hook = app_data_dir.join("transcription_hook");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is moving forward it might be better to reserve dedicated folder hooks/post_transcription

thukabjj added a commit to thukabjj/Handy that referenced this pull request Mar 2, 2026
- PR cjpais#477: Graceful handling when no microphone is connected
  - Validate device config before spawning worker thread
  - Use HandyError with user-friendly messages and recovery suggestions

- PR cjpais#930: Transcription hook for external script processing
  - Add transcription_hook_enabled and transcription_hook_path settings
  - Pipe transcription through external scripts for custom processing

- PR cjpais#814: Secure API key storage in OS keychain
  - Add keyring module for macOS Keychain, Windows Credential Manager, Linux Secret Service
  - Commands: set_api_key, get_api_key, delete_api_key, get_masked_api_key

- PR cjpais#455: Text replacements with regex and magic commands
  - Support literal and regex pattern matching
  - Magic commands: [date], [time], [datetime]
  - Import/export functionality for replacement rules

- PR cjpais#851: Per-entry post-process button for history
  - Retroactively post-process transcription history entries
  - Store post-processed text and prompt used

- PR cjpais#618: Wake-word detection for Active Listening trigger
  - Transcript-based wake phrase detection
  - Configurable trigger actions, cooldown, and threshold
Add support for transcription hook - an executable script in app's data directory.

If `transcription_hook` file exists, Handy runs it passing transcription text via stdin and
uses script stdout as a transcription result.

This approach is a flexible extension point for advanced users
(which nowadays means with access to coding LLM) akin to git hooks.

Here are some possible scenarios:
* simple transcription modifications
* a pipeline involving LLM processing, language detection and translation
* custom paste method (as Handy does nothing if transcription is empty)
* conditional processing based on the active application waiting for the input

See related:
* cjpais#168
* cjpais#162
* cjpais#916
* cjpais#911
* cjpais#834
* cjpais#847
* cjpais#833
* cjpais#662
* cjpais#601
* cjpais#335
* cjpais#739
* cjpais#638
* cjpais#455
* cjpais#157
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant