Skip to main content

Moonsway TTS

Moonsway TTS is a small on-device push-to-toggle dictation CLI for Sway. Moonshine Voice transcribes the microphone locally, and each finalized transcript line is typed into the keyboard-focused application with wtype or xdotool.

Partial hypotheses are deliberately not typed. They can change while you speak, so inserting them would require destructive Backspace-based rewrites.

Requirements

  • Linux with Sway and virtual-keyboard-unstable-v1 support
  • wtype
  • xdotool
  • Python 3.12+
  • A working PortAudio input device

On Arch Linux, install the external system dependencies with:

sudo pacman -S portaudio wtype xdotool

The selected Moonshine model is downloaded on the first daemon launch and reused from the local cache. No API key or hosted speech service is used.

Installation

Run without installing:

uvx moonsway-tts --help

Install as a tool with uv:

uv tool install moonsway-tts

Install with pip:

pip install moonsway-tts

Or use my Forgejo PyPI instance:

uvx --index https://forgejo.chrispaganon.com/api/packages/chris-paganon/pypi/simple/ moonsway-tts --help
uv tool install --index https://forgejo.chrispaganon.com/api/packages/chris-paganon/pypi/simple/ moonsway-tts
pip install --index-url https://forgejo.chrispaganon.com/api/packages/chris-paganon/pypi/simple/ moonsway-tts

Usage

Start the long-running daemon:

moonsway-tts daemon

The model loads immediately, but the microphone remains stopped until a control command is sent. Stopping dictation closes the microphone capture stream, so the idle daemon does not reserve the input device and other applications can continue using it. Starting dictation opens the stream again without reloading the model. From another terminal:

moonsway-tts status
moonsway-tts start
moonsway-tts toggle
moonsway-tts stop

Each completed Moonshine line is trimmed and followed by one space. Before inserting it, Moonsway queries Sway for the focused surface and automatically uses wtype for native Wayland applications or xdotool for XWayland applications. Both backends read the text from standard input without a shell.

This avoids the temporary-keymap incompatibility that can turn wtype text into numbers or control keys in XWayland applications, including some Electron applications. It does not copy dictated text through the clipboard.

Use --separator to change the suffix and --wtype-delay to change the delay between text-injection key events for both backends:

moonsway-tts daemon --separator $'\n' --wtype-delay 2

The default delay is 1 ms because wtype 0.4 rejects a zero delay. At startup, the daemon checks that swaymsg, wtype, and xdotool are available. Inspect all model, language, logging, and socket options with:

moonsway-tts --help
moonsway-tts daemon --help
moonsway-tts --version

Sway configuration

Install Moonsway TTS as a tool, then locate its executable:

uv tool install moonsway-tts
uv tool dir --bin

Add the executable path reported by uv tool dir --bin to the Sway configuration. For the usual uv tool location:

set $moonsway_tts /home/you/.local/bin/moonsway-tts
exec $moonsway_tts daemon
bindsym --release --no-repeat F9 exec $moonsway_tts toggle

Replace /home/you and F9 as needed. An unmodified key released before the command runs avoids physical Ctrl, Shift, Alt, or Super state interfering with injected text.

Do not run another microphone dictation service on the same binding. If replacing Handy, remove or comment out its autostart and binding. Reloading a Sway configuration adds the binding, but Sway's ordinary exec is intended for session startup; start the daemon in a terminal for the current session or restart the Sway session.

Text goes to the keyboard-focused field, not necessarily the window under the mouse pointer. Avoid moving focus or the caret until the finalized line has been inserted.

Development

Clone the repository and install the locked environment:

git clone https://codeberg.org/chris-paganon/moonsway-tts.git
cd moonsway-tts
uv sync --locked

Run the quality checks:

uv run ruff check .
uv run ruff format --check .
uv run mypy src tests
uv run pytest -q

Metadata

Release files for moonsway-tts 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for moonsway-tts 0.2.0
File Size Uploaded
moonsway_tts-0.2.0.tar.gz 9.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for moonsway-tts 0.2.0
File Interpreter ABI Platform
moonsway_tts-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.2 kB

Release files / moonsway_tts-0.2.0.tar.gz

Download URL moonsway_tts-0.2.0.tar.gz
Size 9.6 kB
Tags Source
SHA-256 checksum
How to use checksums
2f84320fb81af6f291c31425117a4745c5488e837098d4dd7fc1e23679fa7d0e
BLAKE2b-256 checksum
How to use checksums
155233194be024de842849d1dcedd45a54c348f03ffcbc0cb07f13b148382d46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / moonsway_tts-0.2.0-py3-none-any.whl

Download URL moonsway_tts-0.2.0-py3-none-any.whl
Size 12.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
58143f1b462b6ec345123404a5dca1f563615ba202c9638c888afdde3faf9d14
BLAKE2b-256 checksum
How to use checksums
57ba71158e985de9149ac2896e5cccfc2528d7730f1689663c9ad3550a02f808
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page