python-voiceio 0.3.6__tar.gz → 0.3.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_voiceio-0.3.6/python_voiceio.egg-info → python_voiceio-0.3.7}/PKG-INFO +1 -1
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/pyproject.toml +2 -2
- {python_voiceio-0.3.6 → python_voiceio-0.3.7/python_voiceio.egg-info}/PKG-INFO +1 -1
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/python_voiceio.egg-info/entry_points.txt +1 -1
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_robustness.py +10 -0
- python_voiceio-0.3.7/voiceio/__init__.py +1 -0
- python_voiceio-0.3.7/voiceio/__main__.py +3 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/cli.py +59 -0
- python_voiceio-0.3.6/voiceio/__init__.py +0 -1
- python_voiceio-0.3.6/voiceio/__main__.py +0 -3
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/LICENSE +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/README.md +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/python_voiceio.egg-info/SOURCES.txt +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/python_voiceio.egg-info/dependency_links.txt +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/python_voiceio.egg-info/requires.txt +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/python_voiceio.egg-info/top_level.txt +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/setup.cfg +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_app_wiring.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_autocorrect.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_backend_probes.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_clipboard_read.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_commands.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_config.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_corrections.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_fallback.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_health.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_hints.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_history.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_ibus_typer.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_llm.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_llm_api.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_numbers.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_platform.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_postprocess.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_prebuffer.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_prompt.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_recorder_integration.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_streaming.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_transcriber.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_tts.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_vad.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_vocabulary.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/tests/test_wordfreq.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/app.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/autocorrect.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/backends.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/clipboard_read.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/commands.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/config.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/corrections.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/demo.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/feedback.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/health.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hints.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/history.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hotkeys/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hotkeys/base.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hotkeys/chain.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hotkeys/evdev.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hotkeys/pynput_backend.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/hotkeys/socket_backend.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/ibus/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/ibus/engine.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/llm.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/llm_api.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/models/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/models/silero_vad.onnx +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/numbers.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/pidlock.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/platform.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/postprocess.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/prompt.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/recorder.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/service.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/sounds/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/sounds/commit.wav +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/sounds/start.wav +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/sounds/stop.wav +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/streaming.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/transcriber.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tray/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tray/_icons.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tray/_indicator.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tray/_pystray.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/base.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/chain.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/edge_engine.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/espeak.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/piper_engine.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/tts/player.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/__init__.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/base.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/chain.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/clipboard.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/ibus.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/pynput_type.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/wtype.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/xdotool.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/typers/ydotool.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/vad.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/vocabulary.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/wizard.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/wordfreq.py +0 -0
- {python_voiceio-0.3.6 → python_voiceio-0.3.7}/voiceio/worker.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-voiceio"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.7"
|
|
8
8
|
description = "Speak → text, locally, instantly."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -50,7 +50,7 @@ Issues = "https://github.com/Hugo0/voiceio/issues"
|
|
|
50
50
|
Changelog = "https://github.com/Hugo0/voiceio/releases"
|
|
51
51
|
|
|
52
52
|
[project.scripts]
|
|
53
|
-
voiceio = "voiceio.cli:
|
|
53
|
+
voiceio = "voiceio.cli:_entry_point"
|
|
54
54
|
# Legacy aliases (prefer: voiceio toggle/doctor/setup/test)
|
|
55
55
|
voiceio-toggle = "voiceio.cli:_cmd_toggle"
|
|
56
56
|
voiceio-doctor = "voiceio.cli:_cmd_doctor_legacy"
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"""Tests for robustness features: stream health, tray watchdog, audio backoff."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
+
import sys
|
|
4
5
|
import threading
|
|
5
6
|
import time
|
|
6
7
|
from unittest.mock import MagicMock, patch
|
|
7
8
|
|
|
8
9
|
import numpy as np
|
|
10
|
+
import pytest
|
|
9
11
|
from voiceio.config import Config
|
|
10
12
|
|
|
11
13
|
|
|
@@ -530,10 +532,18 @@ class TestTrayWatchdog:
|
|
|
530
532
|
# 9. Boot-race and typer re-probe (regression tests for 0.3.6 fix)
|
|
531
533
|
# ===========================================================================
|
|
532
534
|
|
|
535
|
+
_linux_only = pytest.mark.skipif(
|
|
536
|
+
not sys.platform.startswith("linux"),
|
|
537
|
+
reason="Boot-race scenario is Linux-specific "
|
|
538
|
+
"(macOS/Windows detect display server from sys.platform)",
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
|
|
533
542
|
class TestBootRaceAndReProbe:
|
|
534
543
|
"""Tests for the fix where platform.detect's lru_cache froze a stale
|
|
535
544
|
display=unknown result at boot, defeating all re-probe logic."""
|
|
536
545
|
|
|
546
|
+
@_linux_only
|
|
537
547
|
def test_redetect_clears_lru_cache(self):
|
|
538
548
|
"""_redetect_platform must call cache_clear so env changes take effect."""
|
|
539
549
|
from voiceio.app import _redetect_platform
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.7"
|
|
@@ -1092,3 +1092,62 @@ def _cmd_doctor_legacy() -> None:
|
|
|
1092
1092
|
parser = argparse.ArgumentParser(prog="voiceio-doctor")
|
|
1093
1093
|
parser.add_argument("--fix", action="store_true", help="Attempt to auto-fix issues")
|
|
1094
1094
|
_cmd_doctor(parser.parse_args())
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
def _entry_point() -> None:
|
|
1098
|
+
"""PyInstaller entry point.
|
|
1099
|
+
|
|
1100
|
+
On Linux/macOS the console_scripts wrapper that setuptools generates
|
|
1101
|
+
from ``project.scripts`` calls ``main()`` directly, so module-level
|
|
1102
|
+
code here never runs. On Windows we ship a PyInstaller bundle that
|
|
1103
|
+
runs ``cli.py`` as ``__main__`` — without this wrapper, the exe would
|
|
1104
|
+
load all definitions and exit silently (which is exactly what users
|
|
1105
|
+
reported: "installed, clicked, nothing happened").
|
|
1106
|
+
|
|
1107
|
+
This wrapper also catches any unhandled exception and writes it to
|
|
1108
|
+
``crash.log`` before exiting, so a crash before logging is configured
|
|
1109
|
+
still leaves a diagnostic trail. On Windows consoles we pause so the
|
|
1110
|
+
cmd.exe window stays open long enough to read the error.
|
|
1111
|
+
"""
|
|
1112
|
+
try:
|
|
1113
|
+
main()
|
|
1114
|
+
except SystemExit:
|
|
1115
|
+
raise
|
|
1116
|
+
except BaseException:
|
|
1117
|
+
import traceback
|
|
1118
|
+
tb = traceback.format_exc()
|
|
1119
|
+
# Best-effort crash log: write to the standard log dir, and also
|
|
1120
|
+
# stderr. Use a fresh import path in case config import itself
|
|
1121
|
+
# was the thing that crashed.
|
|
1122
|
+
try:
|
|
1123
|
+
import os
|
|
1124
|
+
from pathlib import Path
|
|
1125
|
+
if sys.platform == "win32":
|
|
1126
|
+
log_dir = Path(os.environ.get("LOCALAPPDATA", Path.home())) / "voiceio" / "logs"
|
|
1127
|
+
else:
|
|
1128
|
+
log_dir = Path.home() / ".local" / "state" / "voiceio"
|
|
1129
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
1130
|
+
crash_path = log_dir / "crash.log"
|
|
1131
|
+
with open(crash_path, "a", encoding="utf-8") as f:
|
|
1132
|
+
import datetime
|
|
1133
|
+
f.write(f"\n===== {datetime.datetime.now().isoformat()} =====\n")
|
|
1134
|
+
f.write(f"argv: {sys.argv}\n")
|
|
1135
|
+
f.write(f"platform: {sys.platform}\n")
|
|
1136
|
+
f.write(tb)
|
|
1137
|
+
print(f"\n[voiceio crashed — wrote traceback to {crash_path}]",
|
|
1138
|
+
file=sys.stderr)
|
|
1139
|
+
except Exception:
|
|
1140
|
+
pass # absolute last-resort: nothing we can do
|
|
1141
|
+
print(tb, file=sys.stderr)
|
|
1142
|
+
# On Windows, keep the console window open so the user can read
|
|
1143
|
+
# the error instead of watching cmd.exe flash and close.
|
|
1144
|
+
if sys.platform == "win32" and sys.stdin is not None and sys.stdin.isatty():
|
|
1145
|
+
try:
|
|
1146
|
+
input("\nPress Enter to close...")
|
|
1147
|
+
except (EOFError, KeyboardInterrupt):
|
|
1148
|
+
pass
|
|
1149
|
+
sys.exit(1)
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
if __name__ == "__main__":
|
|
1153
|
+
_entry_point()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.6"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|