Commit graph

298 commits

Author SHA1 Message Date
Till JS
99091ecf9e docs+test: add audio format docs and shared-storage utils tests
- Document all supported audio formats in mukke CLAUDE.md with browser
  compatibility matrix and notes on formats needing transcoding
- Add utils.test.ts for shared-storage: MIME type mappings, audio
  extension validation, and AUDIO_EXTENSIONS completeness checks (19 tests)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:12:58 +01:00
Till JS
7a1ae1284c feat(mukke): support all common audio formats for upload and playback
Expand accepted audio formats beyond MP3/WAV/OGG to include FLAC, AAC,
M4A, AIFF, OPUS, WMA, WebM, ALAC, APE, WavPack, DSF, and DFF.
The HTML5 Audio player already handles whatever the browser supports.

Changes:
- BeatUploader: accept audio/* instead of hardcoded format list
- shared-storage: add MIME type mappings for all common audio formats

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:09:25 +01:00
Till JS
4770e15499 fix(calendar): improve onboarding UX — clearer progress, better selection, apply preferences
- Replace thin progress bar with animated step dots
- Add checkmark icon and stronger highlight for selected options
- Remove redundant step emoji (duplicate of header)
- Hide "Zurück" button on first step instead of just opacity:0
- Remove timezone step (auto-detect is always correct, 4 options too limited)
- Replace unsupported "day" view with "agenda" in view options
- Wire onComplete to actually apply weekStart and defaultView to settingsStore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:00:28 +01:00
Till JS
8a0ab38958 chore: fix wallpaper-generator test script and update CLAUDE.md test count
- Replace vitest run with echo (no test files exist)
- Update Current State section: 25 → 128 test files,
  reflect actual CI/CD and pre-commit setup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:54:21 +01:00
Till JS
5832326010 docs(storage): update README with complete API documentation
Cover all features added in recent commits: hooks, metrics,
Prometheus collector, presigned multipart, move, copy,
deleteByPrefix, getMetadata, stream size validation, CDN URLs.
Update bucket table to match current state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:49:16 +01:00
Till JS
8c2aa261e8 perf(auth): replace bcrypt with bcryptjs (pure JS, no native build tools)
- Switch from bcrypt (native C++ addon) to bcryptjs (pure JavaScript)
- Remove python3/make/g++ build tools from Dockerfile builder stage
- bcryptjs is 100% hash-compatible with bcrypt
- Smaller builder image and faster Docker builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:46:16 +01:00
Till JS
152fa5fe08 feat(storage): add deleteByPrefix, copy, getMetadata and prod lifecycle rules
- Add deleteByPrefix(prefix) for bulk user data deletion (account cleanup)
- Add copy(sourceKey, destKey) via CopyObjectCommand for file duplication
- Add getMetadata(key) via HeadObjectCommand for content-type/size/metadata
- Add FileMetadata type for structured metadata responses
- Add minio-init container to docker-compose.macmini.yml with bucket creation,
  public access policies, and lifecycle rules (matching dev compose)
- 96 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:40:17 +01:00
Till JS
b0e5a9c5ff feat(storage): add upload hooks, metrics integration, and presigned multipart
Upload hooks:
- StorageHooks class with fire-and-forget event emitter pattern
- Events: upload, upload:error, delete, delete:error, download
- All StorageClient operations now emit appropriate events
- Unsubscribe functions for cleanup

Metrics:
- StorageMetricsCollector interface (decoupled from prom-client)
- InMemoryMetrics for testing and local dev
- attachMetrics() wires hooks to any collector automatically
- Backends can create a Prometheus collector via MetricsService

Presigned multipart upload (browser direct-upload):
- createMultipartUpload() initiates and returns uploadId
- getMultipartUploadUrls() generates presigned PUT URLs per part
- completeMultipartUpload() finalizes with part ETags
- abortMultipartUpload() for cleanup on abandoned uploads

90 tests passing across 5 test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:36:46 +01:00
Till JS
822e75368a feat(shared): add DevBuildBadge component and getBuildDefines() helper
- shared-vite-config: getBuildDefines() injects __BUILD_HASH__ and
  __BUILD_TIME__ as compile-time constants via Vite define
- shared-ui: DevBuildBadge component shows git hash + build timestamp
  in a small fixed badge at bottom-right (click to expand)
- Integrated into mukke-web for deployment verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:34:21 +01:00
Till JS
01c4d3a9d1 feat(storage): cleanup buckets, add file-size validation and bulk delete
- Remove archived LIGHTWRITE and NUTRIPHI from BUCKETS
- Add missing PLANTA and PROJECTDOC buckets (were in Docker init but not in code)
- Add maxSizeBytes option to upload() and uploadMultipart() for size enforcement
- Add deleteMany() with automatic batching (1000 keys per S3 request)
- Add factories for createPlantaStorage() and createProjectDocStorage()
- Update tests (62 passing)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:27:42 +01:00
Till JS
720602343e fix(shared-auth): set SSO session cookie on login
The signIn() method only called the custom /api/v1/auth/login endpoint
which returns JWT tokens but doesn't set a session cookie. Without the
cookie, cross-subdomain SSO (trySSO) can never find an active session.

Now also calls Better Auth's native /api/auth/sign-in/email with
credentials:'include' after successful login, which sets the session
cookie with Domain=.mana.how for cross-subdomain SSO.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:27:33 +01:00
Till JS
41fbd2f035 feat(storage): improve shared-storage robustness, scalability, and DX
- Fix exists() to only catch 404/NotFound, rethrow real errors
- Add downloadStream() for memory-efficient large file downloads
- Add uploadMultipart() using @aws-sdk/lib-storage for large files
- Add automatic pagination to list() via continuation tokens
- Add CDN URL support (cdnUrl in BucketConfig, getCdnUrl() method)
- Reduce factory boilerplate with generic createStorage() function
- Add MinIO lifecycle rules for tmp/ prefixes (chat 90d, calendar 30d, picture 7d)
- Add vitest setup with 56 tests covering client, factory, and utils

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:52:34 +01:00
Till JS
67326b738a fix(shared-api-client): add useRuntimeUrl flag for cross-app clients
getBaseUrl() always overrides baseUrl with window.__PUBLIC_BACKEND_URL__,
which breaks cross-app API clients (e.g. calendar→todo, calendar→contacts)
by routing all requests to the host app's backend.

Added useRuntimeUrl: false option to skip the runtime override when
the client already resolves its own base URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:11:31 +01:00
Till JS
afbf5ef00a fix(nav): add missing Phosphor icons for Mukke, Context, Todo, and Storage
Added 9 missing icons to PillNavigation phosphorIcons map: music-notes,
playlist, waveform, file-text, sparkle, sparkles, share, trash, filter.
These were previously rendering as empty SVGs due to missing mappings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:07:54 +01:00
Till JS
ac9ce55128 refactor(nav): move feedback pill into user dropdown across all apps
Feedback is now a sub-item under the Konto (user) dropdown in PillNavigation
instead of a standalone pill in the nav bar. Added feedbackHref prop to
PillNavigation (defaults to /feedback) and removed feedback from nav items
in all 11 apps and shared app-routes config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:00:38 +01:00
Till JS
e848fa5342 feat(mukke): display album cover art in library, playlists, and song lists
Add batch cover-url endpoint (POST /library/cover-urls) to efficiently
resolve multiple cover art presigned URLs in a single request. Integrate
cover art display across all UI surfaces: album grid, album detail header,
song list thumbnails, playlist grid, and playlist detail song list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 20:59:45 +01:00
Till JS
b11e1284dc feat(error-tracking): add GlitchTip integration with shared error-tracking package
Infrastructure:
- Add GlitchTip (web + worker) to docker-compose.macmini.yml (port 8020)
- Add glitchtip.mana.how to Cloudflare Tunnel config
- Add glitchtip database to init-db SQL
- Add GLITCHTIP_DSN to .env.development

Shared Package (@manacore/shared-error-tracking):
- initErrorTracking() - Sentry-compatible init with GlitchTip DSN
- captureException(), captureMessage(), setUser(), setTag(), flush()
- SentryExceptionFilter for NestJS (captures 5xx errors only)
- Graceful no-op when DSN is not configured

Integration:
- Add instrument.ts to calendar, contacts, todo backends
- Import instrument.ts before app bootstrap in all 3 main.ts files
- Error tracking auto-initializes when GLITCHTIP_DSN env var is set

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:30:13 +01:00
Till JS
9fc237d9ed feat(a11y): add skip-to-content links and ARIA labels to calendar, contacts, todo
- Add skip-to-content link ("Zum Inhalt springen") to all 3 app layouts
- Add id="main-content" to main content areas
- Add ariaLabel prop to shared PillNavigation component
- Set aria-label="Hauptnavigation" on nav elements in all 3 apps
- Add aria-label to icon-only nav toggle button in todo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:41:23 +01:00
Till JS
217c48663b feat(swagger): add OpenAPI documentation to calendar, contacts, and todo backends
- Extend shared-nestjs-setup bootstrapApp with optional swagger config
- Auto-setup Swagger/OpenAPI when swagger: true is passed
- Add @nestjs/swagger as optional peer dependency
- Enable swagger in calendar (:3014/api/docs), contacts (:3015/api/docs), todo (:3018/api/docs)
- Migrate todo main.ts from custom bootstrap to shared bootstrapApp
- JWT Bearer auth configured in Swagger UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:38:28 +01:00
Till JS
30ee708a6f feat(branding): add Context and Mukke app branding
- Add Context app icon (sky blue document/knowledge SVG)
- Add Context to MANA_APPS registry with descriptions (DE/EN)
- Add Context app URL mapping (dev: 5192, prod: context.manacore.app)
- Add ContextLogo Svelte component
- Add 'context' and 'mukke' to AppId type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 11:15:09 +01:00
Till JS
7a56699d45 feat(mukke): rename LightWrite to Mukke and add music library, player, playlists
Combines LightWrite (beat/lyrics editor) and Mukke (iOS music player) into
a single web-based music workspace app. Archives the old Mukke mobile app.

- Rename: @lightwrite/* → @mukke/*, all branding, configs, Dockerfiles
- New DB schemas: songs, playlists, playlist_songs + songId FK on projects
- New backend modules: SongModule, PlaylistModule, LibraryModule
- New web: app shell with sidebar, library (songs/albums/artists/genres),
  web player (queue/shuffle/repeat/MediaSession), playlists, search,
  upload, dashboard, album/artist/genre detail pages
- Auth: add forgot-password + reset-password pages, extend auth store
- Tests: 40 backend unit tests (song, playlist, library services)
- Config: env generation, MinIO bucket, docker-compose prod, cloudflare
- Docs: update CLAUDE.md, auth guidelines with SvelteKit checklist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:55:56 +01:00
Till JS
3dc6ec13a4 fix(traces): configure EAS Build for TestFlight and fix bot-services build
Traces:
- Change bundle ID from com.memoro.locations to com.mana.traces
- Update BGTask identifiers to match new bundle ID
- Add react-native-worklets dependency for reanimated compatibility
- Configure eas.json with monorepo-optimized build settings
- Add pnpm patch for reanimated 4.1.x to accept worklets 0.7.x
- Skip auto-fingerprint on EAS (pnpm hoisted mode)
- Disable default cache paths to avoid ENOENT

Bot-services:
- Add types: ["node"] to tsconfig to prevent RN type conflicts in hoisted mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:16:38 +01:00
Till JS
d4c11920c2 Revert "test: verify pre-commit hook works"
This reverts commit abbe12e7e7.
2026-03-17 13:11:31 +01:00
Till JS
abbe12e7e7 test: verify pre-commit hook works 2026-03-17 13:11:24 +01:00
Till JS
bc3a527bf4 chore(matrix-mobile): configure EAS Build for TestFlight and fix type errors
- Update to Expo SDK 53 compatible dependencies (from speculative SDK 55)
- Add EAS Build config (eas.json) with dev/preview/production profiles
- Generate app icons and splash screen assets
- Add NativeWind type augmentation for Pressable className callbacks
- Fix matrix-js-sdk NotificationCountType enum usage in store
- Fix Swipeable render actions type mismatch with Reanimated v3
- Exclude svelte dirs from wallpaper-generator and qr-export tsconfigs
- Remove duplicate scripts in root package.json
- Update pnpm-lock.yaml with @matrix/mobile dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:36:39 +01:00
Till-JS
1d44f918c5 fix(manacore-web): add missing packages to Dockerfile
Add shared-pwa, qr-export, and wallpaper-generator packages
to the Docker build context for manacore-web.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 13:43:08 +01:00
Till-JS
497b12c561 ♻️ refactor(shared-ui): simplify PillNavigation - remove sidebar mode
- Remove isSidebarMode and onModeChange props from PillNavigation
- Remove desktopPosition prop (always bottom now)
- Remove toolbarContent snippet support
- Simplify PillTabGroup (remove sidebar mode)
- Update navigation-simple.ts store factory
- Remove navigation position settings from GlobalSettingsSection
- Update all 12 app layouts to use simplified navigation
- Add missing @sqlite.org/sqlite-wasm dependency to calendar

BREAKING CHANGE: PillNavigation no longer supports sidebar mode.
Navigation is now always horizontal at the bottom of the screen.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 13:27:23 +01:00
Till-JS
e5109da732 feat(wallpaper-generator): add device wallpaper generation package
Add new @manacore/wallpaper-generator package for creating device
wallpapers from QR codes and images.

Features:
- 30 device presets (phones, tablets, desktops)
- 3 layout types (center, corner, pattern)
- 5 gradient presets + solid color backgrounds
- Browser (Canvas) and Node.js (Sharp) renderers
- Svelte WallpaperModal UI component

Integrations:
- @manacore/qr-export: toWallpaper() function
- @manacore/spiral-db: toWallpaper() function
- QRExportModal: "Als Wallpaper" button

Also includes the full @manacore/qr-export package which was
previously untracked.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 12:57:43 +01:00
Till-JS
c480231128 fix(planta-bot): make I18nService optional to diagnose DI issue
Also restore @Global() decorator to I18nModule while keeping
global: true in DynamicModule config for consistency with other
modules like CreditModule.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 12:51:04 +01:00
Till-JS
fd30fdc620 fix(bot-services): add global: true to I18nModule dynamic module config
The @Global() decorator on a module class doesn't apply when using
dynamic modules (forRoot/forRootAsync). The global: true property
must be set directly in the DynamicModule return object.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 12:48:28 +01:00
Till-JS
9b01c094c1 fix(bot-services): remove SessionModule import from I18nModule to prevent DI conflicts
The I18nModule was importing SessionModule.forRoot() internally, which
conflicted with bots that import SessionModule with different options
(e.g., storageMode: 'redis').

Since I18nService uses @Optional() for SessionService, the module should
not force its own SessionModule import. Users who want per-user language
preferences should import SessionModule in their app before I18nModule.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 12:46:33 +01:00
Till-JS
07a4c1c4bc debug: add message handler logging for planta-bot investigation 2026-02-17 12:38:27 +01:00
Till-JS
dcf4438804 feat(mana-bot): add daily morning summary feature
Add configurable morning summaries that aggregate data from multiple sources:
- Weather forecast via Open-Meteo API (free, no API key needed)
- Today's calendar events
- Today's tasks + overdue tasks
- Birthdays from contacts
- Plants needing water from Planta

New commands:
- !morning / !morgen - Get summary now
- !morning-on/off - Enable/disable automatic delivery
- !morning-time HH:MM - Set delivery time
- !morning-location [city] - Set weather location
- !morning-timezone [zone] - Set timezone
- !morning-format [kompakt|ausfuehrlich] - Set format
- !morning-settings - Show current settings

New shared services in @manacore/bot-services:
- WeatherService - Open-Meteo integration with geocoding
- ContactsApiService - Birthday fetching
- PlantaApiService - Watering schedule
- MorningSummaryService - Aggregates all sources
- MorningPreferencesService - User preferences storage

Includes scheduler for automatic daily delivery at user-configured time.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 11:01:47 +01:00
Till-JS
f1518e8c39 feat(spiral-db): add pixel-based spiral database package
Implement SpiralDB - a novel data storage format that encodes structured
data into PNG images using an 8-color palette. Data grows in a spiral
pattern from the center outward, enabling infinite expansion.

Features:
- 8-color palette (3-bit per pixel) for compression robustness
- Spiral coordinate system with ring-based organization
- Schema-based serialization (int, bool, string, timestamp, arrays)
- Record management with CRUD operations and status tracking
- PNG export/import with pako compression
- Browser support (Canvas, Blob, DataURL)
- Todo schema as reference implementation

Storage structure:
- Ring 0: Magic byte (validation)
- Ring 1: Database header (version, flags, counts)
- Ring 2: Schema definition
- Ring 3+: Master index (spans multiple rings if needed)
- Ring 4+: Record data
2026-02-17 10:42:09 +01:00
Till-JS
9704e88e78 feat(planta-bot): add AI plant identification via image upload
- Add handleImageMessage() to BaseMatrixService for image support
- Implement photo upload and Gemini Vision analysis in PlantaService
- Add image handler in MatrixService that downloads, uploads, and analyzes
- Format analysis results with health status, care tips, and confidence
- Update CLAUDE.md documentation with new feature
- Fix type mismatch in onboarding-bot (fullName → displayName)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 10:40:08 +01:00
Till-JS
d6303e4998 feat(storage): add public endpoint support for presigned URLs
When services run in Docker with internal endpoints (e.g., http://minio:9000),
presigned URLs are inaccessible from browsers. This adds S3_PUBLIC_ENDPOINT
support to generate presigned URLs using a publicly accessible endpoint
(e.g., https://minio.mana.how) while keeping internal operations on the
Docker network.

Changes:
- Add publicEndpoint to StorageConfig type
- Create separate S3Client for presigned URL generation
- Add S3_PUBLIC_ENDPOINT to factory configuration
- Configure lightwrite-backend with public MinIO endpoint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 15:35:18 +01:00
Till-JS
1328d92585 🐛 fix(lightwrite): add LightWriteLogo to shared-branding
- Add lightwrite to AppId type
- Add lightwrite branding config (orange theme, music note icon)
- Create LightWriteLogo.svelte component
- Update login/register pages to use proper logo component
- Fixes type-check errors in @lightwrite/web
2026-02-16 13:56:10 +01:00
Till-JS
b92b9bd2b5 feat(onboarding): add app-specific mini-onboarding system
- Create @manacore/shared-app-onboarding package with:
  - createAppOnboardingStore factory function (Svelte 5 runes)
  - MiniOnboardingModal component for select/toggle/info steps
  - TypeScript types for flexible step configuration
- Integrate into Calendar app with questions for:
  - Week start (Monday/Sunday)
  - Default view (Day/Week/Month)
  - Timezone preference (Auto/Manual)
  - Welcome tips

The mini-onboarding stores completion state in deviceSettings,
allowing per-device, per-app onboarding experiences.
2026-02-16 12:50:04 +01:00
Till-JS
5fe16b5eec feat(auth): add organization management endpoints
Add missing organization features for Teams functionality:
- PUT /auth/organizations/:id - update organization
- DELETE /auth/organizations/:id - delete organization
- PATCH /auth/organizations/:orgId/members/:memberId/role - update member role
- GET /auth/organizations/:id/invitations - list org invitations
- GET /auth/invitations - list user invitations
- DELETE /auth/invitations/:id - cancel or reject invitation
2026-02-16 12:47:49 +01:00
Till-JS
bfc2737ce5 ♻️ refactor(credits): simplify credit system by removing free credits and B2B
Remove free credits system (signup bonus, daily credits) and B2B organization
credits to simplify the codebase. Credits now only come from purchases or gifts.

Changes:
- Remove freeCreditsRemaining, dailyFreeCredits, lastDailyResetAt from balances
- Remove organizationBalances and creditAllocations tables from schema
- Simplify transaction types to: purchase, usage, refund, gift
- Remove B2B endpoints from credits controller
- Remove checkDailyReset, allocateCredits, deductCredits from service
- Add redeemPendingGifts method to auto-redeem gifts on registration
- Update frontend to remove free credits display
- Add database migration for the changes
- Update all related tests to match simplified system
2026-02-16 11:54:32 +01:00
Till-JS
78c7383d54 feat(lightwrite): add Beat/Lyrics Editor app
- Add NestJS backend with project, beat, marker, lyrics, export modules
- Add SvelteKit web app with wavesurfer.js waveform visualization
- Add BPM detection using Web Audio API peak detection
- Add marker timeline for parts, hooks, bridges
- Add lyrics editor with timestamp sync
- Add export to LRC, SRT, JSON formats
- Add shared-storage support for lightwrite
- Fix mana-core-auth env loading (add dotenv before validation)
- Add lightwrite to setup-databases.sh
- Fix matrix-onboarding-bot type errors (displayName → fullName)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 11:13:08 +01:00
Till-JS
0f24e085f6 feat(bot-services): add API key support to TranscriptionService
- Add apiKey option to TranscriptionModuleOptions
- Send X-API-Key header in all STT requests when configured
- Support config via module options, stt.apiKey, or STT_API_KEY env var
- Update CLAUDE.md documentation with API key usage example

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 00:11:24 +01:00
Till-JS
69f2eaf2e4 🐛 fix(matrix-bot-common): ignore edit events to prevent bot duplicate responses
When a bot edits its message (like timer updates), other bots were
responding to each edit as if it were a new message. This fix adds
isEditEvent() check to ignore m.replace events.
2026-02-14 14:30:49 +01:00
Till-JS
43ac782892 docs(matrix-bot-common): document bot-to-bot loop prevention
Added documentation for the isBot() method and automatic bot message
filtering that prevents infinite loops when multiple bots share a room.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 14:05:34 +01:00
Till-JS
2e8b3b903b fix(matrix-bot-common): ignore messages from other bots
Prevents infinite message loops when multiple bots are in the same room.
Checks if sender has '-bot' in their Matrix user ID localpart.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 13:40:59 +01:00
Till-JS
acf4512e90 fix(session): add auto-refresh for expired JWT tokens
- Add isTokenValid() to decode JWT and check exp claim
- Refresh tokens 60 seconds before expiry (buffer)
- Auto-fetch fresh token via SSO-Link when cached token expires
- Clear invalid sessions when refresh fails
- Prevents "exp claim timestamp check failed" errors

JWT tokens from mana-core-auth expire after 15 minutes, but sessions
were cached for 7 days. Now tokens are transparently refreshed when
they expire, keeping users authenticated.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 12:19:08 +01:00
Till-JS
5af965ea90 feat(clock-bot): add live timer progress with message editing
- Add editMessage() method to BaseMatrixService for Matrix message editing
- Implement live timer updates every 10 seconds using background interval
- Display progress bar using Unicode block characters (█░)
- Track active timers and update messages with current state
- Show percentage completion and remaining time
- Handle timer pause/resume/finish states
- Clean up tracking on timer completion or errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 12:07:28 +01:00
Till-JS
a4ef703761 feat(manacore): add gift code web UI
Add web interface for redeeming and managing gift codes:
- API service for all gift operations (create, redeem, list, cancel)
- Public preview page at /g/[code] for gift info before login
- Protected redemption flow with riddle support
- Dashboard with tabs: received gifts, created codes, create new
- Gift icon added to navigation and shared-ui
2026-02-14 12:01:24 +01:00
Till-JS
2521a1ea73 feat(matrix): sync recent emojis across apps via mana-core-auth
- Add recentEmojis field to GlobalSettings in shared-theme
- Create userSettings store for Matrix app with JWT token management
- Exchange session cookie for JWT after SSO login
- Update MessageInput to use userSettings instead of localStorage
- Add recentEmojis support to mana-core-auth settings API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 11:30:17 +01:00
Till-JS
4a26926fae 🩹 fix(bot-services): export LOGIN_MESSAGES and auth error helpers
Export the following from @manacore/bot-services:
- LOGIN_MESSAGES: Pre-defined auth error messages for all bot types
- AUTH_ERROR_MESSAGES: Same as LOGIN_MESSAGES (preferred name)
- formatAuthErrorMessage(): Helper to create custom auth error messages

These are used by bots to show consistent error messages when token
refresh fails and the user needs to re-authenticate.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 11:19:55 +01:00