voice-vibecoder 2.1.0__tar.gz → 2.3.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.1.0 → voice_vibecoder-2.3.0}/CHANGELOG.md +6 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/PKG-INFO +1 -1
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/pyproject.toml +1 -1
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/__init__.py +1 -1
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/claude.py +3 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/server.py +3 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/agent_task.py +5 -1
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/definitions.py +9 -3
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/dispatch.py +1 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/panels.py +16 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/.github/workflows/ci.yml +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/.github/workflows/release.yml +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/.gitignore +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/LICENSE +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/README.md +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/app.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/index.html +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/app_config.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/audio.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/cli_serve.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/__init__.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/cursor.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/registry.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/config.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/instances.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/session.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/__init__.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/file_tree.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/handlers.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/__init__.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/callbacks.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/diff_view.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/help_modal.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/screen.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/setup.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/state.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/styles.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/update_modal.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/wizard.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/voice_providers/openai.py +0 -0
- {voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/worktrees.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voice-vibecoder
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.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.3.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"
|
{voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/claude.py
RENAMED
|
@@ -78,6 +78,9 @@ def describe_tool_call(name: str, inp: dict) -> str:
|
|
|
78
78
|
elif name == "WebFetch":
|
|
79
79
|
url = inp.get("url", "")
|
|
80
80
|
return f"\\[WebFetch] {url[:60]}"
|
|
81
|
+
elif name == "ToolSearch":
|
|
82
|
+
query = inp.get("query", "")
|
|
83
|
+
return f"\\[Search tools] {query}" if query else "\\[Search tools]"
|
|
81
84
|
elif name.startswith("mcp__"):
|
|
82
85
|
# MCP tool: mcp__<server>__<tool> → [Server: tool description]
|
|
83
86
|
parts = name.split("__", 2)
|
|
@@ -234,6 +234,7 @@ class WebSocketBridge:
|
|
|
234
234
|
"status": inst.status.value,
|
|
235
235
|
"branch": inst.branch,
|
|
236
236
|
"agentType": inst.agent_type,
|
|
237
|
+
"displayName": inst.display_key,
|
|
237
238
|
})
|
|
238
239
|
# Send buffered output from previous session
|
|
239
240
|
if inst.output_buffer:
|
|
@@ -283,12 +284,14 @@ class WebSocketBridge:
|
|
|
283
284
|
inst = self._session.registry.get_by_id(instance_id) if self._session else None
|
|
284
285
|
branch = inst.branch if inst else ""
|
|
285
286
|
agent_type = inst.agent_type if inst else "claude"
|
|
287
|
+
display_name = inst.display_key if inst else branch
|
|
286
288
|
self._send({
|
|
287
289
|
"type": "instance_status",
|
|
288
290
|
"instanceId": instance_id,
|
|
289
291
|
"status": status.value,
|
|
290
292
|
"branch": branch,
|
|
291
293
|
"agentType": agent_type,
|
|
294
|
+
"displayName": display_name,
|
|
292
295
|
})
|
|
293
296
|
|
|
294
297
|
def _on_tool_call(self, name: str, arguments: dict) -> None:
|
|
@@ -176,7 +176,7 @@ def _handle_send_to_agent(message: str, branch: str | None = None, agent: str |
|
|
|
176
176
|
return f"Sent to {agent_label}."
|
|
177
177
|
|
|
178
178
|
|
|
179
|
-
def _handle_send_to_session(message: str, session_name: str | None = None, agent: str | None = None) -> str:
|
|
179
|
+
def _handle_send_to_session(message: str, session_name: str | None = None, agent: str | None = None, display_name: str | None = None) -> str:
|
|
180
180
|
from voice_vibecoder.tools.dispatch import (
|
|
181
181
|
_default_agent_type, _helper_override,
|
|
182
182
|
_registry, _repo_root,
|
|
@@ -200,6 +200,10 @@ def _handle_send_to_session(message: str, session_name: str | None = None, agent
|
|
|
200
200
|
instance = _registry.get_session_by_name(session_name)
|
|
201
201
|
if not instance:
|
|
202
202
|
instance = _registry.create_session(session_name, agent_type=target_agent)
|
|
203
|
+
# Update display_name if a better one was provided by the LLM
|
|
204
|
+
if display_name and display_name != instance.display_name:
|
|
205
|
+
instance.display_name = display_name
|
|
206
|
+
_registry._save_state()
|
|
203
207
|
|
|
204
208
|
# Update agent type if switching
|
|
205
209
|
resolved_agent = agent or instance.agent_type or target_agent
|
|
@@ -52,9 +52,11 @@ _CORE_TOOLS: list[dict[str, Any]] = [
|
|
|
52
52
|
"Send a NON-CODE task to a session agent. Returns immediately — the agent works in the background. "
|
|
53
53
|
"Use for anything that doesn't change code: research, Jira lookups, CI status, questions, "
|
|
54
54
|
"documentation, planning, analysis, etc. "
|
|
55
|
-
"Use
|
|
55
|
+
"Use short lowercase kebab-case session keys (e.g. 'jira', 'ci-status', 'events'). "
|
|
56
56
|
"Session names are fuzzy-matched — reuse existing sessions for the same topic. "
|
|
57
|
-
"If session_name is omitted, one is auto-generated from the message."
|
|
57
|
+
"If session_name is omitted, one is auto-generated from the message. "
|
|
58
|
+
"Always provide a short, human-friendly display_name in the user's language "
|
|
59
|
+
"(e.g. 'Arrangementer', 'Lønn', 'Jira-oppslag', 'Events', 'Salary')."
|
|
58
60
|
),
|
|
59
61
|
"parameters": {
|
|
60
62
|
"type": "object",
|
|
@@ -65,7 +67,11 @@ _CORE_TOOLS: list[dict[str, Any]] = [
|
|
|
65
67
|
},
|
|
66
68
|
"session_name": {
|
|
67
69
|
"type": "string",
|
|
68
|
-
"description": "
|
|
70
|
+
"description": "Short kebab-case key (e.g. 'events', 'salary'). Auto-generated if omitted.",
|
|
71
|
+
},
|
|
72
|
+
"display_name": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"description": "Human-friendly label shown in the UI (e.g. 'Arrangementer', 'Lønn'). Required.",
|
|
69
75
|
},
|
|
70
76
|
"agent": {
|
|
71
77
|
"type": "string",
|
|
@@ -214,6 +214,7 @@ def handle_tool_call(name: str, arguments: dict[str, Any]) -> str:
|
|
|
214
214
|
arguments.get("message", ""),
|
|
215
215
|
arguments.get("session_name"),
|
|
216
216
|
arguments.get("agent"),
|
|
217
|
+
arguments.get("display_name"),
|
|
217
218
|
)
|
|
218
219
|
elif name == "switch_agent":
|
|
219
220
|
return _handle_switch_agent(
|
|
@@ -93,6 +93,20 @@ class PanelMixin:
|
|
|
93
93
|
except Exception:
|
|
94
94
|
pass
|
|
95
95
|
|
|
96
|
+
def _show_welcome(self) -> None:
|
|
97
|
+
"""Re-show the welcome panel if the grid is empty."""
|
|
98
|
+
try:
|
|
99
|
+
self.query_one("#welcome-panel")
|
|
100
|
+
return # already showing
|
|
101
|
+
except Exception:
|
|
102
|
+
pass
|
|
103
|
+
try:
|
|
104
|
+
grid = self.query_one("#agent-grid", Grid)
|
|
105
|
+
if len(grid.children) == 0:
|
|
106
|
+
grid.mount(Static(self._WELCOME_TEXT, id="welcome-panel"))
|
|
107
|
+
except Exception:
|
|
108
|
+
pass
|
|
109
|
+
|
|
96
110
|
def _create_panels_batch(self, instances: list) -> None:
|
|
97
111
|
"""Create all panels in one mount call for faster startup."""
|
|
98
112
|
if instances:
|
|
@@ -347,5 +361,7 @@ class PanelMixin:
|
|
|
347
361
|
panel_count = len(grid.children)
|
|
348
362
|
if panel_count > 0:
|
|
349
363
|
_apply_grid_size(grid, panel_count, max_columns=3)
|
|
364
|
+
else:
|
|
365
|
+
self._show_welcome()
|
|
350
366
|
except Exception:
|
|
351
367
|
pass
|
|
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.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/cursor.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.1.0 → voice_vibecoder-2.3.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
|
{voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/voice_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.1.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/voice_providers/openai.py
RENAMED
|
File without changes
|
|
File without changes
|