claudedo/pyproject.toml
disqualifier 1a593b95fa v0.2.1: earcons — audio feedback tones (eyes-free confirmation)
short confirmation tones on daemon events so the user gets eyes-free "did it hear me?"
feedback without watching the terminal. NOT TTS — short pre-generated .wav beeps.

- audio_out.py — reusable audio-OUT module (the reverse of audio.py's capture, the
  less-tested WSLg direction). three-tier player: paplay-first (a SEPARATE process, so
  it doesn't contend with the sounddevice mic stream on the duplex-flaky WSLg bridge),
  then in-process sounddevice, then powershell.exe SoundPlayer. best-effort per-backend
  volume. plays a wav path and knows nothing about events — v0.3 TTS reuses it.
- sound.py — Earcons: the single event->tone map (wake/accept/no_match/submit) gated by
  [sound] config (master enabled + per-event flags). daemon._handle wiring: an injected
  command plays accept (submit plays submit); no-match / target-missing / unknown-context
  plays no_match; pure daemon-control commands (list/version/…) play nothing.
- sounds/ — committed earcon wavs + generate.py (regen-only). committed (not generated
  at install) so the package is self-contained and a missing tone can never appear.
  packaged via pyproject [tool.setuptools.package-data].
- [sound] config: enabled (master, on), on_wake (OFF by default — bleed/chatty),
  on_accept/on_no_match/on_submit (on), volume (0-1 best-effort), [sound.files] overrides.
- claudedo test-tone — plays each tone, the audio-OUT gate (mirrors test-audio).
- install.sh now also checks RDPSink (audio-out) alongside RDPSource.

INVARIANT: earcons are fire-and-forget on a worker thread and NEVER block or break the
inject path. a missing tone file or dead speaker logs once and is swallowed, never
raised — a broken speaker must never stop "claudedo yes" from injecting.

de-risks the WSLg audio-OUT path that v0.3 TTS-readback will reuse.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-27 18:32:34 -04:00

34 lines
715 B
TOML

[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "claudedo"
version = "0.2.1"
description = "voice-control daemon for claude code (local STT -> tmux send-keys)"
readme = "README.md"
requires-python = ">=3.10"
license = { text = "Proprietary" }
authors = [{ name = "dsql" }]
dependencies = [
"sounddevice>=0.4.6",
"numpy>=1.24",
"faster-whisper>=1.0.0",
"tomli>=2.0; python_version < '3.11'",
]
[project.scripts]
claudedo = "claudedo.__main__:main"
[tool.setuptools]
package-dir = { "" = "src" }
[tool.setuptools.package-data]
"claudedo.sounds" = ["*.wav"]
[tool.setuptools.packages.find]
where = ["src"]
[tool.flake8]
max-line-length = 120