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.
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/CHANGELOG.md +8 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/PKG-INFO +1 -1
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/pyproject.toml +1 -1
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/__init__.py +1 -1
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/server.py +8 -9
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/.github/workflows/ci.yml +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/.github/workflows/release.yml +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/.gitignore +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/LICENSE +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/README.md +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/app.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/index.html +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/app_config.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/audio.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/cli_serve.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/__init__.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/claude.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/cursor.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/openclaw.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/registry.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/config.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/instances.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/session.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/__init__.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/agent_task.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/definitions.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/dispatch.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/file_tree.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/tools/handlers.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/__init__.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/callbacks.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/diff_view.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/help_modal.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/panels.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/screen.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/setup.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/state.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/styles.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/update_modal.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/ui/wizard.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/gemini.py +0 -0
- {voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/openai.py +0 -0
- {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.
|
|
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.
|
|
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"
|
|
@@ -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", "
|
|
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
|
|
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("
|
|
197
|
-
|
|
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
|
|
317
|
+
if self._session and self._session.text_only:
|
|
319
318
|
return
|
|
320
319
|
self._send({"type": "audio", "data": base64_chunk})
|
|
321
320
|
|
|
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
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/claude.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/cursor.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/openclaw.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/code_providers/registry.py
RENAMED
|
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
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/gemini.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.18.0 → voice_vibecoder-2.19.0}/src/voice_vibecoder/voice_providers/openai.py
RENAMED
|
File without changes
|
|
File without changes
|