# Plugin Architecture Instructions ## Overview Dangerous Pi uses a plugin system that supports: - Remote installation from GitHub releases - Automatic pip dependency management - Hardware access (GPIO, I2C, SPI, serial) with permission enforcement - WebSocket broadcasting for real-time updates - Header widgets for UI notifications - Permission declarations with user consent at install time ## Plugin Distribution Model **Each plugin lives in its own GitHub repo** (e.g., `org/dangerous-pi-multi-flasher`). ### Registry Format A central registry repo (`dangerous-pi-plugin-registry`) contains `plugins.json`: ```json { "version": "1.0.0", "plugins": [ { "id": "plugin_id", "name": "Plugin Name", "repo": "org/repo-name", "description": "Description", "author": "Author", "latest_version": "1.0.0" } ] } ``` ### Plugin Release Format Each plugin repo publishes GitHub releases with: - `plugin.tar.gz` - The plugin archive - `plugin.json` - Metadata with checksum and dependencies ### plugin.json Schema ```json { "id": "plugin_id", "name": "Plugin Name", "version": "1.0.0", "description": "Description", "author": "Author", "checksum": "sha256:...", "dependencies": ["package>=1.0.0"], "permissions": ["gpio", "i2c", "network_access"], "min_app_version": "1.0.0" } ``` ## Plugin Directory Structure ``` app/plugins/{plugin_id}/ plugin.json # Metadata manifest main.py # Entry point (extends PluginBase) services/ # Business logic __init__.py {service}.py api/ # FastAPI router (optional) __init__.py router.py ``` ## Creating a Plugin ### 1. Extend PluginBase ```python from backend.managers.plugin_manager import PluginBase, PluginMetadata class MyPlugin(PluginBase): async def on_load(self): # Initialize services pass async def on_enable(self): # Register hooks, start functionality self.register_hook("hook_name", self.my_callback) async def on_disable(self): # Stop functionality pass async def on_unload(self): # Cleanup resources pass ``` ### 2. Register Hooks Available hooks: - `pm3_command` - Triggered on Proxmark3 commands - `update_check` - Triggered on system update checks - Custom hooks can be added ### 3. Add API Routes (Optional) Plugins can expose their own FastAPI routers mounted under `/api/plugins/{plugin_id}/` ### 4. Register Header Widgets Display notifications in the UI header: ```python from backend.managers.plugin_manager import WidgetSeverity class MyPlugin(PluginBase): async def on_enable(self): # Register a header widget self.register_widget( widget_id="status", # Becomes "plugin.my_plugin.status" severity=WidgetSeverity.INFO, message="Plugin is active", icon="🔌", dismissible=True, action_label="Settings", # Optional action_url="/settings#plugins" ) async def on_disable(self): # Clean up widget self.unregister_widget("status") ``` Widget severity levels: `INFO`, `WARNING`, `ERROR`, `SUCCESS` ### 5. Broadcast WebSocket Events Send real-time updates to connected clients (requires `websocket` permission): ```python class MyPlugin(PluginBase): async def some_operation(self): # Broadcast event to all connected clients # Event type becomes: "plugin.my_plugin.progress" await self.broadcast_event("progress", { "percent": 50, "message": "Processing..." }) ``` WebSocket events are rate-limited to 10 events/second per plugin. ### 6. Access Hardware Get controlled access to hardware interfaces (requires permissions in plugin.json): ```python class MyPlugin(PluginBase): def setup_hardware(self): # Requires "i2c" permission i2c = self.get_i2c(bus=1) # Requires "gpio" permission gpio = self.get_gpio() # Requires "spi" permission spi = self.get_spi(bus=0, device=0) # Requires "serial" permission serial = self.get_serial("/dev/ttyUSB0", baudrate=9600) ``` ## Available Permissions | Permission | Description | Methods Unlocked | |------------|-------------|------------------| | `gpio` | Access GPIO pins | `get_gpio()` | | `i2c` | Access I2C bus | `get_i2c()` | | `spi` | Access SPI bus | `get_spi()` | | `serial` | Access serial ports | `get_serial()` | | `websocket` | Broadcast WebSocket events | `broadcast_event()` | | `camera` | Access camera | (future) | | `network_access` | Make network requests | (unrestricted) | | `pm3_flash` | Flash PM3 devices | (via hooks) | | `script_execution` | Execute user scripts | (sandboxed) | **Note:** Hardware permissions (`gpio`, `i2c`, `spi`, `serial`) require user consent at install time. Attempting to use hardware methods without the required permission raises `PermissionError`. ## Hardware Libraries Plugins can depend on these for hardware access: - `RPi.GPIO` - GPIO pin control - `smbus2` - I2C communication - `spidev` - SPI communication - `gpiozero` - Higher-level GPIO abstraction - `pyserial` - Serial/UART communication - `opencv-python-headless` - Camera/image processing ## Key Files | File | Purpose | |------|---------| | `app/backend/managers/plugin_manager.py` | Core plugin framework, widgets, permissions | | `app/backend/services/hardware_service.py` | Hardware access layer (I2C, GPIO, SPI, Serial) | | `app/backend/websocket/notifications.py` | WebSocket event broadcasting | | `app/backend/api/plugins.py` | Plugin API endpoints | | `app/backend/api/system.py` | Widget API endpoints (`/api/system/widgets`) | | `app/frontend/app/components/HeaderWidgets.tsx` | Widget UI component | | `app/plugins/hello_world/` | Reference implementation | ## Installation Sources 1. **From registry** - Browse webstore → select plugin → auto-install 2. **Direct URL** - Install from any GitHub release URL ## Security Guidelines - Verify SHA256 checksums before extraction - Only install pip packages from PyPI - Sandbox script execution (no os, sys, subprocess access) - Display permissions to user before installation - Log all plugin installations ## Related Plans See `/home/work/.claude/plans/tranquil-toasting-clover.md` for the full implementation plan including: - Multi-Flasher Plugin (parallel PM3 firmware flashing) - Color Detector Plugin (webcam color detection + WebREPL)