Three bugs fixed:
1. api/jobs.ts: remove manual Content-Type header on FormData upload.
Setting it without the multipart boundary caused Quart to reject the
request body — the root cause of brief upload failures.
2. progress.py: include full job.to_dict() in job.progress / job.completed
/ job.failed WebSocket messages. Frontend checks msg.job to call
updateJob() — without it, job cards never updated in real-time.
3. AppShell: move useWebSocket() here from BriefUploadPage so the WS
connection persists across all pages, not just the upload page.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>