PLUGIN_STORE_GUIDE.md
- 19 occurrences of port 5050 -> 5000
- All API paths missing /v3 (e.g. /api/plugins/install ->
/api/v3/plugins/install). Bulk fix.
PLUGIN_REGISTRY_SETUP_GUIDE.md
- Same port + /api/v3 fixes (3 occurrences each)
- "Go to Plugin Store tab" -> "Open the Plugin Manager tab and scroll
to the Install from GitHub section" (the real flow for registry
setup is the GitHub install section, not the Plugin Store search)
PLUGIN_CONFIG_QUICK_START.md
- Port 5001 -> 5000 (5001 is the dev_server.py default, not the web UI)
- "Plugin Store tab" install flow -> real Plugin Manager + Plugin Store
section + per-plugin tab in second nav row
- Removed reference to PLUGIN_CONFIG_TABS_SUMMARY.md (archived doc)
PLUGIN_CONFIGURATION_TABS.md
- "Plugin Management vs Configuration" section confusingly described
a "Plugins Tab" that doesn't exist as a single thing. Rewrote to
describe the real two-piece structure: Plugin Manager tab (browse,
install, toggle) vs per-plugin tabs (configure individual plugins).
PLUGIN_DEPENDENCY_GUIDE.md
- Port 5001 -> 5000
PLUGIN_DEPENDENCY_TROUBLESHOOTING.md
- Wrong port (8080) and wrong UI nav ("Plugin Store or Plugin
Management"). Fixed to the real flow.
PLUGIN_QUICK_REFERENCE.md
- "Plugin Location: ./plugins/ directory" -> default is plugin-repos/
(verified in config/config.template.json:130 and
display_controller.py:132). plugins/ is a fallback.
- File structure diagram showed plugins/ -> plugin-repos/.
- Web UI install flow: "Plugin Store tab" -> "Plugin Manager tab ->
Plugin Store section". Also fixed Configure ⚙️ button (doesn't
exist) and "Drag and drop reorder" (not implemented).
- API examples: replaced ad-hoc Python pseudocode with real curl
examples against /api/v3/plugins/* endpoints. Pointed at
REST_API_REFERENCE.md for the full list.
- "Migration Path Phase 1-5" was a roadmap written before the plugin
system shipped. The plugin system is now stable and live. Removed
the migration phases as they're history, not a roadmap.
- "Quick Migration" section called scripts/migrate_to_plugins.py
which doesn't exist anywhere in the repo. Removed.
- "Plugin Registry Structure" referenced
ChuckBuilds/ledmatrix-plugin-registry which doesn't exist. The
real registry is ChuckBuilds/ledmatrix-plugins. Fixed.
- "Next Steps" / "Questions to Resolve" sections were
pre-implementation planning notes. Replaced with a "Known
Limitations" section that documents the actually-real gaps
(sandboxing, resource limits, ratings, auto-updates).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8.9 KiB
Plugin Configuration Tabs
Overview
Each installed plugin now gets its own dedicated configuration tab in the web interface. This provides a clean, organized way to configure plugins without cluttering the main Plugins management tab.
Features
- Automatic Tab Generation: When a plugin is installed, a new tab is automatically created in the web UI
- JSON Schema-Based Forms: Configuration forms are automatically generated based on each plugin's
config_schema.json - Type-Safe Inputs: Form inputs are created based on the JSON Schema type (boolean, number, string, array, enum)
- Default Values: All fields show current values or fallback to schema defaults
- Reset Functionality: Users can reset all settings to defaults with one click
- Real-Time Validation: Input constraints from JSON Schema are enforced (min, max, maxLength, etc.)
User Experience
Accessing Plugin Configuration
- Navigate to the Plugins tab to see all installed plugins
- Click the Configure button on any plugin card
- You'll be automatically taken to that plugin's configuration tab
- Alternatively, click directly on the plugin's tab button (marked with a puzzle piece icon)
Configuring a Plugin
- Open the plugin's configuration tab
- Modify settings using the generated form
- Click Save Configuration
- Restart the display service to apply changes
Plugin Manager vs Per-Plugin Configuration
- Plugin Manager tab (second nav row): used for browsing the Plugin Store, installing plugins, toggling installed plugins on/off, and updating/uninstalling them
- Per-plugin tabs (one per installed plugin, also in the second
nav row): used for configuring that specific plugin's behavior and
settings via a form auto-generated from its
config_schema.json
For Plugin Developers
Requirements
To enable automatic configuration tab generation, your plugin must:
- Include a
config_schema.jsonfile - Reference it in your
manifest.json:
{
"id": "your-plugin",
"name": "Your Plugin",
"icon": "fas fa-star", // Optional: Custom tab icon
...
"config_schema": "config_schema.json"
}
Note: You can optionally specify a custom icon for your plugin tab. See Plugin Custom Icons Guide for details.
Supported JSON Schema Types
The form generator supports the following JSON Schema types:
Boolean
{
"type": "boolean",
"default": true,
"description": "Enable or disable this feature"
}
Renders as: Toggle switch
Number / Integer
{
"type": "integer",
"default": 60,
"minimum": 1,
"maximum": 300,
"description": "Update interval in seconds"
}
Renders as: Number input with min/max constraints
String
{
"type": "string",
"default": "Hello, World!",
"minLength": 1,
"maxLength": 50,
"description": "The message to display"
}
Renders as: Text input with length constraints
Array
{
"type": "array",
"items": {
"type": "integer",
"minimum": 0,
"maximum": 255
},
"minItems": 3,
"maxItems": 3,
"default": [255, 255, 255],
"description": "RGB color [R, G, B]"
}
Renders as: Text input (comma-separated values)
Example input: 255, 128, 0
Enum (Select)
{
"type": "string",
"enum": ["small", "medium", "large"],
"default": "medium",
"description": "Display size"
}
Renders as: Dropdown select
Example config_schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "My Plugin Configuration",
"description": "Configure my awesome plugin",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable or disable this plugin"
},
"message": {
"type": "string",
"default": "Hello!",
"minLength": 1,
"maxLength": 50,
"description": "The message to display"
},
"update_interval": {
"type": "integer",
"default": 60,
"minimum": 1,
"maximum": 3600,
"description": "Update interval in seconds"
},
"color": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0,
"maximum": 255
},
"minItems": 3,
"maxItems": 3,
"default": [255, 255, 255],
"description": "RGB color [R, G, B]"
},
"mode": {
"type": "string",
"enum": ["scroll", "static", "fade"],
"default": "scroll",
"description": "Display mode"
}
},
"required": ["enabled"],
"additionalProperties": false
}
Best Practices
- Use Descriptive Labels: The
descriptionfield is shown as help text under each input - Set Sensible Defaults: Always provide default values that work out of the box
- Use Constraints: Leverage min/max, minLength/maxLength to guide users
- Mark Required Fields: Use the
requiredarray in your schema - Organize Properties: List properties in order of importance
Form Generation Process
- Web UI loads installed plugins via
/api/plugins/installed - For each plugin, the backend loads its
config_schema.json - Frontend generates a tab button with plugin name
- Frontend generates a form based on the JSON Schema
- Current config values from
config.jsonare populated - When saved, each field is sent to
/api/plugins/configendpoint
Implementation Details
Backend Changes
File: web_interface_v2.py
- Modified
/api/plugins/installedendpoint to includeconfig_schema_data - Loads each plugin's
config_schema.jsonif it exists - Returns schema data along with plugin info
Frontend Changes
File: templates/index_v2.html
New Functions:
generatePluginTabs(plugins)- Creates tab buttons and content for each plugingeneratePluginConfigForm(plugin)- Generates HTML form from JSON SchemasavePluginConfiguration(pluginId)- Saves form data to backendresetPluginConfig(pluginId)- Resets all settings to defaultsconfigurePlugin(pluginId)- Navigates to plugin's tab
Data Flow
Page Load
→ refreshPlugins()
→ /api/plugins/installed
→ Returns plugins with config_schema_data
→ generatePluginTabs()
→ Creates tab buttons
→ Creates tab content
→ generatePluginConfigForm()
→ Reads JSON Schema
→ Creates form inputs
→ Populates current values
User Saves
→ savePluginConfiguration()
→ Reads form data
→ Converts types per schema
→ Sends to /api/plugins/config
→ Updates config.json
→ Shows success notification
Troubleshooting
Plugin Tab Not Appearing
- Ensure
config_schema.jsonexists in plugin directory - Verify
config_schemafield inmanifest.json - Check browser console for errors
- Try refreshing plugins (Plugins tab → Refresh button)
Form Not Generating Correctly
- Validate your
config_schema.jsonagainst JSON Schema Draft 07 - Check that all properties have a
typefield - Ensure
defaultvalues match the specified type - Look for JavaScript errors in browser console
Configuration Not Saving
- Ensure the plugin is properly installed
- Check that config keys match schema properties
- Verify backend API is accessible
- Check browser network tab for API errors
- Ensure display service is restarted after config changes
Migration Guide
For Existing Plugins
If your plugin already has a config_schema.json:
- No changes needed! The tab will be automatically generated.
- Test the generated form to ensure all fields render correctly.
- Consider adding more descriptive
descriptionfields.
If your plugin doesn't have a config schema:
- Create
config_schema.jsonbased on your current config structure - Add descriptions for each property
- Set appropriate defaults
- Add validation constraints (min, max, etc.)
- Reference the schema in your
manifest.json
Backward Compatibility
- Plugins without
config_schema.jsonstill work normally - They simply won't have a configuration tab
- Users can still edit config via the Raw JSON editor
- The Configure button will navigate to a tab with a friendly message
Future Enhancements
Potential improvements for future versions:
- Advanced Schema Features: Support for nested objects, conditional fields
- Visual Validation: Real-time validation feedback as user types
- Color Pickers: Special input for RGB/color array types
- File Uploads: Support for image/asset uploads
- Import/Export: Save and share plugin configurations
- Presets: Quick-switch between saved configurations
- Documentation Links: Link schema fields to plugin documentation
Example Plugins
See these plugins for examples of config schemas:
hello-world: Simple plugin with basic typesclock-simple: Plugin with enum and number types
Support
For questions or issues:
- Check the main LEDMatrix wiki
- Review plugin documentation
- Open an issue on GitHub
- Join the community Discord