@codexstar/pi-listen 1.0.4
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.
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/daemon.py +517 -0
- package/docs/API.md +273 -0
- package/docs/ARCHITECTURE.md +114 -0
- package/docs/backends.md +196 -0
- package/docs/plans/2026-03-12-pi-voice-master-plan.md +613 -0
- package/docs/plans/2026-03-12-pi-voice-model-aware-execution-plan.md +256 -0
- package/docs/plans/2026-03-12-pi-voice-onboarding-remediation-plan.md +391 -0
- package/docs/plans/pi-voice-model-aware-review.md +196 -0
- package/docs/plans/pi-voice-model-detection-qa-plan.md +226 -0
- package/docs/plans/pi-voice-model-detection-research.md +483 -0
- package/docs/plans/pi-voice-onboarding-ux-plan.md +388 -0
- package/docs/plans/pi-voice-release-validation-plan.md +386 -0
- package/docs/plans/pi-voice-remaining-implementation-plan.md +524 -0
- package/docs/plans/pi-voice-review-findings.md +227 -0
- package/docs/plans/pi-voice-technical-remediation-plan.md +613 -0
- package/docs/qa-matrix.md +69 -0
- package/docs/qa-results.md +357 -0
- package/docs/troubleshooting.md +265 -0
- package/extensions/voice/config.ts +206 -0
- package/extensions/voice/diagnostics.ts +212 -0
- package/extensions/voice/install.ts +62 -0
- package/extensions/voice/onboarding.ts +315 -0
- package/extensions/voice.ts +1149 -0
- package/package.json +48 -0
- package/scripts/setup-macos.sh +374 -0
- package/scripts/setup-windows.ps1 +271 -0
- package/transcribe.py +497 -0
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
# pi-voice technical remediation plan
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Turn `pi-voice` into a technically robust package that can support a premium onboarding flow without accumulating more correctness debt. This plan focuses on the architecture behind onboarding, runtime correctness, dependency provisioning, backend metadata, portability, and package structure.
|
|
6
|
+
|
|
7
|
+
## Current technical issues
|
|
8
|
+
|
|
9
|
+
### 1. Config is too thin
|
|
10
|
+
The current config model only captures:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"voice": {
|
|
15
|
+
"enabled": true,
|
|
16
|
+
"language": "en",
|
|
17
|
+
"backend": "auto",
|
|
18
|
+
"model": "small"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
That is not enough to represent:
|
|
24
|
+
- whether onboarding was completed
|
|
25
|
+
- whether the user chose cloud vs local intentionally
|
|
26
|
+
- which scope owns the config (global vs project)
|
|
27
|
+
- whether auto-install is allowed
|
|
28
|
+
- whether the backend was validated successfully
|
|
29
|
+
- which daemon/runtime profile should be active
|
|
30
|
+
|
|
31
|
+
### 2. Global daemon state can drift from config
|
|
32
|
+
Today the extension uses one hard-coded socket path:
|
|
33
|
+
- `extensions/voice.ts` -> `SOCKET_PATH`
|
|
34
|
+
- `daemon.py` -> `DEFAULT_SOCKET`
|
|
35
|
+
|
|
36
|
+
That creates shared mutable state across:
|
|
37
|
+
- projects
|
|
38
|
+
- sessions
|
|
39
|
+
- potentially different backend/model selections
|
|
40
|
+
|
|
41
|
+
`ensureDaemon()` returns early if any daemon is already running, even if that daemon was started with a different backend/model. `transcribeAudio()` currently does not pass `backend` and `model` to the daemon request, so the active daemon can silently continue with stale settings.
|
|
42
|
+
|
|
43
|
+
### 3. Setup persistence is inconsistent
|
|
44
|
+
`loadConfig()` merges global and project settings, but `/voice setup` writes only to global settings. That means the package already behaves as if scoped config matters, but it cannot save project-level intent.
|
|
45
|
+
|
|
46
|
+
### 4. Backend metadata is insufficient for recommendation and provisioning
|
|
47
|
+
`transcribe.py` exposes:
|
|
48
|
+
- `name`
|
|
49
|
+
- `available`
|
|
50
|
+
- `type`
|
|
51
|
+
- `default_model`
|
|
52
|
+
- `install`
|
|
53
|
+
- `models`
|
|
54
|
+
|
|
55
|
+
That is enough for a raw picker, but not for a recommendation engine or enterprise onboarding. The package lacks structured metadata for:
|
|
56
|
+
- privacy posture
|
|
57
|
+
- network requirement
|
|
58
|
+
- expected latency
|
|
59
|
+
- expected disk use
|
|
60
|
+
- install complexity
|
|
61
|
+
- whether warm model caching is supported
|
|
62
|
+
- whether the backend can be auto-installed safely
|
|
63
|
+
- recommended hardware tier
|
|
64
|
+
|
|
65
|
+
### 5. No provisioning abstraction exists
|
|
66
|
+
Installation and dependency repair are currently implicit/manual. There is no dedicated subsystem for:
|
|
67
|
+
- checking prerequisites
|
|
68
|
+
- producing an install plan
|
|
69
|
+
- executing safe install actions
|
|
70
|
+
- collecting stdout/stderr
|
|
71
|
+
- classifying failure modes
|
|
72
|
+
- retrying or falling back
|
|
73
|
+
|
|
74
|
+
### 6. Package shape is too minimal
|
|
75
|
+
The package is technically valid, but not operationally mature. It lacks:
|
|
76
|
+
- docs in the publish list
|
|
77
|
+
- scripts for validation
|
|
78
|
+
- package metadata for discoverability/supportability
|
|
79
|
+
- a modular code layout that can safely absorb onboarding and diagnostics growth
|
|
80
|
+
|
|
81
|
+
## Technical design principles
|
|
82
|
+
|
|
83
|
+
1. **Config is explicit, versioned, and migratable.**
|
|
84
|
+
2. **Runtime profile selection must be deterministic.** The active daemon must always match saved intent.
|
|
85
|
+
3. **Onboarding state is first-class.** “Not configured”, “configured”, and “broken” must be distinct states.
|
|
86
|
+
4. **Backend metadata must drive both UX and install logic.**
|
|
87
|
+
5. **Provisioning must be declarative first, imperative second.** Build an install plan before executing commands.
|
|
88
|
+
6. **Project-local and global scope must both be supported cleanly.**
|
|
89
|
+
7. **Non-interactive and interactive modes must degrade safely.**
|
|
90
|
+
8. **Package structure should be modular before adding more product surface.**
|
|
91
|
+
|
|
92
|
+
## Target architecture
|
|
93
|
+
|
|
94
|
+
## 1. Versioned config model
|
|
95
|
+
|
|
96
|
+
Replace the flat config with a versioned schema.
|
|
97
|
+
|
|
98
|
+
### Proposed shape
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"voice": {
|
|
103
|
+
"version": 2,
|
|
104
|
+
"enabled": true,
|
|
105
|
+
"mode": "local",
|
|
106
|
+
"language": "en",
|
|
107
|
+
"backend": "faster-whisper",
|
|
108
|
+
"model": "small",
|
|
109
|
+
"scope": "global",
|
|
110
|
+
"hotkeys": {
|
|
111
|
+
"editorHoldToTalk": true,
|
|
112
|
+
"toggleShortcut": "ctrl+shift+v",
|
|
113
|
+
"btwShortcut": "ctrl+shift+b"
|
|
114
|
+
},
|
|
115
|
+
"runtime": {
|
|
116
|
+
"warmDaemonOnStart": true,
|
|
117
|
+
"vadEnabled": true,
|
|
118
|
+
"daemonProfile": "global-local-faster-whisper-small-en"
|
|
119
|
+
},
|
|
120
|
+
"onboarding": {
|
|
121
|
+
"state": "completed",
|
|
122
|
+
"schemaVersion": 2,
|
|
123
|
+
"source": "first-run",
|
|
124
|
+
"completedAt": "2026-03-12T00:00:00.000Z",
|
|
125
|
+
"lastValidatedAt": "2026-03-12T00:02:00.000Z",
|
|
126
|
+
"dismissedAt": null
|
|
127
|
+
},
|
|
128
|
+
"provisioning": {
|
|
129
|
+
"autoInstall": true,
|
|
130
|
+
"allowBrew": true,
|
|
131
|
+
"allowPipUser": true,
|
|
132
|
+
"lastPlanId": "install-plan-123"
|
|
133
|
+
},
|
|
134
|
+
"cloud": {
|
|
135
|
+
"provider": null,
|
|
136
|
+
"apiKeyEnv": null
|
|
137
|
+
},
|
|
138
|
+
"health": {
|
|
139
|
+
"status": "ready",
|
|
140
|
+
"lastError": null,
|
|
141
|
+
"lastBackendCheckAt": "2026-03-12T00:01:00.000Z"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Required config helpers
|
|
148
|
+
|
|
149
|
+
Create a dedicated config module with:
|
|
150
|
+
- `loadVoiceConfig(cwd)`
|
|
151
|
+
- `saveVoiceConfig(config, scope, cwd)`
|
|
152
|
+
- `migrateVoiceConfig(input)`
|
|
153
|
+
- `getVoiceSettingsPaths(cwd)`
|
|
154
|
+
- `resolveEffectiveConfig(globalConfig, projectConfig)`
|
|
155
|
+
- `getConfigOwnership(config)`
|
|
156
|
+
|
|
157
|
+
### Scope model
|
|
158
|
+
|
|
159
|
+
Support both:
|
|
160
|
+
- global: `~/.pi/agent/settings.json`
|
|
161
|
+
- project: `<cwd>/.pi/settings.json`
|
|
162
|
+
|
|
163
|
+
Save path must be explicit, not implied.
|
|
164
|
+
|
|
165
|
+
## 2. Onboarding state machine
|
|
166
|
+
|
|
167
|
+
Treat onboarding as a state machine, not a boolean.
|
|
168
|
+
|
|
169
|
+
### Proposed states
|
|
170
|
+
- `unconfigured`
|
|
171
|
+
- `recommended`
|
|
172
|
+
- `provisioning`
|
|
173
|
+
- `validation_pending`
|
|
174
|
+
- `completed`
|
|
175
|
+
- `degraded`
|
|
176
|
+
- `dismissed`
|
|
177
|
+
|
|
178
|
+
### Why this matters
|
|
179
|
+
This separates:
|
|
180
|
+
- first install
|
|
181
|
+
- partially configured local install
|
|
182
|
+
- failed cloud auth
|
|
183
|
+
- a previously good setup that later broke
|
|
184
|
+
|
|
185
|
+
### Trigger logic on `session_start`
|
|
186
|
+
|
|
187
|
+
1. Load and migrate config.
|
|
188
|
+
2. If no UI, skip onboarding and runtime prompts.
|
|
189
|
+
3. If state is `completed` and health is `ready`, proceed.
|
|
190
|
+
4. If state is `unconfigured` or `degraded`, launch guided setup or show repair CTA.
|
|
191
|
+
5. Only start the daemon after the config has been validated for the active runtime profile.
|
|
192
|
+
|
|
193
|
+
## 3. Backend catalog abstraction
|
|
194
|
+
|
|
195
|
+
Move backend registry concerns out of ad-hoc strings and into a structured catalog consumable by both TypeScript and Python.
|
|
196
|
+
|
|
197
|
+
### Proposed backend metadata fields
|
|
198
|
+
|
|
199
|
+
For each backend, expose:
|
|
200
|
+
- `id`
|
|
201
|
+
- `label`
|
|
202
|
+
- `mode` (`local` or `cloud`)
|
|
203
|
+
- `available`
|
|
204
|
+
- `warmModelCapable`
|
|
205
|
+
- `installMethod` (`pip`, `brew`, `env`, `manual`, `mixed`)
|
|
206
|
+
- `installCommands`
|
|
207
|
+
- `models`
|
|
208
|
+
- `defaultModel`
|
|
209
|
+
- `recommendedModelByProfile`
|
|
210
|
+
- `privacy` (`offline`, `cloud`, `hybrid`)
|
|
211
|
+
- `networkRequired`
|
|
212
|
+
- `resourceTier` (`low`, `medium`, `high`)
|
|
213
|
+
- `latencyTier` (`fast`, `balanced`, `slow`)
|
|
214
|
+
- `qualityTier` (`good`, `better`, `best`)
|
|
215
|
+
- `diskEstimate`
|
|
216
|
+
- `hardwareNotes`
|
|
217
|
+
- `apiKeyEnv`
|
|
218
|
+
- `validationStrategy`
|
|
219
|
+
- `autoInstallSupported`
|
|
220
|
+
|
|
221
|
+
### Implementation options
|
|
222
|
+
|
|
223
|
+
Preferred:
|
|
224
|
+
- Add a shared `backends.json` or `backends.ts` manifest at the package level.
|
|
225
|
+
- Keep Python and TypeScript aligned by generating one side from the other, or by treating JSON as the source of truth.
|
|
226
|
+
|
|
227
|
+
Minimum acceptable:
|
|
228
|
+
- keep the Python registry but enrich `--list-backends` output with structured fields
|
|
229
|
+
- consume that richer JSON from the extension
|
|
230
|
+
|
|
231
|
+
## 4. Diagnostics engine
|
|
232
|
+
|
|
233
|
+
Add a diagnostics subsystem that produces a machine-readable readiness report.
|
|
234
|
+
|
|
235
|
+
### Inputs
|
|
236
|
+
- platform / architecture
|
|
237
|
+
- `python3` availability
|
|
238
|
+
- `brew` availability
|
|
239
|
+
- `rec` / SoX availability
|
|
240
|
+
- backend availability from `transcribe.py --list-backends`
|
|
241
|
+
- required env vars
|
|
242
|
+
- optional daemon status
|
|
243
|
+
- optional sample audio validation
|
|
244
|
+
|
|
245
|
+
### Output shape
|
|
246
|
+
|
|
247
|
+
```json
|
|
248
|
+
{
|
|
249
|
+
"status": "ready",
|
|
250
|
+
"recommendedMode": "local",
|
|
251
|
+
"recommendedBackend": "faster-whisper",
|
|
252
|
+
"recommendedModel": "small",
|
|
253
|
+
"issues": [
|
|
254
|
+
{
|
|
255
|
+
"id": "missing-sox",
|
|
256
|
+
"severity": "blocking",
|
|
257
|
+
"message": "SoX is required for microphone recording.",
|
|
258
|
+
"fix": {
|
|
259
|
+
"auto": true,
|
|
260
|
+
"commands": ["brew install sox"]
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
],
|
|
264
|
+
"capabilities": {
|
|
265
|
+
"python": true,
|
|
266
|
+
"brew": true,
|
|
267
|
+
"rec": false,
|
|
268
|
+
"cloudAuth": false
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Responsibilities
|
|
274
|
+
- recommend mode/backend/model
|
|
275
|
+
- classify blockers vs warnings
|
|
276
|
+
- provide install plans
|
|
277
|
+
- power `/voice doctor`
|
|
278
|
+
- feed onboarding defaults
|
|
279
|
+
|
|
280
|
+
## 5. Provisioning subsystem
|
|
281
|
+
|
|
282
|
+
Create a dedicated provisioning layer instead of embedding installation logic inside command handlers.
|
|
283
|
+
|
|
284
|
+
### New module responsibilities
|
|
285
|
+
- build install plan from diagnostics
|
|
286
|
+
- execute allowed steps
|
|
287
|
+
- stream progress and capture logs
|
|
288
|
+
- classify failures
|
|
289
|
+
- emit structured result objects
|
|
290
|
+
|
|
291
|
+
### Proposed install action model
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
interface InstallAction {
|
|
295
|
+
id: string;
|
|
296
|
+
type: "brew" | "pip" | "env-check" | "python-import" | "warm-model" | "validate-cloud";
|
|
297
|
+
label: string;
|
|
298
|
+
command?: string[];
|
|
299
|
+
safeToAutoRun: boolean;
|
|
300
|
+
retryable: boolean;
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Local provisioning flows
|
|
305
|
+
- install SoX if missing
|
|
306
|
+
- install backend runtime if supported
|
|
307
|
+
- optionally warm the selected model
|
|
308
|
+
- verify transcription path
|
|
309
|
+
|
|
310
|
+
### Cloud provisioning flows
|
|
311
|
+
- verify required env var exists
|
|
312
|
+
- optionally validate API access with a lightweight provider request
|
|
313
|
+
- verify selected model is accepted
|
|
314
|
+
|
|
315
|
+
### Failure handling
|
|
316
|
+
Each failed step should produce:
|
|
317
|
+
- step id
|
|
318
|
+
- command
|
|
319
|
+
- exit code
|
|
320
|
+
- stderr excerpt
|
|
321
|
+
- recommended remediation
|
|
322
|
+
|
|
323
|
+
That should be stored in memory during onboarding and surfaced by `/voice doctor`.
|
|
324
|
+
|
|
325
|
+
## 6. Deterministic daemon lifecycle
|
|
326
|
+
|
|
327
|
+
This is the most important runtime fix.
|
|
328
|
+
|
|
329
|
+
### Current problem
|
|
330
|
+
A global daemon can continue using a stale backend/model because the extension does not fully bind requests to the desired config.
|
|
331
|
+
|
|
332
|
+
### Required design change
|
|
333
|
+
Introduce a `RuntimeProfile` abstraction.
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
interface RuntimeProfile {
|
|
337
|
+
mode: "local" | "cloud" | "auto";
|
|
338
|
+
backend: string;
|
|
339
|
+
model: string;
|
|
340
|
+
language: string;
|
|
341
|
+
vadEnabled: boolean;
|
|
342
|
+
scope: "global" | "project";
|
|
343
|
+
profileId: string;
|
|
344
|
+
configHash: string;
|
|
345
|
+
socketPath: string;
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Rules
|
|
350
|
+
1. The extension computes a runtime profile from effective config.
|
|
351
|
+
2. The daemon status endpoint returns enough data to identify the active profile.
|
|
352
|
+
3. If daemon profile != desired profile, the extension reloads or replaces it.
|
|
353
|
+
4. Transcribe requests must include `backend`, `model`, and `language` even when a daemon is already running.
|
|
354
|
+
|
|
355
|
+
### Socket strategy
|
|
356
|
+
|
|
357
|
+
Preferred:
|
|
358
|
+
- derive socket path from `profileId` or `configHash`
|
|
359
|
+
- example: `/tmp/pi-voice-<uid>-<hash>.sock`
|
|
360
|
+
|
|
361
|
+
Benefits:
|
|
362
|
+
- avoids collisions across projects/config scopes
|
|
363
|
+
- allows multiple compatible daemons if needed
|
|
364
|
+
- makes debugging easier
|
|
365
|
+
|
|
366
|
+
Minimum acceptable:
|
|
367
|
+
- keep one socket but always send explicit runtime parameters and force reload on mismatch
|
|
368
|
+
|
|
369
|
+
### Daemon status contract changes
|
|
370
|
+
Add fields to `status`:
|
|
371
|
+
- `backend`
|
|
372
|
+
- `model`
|
|
373
|
+
- `language`
|
|
374
|
+
- `profile_id`
|
|
375
|
+
- `config_hash`
|
|
376
|
+
- `warm_capable`
|
|
377
|
+
- `last_error`
|
|
378
|
+
|
|
379
|
+
### Daemon control changes
|
|
380
|
+
Add or refine commands:
|
|
381
|
+
- `status`
|
|
382
|
+
- `load`
|
|
383
|
+
- `reload`
|
|
384
|
+
- `shutdown`
|
|
385
|
+
- optional `backends`
|
|
386
|
+
|
|
387
|
+
### Important note
|
|
388
|
+
Cloud backends do not need persistent warm models, but they still need a stable profile and health contract.
|
|
389
|
+
|
|
390
|
+
## 7. Runtime module split
|
|
391
|
+
|
|
392
|
+
Refactor the monolithic `extensions/voice.ts` into smaller modules.
|
|
393
|
+
|
|
394
|
+
### Proposed file layout
|
|
395
|
+
|
|
396
|
+
```text
|
|
397
|
+
extensions/
|
|
398
|
+
voice/
|
|
399
|
+
index.ts
|
|
400
|
+
config.ts
|
|
401
|
+
onboarding.ts
|
|
402
|
+
diagnostics.ts
|
|
403
|
+
provisioning.ts
|
|
404
|
+
runtime.ts
|
|
405
|
+
daemon.ts
|
|
406
|
+
backends.ts
|
|
407
|
+
commands.ts
|
|
408
|
+
btw.ts
|
|
409
|
+
types.ts
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Responsibilities
|
|
413
|
+
- `index.ts`: extension registration and lifecycle wiring
|
|
414
|
+
- `config.ts`: load/save/migrate/effective config logic
|
|
415
|
+
- `onboarding.ts`: first-run and reconfigure flow orchestration
|
|
416
|
+
- `diagnostics.ts`: environment scan and health reporting
|
|
417
|
+
- `provisioning.ts`: install actions and remediation execution
|
|
418
|
+
- `runtime.ts`: audio recording and transcription dispatch
|
|
419
|
+
- `daemon.ts`: profile-aware daemon communication
|
|
420
|
+
- `backends.ts`: backend metadata and recommendation helpers
|
|
421
|
+
- `commands.ts`: `/voice`, `/voice doctor`, `/voice reconfigure`, `/voice info`
|
|
422
|
+
- `btw.ts`: BTW-specific logic only
|
|
423
|
+
- `types.ts`: shared TS interfaces
|
|
424
|
+
|
|
425
|
+
This should happen before adding more complex UI or provisioning logic.
|
|
426
|
+
|
|
427
|
+
## 8. Portability strategy
|
|
428
|
+
|
|
429
|
+
The package currently assumes a macOS-ish environment in practice.
|
|
430
|
+
|
|
431
|
+
### Current hidden assumptions
|
|
432
|
+
- `rec` exists and comes from SoX
|
|
433
|
+
- `brew` may be used to install native dependencies
|
|
434
|
+
- `python3` is available
|
|
435
|
+
- local model stacks work on CPU
|
|
436
|
+
|
|
437
|
+
### Portability tiers
|
|
438
|
+
|
|
439
|
+
#### Tier 1: macOS Apple Silicon
|
|
440
|
+
Primary target for polished local onboarding.
|
|
441
|
+
- optimize recommendations for `faster-whisper`
|
|
442
|
+
- provide `brew` + `pip` install paths
|
|
443
|
+
- use this as the first-class supported path
|
|
444
|
+
|
|
445
|
+
#### Tier 2: Linux desktop
|
|
446
|
+
Supported with diagnostics-led setup.
|
|
447
|
+
- no Homebrew assumption
|
|
448
|
+
- more manual/local distro variance
|
|
449
|
+
- provisioning may need to fall back to manual commands
|
|
450
|
+
|
|
451
|
+
#### Tier 3: non-interactive / RPC / CI
|
|
452
|
+
Do not auto-onboard.
|
|
453
|
+
- commands should return structured errors
|
|
454
|
+
- diagnostics should still work
|
|
455
|
+
- setup should be re-runnable when UI exists
|
|
456
|
+
|
|
457
|
+
### Portability policy
|
|
458
|
+
Document explicitly which flows are:
|
|
459
|
+
- fully automated
|
|
460
|
+
- partially automated
|
|
461
|
+
- manual only
|
|
462
|
+
|
|
463
|
+
## 9. Package structure and metadata
|
|
464
|
+
|
|
465
|
+
### `package.json` improvements
|
|
466
|
+
Add:
|
|
467
|
+
- richer description
|
|
468
|
+
- `repository`
|
|
469
|
+
- `homepage`
|
|
470
|
+
- `bugs`
|
|
471
|
+
- `keywords`
|
|
472
|
+
- scripts
|
|
473
|
+
- peerDependencies for Pi runtime packages
|
|
474
|
+
- `README.md` and `docs/` in `files`
|
|
475
|
+
|
|
476
|
+
### Suggested scripts
|
|
477
|
+
|
|
478
|
+
```json
|
|
479
|
+
{
|
|
480
|
+
"scripts": {
|
|
481
|
+
"typecheck": "bunx tsc -p tsconfig.json",
|
|
482
|
+
"check:python": "python3 -m py_compile daemon.py transcribe.py",
|
|
483
|
+
"check": "bun run typecheck && bun run check:python"
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Publish list
|
|
489
|
+
Include:
|
|
490
|
+
- `extensions`
|
|
491
|
+
- `daemon.py`
|
|
492
|
+
- `transcribe.py`
|
|
493
|
+
- `README.md`
|
|
494
|
+
- `docs`
|
|
495
|
+
- any shared backend metadata assets
|
|
496
|
+
|
|
497
|
+
## 10. Recommended implementation sequence
|
|
498
|
+
|
|
499
|
+
### Phase A — correctness foundation
|
|
500
|
+
Files:
|
|
501
|
+
- `extensions/voice.ts`
|
|
502
|
+
- `daemon.py`
|
|
503
|
+
|
|
504
|
+
Tasks:
|
|
505
|
+
- always pass `backend`/`model`/`language` to daemon transcribe requests
|
|
506
|
+
- make daemon status profile-aware
|
|
507
|
+
- stop eager daemon startup until config is validated
|
|
508
|
+
- add safer socket/profile strategy
|
|
509
|
+
|
|
510
|
+
### Phase B — config and metadata foundation
|
|
511
|
+
Files:
|
|
512
|
+
- new `extensions/voice/config.ts`
|
|
513
|
+
- new `extensions/voice/types.ts`
|
|
514
|
+
- `transcribe.py` or shared backend manifest
|
|
515
|
+
|
|
516
|
+
Tasks:
|
|
517
|
+
- versioned config schema
|
|
518
|
+
- scope-aware save/load helpers
|
|
519
|
+
- onboarding state machine
|
|
520
|
+
- richer backend metadata contract
|
|
521
|
+
|
|
522
|
+
### Phase C — diagnostics and provisioning foundation
|
|
523
|
+
Files:
|
|
524
|
+
- new `extensions/voice/diagnostics.ts`
|
|
525
|
+
- new `extensions/voice/provisioning.ts`
|
|
526
|
+
- `transcribe.py`
|
|
527
|
+
|
|
528
|
+
Tasks:
|
|
529
|
+
- machine-readable readiness checks
|
|
530
|
+
- install plan generation
|
|
531
|
+
- execution wrappers and failure classification
|
|
532
|
+
|
|
533
|
+
### Phase D — extension modularization
|
|
534
|
+
Files:
|
|
535
|
+
- split current `extensions/voice.ts` into focused modules
|
|
536
|
+
|
|
537
|
+
Tasks:
|
|
538
|
+
- isolate BTW logic
|
|
539
|
+
- isolate runtime recording/transcription logic
|
|
540
|
+
- isolate command registration
|
|
541
|
+
|
|
542
|
+
### Phase E — onboarding and doctor flows
|
|
543
|
+
Files:
|
|
544
|
+
- `extensions/voice/onboarding.ts`
|
|
545
|
+
- `extensions/voice/commands.ts`
|
|
546
|
+
|
|
547
|
+
Tasks:
|
|
548
|
+
- first-run wizard
|
|
549
|
+
- `/voice doctor`
|
|
550
|
+
- `/voice reconfigure`
|
|
551
|
+
- summary/health reporting
|
|
552
|
+
|
|
553
|
+
### Phase F — package hardening
|
|
554
|
+
Files:
|
|
555
|
+
- `package.json`
|
|
556
|
+
- `README.md`
|
|
557
|
+
- `docs/*`
|
|
558
|
+
|
|
559
|
+
Tasks:
|
|
560
|
+
- metadata
|
|
561
|
+
- docs
|
|
562
|
+
- validation scripts
|
|
563
|
+
- release supportability
|
|
564
|
+
|
|
565
|
+
## Risks and decisions to resolve early
|
|
566
|
+
|
|
567
|
+
### 1. Shared metadata source of truth
|
|
568
|
+
Decide whether backend metadata lives in:
|
|
569
|
+
- Python only,
|
|
570
|
+
- TypeScript only,
|
|
571
|
+
- or shared JSON.
|
|
572
|
+
|
|
573
|
+
Recommendation: **shared JSON or TS-generated JSON**.
|
|
574
|
+
|
|
575
|
+
### 2. Auto-install safety policy
|
|
576
|
+
Decide what the extension may execute automatically:
|
|
577
|
+
- just diagnostics
|
|
578
|
+
- diagnostics + optional package install
|
|
579
|
+
- diagnostics + fully automatic remediation by default
|
|
580
|
+
|
|
581
|
+
Recommendation: **opt-in auto-install during onboarding** with clear user confirmation.
|
|
582
|
+
|
|
583
|
+
### 3. Daemon multiplicity
|
|
584
|
+
Decide whether to support:
|
|
585
|
+
- one daemon per config profile
|
|
586
|
+
- or one daemon that reloads in place
|
|
587
|
+
|
|
588
|
+
Recommendation: **profile-derived socket path**, with reload support as a secondary optimization.
|
|
589
|
+
|
|
590
|
+
### 4. Cloud provider expansion
|
|
591
|
+
Today only Deepgram is implemented for cloud. The config model should be provider-ready even if the first polished flow only supports one cloud backend.
|
|
592
|
+
|
|
593
|
+
## Definition of done for the technical architecture
|
|
594
|
+
|
|
595
|
+
The architecture work is complete when:
|
|
596
|
+
- config has a versioned schema and migration path
|
|
597
|
+
- onboarding state is explicit and persisted
|
|
598
|
+
- project/global scope is saved intentionally
|
|
599
|
+
- backend metadata supports recommendation and install logic
|
|
600
|
+
- diagnostics returns structured readiness data
|
|
601
|
+
- provisioning executes from an install plan, not ad-hoc shelling out
|
|
602
|
+
- daemon/runtime profile selection is deterministic
|
|
603
|
+
- stale daemon config cannot silently override saved user intent
|
|
604
|
+
- code is split into maintainable modules
|
|
605
|
+
- package metadata and validation scripts support shipping the package confidently
|
|
606
|
+
|
|
607
|
+
## Final recommendation
|
|
608
|
+
|
|
609
|
+
Do the technical remediation in this order:
|
|
610
|
+
|
|
611
|
+
**runtime correctness -> config/schema -> backend metadata -> diagnostics -> provisioning -> modularization -> package hardening**
|
|
612
|
+
|
|
613
|
+
That order prevents the team from building a polished onboarding flow on top of an unstable runtime contract.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# pi-voice QA matrix
|
|
2
|
+
|
|
3
|
+
This checklist separates what has already been verified from what is still worth running on a target release machine.
|
|
4
|
+
|
|
5
|
+
## Automated checks completed
|
|
6
|
+
|
|
7
|
+
- [x] TypeScript compiles via `bun run typecheck`
|
|
8
|
+
- [x] Python files compile via `python3 -m py_compile daemon.py transcribe.py`
|
|
9
|
+
- [x] Config migration and scope tests pass
|
|
10
|
+
- [x] Diagnostics recommendation tests pass
|
|
11
|
+
- [x] Provisioning-plan helper tests pass
|
|
12
|
+
- [x] Onboarding fallback/finalization tests pass
|
|
13
|
+
- [x] Model-detection metadata tests pass
|
|
14
|
+
- [x] Model-aware recommendation and labeling tests pass
|
|
15
|
+
- [x] Aggregate verification passes via `bun run check`
|
|
16
|
+
|
|
17
|
+
## RPC-assisted / smoke checks completed
|
|
18
|
+
|
|
19
|
+
### First-run onboarding
|
|
20
|
+
- [x] Fresh install with no config triggers onboarding prompt on interactive startup
|
|
21
|
+
- [x] Choosing `Remind me later` suppresses the prompt during the defer window
|
|
22
|
+
- [x] `/voice reconfigure` reopens the onboarding flow
|
|
23
|
+
- [x] Partial legacy config re-enters onboarding instead of being treated as complete
|
|
24
|
+
- [x] API-vs-Local choice appears correctly in the terminal UI
|
|
25
|
+
|
|
26
|
+
### Local mode and model-aware behavior
|
|
27
|
+
- [x] Local path still offers backend choices even when no cached models are found
|
|
28
|
+
- [x] Suggested commands are sensible for missing SoX and local backend installs
|
|
29
|
+
- [x] Missing-model path is represented cleanly through model-aware provisioning/manual-step logic
|
|
30
|
+
- [x] `/voice doctor` distinguishes current-config repair from recommended alternative
|
|
31
|
+
- [x] Backend scan exposes `installed_models` and `install_detection` metadata
|
|
32
|
+
- [x] `/voice backends` surfaces model-aware backend summaries and detection hints
|
|
33
|
+
- [x] `/voice info` surfaces current model readiness and scope details
|
|
34
|
+
- [x] `/voice test` surfaces current model readiness plus targeted guidance
|
|
35
|
+
|
|
36
|
+
### Scope and reconfiguration
|
|
37
|
+
- [x] Project scope writes to `.pi/settings.json`
|
|
38
|
+
- [x] Reconfigure path saves updated choices
|
|
39
|
+
- [x] Repair-needed states stay incomplete instead of being falsely marked complete
|
|
40
|
+
|
|
41
|
+
## Remaining target-machine checks
|
|
42
|
+
|
|
43
|
+
These are the highest-value checks still worth running on the actual release machine.
|
|
44
|
+
|
|
45
|
+
### Real audio / device validation
|
|
46
|
+
- [ ] Hold-to-talk with a real microphone transcribes successfully after setup
|
|
47
|
+
- [ ] `Ctrl+Shift+V` fallback recording works in the target terminal
|
|
48
|
+
- [ ] `Ctrl+Shift+B` BTW voice path still works end-to-end
|
|
49
|
+
|
|
50
|
+
### Real provider / ready-now validation
|
|
51
|
+
- [ ] Cloud setup completes successfully when `DEEPGRAM_API_KEY` is present
|
|
52
|
+
- [ ] Local setup completes successfully on a machine with SoX installed and a supported backend available
|
|
53
|
+
- [ ] Runtime uses the selected backend/model after reconfiguration
|
|
54
|
+
- [ ] Config-scoped socket behavior avoids silent stale-daemon reuse under real session switching
|
|
55
|
+
|
|
56
|
+
### Installed-model specific validation
|
|
57
|
+
- [ ] At least one machine with an already cached local model shows an explicit ready-now / already-installed path in onboarding
|
|
58
|
+
- [ ] At least one machine with backend installed but selected model missing shows clear download-required messaging
|
|
59
|
+
- [ ] `/voice info` and `/voice test` reflect the selected model's readiness accurately on a machine with real caches
|
|
60
|
+
|
|
61
|
+
## Suggested execution order
|
|
62
|
+
|
|
63
|
+
1. Fresh install / first-run prompt
|
|
64
|
+
2. Remind-me-later and reconfigure path
|
|
65
|
+
3. Project-scope save path
|
|
66
|
+
4. Model-aware local path with no cached models
|
|
67
|
+
5. Installed-model ready-now path on a machine with real caches
|
|
68
|
+
6. Cloud/API happy path with valid credentials
|
|
69
|
+
7. Real microphone / hold-to-talk sanity pass
|