- Add cancelJob() to whisper.ts: sends DELETE /jobs/:id to the whisper
server (best-effort, errors silently ignored)
- DELETE /api/jobs/[id] now calls cancelJob() when cancelling an active
job that has a whisperJobId, stopping GPU use immediately
- Webhook handler guards against locally-cancelled jobs: returns ok early
so whisper's late completion cannot overwrite cancelled status or send
a phantom 'Transcript ready' notification
- Replace blind sleep(Retry-After + 1s) in submitJob() with
waitForModelReady(): subscribes to /model/events SSE and proceeds as
soon as state:ready arrives; falls back to the Retry-After timeout if
SSE is unreachable or closes without model_ready
- Refactor retry tests to use URL-aware makeJobFetch() helper; add 7 new
tests (3 SSE-triggered retry, 3 cancelJob, 1 webhook cancelled-guard)
— 144/144 passing
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tonemark is a SvelteKit PWA for transcribing YouTube videos, audio
and video files, and microphone recordings using a local Whisper backend.
Features:
- Dark glassmorphic UI with electric-lime accent (5 switchable themes)
- Rail nav (desktop) / tab bar (mobile) layout
- Drop zone, YouTube URL input, and live audio recording inputs
- Audio mode waveform cards (none / standard / aggressive / auto)
- Real-time transcription progress with animated waveform
- Job queue with SSE streaming updates
- Push notifications on job completion
- PWA with native SvelteKit service worker
- SRT / TXT / MD / JSON transcript downloads
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>