voice-vibecoder 2.2.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.
Files changed (42) hide show
  1. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/CHANGELOG.md +3 -0
  2. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/PKG-INFO +1 -1
  3. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/pyproject.toml +1 -1
  4. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/__init__.py +1 -1
  5. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/claude.py +3 -0
  6. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/server.py +3 -0
  7. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/agent_task.py +5 -1
  8. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/definitions.py +9 -3
  9. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/dispatch.py +1 -0
  10. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/.github/workflows/ci.yml +0 -0
  11. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/.github/workflows/release.yml +0 -0
  12. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/.gitignore +0 -0
  13. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/LICENSE +0 -0
  14. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/README.md +0 -0
  15. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/app.py +0 -0
  16. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/index.html +0 -0
  17. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/app_config.py +0 -0
  18. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/audio.py +0 -0
  19. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/cli_serve.py +0 -0
  20. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/__init__.py +0 -0
  21. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/cursor.py +0 -0
  22. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/code_providers/registry.py +0 -0
  23. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/config.py +0 -0
  24. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/instances.py +0 -0
  25. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/session.py +0 -0
  26. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/__init__.py +0 -0
  27. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/file_tree.py +0 -0
  28. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/tools/handlers.py +0 -0
  29. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/__init__.py +0 -0
  30. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/callbacks.py +0 -0
  31. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/diff_view.py +0 -0
  32. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/help_modal.py +0 -0
  33. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/panels.py +0 -0
  34. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/screen.py +0 -0
  35. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/setup.py +0 -0
  36. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/state.py +0 -0
  37. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/styles.py +0 -0
  38. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/update_modal.py +0 -0
  39. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/ui/wizard.py +0 -0
  40. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
  41. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/voice_providers/openai.py +0 -0
  42. {voice_vibecoder-2.2.0 → voice_vibecoder-2.3.0}/src/voice_vibecoder/worktrees.py +0 -0
@@ -2,6 +2,9 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v2.3.0 (2026-02-19)
6
+
7
+
5
8
  ## v2.2.0 (2026-02-19)
6
9
 
7
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voice-vibecoder
3
- Version: 2.2.0
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.2.0"
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"
@@ -3,7 +3,7 @@
3
3
  A voice-controlled coding assistant using OpenAI Realtime API + Claude Code.
4
4
  """
5
5
 
6
- __version__ = "2.2.0"
6
+ __version__ = "2.3.0"
7
7
 
8
8
  from voice_vibecoder.app_config import VoiceConfig
9
9
  from voice_vibecoder.ui.screen import VoiceCodingScreen
@@ -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 descriptive session names (e.g. 'jira-research', 'ci-status', 'architecture-review'). "
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": "Descriptive session name (e.g. 'jira-research'). Auto-generated if omitted.",
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(
File without changes
File without changes