voice-vibecoder 2.24.0__tar.gz → 2.25.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.24.0 → voice_vibecoder-2.25.0}/CHANGELOG.md +19 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/PKG-INFO +1 -1
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/pyproject.toml +1 -1
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/__init__.py +1 -1
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/config.py +6 -3
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/tools/file_tree.py +5 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/tools/handlers.py +14 -0
- voice_vibecoder-2.25.0/tests/test_file_tree.py +25 -0
- voice_vibecoder-2.25.0/tests/test_startup_context.py +28 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/.github/workflows/ci.yml +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/.github/workflows/release.yml +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/.gitignore +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/LICENSE +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/README.md +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/app.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/index.html +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/app_config.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/audio.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/audio_macos.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/cli_serve.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/__init__.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/claude.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/cursor.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/openclaw.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/registry.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/instances.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/server.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/session.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/tools/__init__.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/tools/agent_task.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/tools/definitions.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/tools/dispatch.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/__init__.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/callbacks.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/diff_view.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/help_modal.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/panels.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/screen.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/setup.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/state.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/styles.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/update_modal.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/ui/wizard.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/voice_providers/__init__.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/voice_providers/gemini.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/voice_providers/openai.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/worktrees.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/tests/test_audio_gating.py +0 -0
- {voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/tests/test_session_interrupts.py +0 -0
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v2.25.0 (2026-07-13)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- **session**: Resume conversations with recent history in context
|
|
10
|
+
([`a4a60b2`](https://github.com/snokam/voice-vibecoder/commit/a4a60b214c68e028111d873fc6c1d33f47d93967))
|
|
11
|
+
|
|
12
|
+
- **voice**: Follow the user's language instead of locking to one
|
|
13
|
+
([`b828007`](https://github.com/snokam/voice-vibecoder/commit/b82800721340f96aaaa29ada12276c0466eeca2a))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## v2.24.1 (2026-07-13)
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
- **ui**: Show untracked files in the file tree sidebar
|
|
21
|
+
([`e7a5de7`](https://github.com/snokam/voice-vibecoder/commit/e7a5de72cc8597f1d67df01faf29f42d06edd2bc))
|
|
22
|
+
|
|
23
|
+
|
|
5
24
|
## v2.24.0 (2026-07-13)
|
|
6
25
|
|
|
7
26
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voice-vibecoder
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.25.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.25.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"
|
|
@@ -30,7 +30,8 @@ def _agent_names(enabled: list[str] | None = None) -> str:
|
|
|
30
30
|
|
|
31
31
|
_SYSTEM_INSTRUCTIONS: dict[Language, str] = {
|
|
32
32
|
"no": """\
|
|
33
|
-
Du er Olaf, en hjelpsom stemmeassistent for utviklere. Snakk
|
|
33
|
+
Du er Olaf, en hjelpsom stemmeassistent for utviklere. Snakk norsk som standard, \
|
|
34
|
+
men bytt språk umiddelbart hvis brukeren snakker eller ber om et annet språk. \
|
|
34
35
|
Brukeren skal oppleve en helt vanlig samtale — du bare hjelper. \
|
|
35
36
|
Dette er en talesamtale: svar kort, én til to setninger, med mindre brukeren ber om mer.
|
|
36
37
|
|
|
@@ -84,7 +85,8 @@ Visning:
|
|
|
84
85
|
Spørsmål fra agenten:
|
|
85
86
|
- Still spørsmålet til brukeren. Videresend svaret ordrett via answer_agent_question.""",
|
|
86
87
|
"en": """\
|
|
87
|
-
You are Olaf, a helpful voice assistant for developers.
|
|
88
|
+
You are Olaf, a helpful voice assistant for developers. Speak English by default, \
|
|
89
|
+
but switch immediately if the user speaks or asks for another language. \
|
|
88
90
|
The user should experience a normal conversation — you just help. \
|
|
89
91
|
This is a spoken conversation: keep answers short, one or two sentences, unless the user asks for more.
|
|
90
92
|
|
|
@@ -138,7 +140,8 @@ Views:
|
|
|
138
140
|
Questions from the agent:
|
|
139
141
|
- Ask the user the question. Forward their answer verbatim via answer_agent_question.""",
|
|
140
142
|
"sv": """\
|
|
141
|
-
Du är Olaf, en hjälpsam röstassistent för utvecklare. Tala
|
|
143
|
+
Du är Olaf, en hjälpsam röstassistent för utvecklare. Tala svenska som standard, \
|
|
144
|
+
men byt språk direkt om användaren talar eller ber om ett annat språk. \
|
|
142
145
|
Användaren ska uppleva ett helt vanligt samtal — du bara hjälper. \
|
|
143
146
|
Detta är ett röstsamtal: svara kort, en till två meningar, om inte användaren ber om mer.
|
|
144
147
|
|
|
@@ -163,6 +163,11 @@ def get_file_tree(worktree_path: str) -> dict:
|
|
|
163
163
|
if f:
|
|
164
164
|
all_paths[f] = changed.get(f, "unchanged")
|
|
165
165
|
|
|
166
|
+
# Untracked/new files aren't in ls-files but must show in the tree
|
|
167
|
+
for path, status in changed.items():
|
|
168
|
+
if path not in all_paths and status != "deleted":
|
|
169
|
+
all_paths[path] = status
|
|
170
|
+
|
|
166
171
|
# Build tree structure
|
|
167
172
|
tree = {
|
|
168
173
|
"name": root,
|
|
@@ -70,6 +70,20 @@ def get_startup_context() -> str:
|
|
|
70
70
|
for wt in available:
|
|
71
71
|
parts.append(f" - {wt.branch}")
|
|
72
72
|
|
|
73
|
+
if _dispatch._registry:
|
|
74
|
+
recent = _dispatch._registry.get_transcripts()[-8:]
|
|
75
|
+
if recent:
|
|
76
|
+
parts.append(
|
|
77
|
+
"This is a RESUMED conversation. Recent history (oldest first) — "
|
|
78
|
+
"continue naturally from here, do not greet as if meeting for the "
|
|
79
|
+
"first time:"
|
|
80
|
+
)
|
|
81
|
+
for entry in recent:
|
|
82
|
+
role = entry.get("role", "user")
|
|
83
|
+
text = entry.get("text", "").strip().replace("\n", " ")[:200]
|
|
84
|
+
if text:
|
|
85
|
+
parts.append(f" {role}: {text}")
|
|
86
|
+
|
|
73
87
|
if not parts:
|
|
74
88
|
return ""
|
|
75
89
|
return "Current state:\n" + "\n".join(parts)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Regression test: untracked (new, uncommitted) files must appear in the file tree."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
from voice_vibecoder.tools.file_tree import get_file_tree
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_untracked_file_appears_in_tree(tmp_path):
|
|
9
|
+
repo = tmp_path / "repo"
|
|
10
|
+
repo.mkdir()
|
|
11
|
+
run = lambda *args: subprocess.run(args, cwd=repo, capture_output=True, check=True)
|
|
12
|
+
run("git", "init", "-q", "-b", "main")
|
|
13
|
+
run("git", "config", "user.email", "t@t")
|
|
14
|
+
run("git", "config", "user.name", "t")
|
|
15
|
+
(repo / "tracked.txt").write_text("hello")
|
|
16
|
+
run("git", "add", "tracked.txt")
|
|
17
|
+
run("git", "commit", "-q", "-m", "init")
|
|
18
|
+
(repo / "brand_new.txt").write_text("agent made me")
|
|
19
|
+
|
|
20
|
+
data = get_file_tree(str(repo))
|
|
21
|
+
entries = {e["path"]: e["status"] for e in data["entries"]}
|
|
22
|
+
|
|
23
|
+
assert entries.get("tracked.txt") == "unchanged"
|
|
24
|
+
assert entries.get("brand_new.txt") == "new"
|
|
25
|
+
assert data["summary"]["new"] == 1
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Resumed sessions must carry recent conversation into the system prompt."""
|
|
2
|
+
|
|
3
|
+
from voice_vibecoder.instances import InstanceRegistry
|
|
4
|
+
from voice_vibecoder.tools import configure
|
|
5
|
+
from voice_vibecoder.tools.handlers import get_startup_context
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def make_registry() -> InstanceRegistry:
|
|
9
|
+
reg = InstanceRegistry()
|
|
10
|
+
reg._transcript_buffer = [
|
|
11
|
+
{"role": "user", "text": "lag en fil i repoet"},
|
|
12
|
+
{"role": "assistant", "text": "Klart, jeg setter i gang!"},
|
|
13
|
+
]
|
|
14
|
+
return reg
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_startup_context_includes_recent_transcript():
|
|
18
|
+
configure(registry=make_registry(), repo_root=None)
|
|
19
|
+
ctx = get_startup_context()
|
|
20
|
+
assert "RESUMED" in ctx
|
|
21
|
+
assert "lag en fil i repoet" in ctx
|
|
22
|
+
assert "Klart, jeg setter i gang!" in ctx
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_startup_context_empty_without_history():
|
|
26
|
+
configure(registry=InstanceRegistry(), repo_root=None)
|
|
27
|
+
ctx = get_startup_context()
|
|
28
|
+
assert "RESUMED" not in ctx
|
|
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.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/claude.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/cursor.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/code_providers/openclaw.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.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
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/voice_providers/__init__.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/voice_providers/gemini.py
RENAMED
|
File without changes
|
{voice_vibecoder-2.24.0 → voice_vibecoder-2.25.0}/src/voice_vibecoder/voice_providers/openai.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|