Commit Graph
203 Commits
Author SHA1 Message Date
jason.woltje b43e860c40 feat(web): Phase 3 — Dashboard Page (#450) (#453)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-22 21:18:50 +00:00
jason.woltje 716f230f72 feat(ui,web): Phase 2 — Shared Components & Terminal Panel (#449) (#452)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-22 21:12:13 +00:00
jason.woltje a5ed260fbd feat(web): MS15 Phase 1 — Design System & App Shell (#451)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-22 20:57:06 +00:00
jason.woltje 17144b1c42 style(ui): refine login card shape and divider spacing (#439)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-22 06:19:23 +00:00
jason.woltje 06e54328d5 fix(web): force dynamic rendering for runtime env injection (#437)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-22 03:54:12 +00:00
jason.woltje 1b66417be5 fix(web): restore login page design and add runtime config injection (#435)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-21 23:16:02 +00:00
jason.woltje 25ae14aba1 fix(web): resolve flaky CI test failures (#433)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-21 21:12:00 +00:00
jason.woltjeandClaude Opus 4.6 bc4c1f9c70 Merge develop into main
Consolidate all feature and fix branches into main:
- feat: orchestrator observability + mosaic rails integration (#422)
- fix: post-422 CI and compose env follow-up (#423)
- fix: orchestrator startup provider-key requirements (#425)
- fix: BetterAuth OAuth2 flow and compose wiring (#426)
- fix: BetterAuth UUID ID generation (#427)
- test: web vitest localStorage/file warnings (#428)
- fix: auth frontend remediation + review hardening (#421)
- Plus numerous Docker, deploy, and auth fixes from develop

Lockfile conflict resolved by regenerating from merged package.json.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-21 14:52:43 -06:00
jason.woltje af299abdaf debug(auth): log session cookie source 2026-02-18 21:36:01 -06:00
jason.woltje dedc1af080 fix(auth): restore BetterAuth OIDC flow across api/web/compose 2026-02-17 23:37:49 -06:00
Jason Woltje 63c6a129bd fix(runtime): stabilize LinkAutocomplete nav test and wire required compose env 2026-02-17 16:42:34 -06:00
Jason Woltje 9d9a01f5f7 feat(web): add orchestrator readiness badge and resilient events parsing 2026-02-17 16:20:03 -06:00
Jason Woltje 5bce7dbb05 feat(web): show latest orchestrator event in task progress widget 2026-02-17 16:12:40 -06:00
Jason Woltje ab902250f8 feat(web-hud): seed default layout with orchestration widgets 2026-02-17 16:07:09 -06:00
Jason Woltje d34f097a5c feat(web): add orchestrator events widget with matrix signal visibility 2026-02-17 15:56:12 -06:00
Jason Woltje f4ad7eba37 fix(web-hud): support hyphenated widget IDs with regression tests 2026-02-17 15:49:09 -06:00
Jason Woltje 4d089cd020 feat(orchestrator): add recent events API and monitor script 2026-02-17 15:44:43 -06:00
Jason Woltje 3258cd4f4d feat(orchestrator): add SSE events, queue controls, and mosaic rails sync 2026-02-17 15:39:15 -06:00
Jason Woltje 758b2a839b fix(web-tests): stabilize async auth and usage page assertions 2026-02-17 15:15:54 -06:00
Jason Woltje cab8d690ab fix(#411): complete 2026-02-17 remediation sweep
Apply RLS context at task service boundaries, harden orchestrator/web integration and session startup behavior, re-enable targeted frontend tests, and lock vulnerable transitive dependencies so QA and security gates pass cleanly.
2026-02-17 14:19:15 -06:00
Jason WoltjeandClaude Opus 4.6 c917a639c4 fix(#411): wrap login page useSearchParams in Suspense boundary
Next.js 16 requires useSearchParams() to be inside a <Suspense> boundary
for static prerendering. Extracted LoginPageContent inner component and
wrapped it in Suspense with a loading fallback that matches the existing
loading spinner UI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:07:18 -06:00
Jason WoltjeandClaude Opus 4.6 9d3a673e6c fix(#411): resolve CI lint errors — prettier, unused directives, no-base-to-string
- auth.config.ts: collapse multiline template literal to single line
- auth.controller.ts: add eslint-disable for intentional no-unnecessary-condition
- auth.service.ts: remove 5 unused eslint-disable directives (Node 24 resolves
  BetterAuth types), fix prettier formatting, fix no-base-to-string
- login/page.tsx: remove unnecessary String() wrapper
- auth-context.test.tsx: fix prettier line length

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:00:01 -06:00
Jason WoltjeandClaude Opus 4.6 5328390f4c fix(#411): sanitize login error messages through parseAuthError — prevent raw error leakage
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 15:45:40 -06:00
Jason WoltjeandClaude Opus 4.6 d7de20e586 fix(#411): classifyAuthError — return null for normal 401/session-expired instead of 'backend'
Normal authentication failures (401 Unauthorized, 403 Forbidden, session
expired) are not backend errors — they simply mean the user isn't logged in.
Previously these fell through to the `instanceof Error` catch-all and returned
"backend", causing a misleading "having trouble connecting" banner.

Now classifyAuthError explicitly checks for invalid_credentials and
session_expired codes from parseAuthError and returns null, so the UI shows
the logged-out state cleanly without an error banner.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 15:42:44 -06:00
Jason WoltjeandClaude Opus 4.6 b675db1324 test(#411): QA-015 — add credentials fallback test + fix refreshSession test name
Add test for non-string error.message fallback in handleCredentialsLogin.
Rename misleading refreshSession test to match actual behavior.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:05:30 -06:00
Jason WoltjeandClaude Opus 4.6 e0d6d585b3 test(#411): QA-014 — add verifySession non-Error thrown value tests
Verify verifySession returns null when getSession throws non-Error
values (strings, objects) rather than crashing.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:03:08 -06:00
Jason WoltjeandClaude Opus 4.6 df495c67b5 fix(#411): QA-012 — clamp RetryOptions to sensible ranges
fetchWithRetry now clamps maxRetries>=0, baseDelayMs>=100,
backoffFactor>=1 to prevent infinite loops or zero-delay hammering.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:53:29 -06:00
Jason WoltjeandClaude Opus 4.6 3e2c1b69ea fix(#411): QA-009 — fix .env.example OIDC vars and test assertion
Update .env.example to list all 4 required OIDC vars (was missing OIDC_REDIRECT_URI).
Fix test assertion to match username->email rename in signInWithCredentials.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:51:13 -06:00
Jason WoltjeandClaude Opus 4.6 27c4c8edf3 fix(#411): QA-010 — fix minor JSDoc and comment issues across auth files
Fix response.ok JSDoc (2xx not 200), remove stale token refresh claim,
remove non-actionable comment, fix CSRF comment placement, add 403 mapping rationale.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:50:04 -06:00
Jason WoltjeandClaude Opus 4.6 e600cfd2d0 fix(#411): QA-007 — explicit error state on login config fetch failure
Login page now shows error state with retry button when /auth/config
fetch fails, instead of silently falling back to email-only config.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:44:01 -06:00
Jason WoltjeandClaude Opus 4.6 08e32d42a3 fix(#411): QA-008 — derive KNOWN_CODES from ERROR_MESSAGES keys
Eliminates manual duplication of AuthErrorCode values in KNOWN_CODES
by deriving from Object.keys(ERROR_MESSAGES).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:40:48 -06:00
Jason WoltjeandClaude Opus 4.6 752e839054 fix(#411): QA-005 — production logging, error classification, session-expired state
logAuthError now always logs (not dev-only). Replaced isBackendError with
parseAuthError-based classification. signOut uses proper error type.
Session expiry sets explicit session_expired state. Login page logs in prod.
Fixed pre-existing lint violations in auth package (campsite rule).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:37:49 -06:00
Jason WoltjeandClaude Opus 4.6 110e181272 test(#411): add missing test coverage — getAccessToken, isAdmin, null cases, getClientIp
- Add getAccessToken tests (5): null session, valid token, expired token, buffer window, undefined token
- Add isAdmin tests (4): null session, true, false, undefined
- Add getUserById/getUserByEmail null-return tests (2)
- Add getClientIp tests via handleAuth (4): single IP, comma-separated, array, fallback
- Fix pre-existing controller spec failure by adding better-auth vi.mock calls

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 12:37:11 -06:00
Jason WoltjeandClaude Opus 4.6 9696e45265 fix(#411): remediate frontend review findings — wire fetchWithRetry, fix error handling
- Wire fetchWithRetry into login page config fetch (was dead code)
- Remove duplicate ERROR_CODE_MESSAGES, use parseAuthError from auth-errors.ts
- Fix OAuth sign-in fire-and-forget: add .catch() with PDA error + loading reset
- Fix credential login catch: use parseAuthError for better error messages
- Add user feedback when auth config fetch fails (was silent degradation)
- Fix sign-out failure: use logAuthError and set authError state
- Enable fetchWithRetry production logging for retry visibility

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 12:33:25 -06:00
Jason Woltje c233d97ba0 feat(#417): add fetchWithRetry with exponential backoff for auth
Retries network and server errors up to 3 times with exponential
backoff (1s, 2s, 4s). Non-retryable errors fail immediately.

Refs #417
2026-02-16 12:19:46 -06:00
Jason Woltje f1ee0df933 feat(#417): update auth-client.ts error messages to PDA-friendly
Uses parseAuthError from auth-errors module for consistent
PDA-friendly error messages in signInWithCredentials.

Refs #417
2026-02-16 12:15:25 -06:00
Jason Woltje 07084208a7 feat(#417): add session expiry detection to AuthProvider
Adds sessionExpiring and sessionMinutesRemaining to auth context.
Checks session expiry every 60s, warns when within 5 minutes.

Refs #417
2026-02-16 12:12:46 -06:00
Jason Woltje f500300b1f feat(#417): create auth-errors.ts with PDA error parsing and mapping
Adds AuthErrorCode type, ParsedAuthError interface, parseAuthError() classifier,
and getErrorMessage() helper. All messages use PDA-friendly language.

Refs #417
2026-02-16 12:02:57 -06:00
Jason WoltjeandClaude Opus 4.6 d9a3eeb9aa feat(#416): responsive layout + accessibility for login page
- Mobile-first responsive classes (p-4 sm:p-8, text-2xl sm:text-4xl)
- WCAG 2.1 AA: role=status on loading spinner, aria-labels, focus management
- Loading spinner has role=status and aria-label
- All interactive elements keyboard-accessible
- Added 10 new tests for responsive layout and accessibility

Refs #416

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 11:56:13 -06:00
Jason WoltjeandClaude Opus 4.6 077bb042b7 feat(#416): add error display from URL query params on login page
Maps error codes to PDA-friendly messages (no alarming language).
Dismissible error banner with URL param cleanup.

Refs #416

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 11:50:33 -06:00
Jason WoltjeandClaude Opus 4.6 1d7d5a9d01 refactor(#416): delete old LoginButton, replaced by OAuthButton
LoginButton.tsx and LoginButton.test.tsx removed. The login page now
uses OAuthButton, LoginForm, and AuthDivider from the auth redesign.

Refs #416

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 11:48:15 -06:00
Jason WoltjeandClaude Opus 4.6 2020c15545 feat(#416): redesign login page with dynamic provider rendering
Fetches GET /auth/config on mount and renders OAuth + email/password
forms based on backend-advertised providers. Falls back to email-only
if config fetch fails.

Refs #416

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 11:45:44 -06:00
Jason WoltjeandClaude Opus 4.6 81b5204258 feat(#415): theme fix, AuthDivider, SessionExpiryWarning components
- AUTH-014: Fix theme storage key (jarvis-theme -> mosaic-theme)
- AUTH-016: Create AuthDivider component with customizable text
- AUTH-019: Create SessionExpiryWarning floating banner (PDA-friendly, blue)
- Fix lint errors in LoginForm, OAuthButton from parallel agents
- Sync pnpm-lock.yaml for recharts dependency

Refs #415

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 11:37:31 -06:00
jason.woltjeandClaude Opus 4.6 444fa1116a fix(#410): align BetterAuth basePath and auth client with NestJS routing
BetterAuth defaulted basePath to /api/auth but NestJS controller routes
to /auth/* (no global prefix). The auth client also pointed at the web
frontend origin instead of the API server, and LoginButton used a
nonexistent GET /auth/signin/authentik endpoint.

- Set basePath: "/auth" in BetterAuth server config
- Point auth client baseURL to API_BASE_URL with matching basePath
- Add genericOAuthClient plugin to auth client
- Use signIn.oauth2({ providerId: "authentik" }) in LoginButton

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 19:41:08 -06:00
jason.woltjeandClaude Opus 4.6 cf28efa880 merge: resolve conflicts with develop (M10-Telemetry + M12-MatrixBridge)
Merge origin/develop into feature/m13-speech-services to incorporate
M10-Telemetry and M12-MatrixBridge changes. Resolved 4 conflicts:
- .env.example: Added speech config alongside telemetry + matrix config
- Makefile: Added speech targets alongside matrix targets
- app.module.ts: Import both MosaicTelemetryModule and SpeechModule
- docs/tasks.md: Combined all milestone task tracking sections

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 12:31:08 -06:00
jason.woltjeandClaude Opus 4.6 af9c5799af fix(#388): address PR review findings — fix WebSocket/REST bugs, improve error handling, fix types and comments
Critical fixes:
- Fix FormData field name mismatch (audio -> file) to match backend FileInterceptor
- Add /speech namespace to WebSocket connection URL
- Pass auth token in WebSocket handshake options
- Wrap audio.play() in try-catch for NotAllowedError and DOMException handling
- Replace bare catch block with named error parameter and descriptive message
- Add connect_error and disconnect event handlers to WebSocket
- Update JSDoc to accurately describe batch transcription (not real-time partial)

Important fixes:
- Emit transcription-error before disconnect in gateway auth failures
- Capture MediaRecorder error details and clean up media tracks on error
- Change TtsDefaultConfig.format type from string to AudioFormat
- Define canonical SPEECH_TIERS and AUDIO_FORMATS arrays as single source of truth
- Fix voice count from 54 to 53 in provider, AGENTS.md, and docs
- Fix inaccurate comments (Piper formats, tier prop, SpeachesProvider, TextValidationPipe)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:44:33 -06:00
jason.woltjeandClaude Opus 4.6 bc86947d01 feat(#404): add speech settings page with provider config
Implements the SpeechSettings component with four sections:
- STT settings (enable/disable, language preference)
- TTS settings (enable/disable, voice selector, tier preference, auto-play, speed control)
- Voice preview with test button
- Provider status with health indicators

Also adds Slider UI component and getHealthStatus API client function.
30 unit tests covering all sections, toggles, voice loading, and PDA-friendly design.

Fixes #404

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:16:27 -06:00
jason.woltjeandClaude Opus 4.6 74d6c1092e feat(#403): add audio playback component for TTS output
Implements AudioPlayer inline component with play/pause, progress bar,
speed control (0.5x-2x), download, and duration display. Adds
TextToSpeechButton "Read aloud" component that synthesizes text via
the speech API and integrates AudioPlayer for playback. Includes
useTextToSpeech hook with API integration, audio caching, and
playback state management. All 32 tests passing.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:05:39 -06:00
jason.woltjeandClaude Opus 4.6 a943ae139a fix(#375): resolve lint errors in usage dashboard
- Fix prettier formatting for Tooltip formatter props (single-line)
- Fix no-base-to-string by using typed props instead of Record<string, unknown>
- Fix restrict-template-expressions by wrapping number in String()

Refs #375

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:25:51 -06:00
jason.woltjeandClaude Opus 4.6 8e27f73f8f fix(#375): resolve recharts TypeScript strict mode type errors
- Fix Tooltip formatter/labelFormatter type overload conflicts
- Fix Pie label render props type mismatch
- Fix telemetry.ts date split array access type

Refs #375

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:21:54 -06:00