refactor: consolidate codebase — remove archived code, deduplicate packages, standardize middleware

- Delete 17 server-archived/ directories (consolidated into apps/api/)
- Delete apps-archived/ (clock, wisekeep) and services-archived/ (it-landing, ollama-metrics-proxy)
- Fix type safety: replace all `any` casts in cross-app-queries.ts with proper Local* types
- Remove duplicate shared-auth-stores package (identical copy of shared-auth-ui/stores/)
- Remove duplicate theme store from shared-stores (canonical version in shared-theme)
- Migrate memoro-server rate-limiter to shared-hono/rateLimitMiddleware
- Migrate uload-server JWT auth + error handler to shared-hono (authMiddleware, errorHandler)
- Migrate arcade-server error handling to shared-hono
- Merge shared-profile-ui and shared-app-onboarding into shared-ui
- Unify /clock route into /times/clock, remove redirect stubs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-03 12:55:58 +02:00
parent 7ee57b7afd
commit d8ce4eaf34
309 changed files with 172 additions and 21667 deletions

View file

@ -1,34 +0,0 @@
{
"name": "@manacore/shared-app-onboarding",
"version": "0.1.0",
"description": "App-specific mini-onboarding for ManaCore apps",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"svelte": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"svelte": "./src/index.ts",
"default": "./src/index.ts"
}
},
"scripts": {
"type-check": "svelte-kit sync 2>/dev/null || true && svelte-check --tsconfig ./tsconfig.json"
},
"files": [
"src"
],
"dependencies": {
"@manacore/shared-theme": "workspace:*"
},
"devDependencies": {
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.0.0"
},
"peerDependencies": {
"svelte": "^5.0.0"
}
}

View file

@ -1,20 +0,0 @@
// Types
export type {
AppOnboardingOption,
AppOnboardingStepType,
AppOnboardingStepBase,
AppOnboardingSelectStep,
AppOnboardingToggleStep,
AppOnboardingInfoStep,
AppOnboardingStep,
AppOnboardingConfig,
AppOnboardingPreferences,
AppOnboardingStore,
MiniOnboardingModalProps,
} from './types';
// Factory function
export { createAppOnboardingStore } from './create-app-onboarding.svelte';
// Component
export { default as MiniOnboardingModal } from './MiniOnboardingModal.svelte';

View file

@ -1,18 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"types": ["svelte"]
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

View file

@ -1,35 +0,0 @@
{
"name": "@manacore/shared-auth-stores",
"version": "0.0.1",
"private": true,
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"svelte": "./src/index.ts",
"default": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/index.ts",
"svelte": "./src/index.ts",
"files": [
"src"
],
"scripts": {
"type-check": "svelte-check --tsconfig ./tsconfig.json",
"lint": "eslint ."
},
"peerDependencies": {
"svelte": "^5.0.0"
},
"devDependencies": {
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.0.0"
},
"dependencies": {
"@manacore/shared-auth": "workspace:*",
"@manacore/shared-types": "workspace:*"
}
}

View file

@ -1,186 +0,0 @@
/**
* Svelte 5 Auth Store Factory
*
* Creates a reactive auth store using Svelte 5 runes.
* Generic over user type to support app-specific user models.
*
* @example
* ```ts
* // In your app's auth store file
* import { createAuthStore } from '@manacore/shared-auth-stores';
* import { authService } from '$lib/auth';
* import type { AppUser } from '$lib/types';
*
* export const authStore = createAuthStore<AppUser>(authService);
* ```
*/
import type { AuthServiceAdapter, AuthResult, BaseUser } from './types';
/**
* Create a Svelte 5 runes-based auth store
*
* @param authService - Auth service adapter implementing the AuthServiceAdapter interface
* @returns Reactive auth store with state and actions
*/
export function createAuthStore<TUser extends BaseUser>(authService: AuthServiceAdapter<TUser>) {
// Reactive state using Svelte 5 runes
let user = $state<TUser | null>(null);
let loading = $state(true);
let error = $state<string | null>(null);
return {
// Reactive getters
get user() {
return user;
},
get loading() {
return loading;
},
get error() {
return error;
},
get isAuthenticated() {
return !!user;
},
/**
* Initialize auth state from stored tokens/session
*/
async initialize() {
loading = true;
error = null;
try {
const isAuth = await authService.isAuthenticated();
if (isAuth) {
user = await authService.getUserFromToken();
} else {
user = null;
}
} catch (e) {
console.error('Failed to initialize auth:', e);
error = e instanceof Error ? e.message : 'Failed to initialize authentication';
user = null;
} finally {
loading = false;
}
},
/**
* Set user manually (useful for SSR hydration)
*/
setUser(newUser: TUser | null) {
user = newUser;
error = null;
},
/**
* Sign in with email and password
*/
async signIn(email: string, password: string): Promise<AuthResult<TUser>> {
loading = true;
error = null;
try {
const result = await authService.signIn(email, password);
if (result.success) {
user = await authService.getUserFromToken();
} else {
error = result.error || 'Sign in failed';
}
return result;
} catch (e) {
const errorMessage = e instanceof Error ? e.message : 'Sign in failed';
error = errorMessage;
return { success: false, error: errorMessage };
} finally {
loading = false;
}
},
/**
* Sign up with email and password
*/
async signUp(email: string, password: string): Promise<AuthResult<TUser>> {
loading = true;
error = null;
try {
const result = await authService.signUp(email, password);
if (result.success && !result.needsVerification) {
user = await authService.getUserFromToken();
} else if (!result.success) {
error = result.error || 'Sign up failed';
}
return result;
} catch (e) {
const errorMessage = e instanceof Error ? e.message : 'Sign up failed';
error = errorMessage;
return { success: false, error: errorMessage };
} finally {
loading = false;
}
},
/**
* Send password reset email
*/
async forgotPassword(email: string): Promise<{ success: boolean; error?: string }> {
loading = true;
error = null;
try {
const result = await authService.forgotPassword(email);
if (!result.success) {
error = result.error || 'Password reset failed';
}
return result;
} catch (e) {
const errorMessage = e instanceof Error ? e.message : 'Password reset failed';
error = errorMessage;
return { success: false, error: errorMessage };
} finally {
loading = false;
}
},
/**
* Sign out user
*/
async signOut() {
loading = true;
error = null;
try {
await authService.signOut();
user = null;
} catch (e) {
console.error('Sign out failed:', e);
error = e instanceof Error ? e.message : 'Sign out failed';
} finally {
loading = false;
}
},
/**
* Check authentication status
*/
async checkAuth(): Promise<boolean> {
try {
const isAuth = await authService.isAuthenticated();
if (!isAuth) {
user = null;
return false;
}
return true;
} catch (e) {
console.error('Auth check failed:', e);
user = null;
return false;
}
},
/**
* Clear error state
*/
clearError() {
error = null;
},
};
}

View file

@ -1,301 +0,0 @@
/**
* Mana Auth Store Factory
*
* Creates a complete auth store using @manacore/shared-auth.
* Replaces the ~350 lines of duplicated auth.svelte.ts in each app
* with a single factory call.
*
* @example
* ```ts
* // apps/todo/apps/web/src/lib/stores/auth.svelte.ts
* import { createManaAuthStore } from '@manacore/shared-auth-stores';
*
* export const authStore = createManaAuthStore({
* devBackendPort: 3031,
* });
* ```
*
* @example With post-login callback
* ```ts
* import { createManaAuthStore } from '@manacore/shared-auth-stores';
* import { apiClient } from '$lib/api/client';
*
* export const authStore = createManaAuthStore({
* devBackendPort: 3030,
* onAuthenticated: async (authService) => {
* const token = await authService.getAppToken();
* if (token) apiClient.setAccessToken(token);
* },
* });
* ```
*/
import { browser } from '$app/environment';
import {
initializeWebAuth,
type UserData,
type AuthServiceInterface,
} from '@manacore/shared-auth';
export interface ManaAuthStoreConfig {
/** Dev backend port (e.g. 3031 for todo). Only used in development. */
devBackendPort?: number;
/** Dev auth port. Defaults to 3001. */
devAuthPort?: number;
/** Callback after successful authentication (sign in, SSO, 2FA). */
onAuthenticated?: (authService: AuthServiceInterface) => void | Promise<void>;
/** Callback after sign out. */
onSignOut?: () => void | Promise<void>;
}
export function createManaAuthStore(config: ManaAuthStoreConfig = {}) {
const devAuthUrl = `http://localhost:${config.devAuthPort ?? 3001}`;
const devBackendUrl = config.devBackendPort
? `http://localhost:${config.devBackendPort}`
: '';
// URL resolution (runtime, not build-time)
function getAuthUrl(): string {
if (browser && typeof window !== 'undefined') {
const injected = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string })
.__PUBLIC_MANA_CORE_AUTH_URL__;
if (injected) return injected;
return import.meta.env.DEV ? devAuthUrl : '';
}
return process.env.PUBLIC_MANA_CORE_AUTH_URL || devAuthUrl;
}
function getBackendUrl(): string {
if (browser && typeof window !== 'undefined') {
const injected = (window as unknown as { __PUBLIC_BACKEND_URL__?: string })
.__PUBLIC_BACKEND_URL__;
if (injected) return injected;
return import.meta.env.DEV ? devBackendUrl : '';
}
return process.env.PUBLIC_BACKEND_URL || devBackendUrl;
}
// Lazy init (SSR-safe)
let _authService: AuthServiceInterface | null = null;
let _tokenManager: ReturnType<typeof initializeWebAuth>['tokenManager'] | null = null;
function getAuthService() {
if (!browser) return null;
if (!_authService) {
const backendUrl = getBackendUrl();
const auth = initializeWebAuth({
baseUrl: getAuthUrl(),
...(backendUrl ? { backendUrl } : {}),
});
_authService = auth.authService;
_tokenManager = auth.tokenManager;
}
return _authService;
}
function getTokenManager() {
if (!browser) return null;
getAuthService();
return _tokenManager;
}
async function handleAuthenticated() {
if (config.onAuthenticated) {
const svc = getAuthService();
if (svc) await config.onAuthenticated(svc);
}
}
// Reactive state
let user = $state<UserData | null>(null);
let loading = $state(true);
let initialized = $state(false);
return {
// Getters
get user() { return user; },
get loading() { return loading; },
get isAuthenticated() { return !!user; },
get initialized() { return initialized; },
async initialize() {
if (initialized) return;
const authService = getAuthService();
if (!authService) {
initialized = true;
loading = false;
return;
}
loading = true;
try {
let authenticated = await authService.isAuthenticated();
if (!authenticated) {
const ssoResult = await authService.trySSO();
if (ssoResult.success) authenticated = true;
}
if (authenticated) {
user = await authService.getUserFromToken();
await handleAuthenticated();
}
initialized = true;
} catch (error) {
console.error('Failed to initialize auth:', error);
user = null;
} finally {
loading = false;
}
},
// 2FA
async verifyTwoFactor(code: string, trustDevice?: boolean) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
const result = await authService.verifyTwoFactor(code, trustDevice);
if (result.success) {
user = await authService.getUserFromToken();
await handleAuthenticated();
}
return result;
},
async verifyBackupCode(code: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
const result = await authService.verifyBackupCode(code);
if (result.success) {
user = await authService.getUserFromToken();
await handleAuthenticated();
}
return result;
},
// Magic Link
async sendMagicLink(email: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
return authService.sendMagicLink(email);
},
// Passkeys
isPasskeyAvailable(): boolean {
const authService = getAuthService();
if (!authService) return false;
return authService.isPasskeyAvailable();
},
async signInWithPasskey() {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
try {
const result = await authService.signInWithPasskey();
if (!result.success) return { success: false, error: result.error || 'Passkey authentication failed' };
user = await authService.getUserFromToken();
await handleAuthenticated();
return { success: true };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
},
// Sign In
async signIn(email: string, password: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
try {
const result = await authService.signIn(email, password);
if (!result.success) return { success: false, error: result.error || 'Login failed' };
user = await authService.getUserFromToken();
await handleAuthenticated();
return { success: true };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
},
// Sign Up
async signUp(email: string, password: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server', needsVerification: false };
try {
const sourceAppUrl = browser ? window.location.origin : undefined;
const result = await authService.signUp(email, password, sourceAppUrl);
if (!result.success) return { success: false, error: result.error || 'Signup failed', needsVerification: false };
if (result.needsVerification) return { success: true, needsVerification: true };
const signInResult = await this.signIn(email, password);
return { ...signInResult, needsVerification: false };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error', needsVerification: false };
}
},
// Sign Out
async signOut() {
const authService = getAuthService();
if (!authService) { user = null; return; }
try {
await authService.signOut();
user = null;
if (config.onSignOut) await config.onSignOut();
} catch (error) {
console.error('Sign out error:', error);
user = null;
}
},
// Password Reset
async resetPassword(email: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
try {
const redirectTo = browser ? window.location.origin : undefined;
const result = await authService.forgotPassword(email, redirectTo);
if (!result.success) return { success: false, error: result.error || 'Password reset failed' };
return { success: true };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
},
async resetPasswordWithToken(token: string, newPassword: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
try {
const result = await authService.resetPassword(token, newPassword);
if (!result.success) return { success: false, error: result.error || 'Failed to reset password' };
return { success: true };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
},
// Token access
async getAccessToken() {
const authService = getAuthService();
if (!authService) return null;
return await authService.getAppToken();
},
async getValidToken(): Promise<string | null> {
const tokenManager = getTokenManager();
if (!tokenManager) return null;
return await tokenManager.getValidToken();
},
// Email verification
async resendVerificationEmail(email: string) {
const authService = getAuthService();
if (!authService) return { success: false, error: 'Auth not available on server' };
try {
const sourceAppUrl = browser ? window.location.origin : undefined;
const result = await authService.resendVerificationEmail(email, sourceAppUrl);
if (!result.success) return { success: false, error: result.error || 'Failed to send verification email' };
return { success: true };
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
},
};
}
export type ManaAuthStore = ReturnType<typeof createManaAuthStore>;

View file

@ -1,33 +0,0 @@
/**
* @manacore/shared-auth-stores
*
* Svelte 5 auth store factories for the ManaCore monorepo.
*
* @example ManaCore auth store (recommended)
* ```ts
* import { createManaAuthStore } from '@manacore/shared-auth-stores';
* export const authStore = createManaAuthStore();
* ```
*
* @example Generic auth store with custom adapter
* ```ts
* import { createAuthStore } from '@manacore/shared-auth-stores';
* import { authService } from '$lib/auth';
* export const authStore = createAuthStore<AppUser>(authService);
* ```
*/
// Factory functions
export { createManaAuthStore } from './createManaAuthStore.svelte';
export type { ManaAuthStoreConfig, ManaAuthStore } from './createManaAuthStore.svelte';
export { createAuthStore } from './createAuthStore.svelte';
// Types
export type {
BaseUser,
AuthResult,
AuthServiceAdapter,
AuthStoreState,
AuthStoreActions,
AuthStore,
} from './types';

View file

@ -1,92 +0,0 @@
/**
* Shared Auth Store Types
* Generic types for creating auth stores with custom user types
*/
/**
* Base user interface that all app-specific user types must extend
*/
export interface BaseUser {
id: string;
email: string;
}
/**
* Auth operation result with typed user
*/
export interface AuthResult<TUser extends BaseUser = BaseUser> {
success: boolean;
error?: string;
needsVerification?: boolean;
user?: TUser;
}
/**
* Auth service interface that auth stores expect
* Apps implement this to integrate with their auth backend
*/
export interface AuthServiceAdapter<TUser extends BaseUser = BaseUser> {
/** Check if user is authenticated */
isAuthenticated(): Promise<boolean>;
/** Get user data from stored token/session */
getUserFromToken(): Promise<TUser | null>;
/** Sign in with email and password */
signIn(email: string, password: string): Promise<AuthResult<TUser>>;
/** Sign up with email and password */
signUp(email: string, password: string): Promise<AuthResult<TUser>>;
/** Send password reset email */
forgotPassword(email: string): Promise<{ success: boolean; error?: string }>;
/** Sign out user */
signOut(): Promise<void>;
}
/**
* Auth store state interface
*/
export interface AuthStoreState<TUser extends BaseUser = BaseUser> {
user: TUser | null;
loading: boolean;
error: string | null;
isAuthenticated: boolean;
}
/**
* Auth store actions interface
*/
export interface AuthStoreActions<TUser extends BaseUser = BaseUser> {
/** Initialize auth state from stored tokens */
initialize(): Promise<void>;
/** Set user manually */
setUser(user: TUser | null): void;
/** Sign in with email and password */
signIn(email: string, password: string): Promise<AuthResult<TUser>>;
/** Sign up with email and password */
signUp(email: string, password: string): Promise<AuthResult<TUser>>;
/** Send password reset email */
forgotPassword(email: string): Promise<{ success: boolean; error?: string }>;
/** Sign out user */
signOut(): Promise<void>;
/** Check authentication status */
checkAuth(): Promise<boolean>;
/** Clear error state */
clearError(): void;
}
/**
* Complete auth store interface
*/
export interface AuthStore<TUser extends BaseUser = BaseUser>
extends AuthStoreState<TUser>,
AuthStoreActions<TUser> {}

View file

@ -1,18 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"types": ["svelte"]
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

View file

@ -1,29 +0,0 @@
{
"name": "@manacore/shared-profile-ui",
"version": "1.0.0",
"private": true,
"type": "module",
"svelte": "./src/index.ts",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"svelte": "./src/index.ts",
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},
"scripts": {
"check": "svelte-check --tsconfig ./tsconfig.json",
"lint": "eslint ."
},
"dependencies": {},
"devDependencies": {
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.7.3"
},
"peerDependencies": {
"svelte": "^5.0.0"
}
}

View file

@ -1,12 +0,0 @@
/**
* Shared profile UI components for Manacore monorepo
*
* This package contains Svelte 5 components for displaying
* user profile information.
*/
// Pages
export { default as ProfilePage } from './ProfilePage.svelte';
// Types
export type { UserProfile, ProfileActions } from './types';

View file

@ -1,19 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"types": ["svelte"]
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

View file

@ -9,7 +9,6 @@ export {
type NavigationItem,
type NavigationStore,
} from './navigation.svelte';
export { createThemeStore, type ThemeStore, type ThemeMode } from './theme.svelte';
export {
createAppSettingsStore,
type AppSettingsStore,

View file

@ -1,125 +0,0 @@
/**
* Theme Store Factory
* Creates a theme state store with Svelte 5 runes.
*/
export type ThemeMode = 'light' | 'dark' | 'system';
export interface ThemeStore {
readonly isDark: boolean;
readonly mode: ThemeMode;
readonly variant: string;
initialize: () => () => void;
setMode: (mode: ThemeMode) => void;
setVariant: (variant: string) => void;
toggle: () => void;
}
export interface ThemeStoreConfig {
/** Storage key prefix (default: 'theme') */
storagePrefix?: string;
/** Default theme mode */
defaultMode?: ThemeMode;
/** Default theme variant */
defaultVariant?: string;
/** CSS class to add/remove for dark mode */
darkClass?: string;
/** Data attribute for variant */
variantAttribute?: string;
}
/**
* Create a theme store with Svelte 5 runes.
*/
export function createThemeStore(config: ThemeStoreConfig = {}): ThemeStore {
const {
storagePrefix = 'theme',
defaultMode = 'system',
defaultVariant = 'default',
darkClass = 'dark',
variantAttribute = 'data-theme',
} = config;
let isDark = $state(false);
let mode = $state<ThemeMode>(defaultMode);
let variant = $state(defaultVariant);
function updateTheme() {
if (typeof window === 'undefined') return;
let shouldBeDark = false;
if (mode === 'dark') {
shouldBeDark = true;
} else if (mode === 'system') {
shouldBeDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
isDark = shouldBeDark;
document.documentElement.classList.toggle(darkClass, isDark);
}
function initialize(): () => void {
if (typeof window === 'undefined') return () => {};
// Load from localStorage
const savedMode = localStorage.getItem(`${storagePrefix}-mode`) as ThemeMode | null;
const savedVariant = localStorage.getItem(`${storagePrefix}-variant`);
if (savedMode) mode = savedMode;
if (savedVariant) {
variant = savedVariant;
document.documentElement.setAttribute(variantAttribute, variant);
}
updateTheme();
// Listen for system theme changes
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = () => {
if (mode === 'system') {
updateTheme();
}
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}
function setMode(newMode: ThemeMode) {
mode = newMode;
if (typeof localStorage !== 'undefined') {
localStorage.setItem(`${storagePrefix}-mode`, newMode);
}
updateTheme();
}
function setVariant(newVariant: string) {
variant = newVariant;
if (typeof localStorage !== 'undefined') {
localStorage.setItem(`${storagePrefix}-variant`, newVariant);
}
if (typeof document !== 'undefined') {
document.documentElement.setAttribute(variantAttribute, newVariant);
}
}
function toggle() {
setMode(isDark ? 'light' : 'dark');
}
return {
get isDark() {
return isDark;
},
get mode() {
return mode;
},
get variant() {
return variant;
},
initialize,
setMode,
setVariant,
toggle,
};
}

View file

@ -188,6 +188,25 @@ export type { QuickInputItem, QuickAction, CreatePreview, InputBarSettings } fro
// Pages
export { default as AppsPage } from './pages/AppsPage.svelte';
export { default as OfflinePage } from './pages/OfflinePage.svelte';
export { default as ProfilePage } from './pages/ProfilePage.svelte';
export type { UserProfile, ProfileActions } from './pages/profile-types';
// Onboarding
export { createAppOnboardingStore } from './onboarding/create-app-onboarding.svelte';
export { default as MiniOnboardingModal } from './onboarding/MiniOnboardingModal.svelte';
export type {
AppOnboardingOption,
AppOnboardingStepType,
AppOnboardingStepBase,
AppOnboardingSelectStep,
AppOnboardingToggleStep,
AppOnboardingInfoStep,
AppOnboardingStep,
AppOnboardingConfig,
AppOnboardingPreferences,
AppOnboardingStore,
MiniOnboardingModalProps,
} from './onboarding/types';
// Charts - Statistics Visualization
export {

View file

@ -1,5 +1,5 @@
<script lang="ts">
import type { UserProfile, ProfileActions } from './types';
import type { UserProfile, ProfileActions } from './profile-types';
interface Props {
/** User profile data */