finchvox 0.0.1__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 (49) hide show
  1. finchvox-0.0.1/.claude/commands/idea.md +12 -0
  2. finchvox-0.0.1/.claude/settings.local.json +69 -0
  3. finchvox-0.0.1/.gitignore +56 -0
  4. finchvox-0.0.1/CHANGELOG.md +10 -0
  5. finchvox-0.0.1/LICENSE +24 -0
  6. finchvox-0.0.1/PKG-INFO +189 -0
  7. finchvox-0.0.1/README.md +143 -0
  8. finchvox-0.0.1/docs/DEVELOPMENT.md +64 -0
  9. finchvox-0.0.1/docs/RELEASING.md +139 -0
  10. finchvox-0.0.1/docs/demo.gif +0 -0
  11. finchvox-0.0.1/docs/screenshot.png +0 -0
  12. finchvox-0.0.1/examples/webrtc/.claude/settings.local.json +11 -0
  13. finchvox-0.0.1/examples/webrtc/README.md +42 -0
  14. finchvox-0.0.1/examples/webrtc/bot.py +186 -0
  15. finchvox-0.0.1/examples/webrtc/env.example +10 -0
  16. finchvox-0.0.1/examples/webrtc/pyproject.toml +8 -0
  17. finchvox-0.0.1/examples/webrtc/uv.lock +3742 -0
  18. finchvox-0.0.1/pyproject.toml +39 -0
  19. finchvox-0.0.1/src/finchvox/__init__.py +0 -0
  20. finchvox-0.0.1/src/finchvox/__main__.py +81 -0
  21. finchvox-0.0.1/src/finchvox/audio_recorder.py +278 -0
  22. finchvox-0.0.1/src/finchvox/audio_utils.py +123 -0
  23. finchvox-0.0.1/src/finchvox/cli.py +127 -0
  24. finchvox-0.0.1/src/finchvox/collector/__init__.py +0 -0
  25. finchvox-0.0.1/src/finchvox/collector/__main__.py +22 -0
  26. finchvox-0.0.1/src/finchvox/collector/audio_handler.py +146 -0
  27. finchvox-0.0.1/src/finchvox/collector/collector_routes.py +186 -0
  28. finchvox-0.0.1/src/finchvox/collector/config.py +64 -0
  29. finchvox-0.0.1/src/finchvox/collector/server.py +126 -0
  30. finchvox-0.0.1/src/finchvox/collector/service.py +43 -0
  31. finchvox-0.0.1/src/finchvox/collector/writer.py +86 -0
  32. finchvox-0.0.1/src/finchvox/server.py +201 -0
  33. finchvox-0.0.1/src/finchvox/trace.py +115 -0
  34. finchvox-0.0.1/src/finchvox/ui_routes.py +362 -0
  35. finchvox-0.0.1/test_send_spans.py +88 -0
  36. finchvox-0.0.1/tests/__init__.py +0 -0
  37. finchvox-0.0.1/tests/test_service.py +138 -0
  38. finchvox-0.0.1/tests/test_writer.py +178 -0
  39. finchvox-0.0.1/ui/css/app.css +774 -0
  40. finchvox-0.0.1/ui/images/favicon.ico +0 -0
  41. finchvox-0.0.1/ui/images/finchvox-logo.png +0 -0
  42. finchvox-0.0.1/ui/js/time-utils.js +97 -0
  43. finchvox-0.0.1/ui/js/trace_detail.js +1228 -0
  44. finchvox-0.0.1/ui/js/traces_list.js +26 -0
  45. finchvox-0.0.1/ui/lib/alpine.min.js +5 -0
  46. finchvox-0.0.1/ui/lib/wavesurfer.min.js +1 -0
  47. finchvox-0.0.1/ui/trace_detail.html +313 -0
  48. finchvox-0.0.1/ui/traces_list.html +63 -0
  49. finchvox-0.0.1/uv.lock +1797 -0
@@ -0,0 +1,12 @@
1
+ ---
2
+ description: Brainstorm and develop an idea into a fully formed design and spec
3
+ argument-hint: [your idea description]
4
+ ---
5
+
6
+ I've got an idea I want to talk through with you. I'd like you to help me turn it into a fully formed design and spec (and eventually an implementation plan).
7
+
8
+ Check out the current state of the project in our working directory to understand where we're starting off, then ask me questions, one at a time, to help refine the idea.
9
+
10
+ Ideally, the questions would be multiple choice, but open-ended questions are OK, too. Don't forget: only one question per message.
11
+
12
+ Once you believe you understand what we're doing, stop and describe the design to me, in sections of maybe 200-300 words at a time, asking after each section whether it looks right so far.
@@ -0,0 +1,69 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:chatgpt.com)",
5
+ "WebSearch",
6
+ "WebFetch(domain:github.com)",
7
+ "Bash(uv pip install:*)",
8
+ "Bash(pyenv global:*)",
9
+ "Bash(python -m pip:*)",
10
+ "Bash(pytest:*)",
11
+ "Bash(python -m pytest:*)",
12
+ "Bash(brew install:*)",
13
+ "Bash(python test_send_spans.py:*)",
14
+ "Bash(pkill:*)",
15
+ "Bash(python -m mumbles.collector:*)",
16
+ "Bash(cat:*)",
17
+ "Bash(lsof:*)",
18
+ "Bash(python -m json.tool:*)",
19
+ "Bash(while read line)",
20
+ "Bash(do echo \"$line\")",
21
+ "Bash(python -c:*)",
22
+ "Bash(done)",
23
+ "WebFetch(domain:docs.pipecat.ai)",
24
+ "Bash(chmod:*)",
25
+ "Bash(tree:*)",
26
+ "Bash(find:*)",
27
+ "Bash(timeout 10 python:*)",
28
+ "Bash(curl:*)",
29
+ "Bash(.venv/bin/python:*)",
30
+ "Bash(xargs kill -9)",
31
+ "WebFetch(domain:loguru.readthedocs.io)",
32
+ "WebFetch(domain:www.coins5.dev)",
33
+ "Bash(python3:*)",
34
+ "Bash(timeout 5 python:*)",
35
+ "Bash(python bot.py:*)",
36
+ "Bash(uv run python:*)",
37
+ "Bash(head:*)",
38
+ "Bash(wc:*)",
39
+ "Bash(mkdir:*)",
40
+ "Bash(python -m mumbles.ui_server:*)",
41
+ "Bash(sort:*)",
42
+ "mcp__chrome-devtools__list_pages",
43
+ "mcp__chrome-devtools__navigate_page",
44
+ "mcp__chrome-devtools__take_snapshot",
45
+ "mcp__chrome-devtools__list_console_messages",
46
+ "mcp__chrome-devtools__list_network_requests",
47
+ "mcp__chrome-devtools__click",
48
+ "mcp__chrome-devtools__take_screenshot",
49
+ "mcp__chrome-devtools__evaluate_script",
50
+ "Bash(xargs:*)",
51
+ "Bash(grep:*)",
52
+ "WebFetch(domain:docs.honeycomb.io)",
53
+ "Bash(kill:*)",
54
+ "Bash(python -m src.mumbles.ui_server:*)",
55
+ "Bash(ls:*)",
56
+ "mcp__chrome-devtools__wait_for",
57
+ "Bash(pgrep:*)",
58
+ "Bash(git mv:*)",
59
+ "Bash(python -m finchvox:*)",
60
+ "Bash(uv --version:*)",
61
+ "Bash(uv build:*)",
62
+ "Bash(.venv/bin/finchvox:*)",
63
+ "Bash(rm:*)",
64
+ "WebFetch(domain:localhost)",
65
+ "Bash(unzip:*)",
66
+ "WebFetch(domain:hatch.pypa.io)"
67
+ ]
68
+ }
69
+ }
@@ -0,0 +1,56 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ /lib/
14
+ /lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Virtual environments
25
+ venv/
26
+ ENV/
27
+ env/
28
+ .venv/
29
+
30
+ # Testing
31
+ .pytest_cache/
32
+ .coverage
33
+ htmlcov/
34
+ *.cover
35
+
36
+ # IDE
37
+ .vscode/
38
+ .idea/
39
+ *.swp
40
+ *.swo
41
+ *~
42
+
43
+ # Project-specific
44
+ traces/
45
+ PLANNING.md
46
+ TODO.md
47
+
48
+ # Environment variables
49
+ .env
50
+ .env.*
51
+
52
+ # OS
53
+ .DS_Store
54
+ Thumbs.db
55
+
56
+ .worktrees/
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ All notable changes to **Finchvox** will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.0.1] - 2026-1-3
9
+
10
+ Initial public release.
finchvox-0.0.1/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Finchvox Source Available License
2
+
3
+ Copyright (c) 2026 Finchvox
4
+
5
+ Permission is granted, free of charge, to any person obtaining a copy of this
6
+ software and associated documentation files (the "Software"), to use, copy,
7
+ modify, and distribute the Software for internal or private use.
8
+
9
+ You may:
10
+ - Run the Software locally or within your organization
11
+ - Modify the Software for your own use
12
+ - Deploy the Software within your own infrastructure
13
+ - Deploy the Software on behalf of a customer, provided the customer operates
14
+ the Software themselves
15
+
16
+ You may NOT:
17
+ - Offer the Software as a hosted service, managed service, or SaaS
18
+ - Provide access to the Software to third parties as a service
19
+ - Resell, rebrand, or commercially exploit the Software as a service
20
+
21
+ This license does not grant you the right to use the Finchvox name, logo, or
22
+ trademarks.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: finchvox
3
+ Version: 0.0.1
4
+ Summary: Voice AI observability dev tool for Pipecat
5
+ License: Finchvox Source Available License
6
+
7
+ Copyright (c) 2026 Finchvox
8
+
9
+ Permission is granted, free of charge, to any person obtaining a copy of this
10
+ software and associated documentation files (the "Software"), to use, copy,
11
+ modify, and distribute the Software for internal or private use.
12
+
13
+ You may:
14
+ - Run the Software locally or within your organization
15
+ - Modify the Software for your own use
16
+ - Deploy the Software within your own infrastructure
17
+ - Deploy the Software on behalf of a customer, provided the customer operates
18
+ the Software themselves
19
+
20
+ You may NOT:
21
+ - Offer the Software as a hosted service, managed service, or SaaS
22
+ - Provide access to the Software to third parties as a service
23
+ - Resell, rebrand, or commercially exploit the Software as a service
24
+
25
+ This license does not grant you the right to use the Finchvox name, logo, or
26
+ trademarks.
27
+
28
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
29
+ License-File: LICENSE
30
+ Requires-Python: >=3.10
31
+ Requires-Dist: aiofiles>=24.1.0
32
+ Requires-Dist: aiohttp>=3.9.0
33
+ Requires-Dist: fastapi>=0.115.0
34
+ Requires-Dist: grpcio>=1.60.0
35
+ Requires-Dist: loguru>=0.7.0
36
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.27.0
37
+ Requires-Dist: opentelemetry-proto>=1.27.0
38
+ Requires-Dist: protobuf<6.0.0,>=4.25.0
39
+ Requires-Dist: python-multipart>=0.0.9
40
+ Requires-Dist: ruff>=0.14.10
41
+ Requires-Dist: uvicorn[standard]>=0.32.0
42
+ Provides-Extra: dev
43
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
44
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
45
+ Description-Content-Type: text/markdown
46
+
47
+ # <img src="ui/images/finchvox-logo.png" height=24 /> Finchvox - elevated debuggability for Voice AI apps
48
+
49
+ Do your eyes bleed like a Vecna victim watching Pipecat logs fly by? Do OpenTelemetry traces look impressive … yet explain nothing? If so, meet Finchvox, a local debuggability tool purpose-built for Voice AI apps.
50
+
51
+ Finchvox unifies conversation audio and traces in a single UI, highlighting voice-specific problems like interruptions and high user <-> bot latency. Good luck convincing DataDog to add that!
52
+
53
+ <a href="./docs/demo.gif"><img src="./docs/screenshot.png" /></a>
54
+
55
+ ## Table of Contents
56
+
57
+ - [Prerequisites](#prerequisites)
58
+ - [Installation](#installation)
59
+ - [Usage](#usage---finchvox-server)
60
+ - [Setup](#setup)
61
+ - [✨ AI Install](#-let-your-ai-coding-agent-do-the-work)
62
+ - [Step 1 – Enable Tracing in Your Pipecat Application](#step-1---enable-tracing-in-your-pipecat-application)
63
+ - [Step 2 – Enable Audio Recording](#step-2---enable-audio-recording)
64
+ - [Troubleshooting](#troubleshooting)
65
+
66
+ ## Prerequisites
67
+
68
+ - Python 3.10 or higher
69
+ - A Pipecat Voice AI application
70
+
71
+ ## Installation
72
+
73
+ ```bash
74
+ # uv
75
+ uv add finchvox "pipecat-ai[tracing]"
76
+
77
+ # Or with pip
78
+ pip install finchvox "pipecat-ai[tracing]"
79
+ ```
80
+
81
+ ## Usage - Finchvox server
82
+
83
+ ```bash
84
+ uv run finchvox start
85
+ ```
86
+
87
+ For the list of available options, run:
88
+
89
+ ```bash
90
+ uv run finchvox --help
91
+ ```
92
+
93
+ ## Setup
94
+
95
+ ### ✨ Let your AI coding agent do the work!
96
+
97
+ Try this starter prompt:
98
+
99
+ ```
100
+ Follow the "Setup" instructions at https://github.com/itsderek23/finchvox/blob/main/README.md to setup tracing and audio recording for finchvox.
101
+ ```
102
+
103
+ ### Step 1 - Enable Tracing in Your Pipecat Application
104
+
105
+ ```python
106
+ import os
107
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
108
+ from pipecat.utils.tracing.setup import setup_tracing
109
+ ```
110
+
111
+ ```python
112
+ # Step 1: Initialize OpenTelemetry with your chosen exporter
113
+ exporter = OTLPSpanExporter(
114
+ endpoint="http://localhost:4317",
115
+ insecure=True,
116
+ )
117
+
118
+ setup_tracing(
119
+ service_name="my-voice-app",
120
+ exporter=exporter,
121
+ )
122
+
123
+ # Step 2: Enable tracing in your PipelineTask
124
+ task = PipelineTask(
125
+ pipeline,
126
+ params=PipelineParams(
127
+ enable_metrics=True
128
+ ),
129
+ enable_tracing=True,
130
+ enable_turn_tracking=True
131
+ )
132
+ ```
133
+
134
+ For the full list of OpenTelemetry setup options, see the [Pipecat OpenTelemetry docs](https://docs.pipecat.ai/server/utilities/opentelemetry#overview).
135
+
136
+ ### Step 2 - Enable Audio Recording
137
+
138
+ Import the audio recorder and add it to your pipeline:
139
+
140
+ ```python
141
+ from finchvox.audio_recorder import ConversationAudioRecorder
142
+ ```
143
+
144
+ ```python
145
+ audio_recorder = ConversationAudioRecorder()
146
+
147
+ pipeline = Pipeline(
148
+ [
149
+ # Other processors, like STT, LLM, TTS, etc.
150
+ audio_recorder.get_processor(),
151
+ # context_aggregator.assistant(),
152
+ ]
153
+ )
154
+ ```
155
+
156
+ Start and stop recording on client connect/disconnect events:
157
+
158
+ ```python
159
+ @transport.event_handler("on_client_connected")
160
+ async def on_client_connected(transport, client):
161
+ await audio_recorder.start_recording()
162
+
163
+ # Other initialization logic...
164
+
165
+ @transport.event_handler("on_client_disconnected")
166
+ async def on_client_disconnected(transport, client):
167
+ await audio_recorder.stop_recording()
168
+
169
+ # Other cleanup logic...
170
+ ```
171
+
172
+ ## Troubleshooting
173
+
174
+ ### Port already in use
175
+
176
+ If port 4317 is already occupied:
177
+
178
+ ```bash
179
+ # Find process using port
180
+ lsof -i :4317
181
+
182
+ # Kill the process
183
+ kill -9 <PID>
184
+ ```
185
+
186
+ ### No spans being written
187
+
188
+ 1. Check collector is running: Look for "OTLP collector listening on port 4317" log message
189
+ 2. Verify client endpoint: Ensure Pipecat is configured to send to `http://localhost:4317`
@@ -0,0 +1,143 @@
1
+ # <img src="ui/images/finchvox-logo.png" height=24 /> Finchvox - elevated debuggability for Voice AI apps
2
+
3
+ Do your eyes bleed like a Vecna victim watching Pipecat logs fly by? Do OpenTelemetry traces look impressive … yet explain nothing? If so, meet Finchvox, a local debuggability tool purpose-built for Voice AI apps.
4
+
5
+ Finchvox unifies conversation audio and traces in a single UI, highlighting voice-specific problems like interruptions and high user <-> bot latency. Good luck convincing DataDog to add that!
6
+
7
+ <a href="./docs/demo.gif"><img src="./docs/screenshot.png" /></a>
8
+
9
+ ## Table of Contents
10
+
11
+ - [Prerequisites](#prerequisites)
12
+ - [Installation](#installation)
13
+ - [Usage](#usage---finchvox-server)
14
+ - [Setup](#setup)
15
+ - [✨ AI Install](#-let-your-ai-coding-agent-do-the-work)
16
+ - [Step 1 – Enable Tracing in Your Pipecat Application](#step-1---enable-tracing-in-your-pipecat-application)
17
+ - [Step 2 – Enable Audio Recording](#step-2---enable-audio-recording)
18
+ - [Troubleshooting](#troubleshooting)
19
+
20
+ ## Prerequisites
21
+
22
+ - Python 3.10 or higher
23
+ - A Pipecat Voice AI application
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ # uv
29
+ uv add finchvox "pipecat-ai[tracing]"
30
+
31
+ # Or with pip
32
+ pip install finchvox "pipecat-ai[tracing]"
33
+ ```
34
+
35
+ ## Usage - Finchvox server
36
+
37
+ ```bash
38
+ uv run finchvox start
39
+ ```
40
+
41
+ For the list of available options, run:
42
+
43
+ ```bash
44
+ uv run finchvox --help
45
+ ```
46
+
47
+ ## Setup
48
+
49
+ ### ✨ Let your AI coding agent do the work!
50
+
51
+ Try this starter prompt:
52
+
53
+ ```
54
+ Follow the "Setup" instructions at https://github.com/itsderek23/finchvox/blob/main/README.md to setup tracing and audio recording for finchvox.
55
+ ```
56
+
57
+ ### Step 1 - Enable Tracing in Your Pipecat Application
58
+
59
+ ```python
60
+ import os
61
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
62
+ from pipecat.utils.tracing.setup import setup_tracing
63
+ ```
64
+
65
+ ```python
66
+ # Step 1: Initialize OpenTelemetry with your chosen exporter
67
+ exporter = OTLPSpanExporter(
68
+ endpoint="http://localhost:4317",
69
+ insecure=True,
70
+ )
71
+
72
+ setup_tracing(
73
+ service_name="my-voice-app",
74
+ exporter=exporter,
75
+ )
76
+
77
+ # Step 2: Enable tracing in your PipelineTask
78
+ task = PipelineTask(
79
+ pipeline,
80
+ params=PipelineParams(
81
+ enable_metrics=True
82
+ ),
83
+ enable_tracing=True,
84
+ enable_turn_tracking=True
85
+ )
86
+ ```
87
+
88
+ For the full list of OpenTelemetry setup options, see the [Pipecat OpenTelemetry docs](https://docs.pipecat.ai/server/utilities/opentelemetry#overview).
89
+
90
+ ### Step 2 - Enable Audio Recording
91
+
92
+ Import the audio recorder and add it to your pipeline:
93
+
94
+ ```python
95
+ from finchvox.audio_recorder import ConversationAudioRecorder
96
+ ```
97
+
98
+ ```python
99
+ audio_recorder = ConversationAudioRecorder()
100
+
101
+ pipeline = Pipeline(
102
+ [
103
+ # Other processors, like STT, LLM, TTS, etc.
104
+ audio_recorder.get_processor(),
105
+ # context_aggregator.assistant(),
106
+ ]
107
+ )
108
+ ```
109
+
110
+ Start and stop recording on client connect/disconnect events:
111
+
112
+ ```python
113
+ @transport.event_handler("on_client_connected")
114
+ async def on_client_connected(transport, client):
115
+ await audio_recorder.start_recording()
116
+
117
+ # Other initialization logic...
118
+
119
+ @transport.event_handler("on_client_disconnected")
120
+ async def on_client_disconnected(transport, client):
121
+ await audio_recorder.stop_recording()
122
+
123
+ # Other cleanup logic...
124
+ ```
125
+
126
+ ## Troubleshooting
127
+
128
+ ### Port already in use
129
+
130
+ If port 4317 is already occupied:
131
+
132
+ ```bash
133
+ # Find process using port
134
+ lsof -i :4317
135
+
136
+ # Kill the process
137
+ kill -9 <PID>
138
+ ```
139
+
140
+ ### No spans being written
141
+
142
+ 1. Check collector is running: Look for "OTLP collector listening on port 4317" log message
143
+ 2. Verify client endpoint: Ensure Pipecat is configured to send to `http://localhost:4317`
@@ -0,0 +1,64 @@
1
+ # Development Guide
2
+
3
+
4
+ ## Testing
5
+
6
+ ### Run Automated Tests
7
+
8
+ ```bash
9
+ # Run all tests
10
+ pytest tests/
11
+
12
+ # Run with coverage
13
+ pytest tests/ --cov=finchvox.collector --cov-report=term-missing
14
+
15
+ # Run specific test file
16
+ pytest tests/test_writer.py -v
17
+ ```
18
+
19
+ ### Manual Testing with otel-cli
20
+
21
+ For testing without a Pipecat application:
22
+
23
+ #### Via `otel-cli`
24
+
25
+ ```bash
26
+ # Install otel-cli (macOS)
27
+ brew install otel-cli
28
+
29
+ # Send a test span
30
+ otel-cli span --endpoint localhost:4317 --name "test-span" --service "test-service"
31
+
32
+ # Send multiple spans in same trace (they'll be grouped in one file)
33
+ otel-cli span --endpoint localhost:4317 --name "span-1" --service "test" --traceparent "00-12345678901234567890123456789012-1234567890123456-01"
34
+ otel-cli span --endpoint localhost:4317 --name "span-2" --service "test" --traceparent "00-12345678901234567890123456789012-1234567890123457-01"
35
+ ```
36
+
37
+ #### Via test_send_spans.py
38
+
39
+ ```bash
40
+ # Run the test script to send sample spans
41
+ python tests/test_send_spans.py
42
+ ```
43
+
44
+
45
+ ### Running Tests
46
+
47
+ ```bash
48
+ # Watch mode (requires pytest-watch)
49
+ pip install pytest-watch
50
+ ptw tests/
51
+ ```
52
+
53
+ ### Tests failing
54
+
55
+ ```bash
56
+ # Ensure dependencies are installed
57
+ uv pip install --system -e ".[dev]"
58
+
59
+ # Run tests with verbose output
60
+ pytest tests/ -v
61
+
62
+ # Check Python version (requires 3.10+)
63
+ python --version
64
+ ```
@@ -0,0 +1,139 @@
1
+ # Releasing FinchVox to PyPI
2
+
3
+ Step-by-step guide for manually releasing FinchVox to PyPI.
4
+
5
+ ## Prerequisites
6
+
7
+ - [ ] PyPI account with API token configured
8
+ - [ ] `uv` installed (or `pip`)
9
+ - [ ] Clean git working directory
10
+
11
+ ## Release Workflow
12
+
13
+ ### 1. Update Version
14
+
15
+ Edit `pyproject.toml`:
16
+ ```toml
17
+ version = "0.0.2" # Increment version
18
+ ```
19
+
20
+ ### 2. Update Changelog (Optional)
21
+
22
+ Add release notes to `CHANGELOG.md`.
23
+
24
+ ### 3. Commit and Tag
25
+
26
+ ```bash
27
+ # Commit changes
28
+ git add -A
29
+ git commit -m "Release v0.0.2"
30
+
31
+ # Create git tag
32
+ git tag v0.0.2
33
+
34
+ # Push commits and tags
35
+ git push && git push --tags
36
+ ```
37
+
38
+ ## Build Package
39
+
40
+ ### 1. Clean Previous Builds
41
+
42
+ ```bash
43
+ rm -rf dist/
44
+ ```
45
+
46
+ ### 2. Build
47
+
48
+ ```bash
49
+ uv build
50
+ ```
51
+
52
+ Expected output: Creates `dist/finchvox-0.0.2-py3-none-any.whl` and `dist/finchvox-0.0.2.tar.gz`
53
+
54
+ ### 3. Verify Build
55
+
56
+ ```bash
57
+ ls -lh dist/
58
+ ```
59
+
60
+ ## Test Locally
61
+
62
+ ### 1. Create Test Environment
63
+
64
+ ```bash
65
+ python -m venv test-env
66
+ source test-env/bin/activate
67
+ ```
68
+
69
+ ### 2. Install from Wheel
70
+
71
+ ```bash
72
+ pip install dist/finchvox-0.0.2-py3-none-any.whl
73
+ ```
74
+
75
+ ### 3. Verify Installation
76
+
77
+ ```bash
78
+ # Test CLI
79
+ finchvox --help
80
+
81
+ # Test import
82
+ python -c "import finchvox; print('OK')"
83
+ ```
84
+
85
+ ### 4. Cleanup
86
+
87
+ ```bash
88
+ deactivate
89
+ rm -rf test-env
90
+ ```
91
+
92
+ ## Upload to PyPI
93
+
94
+ ### 1. Install Twine (if needed)
95
+
96
+ ```bash
97
+ pip install twine
98
+ ```
99
+
100
+ ### 2. Upload
101
+
102
+ ```bash
103
+ twine upload dist/*
104
+ ```
105
+
106
+ Enter your PyPI API token when prompted.
107
+
108
+ ### 3. Verify Upload
109
+
110
+ Visit: https://pypi.org/project/finchvox/
111
+
112
+ ### 4. Test Install from PyPI
113
+
114
+ ```bash
115
+ pip install finchvox==0.0.2
116
+ ```
117
+
118
+ ## Troubleshooting
119
+
120
+ **Build fails:**
121
+ - Check `pyproject.toml` syntax
122
+ - Verify `src/finchvox/` structure
123
+
124
+ **Upload fails:**
125
+ - Verify PyPI API token is correct
126
+ - Check if version already exists on PyPI (can't overwrite)
127
+ - Ensure `~/.pypirc` is configured if not using token prompt
128
+
129
+ **Import fails after install:**
130
+ - Verify `src/` directory structure matches `packages` in `pyproject.toml`
131
+ - Check `hatchling.build.targets.wheel` configuration
132
+
133
+ **Missing UI files in package:**
134
+ - Verify `force-include` section in `pyproject.toml`
135
+ - Check that `ui/` directory exists and contains files
136
+
137
+ **Version not updating:**
138
+ - Clear pip cache: `pip cache purge`
139
+ - Use `--no-cache-dir`: `pip install --no-cache-dir finchvox==0.0.2`
Binary file