Local speech-to-text for Pi, based on earendil-works/pi-voice.
This fork adds optional hold-Space dictation and configurable model retention, while keeping the original toggle shortcut. Transcripts are inserted into the editor for review; they are not automatically sent to the agent.
The fork's main branch includes Hold Space and model retention:
pi install git:github.com/Zony666/pi-voiceFor a project-local install, add --local.
npm:@earendil-works/pi-voiceis the upstream package, not this fork. Installing it does not install the changes described here. Disable or remove an existing Pi Voice/pi-transcribe installation before loading this fork to avoid duplicate shortcuts, commands, and tools.
For an existing upstream npm installation:
pi remove npm:@earendil-works/pi-voice
pi install git:github.com/Zony666/pi-voiceIf the old installation was project-local, add --local to both commands. For Git-based installations, remove the exact source shown by pi list.
- Start Pi and run
/voice-settings. - Choose your spoken languages, microphone, and a local model. Model downloads require confirmation.
- Leave Voice input mode on Toggle shortcut, or choose Hold Space.
- Leave Keep model loaded on for faster repeated dictation, or turn it off to release memory/VRAM when idle.
| Setting | Default | Behavior |
|---|---|---|
| Voice input mode | Toggle shortcut | Press the shortcut once to start recording, again to stop and transcribe |
| Shortcut | Ctrl+Alt+Z |
Configurable; remains available when Hold Space is enabled |
| Keep model loaded | On | Reuse the same loaded model across takes; Off releases it when idle |
Older settings default to Toggle and model retention On. Changing input mode or the shortcut reloads the extension when settings close. The retention switch applies immediately without a reload.
Enable it in /voice-settings → Voice input mode → Hold Space.
- Hold the space bar in the main editor.
- During cold startup, the widget shows
Preparing speech model… keep holding Space. - Wait for the recording meter before speaking. Hold mode waits for the model to be ready before opening the microphone.
- Release Space to stop recording and insert the transcript into the editor.
- Escape discards recording/transcription. Releasing or cancelling during model preparation prevents that take from opening the microphone.
- Each hold is limited to two minutes.
Short taps remain ordinary spaces. Temporary spaces typed before a hold is recognized are removed without replacing the draft or moving its cursor. Pasted spaces and settings dialogs do not activate recording.
Inspired by OMP's space-hold gesture, this mode recognizes a steady OS auto-repeat cadence. It does not require the terminal to report key-up events:
- A real Space release event stops the hold immediately when available.
- Otherwise, 250ms without another repeated space is treated as release; another key also ends the hold.
- The idle check allows a terminal-input poll turn before deciding, reducing false releases caused by cold native initialization.
- Late repeated spaces from the same hold are drained instead of inserted into the editor.
This is a heuristic, not precise key-up detection. Very slow key-repeat settings or terminal/event-loop stalls may prevent recognition or stop a hold early. If it is unsuitable for your terminal, use Toggle.
Hold Space installs a CustomEditor subclass and may conflict with extensions that also replace the main editor.
Open /voice-settings → Keep model loaded:
- On (default): keep the current model weights in memory/VRAM between recordings and file transcriptions. The same model is loaded on first use and reused afterward.
- Off: unload weights when transcription work is idle. The next use loads them again, trading startup speed for lower idle resource usage.
Turning retention off also releases an already idle model. Active recording/transcription is allowed to finish before unloading. Switching to a different model for transcription or exiting/reloading Pi releases the old weights, regardless of this setting.
Only model weights are retained. Microphone resources and per-take transcription streams are still cleaned up after each take. Retention does not keep the microphone recording in the background.
/voice-settings: configure input mode, model retention, languages, model, Chinese output style, microphone, and shortcut./transcribe: compatibility alias for/voice-settings.transcribe_file: agent tool for transcribing local audio/video files./voice-onboarding: replay setup, available only withPI_VOICE_DEBUG=1.
The /voice command remains reserved for a future voice mode.
By default:
- Settings:
~/.pi/agent/pi-voice.json - Log:
~/.pi/agent/pi-voice.log - Models: Hugging Face cache at
~/.cache/huggingface/hub
On Windows, the default model cache is %USERPROFILE%\.cache\huggingface\hub. A downloaded model can be reused by both the installed extension and a local checkout; it is not stored in the project directory.
PI_CODING_AGENT_DIR overrides the settings/log directory. Hugging Face cache variables such as HF_HUB_CACHE and HF_HOME override the model cache location.
transcribe_file requires the ffmpeg executable to decode audio/video. Decoded audio is limited to 128 MiB (about 35 minutes).
# macOS
brew install ffmpeg
# Debian / Ubuntu
sudo apt install ffmpeg
# Windows
winget install Gyan.FFmpegIf FFmpeg is outside PATH, set PI_VOICE_FFMPEG_PATH before starting Pi. The legacy PI_TRANSCRIBE_FFMPEG_PATH is also supported when the newer variable is unset.
Requires Node.js 22 or newer and a Pi installation available on PATH. CI uses Node 24 on Ubuntu and Windows.
git clone https://github.com/Zony666/pi-voice.git
cd pi-voice
npm ci --ignore-scripts
npm run dev| Command | Purpose |
|---|---|
npm run dev |
Load only this checkout, avoiding other extension registrations |
npm run dev:debug |
Enable detailed logging and /voice-onboarding |
npm run dev:keys |
Load the optional /voice-key-probe terminal-input diagnostic |
npm run check |
Type-check source, tests, and development tools |
npm test |
Type-check and run the regression suite |
Development launchers use pi --no-extensions -e .; they do not permanently install the checkout. They share your existing Pi Voice settings unless you explicitly override PI_CODING_AGENT_DIR.
To inspect your terminal, run npm run dev:keys, then /voice-key-probe in Pi. The probe consumes input and displays press/repeat/release events; Escape exits. Do not type secrets while probing.
For use alongside other extensions, run pi -e . after disabling any other Pi Voice installation. Reload or restart Pi after source changes. Tests do not replace real-terminal and microphone verification.
Detailed Chinese workflow: docs/DEVELOPMENT.zh-CN.md.
mainis this fork's maintained integration branch, including its own features. It does not need to mirror upstream exactly.- New work uses temporary feature branches, merged into
mainafter verification. - The
upstreamremote tracks the original project; a separate upstream-only branch is unnecessary. - Tested releases can be pinned with version tags. No fork release tag has been created yet; the inherited npm-publish workflow is restricted to the original upstream repository.
To merge upstream updates into a clean checkout:
git switch main
git pull --ff-only origin main
git fetch upstream
git merge upstream/main
# Resolve conflicts and commit them if needed.
npm ci --ignore-scripts
npm test
npm run dev # Manually verify Toggle, Hold Space, and model retention.
git push origin mainIf the upstream remote is missing, add it once with git remote add upstream https://github.com/earendil-works/pi-voice.git. Use merges for this published branch rather than rewriting its history with rebases/force pushes.
The old feat/push-to-talk branch has been deleted after its features were merged into main. Branch-qualified installations must migrate: remove the old source shown by pi list and install git:github.com/Zony666/pi-voice instead (preserving --local scope when applicable). Removing the package does not require deleting model files or voice settings.
Legacy settings are read and migrated from pi-transcribe.json when possible. Remove the legacy package before installing this fork:
pi remove git:github.com/earendil-works/pi-transcribe
pi install git:github.com/Zony666/pi-voiceUse --local for project-local installations and the exact installed source if it differs from the example.
MIT. See LICENSE.