From 250e0b20afb3827dd529216205bdc52b1dc75dda Mon Sep 17 00:00:00 2001 From: Till JS Date: Mon, 23 Mar 2026 21:58:14 +0100 Subject: [PATCH] feat: add onboarding to 6 new apps and feature intro step to all 16 apps Add onboarding with feature overview, preference selection, and tips to Zitare, Mukke, Photos, Planta, SkillTree, and Questions. Insert a new first "features" info step into all 10 existing onboarding flows so every app now starts with a core-features overview page. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ apps/mukke/apps/web/package.json | 1 + .../src/lib/stores/app-onboarding.svelte.ts | 64 +++++++ .../src/lib/stores/user-settings.svelte.ts | 18 ++ apps/mukke/apps/web/src/routes/+layout.svelte | 6 + apps/photos/apps/web/package.json | 1 + .../src/lib/stores/app-onboarding.svelte.ts | 70 ++++++++ .../src/lib/stores/user-settings.svelte.ts | 18 ++ .../photos/apps/web/src/routes/+layout.svelte | 6 + .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ apps/planta/apps/web/package.json | 1 + .../src/lib/stores/app-onboarding.svelte.ts | 70 ++++++++ .../src/lib/stores/user-settings.svelte.ts | 18 ++ .../planta/apps/web/src/routes/+layout.svelte | 6 + .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ apps/questions/apps/web/package.json | 1 + .../src/lib/stores/app-onboarding.svelte.ts | 70 ++++++++ .../src/lib/stores/user-settings.svelte.ts | 18 ++ .../apps/web/src/routes/+layout.svelte | 6 + apps/skilltree/apps/web/package.json | 1 + .../src/lib/stores/app-onboarding.svelte.ts | 88 ++++++++++ .../src/lib/stores/user-settings.svelte.ts | 18 ++ .../apps/web/src/routes/+layout.svelte | 6 + .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ .../src/lib/stores/app-onboarding.svelte.ts | 14 ++ apps/zitare/apps/web/package.json | 1 + .../src/lib/stores/app-onboarding.svelte.ts | 64 +++++++ .../src/lib/stores/user-settings.svelte.ts | 18 ++ .../zitare/apps/web/src/routes/+layout.svelte | 6 + pnpm-lock.yaml | 156 ++++++++++++++++++ 35 files changed, 872 insertions(+) create mode 100644 apps/mukke/apps/web/src/lib/stores/app-onboarding.svelte.ts create mode 100644 apps/mukke/apps/web/src/lib/stores/user-settings.svelte.ts create mode 100644 apps/photos/apps/web/src/lib/stores/app-onboarding.svelte.ts create mode 100644 apps/photos/apps/web/src/lib/stores/user-settings.svelte.ts create mode 100644 apps/planta/apps/web/src/lib/stores/app-onboarding.svelte.ts create mode 100644 apps/planta/apps/web/src/lib/stores/user-settings.svelte.ts create mode 100644 apps/questions/apps/web/src/lib/stores/app-onboarding.svelte.ts create mode 100644 apps/questions/apps/web/src/lib/stores/user-settings.svelte.ts create mode 100644 apps/skilltree/apps/web/src/lib/stores/app-onboarding.svelte.ts create mode 100644 apps/skilltree/apps/web/src/lib/stores/user-settings.svelte.ts create mode 100644 apps/zitare/apps/web/src/lib/stores/app-onboarding.svelte.ts create mode 100644 apps/zitare/apps/web/src/lib/stores/user-settings.svelte.ts diff --git a/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts index 31257716b..f5df717a9 100644 --- a/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -7,6 +7,20 @@ import type { CalendarViewType } from '@calendar/shared'; * Calendar-specific onboarding steps */ const calendarOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Kalender!', + description: 'Das kann Kalender für dich tun:', + emoji: '📅', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Termine erstellen & verwalten', + 'Wochen-, Monats- & Agenda-Ansicht', + 'Schnelleingabe per Text', + 'Drag & Drop zum Verschieben', + ], + }, { id: 'weekStart', type: 'select', diff --git a/apps/chat/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/chat/apps/web/src/lib/stores/app-onboarding.svelte.ts index 891f13ed3..5c923045d 100644 --- a/apps/chat/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/chat/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * Chat-specific onboarding steps */ const chatOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Chat!', + description: 'Das kann Chat für dich tun:', + emoji: '💬', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'KI-Chat mit lokalen & Cloud-Modellen', + 'Konversationen organisieren & durchsuchen', + 'Dateien & Bilder teilen', + 'Code-Highlighting & Markdown', + ], + }, { id: 'defaultModel', type: 'select', diff --git a/apps/clock/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/clock/apps/web/src/lib/stores/app-onboarding.svelte.ts index 7abf0417e..faf855557 100644 --- a/apps/clock/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/clock/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * Clock-specific onboarding steps */ const clockOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Clock!', + description: 'Das kann Clock für dich tun:', + emoji: '🕐', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Flexible Timer & Stoppuhr', + 'Pomodoro-Technik für produktives Arbeiten', + 'Voreingestellte Timer-Dauern', + 'Minimalistisches Design', + ], + }, { id: 'defaultTimer', type: 'select', diff --git a/apps/contacts/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/contacts/apps/web/src/lib/stores/app-onboarding.svelte.ts index 85677642a..88ff96482 100644 --- a/apps/contacts/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/contacts/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -6,6 +6,20 @@ import { contactsFilterStore } from './filter.svelte'; * Contacts-specific onboarding steps */ const contactsOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Kontakte!', + description: 'Das kann Kontakte für dich tun:', + emoji: '👥', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Kontakte verwalten & organisieren', + 'Import von Google oder vCard/CSV', + 'Tags & Gruppen für bessere Übersicht', + 'Schnellsuche & Filter', + ], + }, { id: 'sortOrder', type: 'select', diff --git a/apps/context/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/context/apps/web/src/lib/stores/app-onboarding.svelte.ts index 1909eccbe..727dc3ea6 100644 --- a/apps/context/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/context/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * Context-specific onboarding steps */ const contextOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Context!', + description: 'Das kann Context für dich tun:', + emoji: '📄', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Dokumente & Wissen organisieren', + 'KI-gestützte Zusammenfassungen', + 'Persönliche Wissensdatenbank', + 'Schnelle Volltextsuche', + ], + }, { id: 'useCase', type: 'select', diff --git a/apps/manadeck/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/manadeck/apps/web/src/lib/stores/app-onboarding.svelte.ts index 66b196850..e5e2d782d 100644 --- a/apps/manadeck/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/manadeck/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * ManaDeck-specific onboarding steps */ const manadeckOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei ManaDeck!', + description: 'Das kann ManaDeck für dich tun:', + emoji: '🃏', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Kartendecks erstellen & lernen', + 'Spaced Repetition für optimales Lernen', + 'Fortschritt tracken', + 'Verschiedene Kartentypen', + ], + }, { id: 'startAction', type: 'select', diff --git a/apps/mukke/apps/web/package.json b/apps/mukke/apps/web/package.json index bb6a2f7f4..88b2a33db 100644 --- a/apps/mukke/apps/web/package.json +++ b/apps/mukke/apps/web/package.json @@ -52,6 +52,7 @@ "@manacore/shared-theme-ui": "workspace:*", "@manacore/shared-ui": "workspace:*", "@manacore/shared-utils": "workspace:*", + "@manacore/shared-app-onboarding": "workspace:*", "@mukke/shared": "workspace:*", "butterchurn": "^2.6.7", "butterchurn-presets": "^2.4.7", diff --git a/apps/mukke/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/mukke/apps/web/src/lib/stores/app-onboarding.svelte.ts new file mode 100644 index 000000000..fd3e69f25 --- /dev/null +++ b/apps/mukke/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -0,0 +1,64 @@ +import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding'; +import { userSettings } from './user-settings.svelte'; + +const mukkeOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Mukke!', + description: 'Das kann Mukke für dich tun:', + emoji: '🎵', + gradient: { from: 'purple-500', to: 'purple-700' }, + bullets: [ + 'Musik-Bibliothek mit Alben & Künstlern', + 'Playlists erstellen & verwalten', + 'Beat-Editor mit Waveform-Visualisierung', + 'BPM-Erkennung & Lyrics-Sync', + ], + }, + { + id: 'viewMode', + type: 'select', + question: 'Wie möchtest du deine Bibliothek sehen?', + description: 'Du kannst die Ansicht jederzeit wechseln.', + emoji: '📚', + gradient: { from: 'indigo-500', to: 'indigo-700' }, + options: [ + { + id: 'grid', + label: 'Grid-Ansicht', + description: 'Cover-Art im Raster (Empfohlen)', + emoji: '🎨', + }, + { + id: 'list', + label: 'Listenansicht', + description: 'Kompakte Liste mit Details', + emoji: '📋', + }, + ], + defaultValue: 'grid', + }, + { + id: 'welcome', + type: 'info', + question: 'Deine Musik wartet!', + description: 'Hier sind einige Tipps:', + emoji: '🎉', + gradient: { from: 'primary', to: 'primary/70' }, + bullets: [ + 'Lade Songs per Drag & Drop hoch', + 'ID3-Tags werden automatisch erkannt', + 'Erstelle Projekte im Beat-Editor', + 'Exportiere synchronisierte Lyrics als LRC oder SRT', + ], + }, +]; + +export const mukkeOnboarding = createAppOnboardingStore({ + appId: 'mukke', + steps: mukkeOnboardingSteps, + userSettings, + onComplete: async () => {}, + onSkip: async () => {}, +}); diff --git a/apps/mukke/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/mukke/apps/web/src/lib/stores/user-settings.svelte.ts new file mode 100644 index 000000000..9d7bd772a --- /dev/null +++ b/apps/mukke/apps/web/src/lib/stores/user-settings.svelte.ts @@ -0,0 +1,18 @@ +import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const userSettings = createUserSettingsStore({ + appId: 'mukke', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getValidToken(), +}); diff --git a/apps/mukke/apps/web/src/routes/+layout.svelte b/apps/mukke/apps/web/src/routes/+layout.svelte index 7d6051e8e..9b47d155c 100644 --- a/apps/mukke/apps/web/src/routes/+layout.svelte +++ b/apps/mukke/apps/web/src/routes/+layout.svelte @@ -3,6 +3,8 @@ import { onMount, onDestroy } from 'svelte'; import { authStore } from '$lib/stores/auth.svelte'; import { theme } from '$lib/stores/theme.svelte'; + import { MiniOnboardingModal } from '@manacore/shared-app-onboarding'; + import { mukkeOnboarding } from '$lib/stores/app-onboarding.svelte'; let { children } = $props(); @@ -34,4 +36,8 @@
{@render children()}
+ + {#if mukkeOnboarding.shouldShow} + + {/if} {/if} diff --git a/apps/photos/apps/web/package.json b/apps/photos/apps/web/package.json index 210e16e82..32c5c92ef 100644 --- a/apps/photos/apps/web/package.json +++ b/apps/photos/apps/web/package.json @@ -52,6 +52,7 @@ "@manacore/shared-theme-ui": "workspace:*", "@manacore/shared-ui": "workspace:*", "@manacore/shared-utils": "workspace:*", + "@manacore/shared-app-onboarding": "workspace:*", "@photos/shared": "workspace:*", "date-fns": "^4.1.0", "svelte-i18n": "^4.0.1" diff --git a/apps/photos/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/photos/apps/web/src/lib/stores/app-onboarding.svelte.ts new file mode 100644 index 000000000..c7f7d463a --- /dev/null +++ b/apps/photos/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -0,0 +1,70 @@ +import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding'; +import { userSettings } from './user-settings.svelte'; + +const photosOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Photos!', + description: 'Das kann Photos für dich tun:', + emoji: '📸', + gradient: { from: 'emerald-500', to: 'emerald-700' }, + bullets: [ + 'Fotos aus allen ManaCore-Apps an einem Ort', + 'Alben erstellen & organisieren', + 'Smart-Alben nach Datum, Ort & Kamera', + 'EXIF-Daten & Metadaten anzeigen', + ], + }, + { + id: 'gridSize', + type: 'select', + question: 'Welche Galerie-Größe bevorzugst du?', + description: 'Du kannst die Größe jederzeit anpassen.', + emoji: '🖼️', + gradient: { from: 'indigo-500', to: 'indigo-700' }, + options: [ + { + id: 'small', + label: 'Klein', + description: 'Viele Fotos auf einen Blick', + emoji: '🔍', + }, + { + id: 'medium', + label: 'Mittel', + description: 'Gute Balance (Empfohlen)', + emoji: '📐', + }, + { + id: 'large', + label: 'Groß', + description: 'Detailreiche Vorschau', + emoji: '🖼️', + }, + ], + defaultValue: 'medium', + }, + { + id: 'welcome', + type: 'info', + question: 'Deine Galerie ist bereit!', + description: 'Hier sind einige Tipps:', + emoji: '🎉', + gradient: { from: 'primary', to: 'primary/70' }, + bullets: [ + 'Lade neue Fotos direkt per Drag & Drop hoch', + 'Markiere Favoriten für schnellen Zugriff', + 'Nutze Tags für bessere Organisation', + 'Smart-Alben werden automatisch erstellt', + ], + }, +]; + +export const photosOnboarding = createAppOnboardingStore({ + appId: 'photos', + steps: photosOnboardingSteps, + userSettings, + onComplete: async () => {}, + onSkip: async () => {}, +}); diff --git a/apps/photos/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/photos/apps/web/src/lib/stores/user-settings.svelte.ts new file mode 100644 index 000000000..1928eaa67 --- /dev/null +++ b/apps/photos/apps/web/src/lib/stores/user-settings.svelte.ts @@ -0,0 +1,18 @@ +import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const userSettings = createUserSettingsStore({ + appId: 'photos', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getAccessToken(), +}); diff --git a/apps/photos/apps/web/src/routes/+layout.svelte b/apps/photos/apps/web/src/routes/+layout.svelte index 18447473e..fe81a2da6 100644 --- a/apps/photos/apps/web/src/routes/+layout.svelte +++ b/apps/photos/apps/web/src/routes/+layout.svelte @@ -6,6 +6,8 @@ import { theme } from '$lib/stores/theme'; import { authStore } from '$lib/stores/auth.svelte'; import { ToastContainer, setupGlobalErrorHandler } from '@manacore/shared-ui'; + import { MiniOnboardingModal } from '@manacore/shared-app-onboarding'; + import { photosOnboarding } from '$lib/stores/app-onboarding.svelte'; let { children } = $props(); @@ -32,6 +34,10 @@
{@render children()}
+ + {#if photosOnboarding.shouldShow} + + {/if} {/if} diff --git a/apps/picture/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/picture/apps/web/src/lib/stores/app-onboarding.svelte.ts index 381020969..168f7fd72 100644 --- a/apps/picture/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/picture/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * Picture-specific onboarding steps */ const pictureOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Picture!', + description: 'Das kann Picture für dich tun:', + emoji: '🎨', + gradient: { from: 'indigo-500', to: 'indigo-700' }, + bullets: [ + 'KI-Bilder generieren', + 'Verschiedene Modelle & Stile', + 'Galerie mit Grid-Ansicht', + 'Bilder teilen & herunterladen', + ], + }, { id: 'viewMode', type: 'select', diff --git a/apps/planta/apps/web/package.json b/apps/planta/apps/web/package.json index a190bb55d..5a60e5e6b 100644 --- a/apps/planta/apps/web/package.json +++ b/apps/planta/apps/web/package.json @@ -42,6 +42,7 @@ "@manacore/shared-theme-ui": "workspace:*", "@manacore/shared-ui": "workspace:*", "@manacore/shared-utils": "workspace:*", + "@manacore/shared-app-onboarding": "workspace:*", "@planta/shared": "workspace:*", "svelte-i18n": "^4.0.1" }, diff --git a/apps/planta/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/planta/apps/web/src/lib/stores/app-onboarding.svelte.ts new file mode 100644 index 000000000..063491173 --- /dev/null +++ b/apps/planta/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -0,0 +1,70 @@ +import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding'; +import { userSettings } from './user-settings.svelte'; + +const plantaOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Planta!', + description: 'Das kann Planta für dich tun:', + emoji: '🌱', + gradient: { from: 'green-500', to: 'green-700' }, + bullets: [ + 'Pflanzen per Foto identifizieren (KI)', + 'Gieß-Erinnerungen & Pflege-Zeitplan', + 'Pflege-Tipps & Gesundheits-Tracking', + 'Licht-, Wasser- & Feuchtigkeitsempfehlungen', + ], + }, + { + id: 'experience', + type: 'select', + question: 'Wie erfahren bist du mit Pflanzen?', + description: 'Hilft uns, die Tipps anzupassen.', + emoji: '🌿', + gradient: { from: 'emerald-500', to: 'emerald-700' }, + options: [ + { + id: 'beginner', + label: 'Anfänger', + description: 'Gerade erst angefangen', + emoji: '🌱', + }, + { + id: 'intermediate', + label: 'Fortgeschritten', + description: 'Einige Pflanzen zu Hause', + emoji: '🪴', + }, + { + id: 'expert', + label: 'Profi', + description: 'Grüner Daumen seit Jahren', + emoji: '🌳', + }, + ], + defaultValue: 'beginner', + }, + { + id: 'welcome', + type: 'info', + question: 'Dein Pflanzengarten ist bereit!', + description: 'Hier sind einige Tipps:', + emoji: '🎉', + gradient: { from: 'primary', to: 'primary/70' }, + bullets: [ + 'Fotografiere eine Pflanze, um sie zu identifizieren', + 'Gieß-Erinnerungen kommen automatisch', + 'Prüfe regelmäßig den Gesundheitsstatus', + 'Notiere Standort und Lichtverhältnisse', + ], + }, +]; + +export const plantaOnboarding = createAppOnboardingStore({ + appId: 'planta', + steps: plantaOnboardingSteps, + userSettings, + onComplete: async () => {}, + onSkip: async () => {}, +}); diff --git a/apps/planta/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/planta/apps/web/src/lib/stores/user-settings.svelte.ts new file mode 100644 index 000000000..fbb1d1091 --- /dev/null +++ b/apps/planta/apps/web/src/lib/stores/user-settings.svelte.ts @@ -0,0 +1,18 @@ +import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const userSettings = createUserSettingsStore({ + appId: 'planta', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getValidToken(), +}); diff --git a/apps/planta/apps/web/src/routes/+layout.svelte b/apps/planta/apps/web/src/routes/+layout.svelte index ca76de25c..9faad53a3 100644 --- a/apps/planta/apps/web/src/routes/+layout.svelte +++ b/apps/planta/apps/web/src/routes/+layout.svelte @@ -5,6 +5,8 @@ import { isLoading as i18nLoading, _ as t } from 'svelte-i18n'; import { theme } from '$lib/stores/theme'; import { authStore } from '$lib/stores/auth.svelte'; + import { MiniOnboardingModal } from '@manacore/shared-app-onboarding'; + import { plantaOnboarding } from '$lib/stores/app-onboarding.svelte'; let { children } = $props(); @@ -35,4 +37,8 @@
{@render children()}
+ + {#if plantaOnboarding.shouldShow} + + {/if} {/if} diff --git a/apps/presi/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/presi/apps/web/src/lib/stores/app-onboarding.svelte.ts index 78813419f..3cf7ceb3c 100644 --- a/apps/presi/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/presi/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * Presi-specific onboarding steps */ const presiOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Presi!', + description: 'Das kann Presi für dich tun:', + emoji: '🎬', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Präsentationen erstellen & bearbeiten', + 'Slide-Editor mit verschiedenen Folientypen', + 'Presenter-Modus für Vorträge', + 'Teilen über öffentliche Links', + ], + }, { id: 'welcome', type: 'info', diff --git a/apps/questions/apps/web/package.json b/apps/questions/apps/web/package.json index 562094799..c05bd26ed 100644 --- a/apps/questions/apps/web/package.json +++ b/apps/questions/apps/web/package.json @@ -41,6 +41,7 @@ "@manacore/shared-error-tracking": "workspace:*", "@manacore/shared-i18n": "workspace:*", "@manacore/shared-icons": "workspace:*", + "@manacore/shared-app-onboarding": "workspace:*", "@manacore/shared-tailwind": "workspace:*", "@manacore/shared-theme": "workspace:*", "@manacore/shared-theme-ui": "workspace:*", diff --git a/apps/questions/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/questions/apps/web/src/lib/stores/app-onboarding.svelte.ts new file mode 100644 index 000000000..5395f42d6 --- /dev/null +++ b/apps/questions/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -0,0 +1,70 @@ +import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding'; +import { userSettings } from './user-settings.svelte'; + +const questionsOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Questions!', + description: 'Das kann Questions für dich tun:', + emoji: '🔬', + gradient: { from: 'violet-500', to: 'violet-700' }, + bullets: [ + 'Fragen stellen & recherchieren lassen', + 'Web-Suche & automatische Quellenextraktion', + 'KI-generierte Antworten aus Quellen', + 'Sammlungen für bessere Organisation', + ], + }, + { + id: 'researchDepth', + type: 'select', + question: 'Wie gründlich soll die Recherche sein?', + description: 'Du kannst die Tiefe pro Frage anpassen.', + emoji: '🔍', + gradient: { from: 'indigo-500', to: 'indigo-700' }, + options: [ + { + id: 'quick', + label: 'Schnell', + description: '5 Quellen, schnelle Antwort', + emoji: '⚡', + }, + { + id: 'standard', + label: 'Standard', + description: '15 Quellen mit Extraktion (Empfohlen)', + emoji: '📖', + }, + { + id: 'deep', + label: 'Gründlich', + description: '30 Quellen, alle Kategorien', + emoji: '🔬', + }, + ], + defaultValue: 'standard', + }, + { + id: 'welcome', + type: 'info', + question: 'Dein Recherche-Assistent ist bereit!', + description: 'Hier sind einige Tipps:', + emoji: '🎉', + gradient: { from: 'primary', to: 'primary/70' }, + bullets: [ + 'Stelle präzise Fragen für bessere Ergebnisse', + 'Nutze Sammlungen, um Themen zu gruppieren', + 'Quellen werden automatisch extrahiert', + 'Bewerte Antworten, um die Qualität zu verbessern', + ], + }, +]; + +export const questionsOnboarding = createAppOnboardingStore({ + appId: 'questions', + steps: questionsOnboardingSteps, + userSettings, + onComplete: async () => {}, + onSkip: async () => {}, +}); diff --git a/apps/questions/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/questions/apps/web/src/lib/stores/user-settings.svelte.ts new file mode 100644 index 000000000..0514bc682 --- /dev/null +++ b/apps/questions/apps/web/src/lib/stores/user-settings.svelte.ts @@ -0,0 +1,18 @@ +import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const userSettings = createUserSettingsStore({ + appId: 'questions', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getValidToken(), +}); diff --git a/apps/questions/apps/web/src/routes/+layout.svelte b/apps/questions/apps/web/src/routes/+layout.svelte index c3b3f82e9..eee85b411 100644 --- a/apps/questions/apps/web/src/routes/+layout.svelte +++ b/apps/questions/apps/web/src/routes/+layout.svelte @@ -7,6 +7,8 @@ import { authStore } from '$lib/stores/auth.svelte'; import { apiClient } from '$lib/api/client'; import { AppLoadingSkeleton } from '$lib/components/skeletons'; + import { MiniOnboardingModal } from '@manacore/shared-app-onboarding'; + import { questionsOnboarding } from '$lib/stores/app-onboarding.svelte'; let { children } = $props(); @@ -33,4 +35,8 @@
{@render children()}
+ + {#if questionsOnboarding.shouldShow} + + {/if} {/if} diff --git a/apps/skilltree/apps/web/package.json b/apps/skilltree/apps/web/package.json index 3e6a7df6a..faa0c4214 100644 --- a/apps/skilltree/apps/web/package.json +++ b/apps/skilltree/apps/web/package.json @@ -41,6 +41,7 @@ "@manacore/shared-error-tracking": "workspace:*", "@manacore/shared-i18n": "workspace:*", "@manacore/shared-icons": "workspace:*", + "@manacore/shared-app-onboarding": "workspace:*", "@manacore/shared-tailwind": "workspace:*", "@manacore/shared-theme": "workspace:*", "@manacore/shared-ui": "workspace:^", diff --git a/apps/skilltree/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/skilltree/apps/web/src/lib/stores/app-onboarding.svelte.ts new file mode 100644 index 000000000..b84b3b17b --- /dev/null +++ b/apps/skilltree/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -0,0 +1,88 @@ +import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding'; +import { userSettings } from './user-settings.svelte'; + +const skilltreeOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei SkillTree!', + description: 'Das kann SkillTree für dich tun:', + emoji: '🌳', + gradient: { from: 'emerald-500', to: 'emerald-700' }, + bullets: [ + 'RPG-Skill-Baum für echte Fähigkeiten', + '6 Bereiche: Intellekt, Körper, Kreativität, Sozial, Praktisch, Mindset', + 'XP sammeln & Level aufsteigen', + 'Aktivitäten loggen & Fortschritt tracken', + ], + }, + { + id: 'focusBranch', + type: 'select', + question: 'Welcher Bereich interessiert dich am meisten?', + description: 'Du kannst alle Bereiche nutzen — das ist nur dein Startfokus.', + emoji: '🎯', + gradient: { from: 'indigo-500', to: 'indigo-700' }, + options: [ + { + id: 'intellect', + label: 'Intellekt', + description: 'Wissen, Sprachen, Wissenschaft', + emoji: '🧠', + }, + { + id: 'body', + label: 'Körper', + description: 'Fitness, Sport, Gesundheit', + emoji: '💪', + }, + { + id: 'creativity', + label: 'Kreativität', + description: 'Kunst, Musik, Schreiben', + emoji: '🎨', + }, + { + id: 'social', + label: 'Sozial', + description: 'Kommunikation, Führung', + emoji: '👥', + }, + { + id: 'practical', + label: 'Praktisch', + description: 'Handwerk, Kochen, Technik', + emoji: '🔧', + }, + { + id: 'mindset', + label: 'Mindset', + description: 'Meditation, Fokus, Resilienz', + emoji: '🧘', + }, + ], + defaultValue: 'intellect', + }, + { + id: 'welcome', + type: 'info', + question: 'Dein Skill-Baum ist bereit!', + description: 'Hier sind einige Tipps:', + emoji: '🎉', + gradient: { from: 'primary', to: 'primary/70' }, + bullets: [ + 'Erstelle Skills in deinem Fokus-Bereich', + 'Logge Aktivitäten, um XP zu sammeln', + 'Level reichen von Anfänger bis Meister', + 'Bleib dran — regelmäßige Aktivitäten geben Bonus-XP', + ], + }, +]; + +export const skilltreeOnboarding = createAppOnboardingStore({ + appId: 'skilltree', + steps: skilltreeOnboardingSteps, + userSettings, + onComplete: async () => {}, + onSkip: async () => {}, +}); diff --git a/apps/skilltree/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/skilltree/apps/web/src/lib/stores/user-settings.svelte.ts new file mode 100644 index 000000000..7484df27c --- /dev/null +++ b/apps/skilltree/apps/web/src/lib/stores/user-settings.svelte.ts @@ -0,0 +1,18 @@ +import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const userSettings = createUserSettingsStore({ + appId: 'skilltree', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getAccessToken(), +}); diff --git a/apps/skilltree/apps/web/src/routes/+layout.svelte b/apps/skilltree/apps/web/src/routes/+layout.svelte index 748f897c9..7d24968e9 100644 --- a/apps/skilltree/apps/web/src/routes/+layout.svelte +++ b/apps/skilltree/apps/web/src/routes/+layout.svelte @@ -5,6 +5,8 @@ import { isLoading as i18nLoading, _ as t } from 'svelte-i18n'; import { skillStore } from '$lib/stores/skills.svelte'; import { authStore } from '$lib/stores/auth.svelte'; + import { MiniOnboardingModal } from '@manacore/shared-app-onboarding'; + import { skilltreeOnboarding } from '$lib/stores/app-onboarding.svelte'; let { children } = $props(); @@ -33,4 +35,8 @@
{@render children()}
+ + {#if skilltreeOnboarding.shouldShow} + + {/if} {/if} diff --git a/apps/storage/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/storage/apps/web/src/lib/stores/app-onboarding.svelte.ts index 3ca971f05..39b0802d3 100644 --- a/apps/storage/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/storage/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -5,6 +5,20 @@ import { userSettings } from './user-settings.svelte'; * Storage-specific onboarding steps */ const storageOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Storage!', + description: 'Das kann Storage für dich tun:', + emoji: '☁️', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Dateien hochladen & verwalten', + 'Ordnerstruktur & Tags', + 'Sichere Links mit Passwortschutz', + 'Drag & Drop Upload', + ], + }, { id: 'welcome', type: 'info', diff --git a/apps/todo/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/todo/apps/web/src/lib/stores/app-onboarding.svelte.ts index f7b0950ef..314fa9009 100644 --- a/apps/todo/apps/web/src/lib/stores/app-onboarding.svelte.ts +++ b/apps/todo/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -6,6 +6,20 @@ import { todoSettings } from './settings.svelte'; * Todo-specific onboarding steps */ const todoOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Todo!', + description: 'Das kann Todo für dich tun:', + emoji: '✅', + gradient: { from: 'blue-500', to: 'blue-700' }, + bullets: [ + 'Aufgaben erstellen & verwalten', + 'Heute-, Inbox- & Kanban-Ansichten', + 'Fälligkeiten & Prioritäten', + 'Schnelleingabe per Text', + ], + }, { id: 'defaultView', type: 'select', diff --git a/apps/zitare/apps/web/package.json b/apps/zitare/apps/web/package.json index 2a599ad8e..760e10cee 100644 --- a/apps/zitare/apps/web/package.json +++ b/apps/zitare/apps/web/package.json @@ -49,6 +49,7 @@ "@manacore/shared-theme-ui": "workspace:*", "@manacore/shared-ui": "workspace:*", "@manacore/spiral-db": "workspace:^", + "@manacore/shared-app-onboarding": "workspace:*", "@zitare/content": "workspace:*", "svelte-i18n": "^4.0.1" }, diff --git a/apps/zitare/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/zitare/apps/web/src/lib/stores/app-onboarding.svelte.ts new file mode 100644 index 000000000..5d395882d --- /dev/null +++ b/apps/zitare/apps/web/src/lib/stores/app-onboarding.svelte.ts @@ -0,0 +1,64 @@ +import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding'; +import { userSettings } from './user-settings.svelte'; + +const zitareOnboardingSteps: AppOnboardingStep[] = [ + { + id: 'features', + type: 'info', + question: 'Willkommen bei Zitare!', + description: 'Das kann Zitare für dich tun:', + emoji: '✨', + gradient: { from: 'amber-500', to: 'amber-700' }, + bullets: [ + 'Tägliche Inspiration durch ausgewählte Zitate', + 'Zitate-Sammlung zum Stöbern & Entdecken', + 'Immersiver Lesemodus für ungestörtes Lesen', + 'Favoriten & eigene Listen erstellen', + ], + }, + { + id: 'displayMode', + type: 'select', + question: 'Wie möchtest du Zitate lesen?', + description: 'Du kannst den Modus jederzeit wechseln.', + emoji: '👁️', + gradient: { from: 'indigo-500', to: 'indigo-700' }, + options: [ + { + id: 'compact', + label: 'Kompakt', + description: 'Übersichtliche Listenansicht', + emoji: '📋', + }, + { + id: 'immersive', + label: 'Immersiv', + description: 'Großes Zitat mit Hintergrund (Empfohlen)', + emoji: '🖼️', + }, + ], + defaultValue: 'immersive', + }, + { + id: 'welcome', + type: 'info', + question: 'Deine Zitate sind bereit!', + description: 'Hier sind einige Tipps:', + emoji: '🎉', + gradient: { from: 'primary', to: 'primary/70' }, + bullets: [ + 'Swipe oder klicke für das nächste Zitat', + 'Markiere Favoriten mit dem Herz-Symbol', + 'Erstelle eigene Sammlungen', + 'Teile Zitate mit Freunden', + ], + }, +]; + +export const zitareOnboarding = createAppOnboardingStore({ + appId: 'zitare', + steps: zitareOnboardingSteps, + userSettings, + onComplete: async () => {}, + onSkip: async () => {}, +}); diff --git a/apps/zitare/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/zitare/apps/web/src/lib/stores/user-settings.svelte.ts new file mode 100644 index 000000000..320f9eba7 --- /dev/null +++ b/apps/zitare/apps/web/src/lib/stores/user-settings.svelte.ts @@ -0,0 +1,18 @@ +import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; + } + return 'http://localhost:3001'; +} + +export const userSettings = createUserSettingsStore({ + appId: 'zitare', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getAccessToken(), +}); diff --git a/apps/zitare/apps/web/src/routes/+layout.svelte b/apps/zitare/apps/web/src/routes/+layout.svelte index fa2f6ba78..a379fceb9 100644 --- a/apps/zitare/apps/web/src/routes/+layout.svelte +++ b/apps/zitare/apps/web/src/routes/+layout.svelte @@ -7,6 +7,8 @@ import { quotesStore } from '$lib/stores/quotes.svelte'; import { waitLocale } from '$lib/i18n'; import { ToastContainer, setupGlobalErrorHandler } from '@manacore/shared-ui'; + import { MiniOnboardingModal } from '@manacore/shared-app-onboarding'; + import { zitareOnboarding } from '$lib/stores/app-onboarding.svelte'; let { children } = $props(); @@ -54,4 +56,8 @@
{@render children()}
+ + {#if zitareOnboarding.shouldShow} + + {/if} {/if} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4bcb37325..8444d3d1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -455,6 +455,9 @@ importers: '@manacore/shared-errors': specifier: workspace:* version: link:../../../../packages/shared-errors + '@manacore/shared-llm': + specifier: workspace:^ + version: link:../../../../packages/shared-llm '@manacore/shared-nestjs-auth': specifier: workspace:* version: link:../../../../packages/shared-nestjs-auth @@ -1619,6 +1622,9 @@ importers: '@manacore/shared-error-tracking': specifier: workspace:* version: link:../../../../packages/shared-error-tracking + '@manacore/shared-llm': + specifier: workspace:^ + version: link:../../../../packages/shared-llm '@manacore/shared-nestjs-auth': specifier: workspace:* version: link:../../../../packages/shared-nestjs-auth @@ -3143,6 +3149,9 @@ importers: '@manacore/shared-api-client': specifier: workspace:* version: link:../../../../packages/shared-api-client + '@manacore/shared-app-onboarding': + specifier: workspace:* + version: link:../../../../packages/shared-app-onboarding '@manacore/shared-auth': specifier: workspace:* version: link:../../../../packages/shared-auth @@ -3279,6 +3288,9 @@ importers: '@manacore/shared-error-tracking': specifier: workspace:* version: link:../../../../packages/shared-error-tracking + '@manacore/shared-llm': + specifier: workspace:^ + version: link:../../../../packages/shared-llm '@manacore/shared-nestjs-auth': specifier: workspace:* version: link:../../../../packages/shared-nestjs-auth @@ -3655,6 +3667,9 @@ importers: '@manacore/shared-api-client': specifier: workspace:* version: link:../../../../packages/shared-api-client + '@manacore/shared-app-onboarding': + specifier: workspace:* + version: link:../../../../packages/shared-app-onboarding '@manacore/shared-auth': specifier: workspace:* version: link:../../../../packages/shared-auth @@ -4380,6 +4395,9 @@ importers: '@manacore/shared-error-tracking': specifier: workspace:* version: link:../../../../packages/shared-error-tracking + '@manacore/shared-llm': + specifier: workspace:^ + version: link:../../../../packages/shared-llm '@manacore/shared-nestjs-auth': specifier: workspace:* version: link:../../../../packages/shared-nestjs-auth @@ -4501,6 +4519,9 @@ importers: '@manacore/shared-api-client': specifier: workspace:* version: link:../../../../packages/shared-api-client + '@manacore/shared-app-onboarding': + specifier: workspace:* + version: link:../../../../packages/shared-app-onboarding '@manacore/shared-auth': specifier: workspace:* version: link:../../../../packages/shared-auth @@ -4997,6 +5018,9 @@ importers: '@manacore/shared-api-client': specifier: workspace:* version: link:../../../../packages/shared-api-client + '@manacore/shared-app-onboarding': + specifier: workspace:* + version: link:../../../../packages/shared-app-onboarding '@manacore/shared-auth': specifier: workspace:* version: link:../../../../packages/shared-auth @@ -5185,6 +5209,9 @@ importers: '@manacore/shared-api-client': specifier: workspace:* version: link:../../../../packages/shared-api-client + '@manacore/shared-app-onboarding': + specifier: workspace:* + version: link:../../../../packages/shared-app-onboarding '@manacore/shared-auth': specifier: workspace:* version: link:../../../../packages/shared-auth @@ -5844,6 +5871,9 @@ importers: '@manacore/shared-error-tracking': specifier: workspace:* version: link:../../../../packages/shared-error-tracking + '@manacore/shared-llm': + specifier: workspace:^ + version: link:../../../../packages/shared-llm '@manacore/shared-nestjs-auth': specifier: workspace:* version: link:../../../../packages/shared-nestjs-auth @@ -6162,6 +6192,9 @@ importers: '@manacore/shared-api-client': specifier: workspace:* version: link:../../../../packages/shared-api-client + '@manacore/shared-app-onboarding': + specifier: workspace:* + version: link:../../../../packages/shared-app-onboarding '@manacore/shared-auth': specifier: workspace:* version: link:../../../../packages/shared-auth @@ -6854,6 +6887,34 @@ importers: specifier: ^5.0.0 version: 5.9.3 + packages/shared-llm: + dependencies: + '@nestjs/common': + specifier: ^10.0.0 || ^11.0.0 + version: 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/config': + specifier: ^3.0.0 || ^4.0.0 + version: 3.3.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + '@nestjs/core': + specifier: ^10.0.0 || ^11.0.0 + version: 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(@nestjs/websockets@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + reflect-metadata: + specifier: ^0.1.13 || ^0.2.0 + version: 0.2.2 + rxjs: + specifier: ^7.0.0 + version: 7.8.2 + devDependencies: + '@types/node': + specifier: ^20.0.0 + version: 20.19.25 + typescript: + specifier: ^5.0.0 + version: 5.9.3 + vitest: + specifier: ^2.0.0 + version: 2.1.9(@types/node@20.19.25)(jsdom@27.2.0)(lightningcss@1.30.2)(terser@5.44.1) + packages/shared-logger: devDependencies: '@types/node': @@ -7318,6 +7379,9 @@ importers: '@google/generative-ai': specifier: ^0.24.1 version: 0.24.1 + '@manacore/shared-llm': + specifier: workspace:^ + version: link:../../packages/shared-llm '@manacore/shared-storage': specifier: workspace:* version: link:../../packages/shared-storage @@ -33824,6 +33888,23 @@ snapshots: transitivePeerDependencies: - encoding + '@nestjs/core@10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(@nestjs/websockets@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nuxtjs/opencollective': 0.3.2(encoding@0.1.13) + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 3.3.0 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + '@nestjs/platform-express': 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20) + '@nestjs/websockets': 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20)(@nestjs/platform-socket.io@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2) + transitivePeerDependencies: + - encoding + '@nestjs/core@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -33878,6 +33959,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@nestjs/platform-express@10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20)': + dependencies: + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(@nestjs/websockets@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + body-parser: 1.20.3 + cors: 2.8.5 + express: 4.21.2 + multer: 2.0.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + optional: true + '@nestjs/platform-express@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.9)': dependencies: '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -33916,6 +34010,19 @@ snapshots: - utf-8-validate optional: true + '@nestjs/platform-socket.io@10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@10.4.20)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20)(@nestjs/platform-socket.io@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2) + rxjs: 7.8.2 + socket.io: 4.8.1 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + optional: true + '@nestjs/schedule@4.1.2(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@10.4.20)': dependencies: '@nestjs/common': 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) @@ -34085,6 +34192,19 @@ snapshots: '@nestjs/platform-socket.io': 10.4.20(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@10.4.20)(rxjs@7.8.2) optional: true + '@nestjs/websockets@10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20)(@nestjs/platform-socket.io@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(@nestjs/websockets@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + iterare: 1.2.1 + object-hash: 3.0.0 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + optionalDependencies: + '@nestjs/platform-socket.io': 10.4.20(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@10.4.20)(rxjs@7.8.2) + optional: true + '@netlify/blobs@10.4.1': dependencies: '@netlify/dev-utils': 4.3.2 @@ -58518,6 +58638,42 @@ snapshots: - supports-color - terser + vitest@2.1.9(@types/node@20.19.25)(jsdom@27.2.0)(lightningcss@1.30.2)(terser@5.44.1): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@20.19.25)(lightningcss@1.30.2)(terser@5.44.1)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.2.2 + magic-string: 0.30.21 + pathe: 1.1.2 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 1.2.0 + vite: 5.4.21(@types/node@20.19.25)(lightningcss@1.30.2)(terser@5.44.1) + vite-node: 2.1.9(@types/node@20.19.25)(lightningcss@1.30.2)(terser@5.44.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.19.25 + jsdom: 27.2.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@2.1.9(@types/node@24.10.1)(jsdom@27.2.0)(lightningcss@1.30.2)(terser@5.44.1): dependencies: '@vitest/expect': 2.1.9