# Super Productivity Plugin API Overview This document provides a comprehensive overview of the Super Productivity plugin system, its architecture, and API. ## Table of Contents 1. [Plugin Architecture](#plugin-architecture) 2. [Plugin Types](#plugin-types) 3. [Plugin API Reference](#plugin-api-reference) 4. [Security Model](#security-model) 5. [Plugin Development](#plugin-development) 6. [Examples](#examples) ## Plugin Architecture Super Productivity uses a sophisticated plugin system that allows extending the application's functionality through custom plugins. The architecture consists of several key components: ### Core Components - **PluginService** (`/src/app/plugins/plugin.service.ts`): Main orchestrator for plugin lifecycle - **PluginBridgeService** (`/src/app/plugins/plugin-bridge.service.ts`): Communication bridge between plugins and the app - **PluginAPI** (`/src/app/plugins/plugin-api.ts`): API interface exposed to plugins - **PluginRunner** (`/src/app/plugins/plugin-runner.ts`): Executes plugin code in sandboxed environments ### Plugin Loading Process 1. **Discovery**: Built-in plugins from `/assets/` and uploaded plugins from cache 2. **Validation**: Manifest validation and permission checking 3. **Sandboxing**: Code execution in isolated JavaScript environments 4. **Registration**: UI components and hooks registration 5. **Initialization**: Plugin startup and configuration loading ## Plugin Types ### 1. JavaScript Plugins (plugin.js) Traditional plugins that run JavaScript code in a sandboxed environment. ```javascript // Example plugin.js class MyPlugin { constructor() { this.config = {}; } async init() { // Register UI components PluginAPI.registerHeaderButton({ label: 'My Plugin', icon: 'extension', onClick: () => this.showDialog(), }); // Register hooks PluginAPI.registerHook('taskCreated', (task) => { console.log('New task created:', task.title); }); } showDialog() { PluginAPI.openDialog({ title: 'My Plugin Dialog', message: 'Hello from my plugin!', }); } } // Initialize plugin const plugin = new MyPlugin(); plugin.init(); ``` ### 2. Iframe Plugins (index.html) Plugins that render HTML interfaces in sandboxed iframes. ```html My Plugin UI

My Plugin Interface

``` ### 3. Hybrid Plugins Plugins that combine both JavaScript execution and iframe interfaces. ## Plugin API Reference ### Core Methods #### Data Operations - `getTasks()` - Retrieve all tasks - `getTaskById(id)` - Get specific task - `addTask(task)` - Create new task - `updateTask(id, changes)` - Update existing task - `removeTask(id)` - Delete task #### Project Operations - `getProjects()` - Get all projects - `getActiveProject()` - Get currently active project - `addProject(project)` - Create new project #### Data Persistence - `persistDataSynced(data)` - Save plugin data with sync - `loadPersistedData()` - Load saved plugin data #### UI Operations - `showSnack(config)` - Show notification snackbar - `notify(config)` - Show system notification - `openDialog(config)` - Display modal dialog #### Navigation - `showIndexHtmlAsView()` - Show plugin iframe in full view - `showIndexHtmlInSidePanel()` - Show plugin iframe in side panel ### UI Registration Methods (plugin.js only) These methods are restricted to main plugin code for security: #### Header Buttons ```javascript PluginAPI.registerHeaderButton({ label: 'My Button', icon: 'extension', onClick: () => { // Button click handler }, }); ``` #### Menu Entries ```javascript PluginAPI.registerMenuEntry({ label: 'My Plugin', icon: 'extension', onClick: () => { // Menu item click handler }, }); ``` #### Side Panel Buttons ```javascript PluginAPI.registerSidePanelButton({ label: 'My Panel', icon: 'extension', onClick: () => { PluginAPI.showIndexHtmlInSidePanel(); }, }); ``` #### Keyboard Shortcuts ```javascript PluginAPI.registerShortcut({ keys: 'ctrl+alt+m', description: 'My Plugin Shortcut', callback: () => { // Shortcut handler }, }); ``` ### Hook System Plugins can register hooks to respond to application events: ```javascript PluginAPI.registerHook('taskCreated', (task) => { // React to task creation }); PluginAPI.registerHook('taskUpdated', (task, changes) => { // React to task updates }); PluginAPI.registerHook('beforeTaskDelete', (taskId) => { // React before task deletion }); ``` ## Security Model The plugin system implements a multi-layered security model: ### 1. Code Sandboxing - JavaScript plugins run in isolated VM contexts - Limited access to Node.js APIs (desktop app only) - No direct file system access without permissions ### 2. Iframe Sandboxing - HTML content runs in sandboxed iframes - Standard iframe restrictions apply - Communication only via postMessage ### 3. API Access Control Certain methods are restricted based on context: #### Restricted in Iframe Context - `registerHeaderButton` - `registerMenuEntry` - `registerSidePanelButton` - `registerShortcut` - `registerHook` - `executeNodeScript` - `onMessage` #### Available in Iframe Context - All data operations (getTasks, addTask, etc.) - UI operations (showSnack, notify, openDialog) - Data persistence (persistDataSynced, loadPersistedData) ### 4. Permission System Plugins can request specific permissions in their manifest: ```json { "permissions": ["nodeExecution", "fileSystem", "network"] } ``` ## Plugin Development ### Manifest Structure Every plugin requires a `manifest.json` file: ```json { "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "description": "A sample plugin", "author": "Developer Name", "hooks": ["taskCreated", "taskUpdated"], "permissions": ["nodeExecution"], "iFrame": true, "isSkipMenuEntry": false, "minSupVersion": "8.0.0" } ``` ### Plugin Structure ``` my-plugin/ ├── manifest.json # Plugin metadata ├── plugin.js # Main plugin code (optional) ├── index.html # UI interface (optional) ├── iframe-script.js # Iframe-specific code (optional) └── icon.svg # Plugin icon (optional) ``` ### Development Workflow 1. **Create Manifest**: Define plugin metadata and requirements 2. **Implement Logic**: Write plugin.js for core functionality 3. **Create UI**: Design index.html for user interface 4. **Test Integration**: Use development tools to test plugin 5. **Package**: Create ZIP file for distribution ### Best Practices 1. **Error Handling**: Always wrap API calls in try-catch blocks 2. **Async Operations**: Use async/await for all API calls 3. **Resource Cleanup**: Properly clean up timers and listeners 4. **User Feedback**: Provide clear feedback for user actions 5. **Performance**: Minimize impact on app performance ## Examples ### 1. Task Counter Plugin ```javascript // plugin.js class TaskCounterPlugin { constructor() { this.taskCount = 0; } async init() { // Register UI PluginAPI.registerHeaderButton({ label: `Tasks: ${this.taskCount}`, icon: 'assignment', onClick: () => this.showDetails(), }); // Listen for task changes PluginAPI.registerHook('taskCreated', () => this.updateCount()); PluginAPI.registerHook('taskDeleted', () => this.updateCount()); // Initial count await this.updateCount(); } async updateCount() { const tasks = await PluginAPI.getTasks(); this.taskCount = tasks.length; // Update button label... } showDetails() { PluginAPI.openDialog({ title: 'Task Statistics', message: `Total tasks: ${this.taskCount}`, }); } } new TaskCounterPlugin().init(); ``` ### 2. Quick Note Plugin (Iframe) ```html Quick Notes

Quick Notes


``` ### 3. Sync Plugin (Hybrid) Combines both plugin.js for logic and index.html for configuration: ```javascript // plugin.js class SyncPlugin { constructor() { this.config = null; } async init() { this.config = await this.loadConfig(); PluginAPI.registerSidePanelButton({ label: 'Sync Settings', icon: 'sync', onClick: () => PluginAPI.showIndexHtmlInSidePanel(), }); // Start sync if configured if (this.config && this.config.enabled) { this.startSync(); } } async loadConfig() { const data = await PluginAPI.loadPersistedData(); return data ? JSON.parse(data) : null; } async saveConfig(config) { await PluginAPI.persistDataSynced(JSON.stringify(config)); this.config = config; } startSync() { // Implement sync logic } } new SyncPlugin().init(); ``` ## Troubleshooting ### Common Issues 1. **Plugin Not Loading**: Check manifest.json syntax and required fields 2. **API Calls Failing**: Ensure proper async/await usage and error handling 3. **UI Not Registering**: Verify registerUi methods are called from plugin.js, not iframe 4. **Permission Errors**: Check if plugin has required permissions in manifest ### Development Tools - Use browser DevTools for iframe debugging - Check plugin service logs for loading issues - Use the plugin management UI to reload plugins during development ### Getting Help - Check existing plugin examples in `/assets/` directory - Review plugin service source code for API implementation details - Test with minimal plugin examples before adding complexity --- This overview provides the foundation for understanding and developing plugins for Super Productivity. For the most up-to-date API reference, always refer to the source code and existing plugin examples.