voxa-code 0.1.0__py3-none-any.whl

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.
static/pcm-worklet.js ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * pcm-worklet.js
3
+ * AudioWorkletProcessor that downsamples mic audio to 16 kHz mono Int16 PCM
4
+ * and posts ArrayBuffers to the main thread for WebSocket transmission.
5
+ *
6
+ * The AudioContext sample rate (available as global `sampleRate`) is typically
7
+ * 44100 or 48000 Hz. We downsample to 16000 Hz by accumulating samples and
8
+ * stepping through them with a fixed ratio.
9
+ */
10
+
11
+ const TARGET_SAMPLE_RATE = 16000;
12
+
13
+ class PCMProcessor extends AudioWorkletProcessor {
14
+ constructor(options) {
15
+ super(options);
16
+ // Accumulation buffer for input samples before downsampling
17
+ this._accumulator = [];
18
+ // Fractional position in the input for the downsampling cursor
19
+ this._phase = 0;
20
+ // Ratio: how many input samples per one output sample
21
+ this._ratio = sampleRate / TARGET_SAMPLE_RATE;
22
+ }
23
+
24
+ process(inputs) {
25
+ const input = inputs[0];
26
+ if (!input || !input[0] || input[0].length === 0) {
27
+ return true;
28
+ }
29
+
30
+ const channelData = input[0]; // Float32Array, mono
31
+
32
+ // Downsample via nearest-neighbour stepping.
33
+ // For each output sample we need, advance the phase by ratio through the input.
34
+ const outputSamples = [];
35
+ for (let i = 0; i < channelData.length; i++) {
36
+ this._accumulator.push(channelData[i]);
37
+ }
38
+
39
+ // Process accumulated samples
40
+ while (this._phase < this._accumulator.length) {
41
+ const idx = Math.floor(this._phase);
42
+ // Linear interpolation between adjacent samples for slightly better quality
43
+ const next = Math.min(idx + 1, this._accumulator.length - 1);
44
+ const frac = this._phase - idx;
45
+ const sample = this._accumulator[idx] * (1 - frac) + this._accumulator[next] * frac;
46
+ // Clamp and convert Float32 [-1, 1] to Int16 [-32767, 32767]
47
+ const clamped = Math.max(-1, Math.min(1, sample));
48
+ outputSamples.push(Math.round(clamped * 32767));
49
+ this._phase += this._ratio;
50
+ }
51
+
52
+ // Discard consumed input, keep the fractional remainder
53
+ const consumed = Math.floor(this._phase);
54
+ this._accumulator = this._accumulator.slice(consumed);
55
+ this._phase -= consumed;
56
+
57
+ if (outputSamples.length === 0) {
58
+ return true;
59
+ }
60
+
61
+ // Pack output samples into an Int16 little-endian ArrayBuffer and transfer it
62
+ const int16Buffer = new Int16Array(outputSamples);
63
+ this.port.postMessage(int16Buffer.buffer, [int16Buffer.buffer]);
64
+
65
+ return true;
66
+ }
67
+ }
68
+
69
+ registerProcessor('pcm-processor', PCMProcessor);
static/pro.html ADDED
@@ -0,0 +1,29 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="utf-8"><title>Voxa — professional</title>
3
+ <style>
4
+ body{margin:0;font-family:'Inter',system-ui,sans-serif;background:#f6f6f7;color:#0a0a0b}
5
+ h1{padding:28px 36px 2px;font-weight:600;letter-spacing:-.5px}
6
+ p.sub{padding:0 36px;color:#71717a;margin:0 0 8px}
7
+ .grid{display:flex;flex-wrap:wrap;gap:30px;padding:26px 36px;align-items:flex-end}
8
+ .col{display:flex;flex-direction:column;gap:12px;align-items:center}
9
+ .name{font-size:13px;color:#52525b}
10
+ .card{width:200px;height:200px;border-radius:30px;display:flex;align-items:center;justify-content:center}
11
+ .card img{width:170px;height:170px}
12
+ .sm{width:84px;height:84px;border-radius:18px}.sm img{width:84px;height:84px}
13
+ .fav{width:40px;height:40px;border-radius:10px}.fav img{width:40px;height:40px}
14
+ .wmcard{background:#fff;border:1px solid #ececee;border-radius:20px;padding:34px 40px}
15
+ .wmcard img{width:330px}
16
+ </style></head><body>
17
+ <h1>Voxa — minimal · monochrome</h1>
18
+ <p class="sub">No gradient. Ink on white / white on ink. Voice‑ring mark.</p>
19
+ <div class="grid">
20
+ <div class="col"><div class="name">app icon · light</div><div class="card"><img src="/static/voxa-pro-light.svg"></div></div>
21
+ <div class="col"><div class="name">app icon · dark</div><div class="card"><img src="/static/voxa-pro-dark.svg"></div></div>
22
+ <div class="col"><div class="name">small</div>
23
+ <div class="card sm"><img src="/static/voxa-pro-light.svg"></div>
24
+ <div class="card fav"><img src="/static/voxa-pro-dark.svg"></div></div>
25
+ </div>
26
+ <div class="grid">
27
+ <div class="col"><div class="name">wordmark</div><div class="wmcard"><img src="/static/voxa-pro-wordmark.svg"></div></div>
28
+ </div>
29
+ </body></html>
static/pro2.html ADDED
@@ -0,0 +1,33 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="utf-8"><title>Voxa pro</title>
3
+ <style>
4
+ body{margin:0;font-family:'Inter',system-ui,sans-serif;background:#f6f6f7;color:#0a0a0b}
5
+ h1{padding:26px 36px 2px;font-weight:600;letter-spacing:-.5px}
6
+ .row{display:flex;flex-wrap:wrap;gap:26px;padding:14px 36px 4px;align-items:center}
7
+ .opt{font-size:13px;color:#52525b;padding:18px 36px 0;font-weight:600}
8
+ .card{width:180px;height:180px;border-radius:28px;display:flex;align-items:center;justify-content:center}
9
+ .card img{width:150px;height:150px}
10
+ .fav{width:44px;height:44px;border-radius:11px}.fav img{width:44px;height:44px}
11
+ .wmcard{background:#fff;border:1px solid #ececee;border-radius:18px;padding:28px 36px}
12
+ .wmcard img{width:300px}
13
+ .lbl{font-size:12px;color:#71717a;text-align:center;margin-top:6px}
14
+ .col{display:flex;flex-direction:column}
15
+ </style></head><body>
16
+ <h1>Voxa — minimal · professional</h1>
17
+
18
+ <div class="opt">Option A · Voice ring (refined, smooth)</div>
19
+ <div class="row">
20
+ <div class="col"><div class="card"><img src="/static/voxa-ring-light.svg"></div><div class="lbl">light</div></div>
21
+ <div class="col"><div class="card"><img src="/static/voxa-ring-dark.svg"></div><div class="lbl">dark</div></div>
22
+ <div class="col"><div class="card fav"><img src="/static/voxa-ring-dark.svg"></div><div class="lbl">favicon</div></div>
23
+ <div class="col"><div class="wmcard"><img src="/static/voxa-ring-wordmark.svg"></div><div class="lbl">wordmark</div></div>
24
+ </div>
25
+
26
+ <div class="opt">Option B · V with voice dot (ultra‑minimal)</div>
27
+ <div class="row">
28
+ <div class="col"><div class="card"><img src="/static/voxa-vdot-light.svg"></div><div class="lbl">light</div></div>
29
+ <div class="col"><div class="card"><img src="/static/voxa-vdot-dark.svg"></div><div class="lbl">dark</div></div>
30
+ <div class="col"><div class="card fav"><img src="/static/voxa-vdot-dark.svg"></div><div class="lbl">favicon</div></div>
31
+ <div class="col"><div class="wmcard"><img src="/static/voxa-vdot-wordmark.svg"></div><div class="lbl">wordmark</div></div>
32
+ </div>
33
+ </body></html>
@@ -0,0 +1 @@
1
+ <svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g fill="#FFFFFF"><rect x="250.0" y="107.8" width="12" height="50.2" rx="6.0" transform="rotate(0.00 256 256)"/><rect x="250.0" y="86.5" width="12" height="71.5" rx="6.0" transform="rotate(12.00 256 256)"/><rect x="250.0" y="76.4" width="12" height="81.6" rx="6.0" transform="rotate(24.00 256 256)"/><rect x="250.0" y="80.1" width="12" height="77.9" rx="6.0" transform="rotate(36.00 256 256)"/><rect x="250.0" y="96.6" width="12" height="61.4" rx="6.0" transform="rotate(48.00 256 256)"/><rect x="250.0" y="121.6" width="12" height="36.4" rx="6.0" transform="rotate(60.00 256 256)"/><rect x="250.0" y="107.8" width="12" height="50.2" rx="6.0" transform="rotate(72.00 256 256)"/><rect x="250.0" y="86.5" width="12" height="71.5" rx="6.0" transform="rotate(84.00 256 256)"/><rect x="250.0" y="76.4" width="12" height="81.6" rx="6.0" transform="rotate(96.00 256 256)"/><rect x="250.0" y="80.1" width="12" height="77.9" rx="6.0" transform="rotate(108.00 256 256)"/><rect x="250.0" y="96.6" width="12" height="61.4" rx="6.0" transform="rotate(120.00 256 256)"/><rect x="250.0" y="121.6" width="12" height="36.4" rx="6.0" transform="rotate(132.00 256 256)"/><rect x="250.0" y="107.8" width="12" height="50.2" rx="6.0" transform="rotate(144.00 256 256)"/><rect x="250.0" y="86.5" width="12" height="71.5" rx="6.0" transform="rotate(156.00 256 256)"/><rect x="250.0" y="76.4" width="12" height="81.6" rx="6.0" transform="rotate(168.00 256 256)"/><rect x="250.0" y="80.1" width="12" height="77.9" rx="6.0" transform="rotate(180.00 256 256)"/><rect x="250.0" y="96.6" width="12" height="61.4" rx="6.0" transform="rotate(192.00 256 256)"/><rect x="250.0" y="121.6" width="12" height="36.4" rx="6.0" transform="rotate(204.00 256 256)"/><rect x="250.0" y="107.8" width="12" height="50.2" rx="6.0" transform="rotate(216.00 256 256)"/><rect x="250.0" y="86.5" width="12" height="71.5" rx="6.0" transform="rotate(228.00 256 256)"/><rect x="250.0" y="76.4" width="12" height="81.6" rx="6.0" transform="rotate(240.00 256 256)"/><rect x="250.0" y="80.1" width="12" height="77.9" rx="6.0" transform="rotate(252.00 256 256)"/><rect x="250.0" y="96.6" width="12" height="61.4" rx="6.0" transform="rotate(264.00 256 256)"/><rect x="250.0" y="121.6" width="12" height="36.4" rx="6.0" transform="rotate(276.00 256 256)"/><rect x="250.0" y="107.8" width="12" height="50.2" rx="6.0" transform="rotate(288.00 256 256)"/><rect x="250.0" y="86.5" width="12" height="71.5" rx="6.0" transform="rotate(300.00 256 256)"/><rect x="250.0" y="76.4" width="12" height="81.6" rx="6.0" transform="rotate(312.00 256 256)"/><rect x="250.0" y="80.1" width="12" height="77.9" rx="6.0" transform="rotate(324.00 256 256)"/><rect x="250.0" y="96.6" width="12" height="61.4" rx="6.0" transform="rotate(336.00 256 256)"/><rect x="250.0" y="121.6" width="12" height="36.4" rx="6.0" transform="rotate(348.00 256 256)"/><circle cx="256" cy="256" r="22"/></g></svg>
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: voxa-code
3
+ Version: 0.1.0
4
+ Summary: Hands-free voice operator for Claude Code
5
+ Author-email: Ti <voxa@voxa.space>
6
+ License: MIT
7
+ Project-URL: Homepage, https://voxa.space
8
+ Project-URL: Repository, https://github.com/Ti-03/voxa
9
+ Project-URL: Issues, https://github.com/Ti-03/voxa/issues
10
+ Keywords: claude,claude-code,voice,cli,agent,gemini
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: fastapi>=0.110
26
+ Requires-Dist: uvicorn[standard]>=0.29
27
+ Requires-Dist: websockets>=12
28
+ Requires-Dist: google-genai>=0.3
29
+ Requires-Dist: claude-agent-sdk>=0.1
30
+ Requires-Dist: python-dotenv>=1.0
31
+ Requires-Dist: pyjwt[crypto]>=2.8
32
+ Requires-Dist: httpx[http2]>=0.27
33
+ Requires-Dist: qrcode>=7.4
34
+ Requires-Dist: cbor2>=5.6
35
+ Requires-Dist: pyobjc-framework-Quartz>=10; sys_platform == "darwin"
36
+ Requires-Dist: pyobjc-framework-ApplicationServices>=10; sys_platform == "darwin"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest>=8; extra == "dev"
39
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
40
+ Requires-Dist: httpx>=0.27; extra == "dev"
41
+ Dynamic: license-file
42
+
43
+ # Voxa
44
+
45
+ Voxa lets you call into your laptop from a phone browser, talk to a Gemini Live
46
+ "operator," and have it drive Claude Code by voice.
47
+
48
+ **MVP scope (drive mode only):** pick a working directory by voice, send spoken
49
+ instructions, hear Claude's final result read back. Attach mode, voice
50
+ folder-browsing, and barge-in interruption are V2 backlog items (see
51
+ `docs/superpowers/specs/2026-06-27-loop-design.md` and
52
+ `docs/superpowers/plans/2026-06-27-loop-mvp.md`).
53
+
54
+ ---
55
+
56
+ ## Prerequisites
57
+
58
+ - **Python 3.11+** on the laptop.
59
+ - **Tailscale** installed and logged in on both the laptop and the phone (free
60
+ personal plan is fine). The phone must be on the same tailnet as the laptop,
61
+ or MagicDNS must be enabled.
62
+ - **A Gemini API key** from [Google AI Studio](https://aistudio.google.com/live)
63
+ with Gemini Live access.
64
+ - **Claude Code logged in** on the laptop (`claude` CLI authenticated). The
65
+ agent SDK reuses your existing Claude Code credentials; no separate
66
+ `ANTHROPIC_API_KEY` is needed unless you prefer to supply one.
67
+
68
+ ---
69
+
70
+ ## Quickstart
71
+
72
+ Install Voxa on the laptop you want to control with one command.
73
+
74
+ **macOS / Linux:**
75
+
76
+ ```bash
77
+ curl -fsSL https://voxa.space/install.sh | sh
78
+ ```
79
+
80
+ **Windows (PowerShell):**
81
+
82
+ ```powershell
83
+ irm https://voxa.space/install.ps1 | iex
84
+ ```
85
+
86
+ Prefer a package runner? These work on any OS:
87
+
88
+ ```bash
89
+ npx voxa-code # Node users
90
+ uvx voxa-code # Python users (or: pipx install voxa-code)
91
+ ```
92
+
93
+ Then start it:
94
+
95
+ ```bash
96
+ voxa
97
+ ```
98
+
99
+ Voxa is zero-config by default: it uses the hosted relay, so there are no API
100
+ keys to set up. `voxa` starts the server and prints a pairing QR code. Scan it
101
+ with the Voxa phone app (or open the printed URL in your phone browser) to
102
+ connect.
103
+
104
+ ---
105
+
106
+ ## Develop from source
107
+
108
+ Contributors who want to hack on Voxa can run it from a checkout instead of the
109
+ published package.
110
+
111
+ ### 1. Create and activate the virtual environment
112
+
113
+ ```bash
114
+ python3 -m venv .venv
115
+ .venv/bin/pip install -e ".[dev]"
116
+ ```
117
+
118
+ ### 2. Configure secrets
119
+
120
+ ```bash
121
+ cp .env.example .env
122
+ ```
123
+
124
+ Open `.env` and fill in:
125
+
126
+ | Key | Value |
127
+ |---|---|
128
+ | `GEMINI_API_KEY` | Your Google AI Studio key |
129
+ | `VOXA_AUTH_TOKEN` | Any random secret string (protects the WebSocket endpoint on your tailnet) |
130
+
131
+ `GEMINI_LIVE_MODEL`, `VOXA_HOST`, and `VOXA_PORT` have sensible defaults and
132
+ can be left as-is.
133
+
134
+ ### 3. Start the server
135
+
136
+ ```bash
137
+ bash scripts/serve.sh
138
+ ```
139
+
140
+ The script:
141
+ 1. Starts the Voxa FastAPI server on `127.0.0.1:8787` (or `$VOXA_PORT`).
142
+ 2. Calls `tailscale serve` to expose it over HTTPS on your tailnet (required
143
+ because the phone browser needs a secure context for microphone access).
144
+ 3. Prints the full HTTPS URL including your auth token.
145
+
146
+ ### 4. Connect from the phone
147
+
148
+ Open the printed URL on your phone browser. Tap **Connect**, then speak.
149
+
150
+ ---
151
+
152
+ ## Architecture (brief)
153
+
154
+ ```
155
+ Phone browser (static/)
156
+ | HTTPS WebSocket (auth token required)
157
+ v
158
+ FastAPI server (server/app.py)
159
+ | audio bytes (16 kHz PCM)
160
+ v
161
+ GeminiOperator (server/gemini_operator.py) <--> Gemini Live API
162
+ | tool calls (start_claude_session, send_to_claude, …)
163
+ v
164
+ Orchestrator (server/orchestrator.py)
165
+ |
166
+ v
167
+ ClaudeController (server/claude_controller.py) --> Claude Code (agent SDK, bypassPermissions)
168
+ ```
169
+
170
+ Config is loaded from `.env` via `server/config.py`.
171
+
172
+ ---
173
+
174
+ ## Running the test suite
175
+
176
+ ```bash
177
+ .venv/bin/python -m pytest -v
178
+ ```
179
+
180
+ Expected: 22 tests pass, no warnings.
181
+
182
+ ---
183
+
184
+ ## Manual end-to-end smoke test
185
+
186
+ The smoke test requires a real phone, real Tailscale connectivity, and real API
187
+ keys. Run it against a scratch directory, not a real project.
188
+
189
+ **Before you start:**
190
+ - `.env` is fully filled in (real `GEMINI_API_KEY` and `VOXA_AUTH_TOKEN`).
191
+ - Tailscale is running on both the laptop and the phone.
192
+ - Claude Code is logged in on the laptop.
193
+
194
+ **Procedure:**
195
+
196
+ 1. Open a terminal on the laptop and run:
197
+ ```bash
198
+ bash scripts/serve.sh
199
+ ```
200
+ Wait for the line `Voxa is live. On your phone open: https://...`
201
+
202
+ 2. Copy the printed HTTPS URL (it already includes `?token=...`).
203
+
204
+ 3. On the phone, open the URL in Safari or Chrome. You should see the Voxa
205
+ interface. Grant microphone permission when prompted.
206
+
207
+ 4. Tap **Connect**. The button should change state to indicate an active
208
+ session.
209
+
210
+ 5. Speak: "Start a session in `/tmp/loop-smoke` and create a file called
211
+ `hello.txt` that says hi."
212
+
213
+ 6. **Verify:**
214
+ - Gemini acknowledges the instruction verbally (you hear a response through
215
+ the phone speaker).
216
+ - On the laptop terminal you see Claude Code start with `bypassPermissions`
217
+ active (no permission prompts appear).
218
+ - After Claude finishes, `/tmp/loop-smoke/hello.txt` exists on the laptop
219
+ and contains `hi`.
220
+ - Gemini speaks the final result back to you.
221
+
222
+ 7. To stop: press Ctrl-C in the laptop terminal. The `trap` in `serve.sh` will
223
+ kill the server and tear down `tailscale serve`.
224
+
225
+ **Warning:** Use a throwaway scratch directory (like `/tmp/loop-smoke`) for
226
+ your first smoke test. Claude Code runs with `bypassPermissions`, so it will
227
+ write files without asking.
@@ -0,0 +1,47 @@
1
+ server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ server/apns.py,sha256=204SSCPWAKfhIYPNlv4c2Ysj4TutB7kJt7Vj6hoNhlk,3618
3
+ server/app.py,sha256=Qjm6XhI3_Vfz79B2z8L-jD6z8Qw2G0XwksTeA9WXVjo,28556
4
+ server/appattest.py,sha256=BOAd4ynkHLBhtUgvEdTjmpHUZNCdOWqmuxYP7tn9qUA,11806
5
+ server/appstore.py,sha256=SJacKxCD8PubOqZorYW1Gb_CvkAaI3m6ilK9iTxGfI4,5649
6
+ server/attested_store.py,sha256=_nwHV8PZzn8Wc7hXCS7iRe12IoflyNgLWYQxpd4Hraw,2032
7
+ server/auth.py,sha256=v9tCHA9FLtF9BPrXP66-VKcVZedLln4xrWSD-jzVeRk,3004
8
+ server/ax_controller.py,sha256=0cl_gJmLdZOI6Gmua9IzMi-Cm2K9dxaF5SMed8skWfI,7331
9
+ server/billing.py,sha256=WXo8-es8So0ZwG8tzFu3J-FnjskkT73ipS5Wp4dwFIU,7255
10
+ server/call_manager.py,sha256=8PaIAPRBVoqSmY8SKO-0IwRbVMhZeYW9oYUrgin5Rps,3690
11
+ server/claude_controller.py,sha256=lgQ3PaBEP1Y8FTLlsd1skMa9jinXhBJ5jN7KJGvpqjY,5860
12
+ server/cli.py,sha256=KR1jcQ2LPqTak9IbuflxmtI0BxYKp-uaETk2mExL0rE,13399
13
+ server/cloud_app.py,sha256=ZK9BPoCAYLoh2EGgqgIptrIoy_sq87sc4Oy_Zm2Vn1w,16285
14
+ server/config.py,sha256=hVgMFeS6wO59gDXbaBjAyQ_xjiUaUnFD5XNIU6pNS7g,2077
15
+ server/device_registry.py,sha256=SLsNUT1hijilhWdqCsn7tzTfHiKbrRWFp8HNNO-L3TA,1808
16
+ server/gemini_operator.py,sha256=vbUFJhIjJs8ivlV8o646KiwZ22hQ8KWfaOLyvGoLZ3g,36864
17
+ server/hooks.py,sha256=6bHj6kpYzTO4GygL-8mN2M1lmVoHAVe9yywpWq-q1Ow,8073
18
+ server/orchestrator.py,sha256=oWM6GCsSdg-SEqrgXqvTyJ5VaBmbEbfQ3i74EerJNVM,14178
19
+ server/push_routes.py,sha256=_t7YaIXcNFt-KEzJV5xuzLOHgiRrzwXuBOhm26Fxnb0,2103
20
+ server/ratelimit.py,sha256=1JX0Z3arGuB04blaJZZsecoeFiKRcQP6bgm9xFb7PJ0,1609
21
+ server/relay.py,sha256=LkVBdErPiQaBP-Iky5XrVk6jZVtI5Xq8-cGecCizSFI,6084
22
+ server/relay_client.py,sha256=NGNVS_S2bMQJmfhEr2Z6v7bKpOkSlBM2FvxTGg4vBkc,3127
23
+ server/remote_operator.py,sha256=iIm4OwR1O43M9XEU_xXWqEbvaI6AuARUbiAAa5yeMtM,5434
24
+ server/session_hub.py,sha256=U85vu94SlmNjrStT1tS5Ihkgh2yh2UGR9SqLT5mDNf4,1011
25
+ server/terminal_watcher.py,sha256=WGQpvK0P1ggXAVIMTzfbT0OU0MpNwWjnzTv35WG3Fi4,10310
26
+ server/terminals.py,sha256=9xjDUo7jyXoAV3P719oJxRQhuBJztgesHOokNW514UM,17961
27
+ server/tmux_controller.py,sha256=HzmN32ke-IyMAwToME6JxEjTlO-WSUIHkf8MY5Rnc7Y,25453
28
+ server/transcript_monitor.py,sha256=xBjFEcEUcf4Sny5fLMnF0vv8Rb1iMuFgzPr3i6QECFo,4736
29
+ server/transcripts.py,sha256=Ko59HzAu0NSp9Wyr4e-4kMvogH_HQ0emcgacSRnppAE,5214
30
+ server/users.py,sha256=vq518cryA3NeG05BTh6h7YZ2aVHsIkl_BbrWwCeNAGo,3187
31
+ server/voxa_cloud.py,sha256=wiAik-HtQxlT6vqQbqELAvPqUOfBp9vPivp_iXLu4ZU,5588
32
+ server/waitlist.py,sha256=S2w9iD6aBkQ35OTuFmZQCPSO-rdgIV4sOClP13SLGQ8,4750
33
+ server/certs/AppleRootCA-G3.pem,sha256=mjDmYheJjLw__yN1aAO7E1xIa2K10QLokzjzmjBDxU8,847
34
+ server/certs/Apple_App_Attestation_Root_CA.pem,sha256=x3jQmsNB9_2fjzsZ4rgVr2rtStRJDh6SwFyzVSEqUBM,798
35
+ static/app.js,sha256=XUYg19dNspMIsN7RGWEZmCI9xAMdRJT0HzzCd8T_-as,11480
36
+ static/favicon.svg,sha256=JdCUQcrLtuaDdSL5PwaN8x_Q4T_lo5JfJ0hs7--qMAE,3056
37
+ static/index.html,sha256=4y0uGoZ4ZmBtVzO5c0M7ZsiLWXwDTb8-Z6KEXq71cU0,6452
38
+ static/pcm-worklet.js,sha256=RlGxUIVMGSgKJH8qkAGWg2pPAFh3SF9ZcldCjOXrzLE,2440
39
+ static/pro.html,sha256=fxXlopJq4oc9j98KxtUEeRwxnPK9iqRlqXqMY-P6bOg,1699
40
+ static/pro2.html,sha256=fpkaZw5PwP3arncFArh44JVxbU9tGuJQXCCNGyx5QsE,2068
41
+ static/voxa-mark-white.svg,sha256=zJsGK3rnUeRcaMPJavi2KR5k6o6Phpazjwf2ERMxgxA,3000
42
+ voxa_code-0.1.0.dist-info/licenses/LICENSE,sha256=sVPQ_LaBfD73Rag4j42VENF87in8pjUYIauORl6lmUo,1066
43
+ voxa_code-0.1.0.dist-info/METADATA,sha256=sow1S5j23oZ9kslim07kBLQ1Gvk5G_CPNtHU0rofM64,6666
44
+ voxa_code-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
45
+ voxa_code-0.1.0.dist-info/entry_points.txt,sha256=BAhKDED9DiBogHH1cwnQoVdfKrdjW4t_KYWSlULoAMo,41
46
+ voxa_code-0.1.0.dist-info/top_level.txt,sha256=6THs7DkS2J_BX0FjF2W-iDl103KUE1k5yy4K_lCH6zc,14
47
+ voxa_code-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ voxa = server.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Voxa (Ti)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ server
2
+ static