All checks were successful
Deploy / deploy (push) Successful in 3m12s
Adds the tablet side of voice assistant integration. External Python script (openWakeWord + Groq STT + OpenClaw) will POST state transitions to /api/voice/event with a bearer token, and the tablet shows a fullscreen overlay with Siri-style animated blob + current agent + recognized text / response text. - lib/voice-bus.ts — in-process EventEmitter singleton, preserved across hot reloads via globalThis - app/api/voice/event — POST, bearer-auth via VOICE_API_KEY env, validates event kind, broadcasts on voiceBus - app/api/voice/stream — GET, SSE endpoint, per-connection listener with 15s keep-alive ping and abort-signal cleanup - components/VoiceOverlay — full-screen overlay, 3-layer pulsing Siri blob, per-agent palette (cosmo indigo/violet, lusya pink/rose), auto-dismiss timeouts (wake=20s safety, response=6s, error=4s), auto-reconnect on SSE drop - middleware bypasses /api/voice/event so the script does not need a user auth cookie - VoiceOverlay mounted in HomePageInner outside tab routing so it appears on every view
26 lines
889 B
TypeScript
26 lines
889 B
TypeScript
import { NextResponse } from 'next/server'
|
|
import type { NextRequest } from 'next/server'
|
|
|
|
export async function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl
|
|
|
|
// Only protect API routes (except /api/auth and /api/voice/event which has its own bearer auth)
|
|
if (!pathname.startsWith('/api/') || pathname.startsWith('/api/auth') || pathname === '/api/voice/event') {
|
|
return NextResponse.next()
|
|
}
|
|
|
|
// Check auth by forwarding to auth check
|
|
const token = request.cookies.get('auth_token')?.value
|
|
if (!token) {
|
|
return NextResponse.json({ error: 'unauthorized' }, { status: 401 })
|
|
}
|
|
|
|
// Let the request through — individual API routes can do further validation if needed
|
|
// The auth cookie existence is sufficient since it is httpOnly and set by server
|
|
return NextResponse.next()
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ['/api/:path*'],
|
|
}
|