13 Commits

Author SHA1 Message Date
4139eb8fd3 fix: audio pipeline — 16 kHz AudioContext, 4096-sample buffering, SERVER_READY handshake
Root causes of disconnection and slow transcription:
- AudioWorklet was firing every 128 native samples (~48 kHz), sending
  ~375 tiny WebSocket messages/sec. Server flooded with tiny frames
  during silence → keepalive ping timed out → connection dropped.
- JS resampling 48 kHz → 16 kHz added CPU overhead on every chunk.
- Audio started on ws.onopen before server sent SERVER_READY, so early
  frames were dropped.

Fixes:
- audioWorklet.js: accumulate 4096 samples before posting (256 ms/chunk
  at 16 kHz, ~4 messages/sec), transfer ArrayBuffer zero-copy.
- transcriptionService: AudioContext({ sampleRate: 16000 }) — browser
  handles native resampling, no JS resampling needed. Remove
  resampleTo16kHZ entirely.
- Wait for SERVER_READY message before calling setupAudioProcessing().
- Send 'END_OF_AUDIO' string on stop so server can finalise last segment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 07:26:20 +00:00
308889937c fix: transcription segment dedup, store finalisation, and panel colours
- transcriptionService: track finalizedSegmentCount so only newly-final
  segments are emitted per WS message (was re-processing full array each
  time, causing the live segment to freeze in the completed list)
- transcriptionStore: saveSegment isFinal branch now appends the passed
  text directly instead of currentSegment (currentSegment was stale
  relative to the incoming final)
- CCTranscriptionPanel: record button colour changed from var(--color-text)
  to explicit #2563eb so it is visible in dark mode; completed segment
  backgrounds changed from hardcoded #fff to var(--color-muted) so text
  is readable in both themes; keyword Add button gets same blue fix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 07:08:53 +00:00
0345258247 fix: transcription getUserMedia called before enumerateDevices
The old startTranscription() called enumerateDevices() first to find a
device ID, then getUserMedia. Without microphone permission, enumerateDevices()
returns devices with deviceId="" (empty string, falsy). This caused the
!this.selectedDeviceId check to bail out early, never calling getUserMedia,
never prompting the user for mic permission, and never creating the WebSocket.

Result: user clicks Start Recording → isRecording=true → button changes to
Stop Recording → but no mic prompt, no WebSocket, no transcription.

Fix: call getUserMedia directly (with optional echoCancellation/noiseSuppression
if no device pre-selected). getUserMedia triggers the browser permission prompt
automatically. Device selection is still honoured via exact deviceId constraint
when one has been explicitly chosen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 19:32:43 +00:00
5e21a2c7fc fix: add missing transcription entry to PANEL_DIMENSIONS
BasePanel reads PANEL_DIMENSIONS[currentPanelType] to get the panel
dimensions (topOffset, bottomOffset, width). The transcription panel
type was added to the panel list and render switch during CIS Phase 3C
but was never added to PANEL_DIMENSIONS. This caused a crash whenever
the BasePanel rendered with the transcription tab active:

  PANEL_DIMENSIONS["transcription"] === undefined
  undefined.topOffset → TypeError: Cannot read properties of undefined

This crash appeared as a topOffset error anywhere a Tldraw canvas was
rendered (singlePlayerPage, multiplayerUser, etc.).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 19:05:51 +00:00
06f761e750 feat(cis): add Keywords tab — watches, real-time detection, match log (Phase 3C)
- KeywordWatch and KeywordMatch interfaces in transcriptionStore
- loadKeywordWatches, addKeywordWatch, deleteKeywordWatch actions via API with JWT auth
- checkSegmentForKeywords: client-side detection on each final segment, logs events to backend
- clearKeywordMatches: resets session-scoped match list
- Keywords tab in CCTranscriptionPanel: add/delete watches, match log with timestamp
- Match count badge on Keywords tab when hits exist during recording
- Also fixes missing Close import that was present in summary modal
2026-05-21 12:21:17 +00:00
4d10d75003 fix(cis): fix JSX syntax errors and import paths for Phase 3 build
- Fix broken template literal in transcriptionStore.ts export function
- Fix broken regex in Content-Disposition parser
- Fix broken character class in filename sanitization
- Fix LLMConfigModal import path (5 levels up, not 6)
- Export button JSX properly nested in CCTranscriptionPanel
- Build now passes cleanly
2026-05-21 06:35:09 +00:00
cb8c2dab74 feat(cis): add LLM config modal, summary generation, keywords tab, and export button (Phase 3)
- LLMConfigModal: provider dropdown, model field, API key input (localStorage only)
- Summary generation: modal with 5 summary types, calls API, displays result
- Keywords tab: add/delete watches, real-time detection, event logging
- Export button: SRT/TXT/JSON download via API endpoint
- All Phase 3 frontend tasks complete
2026-05-20 22:57:06 +00:00
6bbed42f55 feat(cis): add Supabase integration, canvas event logger, and sessions tab (Phase 2)
- Connect transcriptionStore to Supabase (start/stop session, save segments)
- Add CanvasEventLogger for silent TLDraw activity tracking
- Add Sessions tab to CCTranscriptionPanel with past sessions list
- Auto-detect timetable context on panel mount
- Flush canvas events to API every 5 seconds during recording
2026-05-20 22:06:31 +00:00
2ee4e4afe7 feat(cis): add CCTranscriptionPanel Live tab to sidebar (Phase 1)
- Add CCTranscriptionPanel component with Live tab
- Add Zustand transcriptionStore for session state management
- Wire panel into BasePanel sidebar system
- Fix merged switch cases in getIconForPanel, getDescriptionForPanel, renderCurrentPanel
- Add VITE_WHISPERLIVE_URL to .env
2026-05-20 21:34:21 +00:00
Agent Zero
067df34c50 fix: correct Material UI icon naming in Header.tsx and update timetable components
- Fix icon naming: remove 'Icon' suffix from MUI icon components in Header.tsx
  (AccessTime, Close, Person, School, Schedule, Class, Book, Settings, Student, Login, Logout)
- Update timetable components to use UserContext instead of ProfileContext
- Fix timetableService naming collision and circular reference
- Update various components for consistency
2026-02-26 07:28:47 +00:00
5c100a015d feat: update source files, Dockerfile, vite config and service worker 2026-02-21 16:25:42 +00:00
3b4876793e latest 2025-11-14 14:47:26 +00:00
8a7ab3ac24 Initial commit 2025-07-11 13:21:49 +00:00