✨ Major Features Added: - Complete magical theming and rebranding from LifeRPG to The Wizard's Grimoire - Production-grade React frontend with Tailwind CSS v4 and magical aesthetics - Comprehensive analytics dashboard with Recharts integration (ScryingPortal) - Push notifications system with PWA service worker support - Drag & drop functionality using @dnd-kit for habit reordering - Social features with friends system and leaderboards - Performance optimization tools and monitoring - Mobile app enhancement with PWA installation support 🏗️ Technical Infrastructure: - Advanced service worker with offline support and background sync - Zustand state management for scalable application state - Production-ready UI component system with enhanced Button, Card, Input - Progressive Web App (PWA) with manifest and app installation - FastAPI backend with comprehensive API endpoints - Docker containerization and CI/CD pipeline setup 📱 Progressive Web App Features: - Offline functionality with intelligent caching - Push notification support for habit reminders - App installation on mobile and desktop platforms - Background sync for offline data management - Performance monitoring and optimization tools 🎨 User Experience: - Magical wizard/grimoire theming throughout application - Responsive design optimized for all device sizes - Drag & drop habit management with smooth animations - Interactive analytics with multiple chart types - Social connectivity with friends and competitive features - Comprehensive notification and performance settings 🔧 Developer Experience: - Modern development stack with Vite and React - Comprehensive testing setup and CI/CD pipelines - Code quality tools with pre-commit hooks - Docker development environment - Detailed documentation and implementation guides This represents a complete transformation from prototype to production-ready application with enterprise-grade features and magical user experience.
15 KiB
LifeRPG Plugin System
This document outlines the design and implementation of the LifeRPG plugin system using WebAssembly (WASM) for secure sandboxing.
Overview
The LifeRPG plugin system enables users and developers to extend the functionality of the application without modifying the core codebase. Plugins run in a secure sandbox environment with controlled access to application resources.
Design Goals
- Security: Plugins must run in a secure sandbox with explicit permissions
- Performance: Minimal overhead for plugin execution
- Simplicity: Easy to develop and deploy plugins
- Portability: Plugins should work across all platforms (web, mobile, desktop)
- Versioning: Support for plugin versioning and compatibility checking
Architecture
High-Level Architecture
┌───────────────────────────────────────────────────────────────┐
│ LifeRPG Core │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ Plugin Manager │ │ Plugin Registry │ │ Core API │ │
│ └────────┬────────┘ └───────┬─────────┘ └──────┬──────┘ │
│ │ │ │ │
└───────────┼────────────────────┼────────────────────┼─────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────────────┐
│ Plugin Interface │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ Host Functions │ │ Extension Points│ │ Plugin API │ │
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
│ │
└───────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────────────┐
│ Plugin Sandbox │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ WASM Runtime │ │ Resource Limits │ │ Plugin Code │ │
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
│ │
└───────────────────────────────────────────────────────────────┘
Key Components
1. Plugin Manager
The Plugin Manager is responsible for:
- Loading and unloading plugins
- Managing plugin lifecycle
- Enforcing permissions and resource limits
- Handling plugin errors and crashes
class PluginManager {
// Load a plugin from a WASM binary
async loadPlugin(pluginId: string, wasmBinary: ArrayBuffer): Promise<Plugin>;
// Unload a plugin
async unloadPlugin(pluginId: string): Promise<void>;
// Get a list of loaded plugins
getLoadedPlugins(): Plugin[];
// Enable/disable a plugin
setPluginEnabled(pluginId: string, enabled: boolean): void;
}
2. Plugin Registry
The Plugin Registry manages:
- Plugin metadata storage
- Version compatibility checking
- Plugin discovery and marketplace
- User plugin preferences
class PluginRegistry {
// Register a new plugin
async registerPlugin(metadata: PluginMetadata, wasmBinary: ArrayBuffer): Promise<string>;
// Update an existing plugin
async updatePlugin(pluginId: string, metadata: PluginMetadata, wasmBinary: ArrayBuffer): Promise<void>;
// Get plugin metadata
getPluginMetadata(pluginId: string): PluginMetadata;
// List available plugins
listAvailablePlugins(filters?: PluginFilters): PluginMetadata[];
// Check if a plugin is compatible with the current app version
isPluginCompatible(pluginId: string): boolean;
}
3. Plugin Interface
The Plugin Interface defines:
- Host functions available to plugins
- Extension points where plugins can integrate
- Standard plugin API
interface PluginInterface {
// Core APIs available to plugins
core: {
// Data access APIs
data: {
getHabits(): Promise<Habit[]>;
getProjects(): Promise<Project[]>;
// ...etc
};
// UI integration
ui: {
registerView(viewId: string, component: PluginView): void;
registerMenuItem(menuId: string, item: MenuItem): void;
// ...etc
};
// Events
events: {
on(event: string, callback: Function): void;
emit(event: string, data: any): void;
// ...etc
};
};
// Host environment information
environment: {
appVersion: string;
platform: 'web' | 'mobile' | 'desktop';
capabilities: string[];
};
// Utilities
utils: {
logger: Logger;
storage: PluginStorage;
http: HttpClient;
};
}
4. WASM Sandbox
The WASM Sandbox provides:
- Secure execution environment
- Memory and CPU limits
- Network access controls
- Storage quotas
class WasmSandbox {
// Create a new sandbox with specified limits
constructor(options: SandboxOptions);
// Load WASM binary into the sandbox
async loadWasmModule(binary: ArrayBuffer): Promise<WasmModule>;
// Execute a function in the sandbox
async callFunction(functionName: string, ...args: any[]): Promise<any>;
// Set resource limits
setResourceLimits(limits: ResourceLimits): void;
// Check resource usage
getResourceUsage(): ResourceUsage;
// Terminate sandbox (for runaway plugins)
terminate(): void;
}
Plugin Development
Plugin Structure
A plugin consists of:
- WASM binary (compiled from various languages)
- Manifest file (metadata, permissions, extension points)
- Optional assets (images, styles, etc.)
// plugin.json manifest example
{
"id": "com.example.myplugin",
"name": "My Custom Plugin",
"version": "1.0.0",
"author": "Example Developer",
"description": "A custom plugin for LifeRPG",
"homepage": "https://example.com/myplugin",
"targetApiVersion": "1.0",
"minAppVersion": "2.0.0",
"permissions": [
"habits:read",
"projects:read",
"ui:dashboard",
"storage:plugin"
],
"extensionPoints": [
"dashboard.widget",
"habit.actions",
"reports.custom"
],
"entryPoint": "initialize",
"resourceLimits": {
"memory": "16MB",
"storage": "5MB",
"cpu": "moderate"
}
}
Supported Languages
Plugins can be developed in any language that compiles to WebAssembly:
- TypeScript/JavaScript (via AssemblyScript)
- Rust (native WASM support)
- C/C++ (via Emscripten)
- Go (with WASM target)
The recommended language is TypeScript with AssemblyScript for ease of development and type safety.
Development Workflow
-
Setup: Use the LifeRPG Plugin SDK
npm install @liferpg/plugin-sdk -
Develop: Create your plugin using the plugin template
// plugin.ts import { LifeRPG, PluginContext } from '@liferpg/plugin-sdk'; export function initialize(context: PluginContext): void { // Register a dashboard widget context.ui.registerDashboardWidget({ id: 'my-custom-widget', title: 'My Widget', size: 'medium', render: () => { // Return widget HTML/components return `<div>My Custom Widget</div>`; } }); // Listen for events context.events.on('habit.completed', (habit) => { context.logger.info(`Habit completed: ${habit.title}`); }); } -
Build: Compile to WASM
npm run build -
Test: Use the plugin development server
npm run dev -
Package: Create a plugin package
npm run package -
Publish: Submit to the LifeRPG plugin marketplace or distribute directly
Extension Points
The plugin system offers various extension points where plugins can integrate with the application:
UI Extension Points
- Dashboard Widgets: Add custom widgets to the dashboard
- Habit Views: Custom views for habits
- Project Views: Custom views for projects
- Reports: Custom reporting and analytics
- Settings Pages: Add custom settings pages
- Navigation Items: Add items to navigation menus
Data Extension Points
- Custom Fields: Add custom fields to habits, projects, etc.
- Data Validators: Add custom validation rules
- Data Processors: Process data before/after CRUD operations
- Exporters/Importers: Custom data export/import formats
Logic Extension Points
- Achievement Rules: Define custom achievement conditions
- Habit Completion Rules: Custom rules for habit completion
- Scoring Algorithms: Custom XP calculation
- Notification Triggers: Custom notification conditions
Security Model
Permission System
Plugins must request permissions for the resources they need to access:
habits:read - Read habit data
habits:write - Create/update habits
projects:read - Read project data
projects:write - Create/update projects
ui:dashboard - Add dashboard widgets
ui:settings - Add settings pages
storage:plugin - Use plugin storage
network:same-origin - Make network requests to same origin
network:external - Make network requests to external domains
Permissions are shown to users during plugin installation and updates.
Sandbox Restrictions
- Memory: Limited heap size
- CPU: Execution time limits
- Network: Controlled via permissions
- Storage: Quota-based plugin storage
- DOM: No direct DOM access (must use provided APIs)
Validation and Review
- Automatic Validation: Static analysis for security issues
- Manual Review: Optional review process for marketplace plugins
- User Ratings: Community reviews and ratings
- Revocation: Ability to revoke plugins with security issues
Implementation Plan
Phase 1: Core Infrastructure
- Implement basic WASM sandbox
- Create plugin manager and registry
- Define plugin interface and host functions
- Build plugin packaging tools
Phase 2: Basic Extension Points
- Implement dashboard widget extension point
- Add settings page extension point
- Create custom reporting extension point
- Build plugin marketplace UI
Phase 3: Advanced Features
- Add more extension points
- Implement comprehensive permission system
- Add resource monitoring and limits
- Create plugin developer documentation and examples
Example Plugins
1. Pomodoro Timer
A plugin that adds a Pomodoro timer widget to the dashboard and integrates with habit tracking.
// pomodoro-plugin.ts
export function initialize(context: PluginContext): void {
// Add dashboard widget
context.ui.registerDashboardWidget({
id: 'pomodoro-timer',
title: 'Pomodoro Timer',
size: 'medium',
render: () => {
return renderPomodoroTimer();
}
});
// Add settings page
context.ui.registerSettingsPage({
id: 'pomodoro-settings',
title: 'Pomodoro Settings',
render: () => {
return renderPomodoroSettings();
}
});
// When timer completes, offer to mark related habit as complete
context.events.on('pomodoro.complete', async () => {
const habits = await context.data.getHabits({ today: true });
// Show completion dialog
});
}
2. GitHub Integration
A plugin that connects with GitHub to track coding-related habits and progress.
// github-plugin.ts
export function initialize(context: PluginContext): void {
// Add GitHub connection settings
context.ui.registerSettingsPage({
id: 'github-settings',
title: 'GitHub Connection',
render: () => {
return renderGitHubSettings();
}
});
// Add GitHub stats widget
context.ui.registerDashboardWidget({
id: 'github-stats',
title: 'GitHub Activity',
size: 'large',
render: async () => {
const stats = await fetchGitHubStats();
return renderGitHubStatsWidget(stats);
}
});
// Sync GitHub activity daily
context.scheduler.scheduleDaily('github-sync', async () => {
await syncGitHubActivity();
});
}
3. Custom Data Visualizer
A plugin that provides advanced data visualization for habit tracking.
// data-viz-plugin.ts
export function initialize(context: PluginContext): void {
// Register custom report
context.ui.registerReport({
id: 'advanced-visualization',
title: 'Advanced Analytics',
render: async () => {
const habitData = await context.data.getHabitLogs({
timeRange: { from: '30d' }
});
return renderAdvancedVisualization(habitData);
}
});
// Add visualization widget to dashboard
context.ui.registerDashboardWidget({
id: 'viz-summary',
title: 'Progress Visualization',
size: 'large',
render: async () => {
return renderVisualizationSummary();
}
});
}
Conclusion
The LifeRPG plugin system provides a powerful yet secure way to extend the application's functionality. By using WebAssembly for sandboxing, we can offer both security and performance while supporting a wide range of programming languages for plugin development.
This design allows for a rich ecosystem of plugins that can enhance the LifeRPG experience without compromising on security or stability.