feat(dictate): add voice-reactive listening waveform

This commit is contained in:
jb
2026-08-26 13:40:47 -04:00
parent e234468a73
commit d1a811a5c5
16 changed files with 383 additions and 73 deletions
+47 -3
View File
@@ -77,10 +77,17 @@ function createHarness() {
const sockets: FakeSocket[] = [];
const socketPaths: string[] = [];
const statuses: Array<string | undefined> = [];
const themeCalls: Array<{ color: string; text: string }> = [];
const notifications: Array<{ message: string; type?: string }> = [];
const pasted: string[] = [];
const context = {
ui: {
theme: {
fg: (color: string, text: string) => {
themeCalls.push({ color, text });
return text;
},
},
setStatus: (_key: string, text: string | undefined) => statuses.push(text),
notify: (message: string, type?: string) =>
notifications.push({ message, type }),
@@ -134,6 +141,7 @@ function createHarness() {
sockets,
socketPaths,
statuses,
themeCalls,
notifications,
pasted,
context,
@@ -213,7 +221,11 @@ test("rejects a mismatched protocol version before sending start", async () => {
assert.ok(socket);
socket.connect();
const hello = harness.sentFrames(socket)[0];
socket.frame({ version: 2, type: "pong", requestId: hello?.requestId });
socket.frame({
version: PROTOCOL_VERSION + 1,
type: "pong",
requestId: hello?.requestId,
});
assert.equal(harness.sentFrames(socket).length, 1);
assert.match(harness.notifications[0]?.message ?? "", /version mismatch/i);
@@ -266,19 +278,51 @@ test("renders authoritative service states and sends a bounded stop command", as
assert.deepEqual(harness.statuses, [
"loading model...",
"listening...",
"● listening ▁▁▁▁▁▁▁▁▁▁▁▁",
"stopping...",
"transcribing...",
]);
});
test("scrolls bounded audio levels through the listening waveform", async () => {
const harness = createHarness();
const { socket, generationId } = await connectAndNegotiate(harness);
serviceFrame(socket, generationId, "state", { state: "listening" });
assert.deepEqual(harness.themeCalls, [
{ color: "error", text: "●" },
{ color: "dim", text: "listening" },
{ color: "accent", text: "▁▁▁▁▁▁▁▁▁▁▁▁" },
]);
serviceFrame(socket, generationId, "level", { level: 0.5 });
serviceFrame(socket, generationId, "level", { level: 1 });
assert.deepEqual(harness.statuses, [
"● listening ▁▁▁▁▁▁▁▁▁▁▁▁",
"● listening ▁▁▁▁▁▁▁▁▁▁▁▅",
"● listening ▁▁▁▁▁▁▁▁▁▁▅█",
]);
});
test("rejects audio levels outside listening or the normalized range", async () => {
const beforeListening = createHarness();
const pending = await connectAndNegotiate(beforeListening);
serviceFrame(pending.socket, pending.generationId, "level", { level: 0.5 });
assert.match(beforeListening.notifications[0]?.message ?? "", /audio level is invalid/i);
const outOfRange = createHarness();
const active = await connectAndNegotiate(outOfRange);
serviceFrame(active.socket, active.generationId, "state", { state: "listening" });
serviceFrame(active.socket, active.generationId, "level", { level: 1.1 });
assert.match(outOfRange.notifications[0]?.message ?? "", /audio level is invalid/i);
});
test("ignores stale generations but rejects malformed and oversized frames", async () => {
const staleHarness = createHarness();
const { socket: staleSocket, generationId } = await connectAndNegotiate(staleHarness);
serviceFrame(staleSocket, "old-generation", "state", { state: "listening" });
assert.deepEqual(staleHarness.statuses, []);
serviceFrame(staleSocket, generationId, "state", { state: "listening" });
assert.deepEqual(staleHarness.statuses, ["listening..."]);
assert.deepEqual(staleHarness.statuses, ["● listening ▁▁▁▁▁▁▁▁▁▁▁▁"]);
const malformedHarness = createHarness();
const malformed = await connectAndNegotiate(malformedHarness);