Commit Graph
82 Commits
Author SHA1 Message Date
jason.woltje 5cd6b8622d feat(web): add admin users settings page (MS21-UI-001) (#573)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-28 20:50:11 +00:00
jason.woltje 20c9e68e1b feat(web): wire workspaces settings page to real API (MS21-UI-003) (#574)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-28 20:48:24 +00:00
jason.woltje ffc10c9a45 feat(api): add MS21 user fields for admin, local auth, and invitations (#553)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-28 17:47:03 +00:00
jason.woltje 128431ba58 fix(api,web): separate workspace context from auth session (#551)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-28 15:14:29 +00:00
jason.woltje 66fe475fa1 fix(web): convert favicon.ico to RGBA format for Turbopack (#544)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-27 11:10:38 +00:00
jason.woltje c38bfae16c fix(web): fix personalities page dark mode theming and wire to API (#540)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-27 10:59:04 +00:00
jason.woltje dd0568cf15 fix(web): add workspace context to domain and project creation (#536)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-27 10:28:40 +00:00
jason.woltje edcff6a0e0 fix(api,web): add workspace context to widgets and auto-detect workspace ID (#532)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-27 04:53:07 +00:00
jason.woltje e3cba37e8c fix(api,web): resolve RLS context SQL error, workspace guard crash, and projects response unwrapping (#531)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-27 04:18:35 +00:00
jason.woltje 7de0e734b0 feat(web): implement SSE chat streaming with real-time token rendering (#516)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-26 02:39:43 +00:00
jason.woltje cc56f2cbe1 feat(web): migrate dashboard to WidgetGrid with layout persistence (#497)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-24 00:50:24 +00:00
jason.woltje 05b1a93ccb feat(web): add logs and telemetry page with filtering and auto-refresh (#480)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 04:38:15 +00:00
jason.woltje a78a8b88e1 feat(web): add project workspace page with tasks and agent sessions (#479)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 04:29:39 +00:00
jason.woltje 172ed1d40f feat(web): add kanban board page with drag-and-drop (#478)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 04:26:25 +00:00
jason.woltje ee2ddfc8b8 feat(web): add projects page with CRUD operations (#477)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 04:13:26 +00:00
jason.woltje 5a6d00a064 feat(web): wire knowledge pages to real API data (#476)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 04:12:14 +00:00
jason.woltje f97be2e6a3 feat(web): wire calendar page to real API data (#474)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 03:51:15 +00:00
jason.woltje 97606713b5 feat(web): wire tasks page to real API data (#473)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 03:51:08 +00:00
jason.woltje 7581d26567 Phase 2: Task Ingestion Pipeline (#459) (#460)
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-02-23 00:54:55 +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 af299abdaf debug(auth): log session cookie source 2026-02-18 21:36:01 -06:00
Jason Woltje ab902250f8 feat(web-hud): seed default layout with orchestration widgets 2026-02-17 16:07:09 -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 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 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 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 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 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
jason.woltjeandClaude Opus 4.6 a5ee974765 feat(#375): frontend token usage and cost dashboard
- Install recharts for data visualization
- Add Usage nav item to sidebar navigation
- Create telemetry API service with data fetching functions
- Build dashboard page with summary cards, charts, and time range selector
- Token usage line chart, cost breakdown bar chart, task outcome pie chart
- Loading and empty states handled
- Responsive layout with PDA-friendly design
- Add unit tests (14 tests passing)

Refs #375

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 6a5a4e4de8 feat(web): add credential management UI pages and components
Add credentials settings page, audit log page, CRUD dialog components
(create, view, edit, rotate), credential card, dialog UI component,
and API client for the M7-CredentialSecurity feature.

Refs #346

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-10 09:42:41 -06:00
Jason WoltjeandClaude Opus 4.6 893a139087 feat(web): Integrate M4-LLM error handling improvements
Port high-value features from work/m4-llm branch into develop's
security-hardened codebase:

- Separate LLM vs persistence error handling in useChat (shows
  assistant response even when save fails)
- Add structured error context logging with errorType, messagePreview,
  messageCount fields for debugging
- Enforce state invariant in useChatOverlay: cannot be minimized when
  closed
- Add onStorageError callback with user-friendly messages and
  per-error-type deduplication
- Add error logging to Chat imperative handle methods
- Create Chat.test.tsx with loadConversation failure mode tests

Skipped from work/m4-llm (superseded by develop):
- AbortSignal timeout (develop has centralized client timeout)
- Custom toast system (duplicates @mosaic/ui)
- ErrorBoundary (develop has its own)
- WebSocket typed events (develop's ref-based pattern is superior)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-06 20:04:53 -06:00
Jason WoltjeandClaude Opus 4.6 1005b7969c fix(SEC-WEB-37): Gate federation mock data behind NODE_ENV check
Replace exported const mockConnections with getMockConnections() function
that returns mock data only when NODE_ENV === "development". In production
and test environments, returns an empty array as defense-in-depth alongside
the existing ComingSoon page gate (SEC-WEB-4).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-06 18:22:12 -06:00
Jason WoltjeandClaude Opus 4.6 12fa093f58 fix(SEC-WEB-33+35): Fix Mermaid error display + useWorkspaceId error logging
SEC-WEB-33: Replace raw diagram source and detailed error messages in
MermaidViewer error UI with a generic "Diagram rendering failed" message.
Detailed errors are logged to console.error for debugging only.

SEC-WEB-35: Add console.warn in useWorkspaceId when no workspace ID is
found in localStorage, making it easier to distinguish "no workspace
selected" from silent hook failure.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-06 18:16:07 -06:00
Jason WoltjeandClaude Opus 4.6 014264c592 fix(SEC-WEB-32+34): Add input maxLength limits + API request timeout
SEC-WEB-32: Added maxLength to form inputs (names: 100, descriptions: 500,
emails: 254) in WorkspaceSettings, TeamSettings, InviteMember components.

SEC-WEB-34: Added AbortController timeout (30s default, configurable) to
apiRequest and apiPostFormData in API client.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-06 18:11:00 -06:00
Jason WoltjeandClaude Opus 4.6 14b547d468 fix(SEC-WEB-30+31+36): Validate JSON.parse/localStorage deserialization
Add runtime type validation after all JSON.parse calls in the web app to
prevent runtime crashes from corrupted or tampered storage data. Creates a
shared safeJsonParse utility with type guard functions for each data shape
(Message[], ChatOverlayState, LayoutConfigRecord). All four affected
callsites now validate parsed data and fall back to safe defaults on
mismatch.

Files changed:
- apps/web/src/lib/utils/safe-json.ts (new utility)
- apps/web/src/lib/utils/safe-json.test.ts (25 tests)
- apps/web/src/hooks/useChat.ts (deserializeMessages)
- apps/web/src/hooks/useChat.test.ts (3 new corruption tests)
- apps/web/src/hooks/useChatOverlay.ts (loadState)
- apps/web/src/hooks/useChatOverlay.test.ts (3 new corruption tests)
- apps/web/src/components/chat/ConversationSidebar.tsx (ideaToConversation)
- apps/web/src/lib/hooks/useLayout.ts (layout loading)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-06 15:46:58 -06:00
Jason WoltjeandClaude Opus 4.5 203bd1e7f2 fix(#338): Standardize API base URL and auth mechanism across components
- Create centralized config module (apps/web/src/lib/config.ts) exporting:
  - API_BASE_URL: Main API server URL from NEXT_PUBLIC_API_URL
  - ORCHESTRATOR_URL: Orchestrator service URL from NEXT_PUBLIC_ORCHESTRATOR_URL
  - Helper functions for building full URLs
- Update client.ts to import from central config
- Update LoginButton.tsx to use API_BASE_URL from config
- Update useWebSocket.ts to use API_BASE_URL from config
- Update AgentStatusWidget.tsx to use ORCHESTRATOR_URL from config
- Update TaskProgressWidget.tsx to use ORCHESTRATOR_URL from config
- Update useGraphData.ts to use API_BASE_URL from config
  - Fixed wrong default port (was 8000, now uses correct 3001)
- Add comprehensive tests for config module
- Update useWebSocket tests to properly mock config module

Refs #338

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-02-05 18:04:01 -06:00