Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
216
.claude/instructions/plugin-architecture.md
Normal file
216
.claude/instructions/plugin-architecture.md
Normal file
@@ -0,0 +1,216 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user