- Add VoiceCapability interface with whisperAvailable, piperAvailable, voiceTierSufficient
- Extend HardwareInfo with voiceCapability field
- Add detectVoiceCapability() probing whisper-cpp/whisper and piper with 2s timeout each
- voiceTierSufficient: true for apple_silicon/gpu, or cpu_only with >= 4GB free RAM
- Wrap voice probe in 3s timeout to avoid slowing hardware detection
- Route automatically includes voiceCapability via existing HardwareInfo return
- Add streaming prop (default true) to ChatVoicePlayerProps
- Connect to POST /api/synthesize/stream via fetch + ReadableStream
- Parse SSE lines manually from response body stream
- First sentence audio begins playing as soon as first chunk arrives
- Subsequent sentences auto-play in sequence from audioQueue
- Show 'Sentence N of M' progress indicator during streaming playback
- Dot progress bar shows completed vs pending sentences
- Falls back to full-fetch mode on stream error or streaming=false
- Clean up all object URLs on unmount or new text
- Export splitSentences() with title-abbreviation protection (Dr., Mr. etc.)
- Add synthesizeSentenceStream() AsyncGenerator yielding per-sentence audio chunks
- Add synthesizeMultiLang() synthesizing same text in N voices via Promise.all
- Add POST /api/synthesize/stream SSE endpoint with base64 audio per sentence
- Add POST /api/synthesize/multi-lang returning array of voiceId+audio pairs
- Existing POST /api/synthesize unchanged (backward compatible)
- Refactor text relay into shared relayToAgent() used by both text/voice handlers
- Add bot.on('message:voice') handler: send 'Transcribing...' immediately, process async
- Download OGG from Telegram CDN via ctx.getFile() + fetch, transcribe via voicePipelineService
- Synthesize agent responses to OGG Opus via transcodeToOggOpus() and ctx.replyWithVoice()
- TTS failure degrades gracefully (text reply already sent, voice is bonus)
- telegram.ts stays at 322 lines (under 500-line TGRAM-06 constraint)
- Import telegramService, telegramRoutes, nexusSettingsService
- Mount /telegram routes under /api prefix
- Conditionally start Telegram bot on boot if telegramToken is configured
- Token route restarts bot after saving new token
- Install grammy v2 for long polling Telegram bot
- telegramService: text relay handler, agent prefix, session map, deleteWebhook lifecycle
- telegramRoutes: POST /telegram/token (getMe validation), GET /telegram/status
- telegram.ts under 500 lines (187 lines)
- BotFather numbered instructions (4-step setup guide)
- Token input with live validation via POST /api/telegram/token
- Success state showing connected bot username
- Error state with descriptive message
- Skip/Back/Next navigation; Next enabled only after validation
- postMessageAndStream data type extended with optional voiceMode field
- startStream signature updated: (userMessage, agentId?, voiceMode?)
- voiceMode forwarded into fetch body via postMessageAndStream call
- VoiceModeToggle: Text / Voice In / Full Voice pills with active/inactive styling
- Auto-play checkbox in full_voice mode, persists to nexus:voice:autoplay in localStorage
- useVoiceMode: reads/writes voiceMode via PATCH /api/nexus/settings with loading state
(deviation Rule 3: created missing blocking dependency for VoiceModeToggle)
- VoiceWaveform: 80x32 canvas with Web Audio AnalyserNode (fftSize=64), 20 animated bars drawn from frequency data using --primary color
- VoiceMicButton: three visual states — idle (Mic icon), recording (VoiceWaveform + ring-2 ring-primary), processing (Loader2 animate-spin)
- All three states have correct aria-labels per UI spec copywriting contract
- Add @ricky0123/vad-react dependency to ui/package.json
- Add copy-vad-assets npm script for reproducible asset copying
- Copy vad.worklet.bundle.min.js, silero_vad_legacy.onnx, silero_vad_v5.onnx to ui/public/
- Add COOP/COEP headers to Vite dev server config (SharedArrayBuffer support in dev)
- Update pnpm lockfile
- Add Cross-Origin-Opener-Policy: same-origin middleware before all routes
- Add Cross-Origin-Embedder-Policy: require-corp middleware before all routes
- Required for @ricky0123/vad-react (VAD uses SharedArrayBuffer internally)
- Create 37-01-SUMMARY.md with task results and deviations
- Update STATE.md: advance to plan 2, add decisions, update progress to 57%
- Update ROADMAP.md: phase 37 in progress (1/4 plans complete)
- Mark WCHAT-01, WCHAT-02, WCHAT-04 complete in REQUIREMENTS.md