voice-vibecoder 2.18.0__tar.gz → 2.19.0__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.
Files changed (44) hide show
  1. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/CHANGELOG.md +8 -0
  2. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/PKG-INFO +1 -1
  3. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/pyproject.toml +1 -1
  4. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/__init__.py +1 -1
  5. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/server.py +8 -9
  6. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/.github/workflows/ci.yml +0 -0
  7. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/.github/workflows/release.yml +0 -0
  8. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/.gitignore +0 -0
  9. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/LICENSE +0 -0
  10. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/README.md +0 -0
  11. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/app.py +0 -0
  12. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/index.html +0 -0
  13. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/app_config.py +0 -0
  14. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/audio.py +0 -0
  15. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/cli_serve.py +0 -0
  16. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/__init__.py +0 -0
  17. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/claude.py +0 -0
  18. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/cursor.py +0 -0
  19. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/openclaw.py +0 -0
  20. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/registry.py +0 -0
  21. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/config.py +0 -0
  22. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/instances.py +0 -0
  23. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/session.py +0 -0
  24. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/__init__.py +0 -0
  25. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/agent_task.py +0 -0
  26. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/definitions.py +0 -0
  27. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/dispatch.py +0 -0
  28. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/file_tree.py +0 -0
  29. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/handlers.py +0 -0
  30. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/__init__.py +0 -0
  31. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/callbacks.py +0 -0
  32. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/diff_view.py +0 -0
  33. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/help_modal.py +0 -0
  34. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/panels.py +0 -0
  35. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/screen.py +0 -0
  36. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/setup.py +0 -0
  37. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/state.py +0 -0
  38. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/styles.py +0 -0
  39. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/update_modal.py +0 -0
  40. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/wizard.py +0 -0
  41. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
  42. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/gemini.py +0 -0
  43. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/openai.py +0 -0
  44. {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/worktrees.py +0 -0
@@ -2,6 +2,14 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v2.19.0 (2026-02-23)
6
+
7
+ ### Features
8
+
9
+ - Replace audio opt-in with text_only flag in sync_state protocol
10
+ ([`5c428ab`](https://github.com/snokam/voice-vibecoder/commit/5c428ab2c231e91b72fd72dfc3eece6597486ffe))
11
+
12
+
5
13
  ## v2.18.0 (2026-02-23)
6
14
 
7
15
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voice-vibecoder
3
- Version: 2.18.0
3
+ Version: 2.19.0
4
4
  Summary: Olaf The Vibecoder — a voice-controlled coding assistant using OpenAI Realtime API + Claude Code
5
5
  Project-URL: Homepage, https://github.com/snokam/voice-vibecoder
6
6
  Project-URL: Repository, https://github.com/snokam/voice-vibecoder
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "voice-vibecoder"
7
- version = "2.18.0"
7
+ version = "2.19.0"
8
8
  description = "Olaf The Vibecoder — a voice-controlled coding assistant using OpenAI Realtime API + Claude Code"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -3,7 +3,7 @@
3
3
  A voice-controlled coding assistant using OpenAI Realtime API + Claude Code.
4
4
  """
5
5
 
6
- __version__ = "2.18.0"
6
+ __version__ = "2.19.0"
7
7
 
8
8
  from voice_vibecoder.app_config import VoiceConfig
9
9
  from voice_vibecoder.ui.screen import VoiceCodingScreen
@@ -6,9 +6,11 @@ The browser sends/receives JSON frames — never talks to OpenAI directly.
6
6
 
7
7
  Protocol (client -> server):
8
8
  {"type": "auth", "token": "<JWT>"} — must be the first message when auth is enabled
9
- {"type": "sync_state", "audio": true, "ui_commands": true} — full state sync (audio/ui_commands opt in)
9
+ {"type": "sync_state", "ui_commands": true} — full state sync, connects voice provider
10
+ {"type": "sync_state", "text_only": true} — text-only mode: skip voice provider entirely
10
11
  {"type": "audio", "data": "<base64 PCM16 24kHz>"}
11
12
  {"type": "audio.commit"}
13
+ {"type": "text", "text": "..."} — send text (routes via voice or directly to agent)
12
14
  {"type": "update_settings", "settings": {...}} — partial settings update, reconnects provider
13
15
 
14
16
  Protocol (server -> client):
@@ -110,7 +112,6 @@ class WebSocketBridge:
110
112
  self._user_jwt = user_jwt
111
113
  self._messages_task: asyncio.Task | None = None
112
114
  self._ui_commands_enabled = False
113
- self._audio_enabled = False
114
115
 
115
116
  async def run(self) -> None:
116
117
  provider = create_provider(self._settings)
@@ -138,8 +139,8 @@ class WebSocketBridge:
138
139
  # Load saved instances — panels appear dynamically as sessions/instances are created
139
140
  restored = self._session.registry.load_state()
140
141
 
141
- # Don't connect voice provider yet — wait for sync_state with audio: true.
142
- # Text-only clients skip the voice provider entirely.
142
+ # Don't connect voice provider yet — wait for sync_state.
143
+ # Text-only clients (no sync_state) skip the voice provider entirely.
143
144
  self._send({"type": "status", "status": "ready"})
144
145
 
145
146
  try:
@@ -190,12 +191,10 @@ class WebSocketBridge:
190
191
  elif msg_type == "update_settings":
191
192
  await self._handle_settings_update(msg.get("settings", {}))
192
193
  elif msg_type == "sync_state":
193
- # Opt-in flags
194
194
  if msg.get("ui_commands"):
195
195
  self._ui_commands_enabled = True
196
- if msg.get("audio"):
197
- self._audio_enabled = True
198
- # Connect voice provider now (lazy)
196
+ if not msg.get("text_only"):
197
+ # Connect voice provider (skipped for text_only clients)
199
198
  await self._connect_voice_provider()
200
199
  self._send({"type": "status", "status": "syncing"})
201
200
  await self._sync_state_to_frontend()
@@ -315,7 +314,7 @@ class WebSocketBridge:
315
314
  logger.warning("Failed to send WS frame", exc_info=True)
316
315
 
317
316
  def _on_audio(self, base64_chunk: str) -> None:
318
- if not self._audio_enabled:
317
+ if self._session and self._session.text_only:
319
318
  return
320
319
  self._send({"type": "audio", "data": base64_chunk})
321
320