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