Commit graph

1139 commits

Author SHA1 Message Date
Till-JS
99a23d04d2 🚀 feat(infra): expose STT and TTS APIs externally
- Add stt-api.mana.how -> localhost:3020
- Add tts-api.mana.how -> localhost:3021

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 17:39:59 +01:00
Till-JS
e7e6281d54 🔧 fix(docker): add missing shared packages to all backend Dockerfiles
All backend Dockerfiles were missing required shared package dependencies,
causing CI builds to fail with TypeScript compilation errors.

Fixed Dockerfiles:
- chat: added credit-operations, nestjs-integration, health, metrics, setup, tsconfig
- todo: added credit-operations, nestjs-integration, health, metrics, tsconfig
- contacts: added health, metrics, setup, tsconfig
- calendar: added credit-operations, nestjs-integration, health, metrics, setup, tsconfig
- presi: added health, setup, tsconfig
- picture: added credit-operations, nestjs-integration, health, storage, tsconfig
- clock: added health, metrics, setup, tsconfig
- storage: added health, tsconfig
- manadeck: added credit-operations, tsconfig
- skilltree: added health, metrics, tsconfig

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 16:47:00 +01:00
Till-JS
21d50d1e0b 📝 docs(mana-stt): document Whisper + Mistral API architecture
- Disable vLLM by default (has issues on macOS CPU)
- Use Mistral API for Voxtral transcription (cloud-based)
- Keep Whisper-MLX for local transcription
- Update README with architecture diagram

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 16:34:03 +01:00
Till-JS
7c9c2645e3 🐛 fix(mana-stt): adjust vLLM config for CPU mode
- Reduce max-model-len to 4096 for CPU compatibility
- Add max-num-batched-tokens matching the context size
- Add enforce-eager for stable CPU inference

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 16:14:14 +01:00
Till-JS
60394076e5 feat(mana-stt): add vLLM integration for Voxtral transcription
- Add vllm_service.py as proxy to vLLM server for Voxtral 3B/4B
- Add voxtral_api_service.py for Mistral API fallback
- Update main.py with /transcribe/voxtral endpoint using vLLM
- Add /transcribe/auto endpoint with automatic fallback chain
- Create setup-vllm.sh and start-vllm-voxtral.sh scripts
- Add launchd plist files for Mac Mini deployment
- Add install-services.sh for automated service installation

Architecture:
- vLLM server runs Voxtral models on port 8100
- mana-stt proxies to vLLM with Mistral API fallback
- Fallback chain: vLLM -> Mistral API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-11 16:10:00 +01:00
Till-JS
a2e2a5b73c feat(admin): add user data dashboard for cross-project data visualization
Add comprehensive admin dashboard to view and manage user data across all projects:

Backend:
- Add admin endpoints to Chat, Todo, Contacts, Calendar, Picture, Zitare, Presi
- Each backend exposes GET/DELETE /api/v1/admin/user-data/:userId
- Service-to-service auth via X-Service-Key header

Aggregation (mana-core-auth):
- GET /api/v1/admin/users - Paginated user list with search
- GET /api/v1/admin/users/:userId/data - Aggregated data from all backends
- DELETE /api/v1/admin/users/:userId/data - GDPR deletion across all projects

Frontend (ManaCore web):
- New User Data tab in admin navigation
- User search page at /admin/user-data
- User detail page with ProjectDataCard components
- GDPR deletion dialog with email confirmation

Presi:
- Migrate user_id from UUID to TEXT for Better Auth compatibility
- Add SQL migration script
2026-02-11 14:59:18 +01:00
Till-JS
5b6f231e1a 🐛 fix(todo,matrix): improve click targets and type safety
- todo: Make task-content button fill full height for better click target
- matrix: Fix TypeScript errors by using Boolean() for template expressions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 14:53:49 +01:00
Till-JS
bf0e788cba ♻️ refactor(todo,contacts): remove sidebar mode from PillNavigation
Simplify navigation by removing unused sidebar mode from both apps:

Todo App:
- Remove isSidebarMode state, handlers, and localStorage persistence
- Remove sidebar-related CSS classes and styles
- Simplify TodoToolbar to pure wrapper component

Contacts App:
- Remove isSidebarMode state, handlers, and localStorage persistence
- Remove sidebar-related CSS from ContactsToolbar and ContactAlphabetView
- Always show view-mode-pill (no longer conditional on sidebar mode)

This removes ~250 lines of unused code across 5 files.
2026-02-02 19:16:56 +01:00
Till-JS
12a900346c ♻️ refactor(calendar): remove sidebar mode from PillNavigation
Simplify the bottom bars by removing the unused sidebar mode:
- Remove isSidebarMode prop from all components
- Remove sidebar-related CSS classes and styles
- Simplify CalendarToolbar to pure wrapper component
- Remove localStorage persistence for sidebar mode

This removes ~230 lines of unused code across 8 files.
2026-02-02 19:06:32 +01:00
Till-JS
c475923864 fix(mana-media): simplify Dockerfile to single build stage
Use simpler approach that handles pnpm install failures gracefully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 19:03:05 +01:00
Till-JS
b3dd3c51d3 fix(mana-media): fix Dockerfile build and health check paths
- Use --ignore-scripts to skip postinstall builds during install
- Remove unnecessary shared-builder stage
- Fix health check URL to /api/v1/health

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:57:50 +01:00
Till-JS
c965f7e440 fix(mana-media): simplify Dockerfile for pnpm hoisted dependencies
pnpm hoists dependencies to root node_modules, so we don't need to copy
service-level node_modules that don't exist.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:55:49 +01:00
Till-JS
bd9bd556f4 🚸 feat(calendar): hide tasks by default and scroll to midday on load
- Add showTasksInCalendar setting (default: false) to hide task blocks
- Auto-scroll time-grid views to 12:00 on initial load for better UX
- Tasks can be re-enabled via settings toggle
2026-02-02 18:54:05 +01:00
Till-JS
5c19500748 fix(mana-media): change userId from UUID to TEXT for Matrix user IDs
Matrix user IDs like @user:matrix.org are not UUIDs, so the schema
needs to accept text strings for the userId field in media_references.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:45:40 +01:00
Till-JS
cee30ff7ed feat(matrix-todo-bot): improve UX with German commands without ! prefix
- heute command now shows both today's tasks AND inbox tasks
- All commands work without ! prefix (e.g., 'heute' instead of '!heute')
- Updated all help text and messages to show German commands
- Added direct command recognition for: neu, heute, erledigt, löschen, etc.
- Commands still work with ! prefix for backwards compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:32:00 +01:00
Till-JS
d4663b5643 feat(mana-media): add centralized media storage with NutriPhi integration
- Implement mana-media service with PostgreSQL/Drizzle ORM persistence
- Add content-addressable storage (SHA-256) for automatic deduplication
- Add Matrix MXC URL import endpoint to copy images from Matrix
- Create @manacore/media-client package for service consumption
- Integrate mana-media into NutriPhi bot for persistent image storage
- Update pnpm-workspace.yaml to include nested service packages
- Add mana-media to docker-compose with port 3015

Images sent to NutriPhi bot are now stored in mana-media after analysis,
providing persistent storage with deduplication across all apps.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 17:30:14 +01:00
Till-JS
171cf7a854 fix(contacts-web): use runtime URLs instead of build-time baked values
- user-settings.svelte.ts: use getAuthUrl() for settings API
- contacts.ts: use getAuthUrl() for tags API client
- feedback.ts: use getAuthUrl() for feedback service

This fixes Mixed Content errors where the app was trying to reach
internal Docker URLs (http://mana-auth:3001) instead of production
URLs (https://auth.mana.how).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 17:22:59 +01:00
Till-JS
30f0dbef5d feat(contacts-web): add hooks.server.ts for runtime URL injection
Fixes contacts-web using localhost URLs instead of production URLs.
SvelteKit bakes environment variables at build time, so we need to
inject runtime URLs via hooks.server.ts for Docker deployments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 17:14:03 +01:00
Till-JS
1fe498e758 fix(shared-ui): export calculateFadeOpacity from index
This utility function was used by contacts-web skeletons but wasn't
exported from the main shared-ui package entry point.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 17:07:49 +01:00
Till-JS
49c5873af1 chore(docker): build contacts-web locally instead of using GHCR image
GHCR image was outdated (2026-01-29), missing:
- Demo mode removal (2026-01-30)
- SSO implementation (2026-02-02)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 17:06:12 +01:00
Till-JS
5b3c87b245 fix(docker): use monorepo root as build context for mana-auth
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:52:09 +01:00
Till-JS
ce5f3b5384 chore(docker): build mana-auth locally instead of using GHCR image
Allows faster iteration on auth fixes without needing to push to GHCR.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:51:25 +01:00
Till-JS
85df234ff2 feat(mana-core-auth): auto-link Matrix users on OIDC login
When users log into Matrix via OIDC (Sign in with Mana Core), their
Matrix user ID is now automatically linked to their Mana account.
This enables automatic bot authentication without requiring a
separate !login command.

- Add autoLinkOnOidcLogin() method to MatrixSessionService
- Hook into OIDC userinfo endpoint to create links automatically
- Calculate Matrix user ID from email using Synapse's template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:50:28 +01:00
Till-JS
75937d6ce9 fix(mana-core-auth): align JWT issuer validation with Better Auth signing config
Better Auth signs JWTs with issuer=BASE_URL (https://auth.mana.how) for OIDC
compatibility, but validation was using jwt.issuer config which defaults to
'manacore'. This caused "unexpected iss claim value" errors.

Fixed in:
- better-auth.service.ts validateToken()
- jwt-auth.guard.ts
- optional-auth.guard.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:50:04 +01:00
Till-JS
0538a6ca10 fix(mana-core-auth): use Better Auth signJWT in refresh endpoint
The refresh endpoint was using manual jwt.sign with RSA keys, but the
server doesn't have JWT_PRIVATE_KEY configured. Changed to use Better
Auth's signJWT method which uses the JWKS/EdDSA keys from the database.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:40:37 +01:00
Till-JS
c196144d1c fix(mana-core-auth): return real refreshToken from signIn endpoint
Same issue as sessionToToken - the signIn method was returning the
session cookie token as refreshToken, but the /api/v1/auth/refresh
endpoint expects the actual refreshToken field from the sessions table.

Now signIn:
- Fetches the session from database after Better Auth creates it
- Uses existing refreshToken if available
- Generates and stores a new refreshToken if missing
- Returns the actual refreshToken that works with token refresh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:37:54 +01:00
Till-JS
d64016d1e5 fix(mana-core-auth): exclude /api/auth/get-session from global prefix
The get-session endpoint needs to be accessible at /api/auth/get-session
(without the /api/v1 prefix) for SSO to work.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:29:17 +01:00
Till-JS
95e9b3764d feat(mana-core-auth): add /api/auth/get-session endpoint for SSO
The SSO flow in client apps calls /api/auth/get-session with cookies
to check if the user has a valid session. This endpoint was missing
from the NestJS passthrough controller.

Now the endpoint forwards the request with cookies to Better Auth's
native handler and returns the session data.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:27:39 +01:00
Till-JS
9c45879363 feat(nutriphi-bot): auto-analyze images when received
Images are now automatically analyzed when sent to the bot, removing
the need for the !analyze command after sending a photo.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:27:03 +01:00
Till-JS
f556665ac2 fix(shared-nestjs-setup): export compiled JS instead of TypeScript
The package was incorrectly exporting src/index.ts which causes runtime
errors when used with plain Node.js. Changed to export from dist/.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:19:39 +01:00
Till-JS
ad22d264aa fix(nutriphi): add shared-drizzle-config and make db:push non-fatal
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:17:22 +01:00
Till-JS
b6925e0b63 feat(matrix-bots): enable cross-bot SSO via Redis sessions
All 19 Matrix bots now use SessionModule.forRoot({ storageMode: 'redis' })
to share user sessions across all bots via Redis. Users only need to
login once with any bot to be authenticated with all bots.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:16:22 +01:00
Till-JS
0cafd4f94f chore: update pnpm-lock.yaml for express dependency
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:14:51 +01:00
Till-JS
ac477aae24 fix(nutriphi): add missing shared packages to Dockerfile
Added shared-tsconfig, shared-nestjs-setup, and shared-nestjs-health
packages required for the backend build.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:14:04 +01:00
Till-JS
509bbb9920 fix(nutriphi): add shared-nestjs-setup to Dockerfile
The package is required for the bodyLimit configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:09:44 +01:00
Till-JS
b404ddc9a8 fix(nutriphi): increase body size limit to 50mb for image uploads
The NutriPhi bot was failing with 413 "request entity too large" when
analyzing images via Base64. Added configurable bodyLimit option to
shared-nestjs-setup and set NutriPhi backend to 50mb.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:08:14 +01:00
Till-JS
c2c80efc50 feat(matrix-bots): add i18n system and direct message fallback
- Add I18nService with per-user language preferences (de/en)
- Add !language/!sprache command to all 4 bots (todo, calendar, contacts, clock)
- Add fallback behavior: messages without commands create tasks/events/contacts/timers
- Improve clock bot duration parsing to accept bare numbers as minutes (e.g. "25" = 25min)
- Add support for more duration formats: "25 minuten", "1 stunde", etc.

Language preferences stored in SessionService, default configurable via BOT_DEFAULT_LANGUAGE env var.
2026-02-02 16:07:27 +01:00
Till-JS
5c688d713e fix(mana-core-auth): return real refreshToken in SSO session-to-token exchange
The sessionToToken method was incorrectly returning the session cookie
token instead of the actual refreshToken from the database. This caused
"No refresh token available" errors when users logged in via SSO
(cross-domain cookie) because the /api/v1/auth/refresh endpoint expects
the refreshToken field from the sessions table, not the cookie token.

Now the method:
- Fetches the session from database by cookie token
- Uses existing refreshToken if available
- Generates and stores a new refreshToken if missing
- Returns the actual refreshToken that works with token refresh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:05:44 +01:00
Till-JS
9d7e6c670e fix(matrix-web): change bots page to single column layout
More readable and cleaner UX with narrower max-width

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:46:35 +01:00
Till-JS
23852cf605 feat(matrix-web): add bots page with all 19 Matrix bots
- Add /bots route with bot overview grid
- Create BotCard component with expandable details
- Implement search and category filtering (AI, Productivity, Media, Lifestyle, Tools)
- Add bot data structure with commands, descriptions, and metadata
- Support starting chat with bots (creates DM or navigates to existing room)
- Add German and English translations
- Add robot icon to PillNavigation component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:36:49 +01:00
Till-JS
aba79f5c16 fix(mana-llm): fix SSE double data prefix causing message parsing issues
EventSourceResponse from sse-starlette adds its own 'data:' prefix,
so we should yield dicts with a 'data' key instead of pre-formatted
SSE strings. This was causing 'data: data:' double prefixes and
backticks appearing in chat messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:29:11 +01:00
Till-JS
60d2f6422c fix(matrix-bots): update all bots for async SessionService methods
Update all Matrix bots to properly await async SessionService methods
after the migration to Redis-backed session storage. This includes:

- Adding await to getSessionData, getSession, getToken, isLoggedIn calls
- Making requireAuth helper methods async and return Promise<string>
- Making session data helper methods async (getCurrentConversation, etc.)
- Fixing handleLogout and other methods that use session operations

Affected bots:
- matrix-chat-bot (extensive changes for session helpers)
- matrix-clock-bot (getToken helper + session calls)
- matrix-contacts-bot, matrix-manadeck-bot, matrix-nutriphi-bot
- matrix-ollama-bot, matrix-picture-bot, matrix-planta-bot
- matrix-presi-bot, matrix-project-doc-bot, matrix-skilltree-bot
- matrix-storage-bot, matrix-zitare-bot, matrix-tts-bot
- matrix-mana-bot (help handler)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:04:30 +01:00
Till-JS
0b46d203bb feat(infra): add mana-llm service to production deployment
- Add mana-llm FastAPI service for LLM API gateway
- Configure CORS for playground.mana.how
- Use shared Redis from existing infra
- Connect playground to mana-llm container

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:58:44 +01:00
Till-JS
a416dade7b fix(playground): add missing shared packages to Dockerfile
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:55:02 +01:00
Till-JS
8525020e8a feat(playground): integrate shared auth UI for consistent login experience
- Add PlaygroundLogo to shared-branding package
- Add playground to APP_BRANDING, APP_ICONS, and APP_URLS
- Replace custom login/register pages with shared-auth-ui components
- Update authStore with resendVerificationEmail and improved signUp
- Add Caddy reverse proxy entry for playground.mana.how

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:53:51 +01:00
Till-JS
2777f604fd feat(bots): enable Redis SSO for todo-bot and calendar-bot
- Activate Redis session storage in both bots for cross-bot SSO
- Update SessionHelper to async methods for Redis-backed SessionService
- Fix async/await issues in todo-bot and calendar-bot matrix.service.ts
- Remove unused imports from calendar-api and todo-api services
- Add CALENDAR_BACKEND_URL and MANA_CORE_SERVICE_KEY to .env.development

Note: SessionService methods are now async (Redis-backed). Other bots
need their matrix.service.ts updated to await these async calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:51:23 +01:00
Till-JS
7bad849258 docs(server): document Docker on external SSD and Matrix Bots
- Add Docker Desktop relocation to external SSD via symlink
- Document ~80GB freed on internal SSD
- Add Matrix Bots section with all 10 bots and ports
- Include health check, logs, and management commands

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 13:43:39 +01:00
Till-JS
feaf27dd14 feat(auth): implement cross-subdomain SSO for all web apps
Add Single Sign-On (SSO) support across all mana.how subdomains:

- Add trySSO() method to @manacore/shared-auth that exchanges session
  cookies for JWT tokens
- Add /api/v1/auth/session-to-token endpoint to mana-core-auth service
- Update all 15 web apps to try SSO during auth initialization

SSO Flow:
1. User logs in on any app (e.g., calendar.mana.how)
2. Session cookie is set with Domain=.mana.how
3. When visiting another app (e.g., todo.mana.how), it checks for
   local tokens first
4. If no local tokens, tries SSO via session cookie
5. Session cookie is exchanged for JWT tokens via new endpoint
6. User is automatically authenticated

Apps updated: calendar, chat, clock, contacts, manacore, manadeck,
nutriphi, picture, planta, presi, questions, skilltree, storage,
todo, zitare

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 13:17:04 +01:00
Till-JS
352070fb2f docs(auth): add SSO documentation and test credentials
- Document cross-domain SSO with COOKIE_DOMAIN configuration
- Add production test credentials for automated testing
- Explain cookie-based SSO flow across *.mana.how subdomains

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 04:09:07 +01:00
Till-JS
f03c09ff17 feat(auth): enable cross-domain SSO via shared cookies on .mana.how
- Configure Better Auth with crossSubDomainCookies for .mana.how domain
- Add COOKIE_DOMAIN environment variable (production: .mana.how)
- Sync trustedOrigins with all production subdomains
- Users now login once and are authenticated across all apps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 03:58:29 +01:00