No ManaCore app provides favicon.png (all use favicon.svg). The default
caused prerender 404 errors for any app with an /offline page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add focus trap (Tab/Shift+Tab cycling) to AuthGateModal and
GuestWelcomeModal with auto-focus on primary action
- Add aria-disabled to all disabled buttons across 8 components
for proper screen reader announcements
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add locale prop (de/en) to SessionManager with full English translations
- Extract duplicated parseUserAgent/getDeviceType to utils/userAgent.ts
- Fix hardcoded aria-label in SessionManager refresh button
- Add prefers-reduced-motion to PasskeyManager, TwoFactorSetup,
SessionExpiredBanner
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add locale prop (de/en) to PasswordStrength, ChangePassword,
SecurityOnboarding, AuditLog, AuthGate tier screen
- Add 13 new i18n keys to LoginTranslations for 2FA, lockout, magic link
- Fix date formatting to use locale in AuditLog
- Rewrite ForgotPasswordPage to Tailwind (matching Login/Register)
- Fix HTML injection in ForgotPasswordPage (remove @html with email)
- Guard DEV credentials behind isDevMode check in LoginPage
- Extend AuthResult type with twoFactorRedirect and retryAfter
- Remove as any casts in LoginPage
- Replace scoped CSS with Tailwind in AuthGate tier-denied screen
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tag import from @manacore/shared-icons (component) collided with Tag type
import from constants, causing "Identifier 'Tag' has already been declared"
in Svelte 5 builds. Renamed type to TagType.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ~700 lines of scoped CSS with Tailwind utility classes for
consistency with the rest of the monorepo. Both pages now use identical
patterns: Tailwind for layout/sizing/spacing, style: bindings for
dynamic dark/light colors, minimal <style> block for keyframe animations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrate 41 inline SVG icons to Phosphor components across 21 shared-ui
files including CommandBar, InputBar, Sidebar, AudioPlayer, PageHeader,
Select, TagBadge, SettingsRow, and more.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces a tiered access control system so apps can be released
gradually (founder → alpha → beta → public) without extra infrastructure.
Users are gated at the AuthGate level based on their tier vs the app's
requiredTier. All apps remain deployed and reachable, but only users
with sufficient tier can enter.
- Add accessTier enum + column to users schema (default: 'public')
- Add tier claim to JWT payload in better-auth config
- Add requiredTier field to ManaApp interface + all 25 apps
- Add hasAppAccess(), getAccessibleManaApps(), ACCESS_TIER_LABELS
- Update AuthGate with tier check + access denied screen
- Update getPillAppItems + Home page to filter by user tier
- Update all 22 app layouts to pass user tier to PillNav
- Add admin API: GET/PUT /api/v1/admin/users/:id/tier
- Document access tier system in CLAUDE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ManaLinkBadge now resolves the correct URL for the linked record's
detail view (e.g. /event/{id}, /contacts/{id}, /deck/{id}) instead
of just linking to the app's root page.
Uses an anchor tag by default for standard browser navigation, with
onclick prop override for custom behavior. Supports all 12 apps with
their specific routing patterns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New modal component that searches across app databases (calendar events,
contacts) and creates bidirectional links with cached display data.
Integrated into Todo's TaskEditModal with "+ Verknüpfen" button.
Search uses debounced text matching against IndexedDB records with
lazy-initialized cross-app readers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New shared package enabling bidirectional links between records across
apps (e.g. todo→calendar, task→file). Each link creates a forward+reverse
pair sharing a pairId for efficient queries from both sides. Stored in
dedicated IndexedDB (manacore-links), synced via mana-sync.
Includes: types, store, mutations, reactive queries, cached display data
resolvers, ManaLinkBadge and ManaLinkList UI components.
Integrates into Todo app as first consumer — link store initialized in
layout, ManaLinkList rendered in TaskEditModal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move from apps-archived/ to apps/
- Delete NestJS API, Docker files, old docs, browser extension
- Create Hono/Bun server with content extraction (Mozilla Readability)
and AI feed API reading from mana-sync's sync_changes
- Create local-first store (articles, categories) with guest seed data
- Rewrite web app: Feed page, Saved articles with URL extraction,
auth pages using shared-auth-ui, AuthGate with guest mode
- Add news to shared-branding (app icon, mana-apps registry)
- Add CLAUDE.md, dev scripts, root CLAUDE.md entry
- 0 type errors on both server and web
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Project detail page (/projects/[id]): stats, budget progress, inline
edit, full entry list with billing value calculation
- Client detail page (/clients/[id]): stats, project cards, entry list,
billing value summary
- Duration rounding: configurable increment (1-15 min) and method
(up/down/nearest), applied automatically when timer stops
- ConfirmDialog component: reusable modal for destructive actions
- Confirmation required before deleting entries, projects, and clients
- 18 new rounding tests (67 total, all passing)
- i18n: added deleteConfirm keys for DE and EN
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New calculator app with standard, scientific, programmer, unit converter,
currency, finance, date, and percentage modes. Includes 5 visual skins:
Modern, HP-35 (1972), Casio fx (1985), TI-84 (2004), and Minimal.
Local-first with IndexedDB history, keyboard support, safe math parser.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New app for professional time tracking with timer, projects, clients,
and reports. Local-first architecture with IndexedDB + mana-sync.
- Timer store with start/stop/resume, auto-save every 10s
- 6 local-store collections: clients, projects, timeEntries, tags, templates, settings
- TimerCard with live counter, project selector, billable toggle
- EntryItem with inline-expand editing, EntryList with day grouping
- EntryForm modal with quick-duration buttons (15m-4h)
- QuickStart pills from recent entries
- Projects page: card grid, color coding, budget progress, inline CRUD
- Clients page: billing rates, project rollup, inline CRUD
- Reports page: stats grid, billable breakdown, project/daily charts
- i18n: German + English
- Registered in shared-branding with icon, URLs, dev scripts
- Guest seed: 2 clients, 3 projects, 5 time entries, 4 tags
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
loader.ts imports schemas from content.ts but they were defined in
schemas.ts. Add re-exports to fix Rollup build resolution.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add <SyncIndicator /> from @manacore/shared-ui to every app layout.
Shows floating pill when browser goes offline ("Offline") and briefly
when reconnecting ("Wieder online"). Auto-fades after 3 seconds.
Simplified component: uses browser online/offline events instead of
sync engine coupling. Works universally without any props.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Homepage fixes:
- Add loading state: show TaskListSkeleton while liveQuery loads
- Fix $derived(() => ...) anti-pattern → $derived.by()
- Stabilize date calculations (compute once, not per re-render)
- Remove double error check (mutation errors shown via toast)
TaskItem improvements:
- Show completed-at date (small, 50% opacity) on right side of
completed tasks
- Click completed date to toggle showing created-at date above it
Shared: Add `loading` field to useLiveQueryWithDefault (was missing,
prevented proper loading states in consumers)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Created createManaAuthStore in @manacore/shared-auth-stores that replaces
~350 lines of duplicated auth.svelte.ts per app with a ~10 line factory call.
The factory handles: SSO, passkeys, 2FA, magic links, token management,
password reset, sign up/in/out — everything the old stores did.
Each app only provides devBackendPort and optional onAuthenticated callback.
Before: 21 apps × ~350 lines = 6,800 lines of duplicated auth code
After: 21 apps × ~10 lines = 182 lines total (97% reduction)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merged shared-subscription-types + shared-subscription-ui into
@manacore/subscriptions. Updated imports in 15 web apps.
Package count: 49 → 47
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merged shared-feedback-types + shared-feedback-service + shared-feedback-ui
into a single @manacore/feedback package. Updated imports in all 21 apps.
Before: 3 packages (types, service, ui) with cross-dependencies
After: 1 package with direct imports, no circular refs
Note: ESLint warnings from pre-existing unused vars in chat/mukke
servers are unrelated to this change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shared Go utilities for all ManaCore Go services:
- httputil: WriteJSON, WriteError, DecodeJSON
- envutil: Get, GetInt, GetBool, GetSlice
- 8 tests, all passing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add credits.ts to @manacore/shared-hono as replacement for
CreditClientService from @mana-core/nestjs-integration.
Exports: getBalance, validateCredits, consumeCredits, refundCredits
Calls mana-credits service via MANA_CREDITS_URL + X-Service-Key.
Same API surface as the NestJS version but as pure functions
instead of an @Injectable() service class.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TypeScript's ReturnType<> inference truncates large object literals,
showing only ~27 of 37 methods. This caused 5 apps to skip type-check
because verifyTwoFactor, signInWithPasskey, sendMagicLink, etc. were
invisible to consumers.
Fix: Define explicit AuthServiceInterface with all 37 methods and use
it as the return type of createAuthService(). This ensures all methods
are visible regardless of object literal size.
Verified: chat/web and presi/web now pass svelte-check for auth methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Todo: Replace manual fetch/state stores with useLiveQuery() for tasks,
projects, and tags. Components use Svelte context instead of store imports.
Stores reduced to mutation-only services. Removes ~200 lines of manual
state management. Enables multi-tab sync and auto-refresh on data changes.
- Tags (all 16 apps): Migrate from API-based createTagStore() to shared
local-first IndexedDB ('manacore-tags'). Tags now work offline and in
guest mode with default seed data. All apps share the same tag DB via
tagLocalStore + useAllTags() + setContext pattern.
- Cleanup: Delete unused Todo API files (projects.ts, labels.ts,
reminders.ts), remove dead labels store, clean up barrel exports.
Apps migrated: Todo, Zitare, Questions, Planta, Clock, Presi, Mukke,
Context, CityCorners, ManaDeck, Chat, Contacts, Calendar, Picture,
Storage, Photos
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both apps are fully local-first via Dexie.js + mana-sync. Their NestJS
backends were pure CRUD wrappers (20 + 31 source files) that are no
longer needed.
Changes:
- Add packages/shared-hono: JWT auth via JWKS (jose), Drizzle DB factory,
health route, generic GDPR admin handler, error middleware
- Migrate zitare lists page from fetch() to listsStore (local-first)
- Rewrite clock timers store from API-based to timerCollection (Dexie)
- Update clock +layout.svelte CommandBar search to use local collections
- Remove zitare-backend + clock-backend from docker-compose, CI/CD,
Prometheus, env generation, setup scripts
- Add docs/TECHNOLOGY_AUDIT_2026_03.md with full repo analysis
Net result: -2 Docker containers, -2 ports, -2728 lines of code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update consumers to call the new standalone mana-credits service instead
of the credit endpoints embedded in mana-core-auth.
Changes:
- CreditClientService: Add getCreditsUrl() reading MANA_CREDITS_URL
(falls back to MANA_CORE_AUTH_URL for backward compatibility).
All credit calls now use /api/v1/internal/* endpoints.
- BetterAuthService: Replace direct DB inserts for credit balance and
guild pool init with HTTP calls to mana-credits internal API.
Replace local gift redemption with HTTP call.
- .env.development: Add MANA_CREDITS_URL=http://localhost:3060
- CLAUDE.md: Add mana-credits to services list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add API key authentication to all GPU services (X-API-Key header)
- /health and /docs remain public (no key needed)
- Shared key configured via GPU_API_KEY env variable
- Add VRAM auto-unload for mana-image-gen (5min) and mana-stt (10min)
- FLUX.2 pipeline freed after idle, recovering ~13GB VRAM
- WhisperX models freed after idle, recovering ~3GB VRAM
- Install Piper TTS voices (Thorsten + Kerstin) for local German TTS
- Update @manacore/shared-gpu client to support apiKey parameter
- Add GPU_API_KEY to .env.development
- Document API auth and VRAM management in setup guide
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 21 separate NestJS Matrix bot processes (~2.1 GB RAM, ~4.2 GB Docker images)
with a single Go binary using plugin architecture (8.6 MB binary, ~30 MB RAM).
New services:
- services/mana-matrix-bot/ — Go Matrix bot with 21 plugins (mautrix-go, Redis sessions)
- services/mana-api-gateway-go/ — Go API gateway (rate limiting, API keys, credit billing)
Deleted:
- 21 services/matrix-*-bot/ directories
- packages/bot-services/ and packages/matrix-bot-common/
- Legacy deploy scripts and CI build jobs
Updated:
- docker-compose.macmini.yml: new Go services, legacy bots removed
- CI/CD: change detection + build jobs for Go services
- Root package.json: new dev:matrix, build:matrix, test:matrix scripts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auth store starts/stops sync on login/logout
- LocalStore queues all existing records for initial sync (guest→auth transition)
- LocalCollection.queueAllForSync() creates pending inserts for all local records
- Skips initial queue if sync cursor exists (already synced before)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Session management:
- GET /auth/sessions and DELETE /auth/sessions/:id endpoints
- listSessions() and revokeSession() in shared-auth client
- SessionManager component: active sessions list with device info,
"Aktuell" badge, revoke individual or all other sessions
- Integrated in ManaCore settings page
Account lockout UX:
- Dedicated amber lockout banner (distinct from generic rate-limit)
- "Konto vorübergehend gesperrt" with MM:SS countdown
- "Passwort zurücksetzen" link as alternative action
- formatCountdown helper for clean time display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace old 3-tier model (Plus/Pro/Ultra) with 5 size-based tiers (S/M/L/XL/XXL).
New naming: "Mana Quelle" for subscriptions, "Mana Trank" for one-time purchases.
Create new Stripe products and prices, archive old ones, update all UI and seed data.
Subscription tiers: S (500 Mana, 4.99€), M (1000, 9.99€), L (2000, 19.99€),
XL (4000, 39.99€), XXL (10000, 99.99€). Yearly: 20% discount.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace removed B2B org credit system with consumer-friendly shared
Mana pools. Members spend directly from a guild pool managed by the
Gildenmeister (owner). Supports funding from personal balance,
per-member spending limits, and credit source routing.
New endpoints: /gilden/* (guild CRUD) and /credits/guild/* (pool ops).
POST /credits/use now accepts optional creditSource for guild routing.
Delete broken b2b-journey E2E tests that tested phantom endpoints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>