Commit Graph
100 Commits
Author SHA1 Message Date
jason.woltjeandClaude Opus 4.6 491675b613 docs: add auth & frontend remediation plan
Comprehensive plan for fixing the production 500 on POST /auth/sign-in/oauth2
and redesigning the frontend login page to be OIDC-aware with multi-method
authentication support.

Key areas covered:
- Backend: OIDC startup validation, auth config discovery endpoint, BetterAuth
  error handling, PKCE, session hardening, trustedOrigins extraction
- Frontend: Multi-method login page, PDA-friendly error display, adaptive UI
  based on backend-advertised providers, loading states, accessibility
- Security: CSRF rationale, secret leakage prevention, redirect URI validation,
  session idle timeout, OIDC health checks
- 6 implementation phases with file change map and testing strategy

Created with input from frontend design, backend, security, and auth architecture
specialist reviews.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 04:43:38 -06:00
jason.woltjeandClaude Opus 4.6 4b3eecf05a fix(#410): pass OIDC_ENABLED to API container in docker-compose
The genericOAuth plugin is conditionally loaded based on OIDC_ENABLED
env var. Without it, BetterAuth has no /sign-in/oauth2 route, causing
404 when the login button is clicked.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 04:04:42 -06:00
jason.woltjeandClaude Opus 4.6 3376d8162e fix(#410): skip CSRF guard on auth catch-all route
The global CsrfGuard blocks POST /auth/sign-in/oauth2 with 403 because
unauthenticated users have no session and therefore no CSRF token.
BetterAuth handles its own CSRF protection via toNodeHandler().

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 03:41:50 -06:00
jason.woltjeandClaude Opus 4.6 e2ffaa71b1 fix: exempt health endpoint from rate limiting
Docker/load-balancer health probes hit GET /health every ~5s from
127.0.0.1, exhausting the rate limit and causing all subsequent checks
to return 429 — making the service appear unhealthy.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 03:21:46 -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 31ce9e920c fix: replace flaky timing-based test with deterministic assertion
The constant-time comparison test used Date.now() deltas with a 10ms
threshold which is unreliable in CI. Replace with deterministic tests
that verify both same-length and different-length key rejection paths
work correctly. The actual timing-safe behavior is guaranteed by
Node's crypto.timingSafeEqual which the guard uses.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 19:11:15 -06:00
jason.woltjeandClaude Opus 4.6 ba54de88fd fix(#410): use toNodeHandler for BetterAuth Express compatibility
BetterAuth expects Web API Request objects (Fetch API standard) with
headers.get(), but NestJS/Express passes IncomingMessage objects with
headers[] property access. Use better-auth/node's toNodeHandler to
properly convert between Express req/res and BetterAuth's Web API handler.

Also fixes vitest SWC config to read the correct tsconfig for NestJS
decorator metadata emission, which was causing DI injection failures
in tests.

Fixes #410

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 19:06:49 -06:00
jason.woltjeandClaude Opus 4.6 ca21416efc fix: switch Docker images from Alpine to Debian slim for native addon compatibility
Alpine (musl libc) is incompatible with matrix-sdk-crypto-nodejs native binary
which requires glibc's ld-linux-x86-64.so.2. Switched all Node.js Dockerfiles
to node:24-slim (Debian/glibc). Also fixed docker-compose.matrix.yml network
naming from undefined mosaic-network to mosaic-internal.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:02:23 -06:00
jason.woltjeandClaude Opus 4.6 1bad7a8cca fix: allow matrix-sdk-crypto-nodejs build scripts for native binary
pnpm 10 blocks build scripts by default. The matrix-bot-sdk requires
@matrix-org/matrix-sdk-crypto-nodejs which downloads a platform-specific
native binary via postinstall. Added to onlyBuiltDependencies so the
Alpine (musl) binary gets installed in Docker builds.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 15:27:36 -06:00
jason.woltjeandClaude Opus 4.6 6015ace1de fix: update @mosaicstack/telemetry-client to 0.1.1 for CJS compatibility
The 0.1.0 package was ESM-only, causing ERR_PACKAGE_PATH_NOT_EXPORTED
when loaded by NestJS (which compiles to CommonJS). Version 0.1.1 ships
dual ESM/CJS builds.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 15:09:02 -06:00
jason.woltjeandClaude Opus 4.6 92de2f282f fix(database): resolve migration failures and schema drift
Root cause: migration 20260129235248_add_link_storage_fields dropped the
personalities table and FormalityLevel enum, but migration
20260208000000_add_missing_tables later references personalities in a FK
constraint, causing ERROR: relation "personalities" does not exist on any
fresh database deployment.

Fix 1 — 20260208000000_add_missing_tables:
  Recreate FormalityLevel enum and personalities table (with current schema
  structure) at the top of the migration, before the FK constraint.

Fix 2 — New migration 20260215100000_fix_schema_drift:
  - Create missing instances table (Federation module, never migrated)
  - Recreate knowledge_links unique index (dropped, never recreated)
  - Add 7 missing @@unique([id, workspaceId]) composite indexes
  - Add missing agent_tasks.agent_type index

Verified: all 27 migrations apply cleanly on a fresh PostgreSQL 17 database
with pgvector.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 14:42:06 -06:00
jason.woltje 1fde25760a Merge pull request 'feat: M13-SpeechServices — TTS & STT integration' (#409) from feature/m13-speech-services into develop
Reviewed-on: http://git.mosaicstack.dev/mosaic/stack/pulls/409
2026-02-15 18:37:53 +00: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.woltje 11d284554d Merge pull request 'feat: M12-MatrixBridge — Matrix/Element chat bridge integration' (#408) from feature/m12-matrix-bridge into develop
Reviewed-on: http://git.mosaicstack.dev/mosaic/stack/pulls/408
2026-02-15 18:22:16 +00:00
jason.woltjeandClaude Opus 4.6 3cc2030446 fix(#377): add pnpm overrides for matrix-bot-sdk transitive vulnerabilities
matrix-bot-sdk depends on the deprecated `request` library which pulls
in vulnerable form-data (<2.5.4, critical: unsafe random boundary) and
qs (<6.14.1, high: DoS via memory exhaustion). Add pnpm overrides to
force patched versions since matrix-bot-sdk has no newer release.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 12:17:17 -06:00
jason.woltjeandClaude Opus 4.6 eca2c46e9d merge: resolve conflicts with develop (telemetry + lockfile)
Keep both Mosaic Telemetry section (from develop) and Matrix Dev
Environment section (from feature branch) in .env.example.
Regenerate pnpm-lock.yaml with both dependency trees merged.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 12:12:43 -06:00
jason.woltjeandClaude Opus 4.6 c5a87df6e1 fix(#374): add pip.conf to coordinator Docker build for private registry
The Docker build failed because pip couldn't find mosaicstack-telemetry
from the private Gitea PyPI registry. Copy pip.conf into the image so
pip resolves the extra-index-url during docker build.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 12:05:04 -06:00
jason.woltje 17ee28b6f6 Merge pull request 'feat: M10-Telemetry — Mosaic Telemetry integration' (#407) from feature/m10-telemetry into develop
Reviewed-on: http://git.mosaicstack.dev/mosaic/stack/pulls/407
2026-02-15 17:32:07 +00: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 dcbc8d1053 chore(orchestrator): finalize M13-SpeechServices tasks.md — all 18/18 done
All tasks completed successfully across 7 phases:
- Phase 1: Config + Module foundation (2/2)
- Phase 2: STT + TTS providers (5/5)
- Phase 3: Middleware + REST endpoints (3/3)
- Phase 4: WebSocket streaming (1/1)
- Phase 5: Docker/DevOps (2/2)
- Phase 6: Frontend components (3/3)
- Phase 7: E2E tests + Documentation (2/2)

Total: ~500+ tests across API and web packages.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:27:21 -06:00
jason.woltje d2c7602430 test(#405): add E2E integration tests for speech services
Adds comprehensive integration tests covering all 9 required scenarios:
1. REST transcription (POST /speech/transcribe)
2. REST synthesis (POST /speech/synthesize)
3. Provider fallback (premium -> default -> fallback chain)
4. WebSocket streaming transcription lifecycle
5. Audio MIME type validation (reject invalid formats)
6. File size limit enforcement (25 MB max)
7. Authentication on all endpoints (401 without token)
8. Voice listing with tier filtering (GET /speech/voices)
9. Health check status (GET /speech/health)

Uses NestJS testing module with mocked providers (CI-compatible).
30 test cases, all passing.

Fixes #405
2026-02-15 03:26:05 -06:00
jason.woltjeandClaude Opus 4.6 24065aa199 docs(#406): add speech services documentation
Comprehensive documentation for the speech services module:
- docs/SPEECH.md: Architecture, API reference, WebSocket protocol,
  environment variables, provider configuration, Docker setup,
  GPU VRAM budget, and frontend integration examples
- apps/api/src/speech/AGENTS.md: Module structure, provider pattern,
  how to add new providers, gotchas, and test patterns
- README.md: Speech capabilities section with quick start

Fixes #406

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:23:22 -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 03d0c032e4 chore(orchestrator): Add review remediation phase to tasks.md
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:02:27 -06:00
jason.woltjeandClaude Opus 4.6 8d19ac1f4b fix(#377): remediate code review and security findings
- Fix sendThreadMessage room mismatch: use channelId from options instead of hardcoded controlRoomId
- Add .catch() to fire-and-forget handleRoomMessage to prevent silent error swallowing
- Wrap dispatchJob in try-catch for user-visible error reporting in handleFixCommand
- Add MATRIX_BOT_USER_ID validation in connect() to prevent infinite message loops
- Fix streamResponse error masking: wrap finally/catch side-effects in try-catch
- Replace unsafe type assertion with public getClient() in MatrixRoomService
- Add orphaned room warning in provisionRoom on DB failure
- Add provider identity to Herald error logs
- Add channelId to ThreadMessageOptions interface and all callers
- Add missing env var warnings in BridgeModule factory
- Fix JSON injection in setup-bot.sh: use jq for safe JSON construction

Fixes #377

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 03:00:53 -06:00
jason.woltjeandClaude Opus 4.6 28c9e6fe65 feat(#397): implement WebSocket streaming transcription gateway
Add SpeechGateway with Socket.IO namespace /speech for real-time
streaming transcription. Supports start-transcription, audio-chunk,
and stop-transcription events with session management, authentication,
and buffer size rate limiting. Includes 29 unit tests covering
authentication, session lifecycle, error handling, cleanup, and
client isolation.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:54:41 -06:00
jason.woltje b3d6d73348 feat(#400): add Docker Compose swarm/prod deployment for speech services
Add docker/docker-compose.sample.speech.yml for standalone speech services
deployment in Docker Swarm with Portainer compatibility:

- Speaches (STT + basic TTS) with Whisper model configuration
- Kokoro TTS (default high-quality TTS) always deployed
- Chatterbox TTS (premium, GPU) commented out as optional
- Traefik labels for reverse proxy routing with TLS
- Health checks on all services
- Volume persistence for Whisper models
- GPU reservation via Swarm generic resources for Chatterbox
- Environment variable substitution for Portainer
- Comprehensive header documentation

Fixes #400
2026-02-15 02:51:13 -06:00
jason.woltjeandClaude Opus 4.6 527262af38 feat(#392): create /api/speech/transcribe REST endpoint
Add SpeechController with POST /api/speech/transcribe for audio
transcription and GET /api/speech/health for provider status.
Uses AudioValidationPipe for file upload validation and returns
results in standard { data: T } envelope.

Includes 10 unit tests covering transcribe with options, error
propagation, and all health status combinations.

Fixes #392

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:47:52 -06:00
jason.woltjeandClaude Opus 4.6 a1f0d1dd71 chore(orchestrator): All M12-MatrixBridge tasks complete
All 10 tasks done:
- MB-001: MatrixService skeleton (5b5d381)
- MB-002: Dev docker-compose (4a5cb64)
- MB-003: BridgeModule conditional loading (771ed48)
- MB-004: Workspace-Room mapping (7d22c24)
- MB-005: Matrix command handling (ad24720)
- MB-006: Herald multi-provider adapter (ad24720)
- MB-007: Streaming AI responses (93cd314)
- MB-008: Integration tests - 26 tests (9cc70db)
- MB-009: Documentation (68808c0)
- MB-010: Sample compose (6e20fc5, pre-existing)

95 matrix tests pass. Ready for PR.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:40:47 -06:00
jason.woltjeandClaude Opus 4.6 9cc70dbe31 test(#385): Matrix bridge integration tests
- BridgeModule DI verification (conditional loading)
- Command flow: message -> parser -> dispatch
- Herald multi-provider broadcast
- Room-workspace mapping integration
- Streaming flow verification
- Multi-provider coexistence

Refs #385

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:39:59 -06:00
jason.woltjeandClaude Opus 4.6 6c465566f6 feat(#395): implement Piper TTS provider via OpenedAI Speech
Add fallback-tier TTS provider using Piper via OpenedAI Speech for
ultra-lightweight CPU-only synthesis. Maps 6 standard OpenAI voice
names (alloy, echo, fable, onyx, nova, shimmer) to Piper voices.
Update factory to use the new PiperTtsProvider class, replacing the
inline stub. Includes 37 unit tests covering provider identity,
voice mapping, and voice listing.

Fixes #395

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:39:20 -06:00
jason.woltjeandClaude Opus 4.6 68808c0933 docs(#386): Matrix bridge setup and architecture documentation
- Quick start guide for dev environment
- Architecture overview with service responsibilities
- Command reference with examples
- Configuration reference
- Streaming response architecture
- Deployment considerations

Refs #386

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:39:20 -06:00
jason.woltje 7b4fda6011 feat(#398): add audio/text validation pipes and speech DTOs
Create AudioValidationPipe for MIME type and file size validation,
TextValidationPipe for TTS text input validation, and DTOs for
transcribe/synthesize endpoints. Includes 36 unit tests.

Fixes #398
2026-02-15 02:37:54 -06:00
jason.woltjeandClaude Opus 4.6 0819dfa470 chore(orchestrator): Update tasks — Phase 4 complete, Phase 5+6 starting
MB-007 (Streaming AI responses) done in commit 93cd314.
20 new tests, 132 total bridge tests pass.
Launching MB-008 (E2E tests) and MB-009 (Docs) in parallel.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:35:53 -06:00
jason.woltjeandClaude Opus 4.6 93cd31435b feat(#383): Streaming AI responses via Matrix message edits
- Add MatrixStreamingService with editMessage, setTypingIndicator, streamResponse
- Rate-limited edits (500ms) for incremental streaming output
- Typing indicator management during generation
- Graceful error handling and fallback for non-streaming scenarios
- Add optional editMessage to IChatProvider interface
- Add getClient() accessor to MatrixService for streaming service
- Register MatrixStreamingService in BridgeModule
- Tests: 20 tests pass

Refs #383

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:34:36 -06:00
jason.woltjeandClaude Opus 4.6 d37c78f503 feat(#394): implement Chatterbox TTS provider with voice cloning
Add ChatterboxSynthesizeOptions interface with referenceAudio and
emotionExaggeration fields, and comprehensive unit tests (26 tests)
covering voice cloning, emotion control, clamping, graceful degradation,
and cross-language support.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:29:38 -06:00
jason.woltjeandClaude Opus 4.6 aa106a948a chore(orchestrator): Update tasks — Phase 3 complete, Phase 4 starting
MB-005 (Matrix command handling) and MB-006 (Herald adapter) done.
Both committed in ad24720 (bundled by pre-commit hooks).
49 Matrix tests pass, 112 total bridge tests pass.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:28:25 -06:00
jason.woltjeandClaude Opus 4.6 79b1d81d27 feat(#393): implement Kokoro-FastAPI TTS provider with voice catalog
Extract KokoroTtsProvider from factory into its own module with:
- Full voice catalog of 54 built-in voices across 8 languages
- Voice metadata parsing from ID prefix (language, gender, accent)
- Exported constants for supported formats and speed range
- Comprehensive unit tests (48 tests)
- Fix lint/type errors in chatterbox provider (Prettier + unsafe cast)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:27:47 -06:00
jason.woltje ad24720616 feat(#382): Herald Service: broadcast to all active chat providers
- Replace direct DiscordService injection with CHAT_PROVIDERS array
- Herald broadcasts to ALL active chat providers (Discord, Matrix, future)
- Graceful error handling — one provider failure doesn't block others
- Skips disconnected providers automatically
- Tests verify multi-provider broadcasting behavior
- Fix lint: remove unnecessary conditional in matrix.service.ts

Refs #382
2026-02-15 02:25:55 -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
jason.woltje b5edb4f37e feat(#391): add base TTS provider and factory classes
Add the BaseTTSProvider abstract class and TTS provider factory that were
part of the tiered TTS architecture but missed from the previous commit.

- BaseTTSProvider: abstract base with synthesize(), listVoices(), isHealthy()
- tts-provider.factory: creates Kokoro/Chatterbox/Piper providers from config
- 30 tests (22 base provider + 8 factory)

Refs #391
2026-02-15 02:20:24 -06:00
jason.woltje 4a9ecab4dd chore(orchestrator): Update tasks — Phase 2 complete, Phase 3 starting
MB-003 (BridgeModule conditional loading): done — commit 771ed48
MB-004 (Workspace-Room mapping): done — commit 7d22c24
MB-005, MB-006: in-progress

Refs #377
2026-02-15 02:20:11 -06:00
jason.woltje 3ae9e53bcc feat(#391): implement tiered TTS provider architecture with base class
Add abstract BaseTTSProvider class that implements common OpenAI-compatible
TTS logic using the OpenAI SDK with configurable baseURL. Includes synthesize(),
listVoices(), and isHealthy() methods. Create TTS provider factory that
dynamically registers Kokoro (default), Chatterbox (premium), and Piper
(fallback) providers based on configuration. Update SpeechModule to use
the factory for TTS_PROVIDERS injection token.

Also fixes lint error in speaches-stt.provider.ts (Array<T> -> T[]).

30 tests added (22 base provider + 8 factory), all passing.

Fixes #391
2026-02-15 02:19:46 -06:00
jason.woltje 771ed484e4 feat(#379): Register MatrixService in BridgeModule with conditional loading
- Add CHAT_PROVIDERS injection token for bridge-agnostic access
- Conditional loading based on env vars (DISCORD_BOT_TOKEN, MATRIX_ACCESS_TOKEN)
- Both bridges can run simultaneously
- No crash if neither bridge is configured
- Tests verify all configuration combinations

Refs #379
2026-02-15 02:18:55 -06:00
jason.woltjeandClaude Opus 4.6 2eafa91e70 fix(#370): add mypy import-untyped ignore for mosaicstack_telemetry
The mosaicstack-telemetry package lacks py.typed marker. Add type
ignore comment consistent with other import sites.

Refs #370

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:16:44 -06:00
jason.woltje 7d22c2490a feat(#380): Workspace-to-Matrix-Room mapping and provisioning
- Add matrix_room_id column to workspace table (migration)
- Create MatrixRoomService for room provisioning and mapping
- Auto-create Matrix room on workspace provisioning (when configured)
- Support manual room linking for existing workspaces
- Unit tests for all mapping operations

Refs #380
2026-02-15 02:16:29 -06:00
jason.woltjeandClaude Opus 4.6 248f711571 fix(#370): add Gitea PyPI registry to coordinator CI install step
The mosaicstack-telemetry package is hosted on the Gitea PyPI registry.
CI pip install needs --extra-index-url to find it.

Refs #370

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:14:11 -06:00
jason.woltjeandClaude Opus 4.6 306c2e5bd8 fix(#371): resolve TypeScript strictness errors in telemetry tracking
- llm-cost-table.ts: Add undefined guard for MODEL_COSTS lookup
- llm-telemetry-tracker.service.ts: Allow undefined in callingContext
  for exactOptionalPropertyTypes compatibility

Refs #371

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 746ab20c38 chore: update tasks.md — all M10-Telemetry tasks complete
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -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 5958569cba docs(#376): telemetry integration guide
- Create comprehensive telemetry documentation at docs/telemetry.md
- Cover configuration, event schema, predictions, SDK reference
- Include development guide with dry-run mode and troubleshooting
- Link from main README.md

Refs #376

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 d6c6af10d9 feat(#372): track orchestrator agent task completions via telemetry
- Instrument Coordinator.process_queue() with timing and telemetry events
- Instrument OrchestrationLoop.process_next_issue() with quality gate tracking
- Add agent-to-telemetry mapping (model, provider, harness per agent name)
- Map difficulty levels to Complexity enum and gate names to QualityGate enum
- Track retry counts per issue (increment on failure, clear on success)
- Emit FAILURE outcome on agent spawn failure or quality gate rejection
- Non-blocking: telemetry errors are logged and swallowed, never delay tasks
- Pass telemetry client from FastAPI lifespan to Coordinator constructor
- Add 33 unit tests covering all telemetry scenarios

Refs #372

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 ed23293e1a feat(#373): prediction integration for cost estimation
- Create PredictionService for pre-task cost/token estimates
- Refresh common predictions on startup
- Integrate predictions into LLM telemetry tracker
- Add GET /api/telemetry/estimate endpoint
- Graceful degradation when no prediction data available
- Add unit tests for prediction service

Refs #373

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 fcecf3654b feat(#371): track LLM task completions via Mosaic Telemetry
- Create LlmTelemetryTrackerService for non-blocking event emission
- Normalize token usage across Anthropic, OpenAI, Ollama providers
- Add cost table with per-token pricing in microdollars
- Instrument chat, chatStream, and embed methods
- Infer task type from calling context
- Aggregate streaming tokens after stream ends with fallback estimation
- Add 69 unit tests for tracker service, cost table, and LLM service

Refs #371

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 24c21f45b3 feat(#374): add telemetry config to docker-compose and .env
- Add MOSAIC_TELEMETRY_* variables to .env.example with descriptions
- Pass telemetry env vars to api service in production compose
- Pass telemetry env vars to coordinator service in dev and swarm composes
- Swarm composes default to production URL (https://tel-api.mosaicstack.dev)
- Dev compose includes commented-out telemetry-api service placeholder
- All compose files default MOSAIC_TELEMETRY_ENABLED to false for safety

Refs #374

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 314dd24dce feat(#369): install @mosaicstack/telemetry-client in API
- Add .npmrc with scoped Gitea npm registry for @mosaicstack packages
- Create MosaicTelemetryModule (global, lifecycle-aware) at
  apps/api/src/mosaic-telemetry/
- Create MosaicTelemetryService wrapping TelemetryClient with
  convenience methods: trackTaskCompletion, getPrediction,
  refreshPredictions, eventBuilder
- Create mosaic-telemetry.config.ts for env var integration via
  NestJS ConfigService
- Register MosaicTelemetryModule in AppModule
- Add 32 unit tests covering module init, service methods, disabled
  mode, dry-run mode, and lifecycle management

Refs #369

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 8d8d37dbf9 feat(#370): install mosaicstack-telemetry in Coordinator
- Add mosaicstack-telemetry>=0.1.0 to pyproject.toml dependencies
- Configure Gitea PyPI registry via pip.conf (extra-index-url)
- Integrate TelemetryClient in FastAPI lifespan (start_async/stop_async)
- Store client on app.state.mosaic_telemetry for downstream access
- Create mosaic_telemetry.py helper module with:
  - get_telemetry_client(): retrieve client from app state
  - build_task_event(): construct TaskCompletionEvent with coordinator defaults
  - create_telemetry_config(): create config from MOSAIC_TELEMETRY_* env vars
- Add 28 unit tests covering config, helpers, disabled mode, and lifespan
- New module has 100% test coverage

Refs #370

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:10:22 -06:00
jason.woltjeandClaude Opus 4.6 c40373fa3b feat(#389): create SpeechModule with provider abstraction layer
Add SpeechModule with provider interfaces and service skeleton for
multi-tier TTS fallback (premium -> default -> fallback) and STT
transcription support. Includes 27 unit tests covering provider
selection, fallback logic, and availability checks.

- ISTTProvider interface with transcribe/isHealthy methods
- ITTSProvider interface with synthesize/listVoices/isHealthy methods
- Shared types: SpeechTier, TranscriptionResult, SynthesisResult, etc.
- SpeechService with graceful TTS fallback chain
- NestJS injection tokens (STT_PROVIDER, TTS_PROVIDERS)
- SpeechModule registered in AppModule
- ConfigModule integration via speechConfig registerAs factory

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:09:45 -06:00
jason.woltjeandClaude Opus 4.6 52553c8266 feat(#399): add Docker Compose dev overlay for speech services
Add docker-compose.speech.yml with three speech services:
- Speaches (STT via Whisper + basic TTS) on port 8090
- Kokoro-FastAPI (default TTS) on port 8880
- Chatterbox TTS (premium, GPU-required) on port 8881 behind
  the premium-tts profile

All services include health checks, connect to the mosaic-internal
network, and follow existing naming/labeling conventions. Makefile
targets added: speech-up, speech-down, speech-logs.

Fixes #399

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:06:21 -06:00
jason.woltje f238867eae chore(orchestrator): Update tasks — Phase 1 complete, Phase 2 starting
MB-001 (MatrixService skeleton): done — commit 5b5d381
MB-002 (Synapse dev compose): done — commit 4a5cb64
MB-003, MB-004: in-progress

Refs #377
2026-02-15 02:06:01 -06:00
jason.woltjeandClaude Opus 4.6 5b5d3811d6 feat(#378): Install matrix-bot-sdk and create MatrixService skeleton
- Add matrix-bot-sdk dependency to @mosaic/api
- Create MatrixService implementing IChatProvider interface
- Support connect/disconnect, message sending, thread management
- Parse @mosaic and !mosaic command prefixes
- Delegate commands to StitcherService (same flow as Discord)
- Add comprehensive unit tests with mocked MatrixClient (31 tests)
- Add Matrix env vars to .env.example

Refs #378

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:04:39 -06:00
jason.woltje 4cc43bece6 feat(#401): add speech services config and env vars
Add SpeechConfig with typed configuration and startup validation for
STT (Whisper/Speaches), TTS default (Kokoro), TTS premium (Chatterbox),
and TTS fallback (Piper/OpenedAI). Includes registerAs factory for
NestJS ConfigModule integration, .env.example documentation, and 51
unit tests covering all validation paths.

Refs #401
2026-02-15 02:03:21 -06:00
jason.woltjeandClaude Opus 4.6 4a5cb6441e feat(#384): Add Synapse + Element Web to docker-compose for dev
- Create docker-compose.matrix.yml as optional dev overlay
- Add Synapse homeserver config with shared PostgreSQL
- Add Element Web client config (port 8501)
- Add bot account setup script (docker/matrix/scripts/setup-bot.sh)
- Add Makefile targets: matrix-up, matrix-down, matrix-logs, matrix-setup-bot
- Document Matrix env vars in .env.example
- Synapse accessible at localhost:8008, Element at localhost:8501
- Usage: docker compose -f docker/docker-compose.yml -f docker/docker-compose.matrix.yml up

Refs #384

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 02:02:22 -06:00
jason.woltje 6e4236b359 chore(orchestrator): Bootstrap M12-MatrixBridge tasks.md
Parsed 11 issues into 10 tasks across 6 phases.
#387 already completed. Estimated total: ~160K tokens.

Refs #377
2026-02-15 01:58:10 -06:00
jason.woltjeandClaude Opus 4.6 fb53272fa9 chore(orchestrator): Bootstrap M13-SpeechServices tasks.md
18 tasks across 7 phases for TTS & STT integration.
Estimated total: ~322K tokens.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:56:06 -06:00
jason.woltjeandClaude Opus 4.6 8ce6843af2 fix(database,api): add 6 missing table migrations and fix CORS health checks
Database: 6 models in the Prisma schema had no CREATE TABLE migration:
cron_schedules, workspace_llm_settings, quality_gates, task_rejections,
token_budgets, llm_usage_logs. Same root cause as the federation tables.

CORS: Health check requests (Docker, load balancers) don't send Origin
headers. The CORS config was rejecting these in production, causing
/health to return 500 and Docker to mark the container as unhealthy.
Requests without Origin headers are not cross-origin per the CORS spec
and should be allowed through.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:49:13 -06:00
jason.woltjeandClaude Opus 4.6 dfe89b7a3b fix(devops): add CSRF_SECRET to all compose files
Added CSRF_SECRET to docker-compose.swarm.portainer.yml (the active
Portainer deployment) and both example compose files. Also added
ENCRYPTION_KEY to the example files where it was missing.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:44:45 -06:00
jason.woltjeandClaude Opus 4.6 7aee5ed5ba fix(devops): add CSRF_SECRET and ENCRYPTION_KEY to compose files
Both env vars were missing from the API service environment in
docker-compose.prod.yml and docker-compose.build.yml, causing the
CSRF_SECRET check to fail at startup even when set in .env.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:41:35 -06:00
jason.woltjeandClaude Opus 4.6 3d54f7a7f0 docs: add CSRF_SECRET to .env.example
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:36:55 -06:00
jason.woltjeandClaude Opus 4.6 6e20fc5d16 feat: Sample Matrix swarm deployment compose file (#387)
Standalone Synapse + Element Web deployment for Docker Swarm/Portainer.
Separate infrastructure from Mosaic Stack (same pattern as Authentik).

Includes: Synapse, Element Web, dedicated PostgreSQL, optional coturn.
Traefik labels match existing Stack conventions.

Refs #387

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:12:41 -06:00
jason.woltjeandClaude Opus 4.6 d2003a7b03 fix(api): make federation config validation non-fatal at startup
Federation is optional and should not prevent the app from starting
when DEFAULT_WORKSPACE_ID is not set. Changed from throwing (crash)
to logging a warning. The endpoint-level validation in the controller
still rejects requests when federation is unconfigured.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 01:08:09 -06:00
jason.woltjeandClaude Opus 4.6 8733a643bf fix(api): remove "type": "module" conflicting with CommonJS build output
The NestJS tsconfig compiles to CommonJS (module: "CommonJS") but
package.json had "type": "module", causing Node.js v24 to treat the
CJS output as ESM and fail with "exports is not defined in ES module
scope" at startup.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 00:53:43 -06:00
jason.woltjeandClaude Opus 4.6 91307c87cc fix(database): add missing federation table migrations
Federation models (FederationConnection, FederatedIdentity,
FederationMessage) and their enums were defined in the Prisma schema
but never had CREATE TABLE migrations. This caused the
20260203_add_federation_event_subscriptions migration to fail with
"relation federation_messages does not exist".

Adds new migration 20260202200000 to create the 3 missing enums,
3 missing tables, all indexes, and foreign keys. Removes the
now-redundant ALTER TABLE from the 20260203 migration since
event_type is created with the table.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 00:29:37 -06:00
jason.woltjeandClaude Opus 4.6 f4e759c07a fix(devops): bypass OpenBao base entrypoint to prevent dev-mode flags
The base openbao image's docker-entrypoint.sh injects -dev-root-token-id
and -dev-listen-address flags when it sees 'server' as $1, causing the
server to exit immediately (code 0). Override entrypoint with dumb-init
and call bao directly to avoid the dev-mode flag injection.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 00:13:57 -06:00
jason.woltjeandClaude Opus 4.6 b6d272992a fix(devops): fix OpenBao healthcheck URL truncation with CMD-SHELL
The CMD exec form drops everything after & in the healthcheck URL,
causing uninitcode=200 and sealedcode=200 params to be lost. Without
them, OpenBao returns 501 when uninitialized, healthcheck fails, and
Swarm kills the container before the init sidecar can reach it.

Switch to CMD-SHELL with single-quoted URL to preserve query params.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 00:08:12 -06:00
jason.woltjeandClaude Opus 4.6 14162b9213 fix(api): use node_modules prisma binary in entrypoint
npx is unavailable in production image since npm is removed.
Use ./node_modules/.bin/prisma directly instead.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 00:05:46 -06:00
jason.woltjeandClaude Opus 4.6 44a44b5f56 fix(ci): remove SHA tags, use only dev/latest/vX.X.X
Align image tagging with semver convention:
- develop branch → :dev
- main branch → :latest
- git tags → :vX.X.X

Removes commit SHA tags from all 5 pipelines (api, web, orchestrator,
coordinator, infra) and updates Trivy scans to reference branch/tag.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-14 23:58:51 -06:00
jason.woltjeandClaude Opus 4.6 899faba7e2 fix(devops): set Valkey maxmemory-policy to noeviction for BullMQ
BullMQ requires noeviction to prevent silent job data loss. With
allkeys-lru, Valkey could evict keys BullMQ depends on for job tracking.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-14 16:51:42 -06:00
jason.woltjeandClaude Opus 4.6 bcee4fa601 fix(api): auto-run migrations on container start and fix ESM warning
- Add docker-entrypoint.sh that runs prisma migrate deploy before
  starting the app, ensuring all tables exist on deployment
- Add "type": "module" to package.json to eliminate Node.js ESM
  reparsing warning for eslint.config.js

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-14 16:47:57 -06:00
jason.woltjeandClaude Opus 4.6 ab52827d9c chore: add install scripts, doctor command, and AGENTS.md
- Add one-line installer (scripts/install.sh) with platform detection
- Add doctor command (scripts/commands/doctor.sh) for environment diagnostics
- Add shared libraries: dependencies, docker, platform, validation
- Update README with quick-start installer instructions
- Add AGENTS.md with codebase patterns for AI agent context

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-14 11:04:36 -06:00
jason.woltjeandClaude Opus 4.6 0ca3945061 fix(api): resolve Docker startup failures (secrets, Redis, Prisma)
- Pass BETTER_AUTH_SECRET through all 6 docker-compose files to API container
- Fix BullModule to parse VALKEY_URL instead of VALKEY_HOST/VALKEY_PORT,
  matching all other Redis consumers in the codebase
- Migrate Prisma encryption from removed $use() middleware to $extends()
  client extensions (Prisma 6.x compatibility), keeping extends PrismaClient
  pattern with only account and llmProviderInstance getters overridden

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-14 11:04:04 -06:00
jason.woltjeandClaude Opus 4.6 7b892d5197 fix(api): import AuthModule in FederationModule for DI resolution
AuthGuard used across federation controllers depends on AuthService,
which requires AuthModule to be imported. Matches pattern used by
TasksModule, ProjectsModule, and CredentialsModule.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-13 22:36:11 -06:00
jason.woltjeandClaude Opus 4.6 e23490a5f7 fix(api): remove redundant CsrfGuard from FederationController
CsrfGuard is already applied globally via APP_GUARD in AppModule.
The explicit @UseGuards(CsrfGuard) on FederationController caused a
DI error because CsrfService is not provided in FederationModule.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-13 22:14:03 -06:00
jason.woltje 1b3ff1b5e1 Merge pull request 'fix(ci): Node.js 20 → 24 LTS + pipeline fixes (#366, #367)' (#368) from fix/ci-366 into develop
Reviewed-on: http://git.mosaicstack.dev/mosaic/stack/pulls/368
2026-02-13 23:18:04 +00:00
jason.woltje 46be7aa36f Merge branch 'develop' into fix/ci-366 2026-02-13 23:17:55 +00:00
jason.woltje 2ab795a95d Merge pull request 'fix(ci): fix pipeline #366 — web @mosaic/ui build, Dockerfile find bug, event handler types' (#366) from fix/ci-366 into develop
Reviewed-on: http://git.mosaicstack.dev/mosaic/stack/pulls/366
2026-02-13 00:27:48 +00:00
jason.woltjeandClaude Opus 4.6 e368083e84 fix(api): import AuthModule in CredentialsModule for DI resolution
CredentialsController uses AuthGuard which depends on AuthService.
NestJS resolves guard dependencies in the module context, so
CredentialsModule needs to import AuthModule directly.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 21:14:20 -06:00
jason.woltjeandClaude Opus 4.6 4a4d3efbfb fix(ci): move pipeline config into .woodpecker/ directory
Woodpecker v3 ignores .woodpecker.yml when a .woodpecker/ directory
exists, reading only files from the directory. Since develop has
.woodpecker/codex-review.yml, the main build pipeline was invisible
to Woodpecker on develop. Move it into the directory as build.yml.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 20:58:26 -06:00
jason.woltjeandClaude Opus 4.6 3a922d447f ci: test webhook trigger on develop branch
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 20:57:24 -06:00
jason.woltjeandClaude Opus 4.6 9ff1e69860 chore(api): remove debug statements from Dockerfile
Remove temporary debug RUN layers that were added during initial
build troubleshooting. These add build time and leak directory
structure into build logs unnecessarily.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 20:54:37 -06:00
jason.woltjeandClaude Opus 4.6 c8bf7f6b70 chore: trigger CI pipeline on develop
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 20:31:24 -06:00
jason.woltjeandClaude Opus 4.6 64396cf9de chore: trigger CI rebuild from current develop HEAD
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 20:30:42 -06:00
jason.woltje 1456a6f149 chore: trigger CI rebuild for develop images 2026-02-11 19:43:44 -06:00
jason.woltje fc2a13ad74 chore: trigger CI pipeline rebuild 2026-02-11 19:42:26 -06:00
jason.woltjeandClaude Opus 4.6 72b1d9f4f2 fix(devops): make OpenBao compose Swarm/Portainer compatible
Convert docker-compose.openbao.yml from standalone Docker Compose
to Swarm-compatible format:
- Remove container_name, depends_on, restart (not supported in Swarm)
- Add deploy.restart_policy sections
- Remove 127.0.0.1 port binding (use overlay network instead)
- Remove env_file (use Portainer environment instead)
- Init sidecar limited to 5 restart attempts with 10s delay

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 19:41:05 -06:00
jason.woltjeandClaude Opus 4.6 b3c0f51dc9 fix(devops): enable OpenBao in Swarm and fix healthchecks
- Enable OpenBao + init sidecar in Swarm compose (was commented out)
- Fix healthcheck to accept uninitialized/sealed vault states
  (add ?uninitcode=200&sealedcode=200 to /v1/sys/health)
- Replace nc-based healthcheck with wget in dev compose
- Add ORCHESTRATOR_URL env var to API service in Swarm compose
- Uncomment OpenBao volumes in Swarm compose

The healthcheck was returning HTTP 501 for uninitialized vault,
causing Swarm to restart OpenBao before init sidecar could run.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-11 19:38:34 -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 ab64583951 fix: resolve deployment crashes in coordinator and API services
Coordinator: install all dependencies from pyproject.toml instead of
hardcoded subset (missing slowapi, anthropic, opentelemetry-*).

API: FederationAgentService now gracefully disables when orchestrator
URL is not configured instead of throwing and crashing the app.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-10 09:41:54 -06:00