mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-15 17:30:13 +00:00
docs: make plugin guidance capability-first
Signed-off-by: barlind <tobias@barlind.se>
This commit is contained in:
+11
-30
@@ -1,6 +1,6 @@
|
||||
# Plugin Authoring Guide
|
||||
|
||||
Slopsmith's plugin system is the primary extension point. Each plugin lives in `plugins/<name>/` with a `plugin.json` manifest and can provide any combination of frontend (HTML/JS), backend (Python routes), settings UI, diagnostics, and visualization renderers.
|
||||
Slopsmith's plugin system is the primary extension point. Each plugin lives in `plugins/<name>/` with a `plugin.json` manifest that declares the capability domains, UI contributions, settings metadata, diagnostics, and runtime files the plugin participates in.
|
||||
|
||||
This guide is the entry point. Each topic below has a dedicated doc — read what's relevant to what you're building.
|
||||
|
||||
@@ -9,14 +9,14 @@ This guide is the entry point. Each topic below has a dedicated doc — read wha
|
||||
```text
|
||||
plugins/my_plugin/
|
||||
├── plugin.json Manifest (required) — see docs/plugin-manifest.md
|
||||
├── screen.html Optional — markup mounted at #plugin-my_plugin
|
||||
├── screen.js Optional — runs in global scope on page load
|
||||
├── routes.py Optional — exports setup(app, context)
|
||||
├── settings.html Optional — settings-panel HTML
|
||||
├── screen.html Optional — UI declared through `ui` contributions
|
||||
├── screen.js Optional — hydrates declared frontend capabilities
|
||||
├── routes.py Optional — backend provider/requester implementation
|
||||
├── settings.html Optional — settings UI declared through `ui.settings`
|
||||
└── requirements.txt Optional — pip deps auto-installed on load
|
||||
```
|
||||
|
||||
The minimum viable plugin is a `plugin.json` with just `id` and `name`. Everything else is opt-in.
|
||||
Start every new plugin by describing its Slopsmith-facing behavior in the manifest. A plugin with no behavior beyond metadata can be this small:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -26,7 +26,7 @@ The minimum viable plugin is a `plugin.json` with just `id` and `name`. Everythi
|
||||
}
|
||||
```
|
||||
|
||||
Capability-aware plugins should also declare the `capability-pipelines.v1` standard and the domains they participate in. Legacy fields such as `nav`, `screen`, `settings`, `type: "visualization"`, shortcuts, overlays, and mixer faders still work, but native metadata lets diagnostics, the Capability Inspector, and migration tooling explain plugin behavior without scraping private globals.
|
||||
Any plugin that participates in app behavior should also declare `standards: ["capability-pipelines.v1"]`, native `capabilities`, and redaction-safe `ui` metadata. Capability declarations are the source of truth for diagnostics, the Capability Inspector, and migration tooling.
|
||||
|
||||
## Topics
|
||||
|
||||
@@ -34,12 +34,12 @@ Capability-aware plugins should also declare the `capability-pipelines.v1` stand
|
||||
|---|---|---|
|
||||
| **Manifest reference** | [plugin-manifest.md](plugin-manifest.md) | Field-by-field reference for `plugin.json`. Read first. |
|
||||
| **Capability declarations** | [plugin-manifest.md#capabilities](plugin-manifest.md#capabilities) | Declaring provider/requester/observer intent with `capability-pipelines.v1`. |
|
||||
| **Capability domains** | [capability-domains.md](capability-domains.md) | Active domains, planned domains, and promotion rules. |
|
||||
| **Capability recipes** | [capability-recipes.md](capability-recipes.md) | Copyable manifest patterns for provider/requester/observer plugins. |
|
||||
| **Visualization contracts** | [plugin-visualization-contracts.md](plugin-visualization-contracts.md) | Building a highway renderer (setRenderer), an overlay layer, or a note-state provider. |
|
||||
| **Plugin styles** | [plugin-styles.md](plugin-styles.md) | Shipping a plugin-owned prebuilt stylesheet via `styles: "assets/plugin.css"`. |
|
||||
| **Audio mixer faders** | [plugin-audio-mixer.md](plugin-audio-mixer.md) | Plugin produces audio outside the song `<audio>` element. |
|
||||
| **Backend logging** | [plugin-logging.md](plugin-logging.md) | Plugin has a `routes.py`. Use `context["log"]`, never `print()`. |
|
||||
| **Diagnostics contribution** | [plugin-diagnostics.md](plugin-diagnostics.md) | Adding plugin state to the Export Diagnostics bundle. |
|
||||
| **Keyboard shortcuts** | [plugin-keyboard-shortcuts.md](plugin-keyboard-shortcuts.md) | Registering keys via `window.registerShortcut()`. |
|
||||
| **Sibling Python imports** | [plugin-sibling-imports.md](plugin-sibling-imports.md) | Multi-file backend plugins. Use `context["load_sibling"]`. |
|
||||
| **WebSocket protocol** | [websocket-protocol.md](websocket-protocol.md) | Plugins that read the highway stream directly. |
|
||||
| **Testing plugins** | [testing-plugins.md](testing-plugins.md) | Conftest fixtures and Playwright patterns for plugin tests. |
|
||||
@@ -50,28 +50,9 @@ Capability-aware plugins should also declare the `capability-pipelines.v1` stand
|
||||
|
||||
- Wrap your plugin code in an IIFE: `(function () { 'use strict'; ... })();`
|
||||
- Declare `standards: ["capability-pipelines.v1"]` and native `capabilities` when your plugin participates in a Slopsmith capability domain.
|
||||
- Use `ui` / `ui_contributions` for plugin-owned UI surfaces so the host can attribute them in diagnostics and support bundles.
|
||||
- Use `localStorage` for user-facing settings, prefixed with your plugin id.
|
||||
- If hooking `window.playSong`, always call the original and `await` it.
|
||||
- If hooking `window.showScreen`, clean up your state when leaving the player screen.
|
||||
- Use `window.slopsmith.emit()` / `window.slopsmith.on()` for inter-plugin communication.
|
||||
- Use `window.registerShortcut()` to add keyboard shortcuts. Clean up with `window.unregisterShortcut(key, scope)` — pass the same scope you registered with, since the default is `'global'` and won't match `player`/`library`/`settings`/`plugin-*` bindings. For panel-scoped shortcuts, prefer `panel.clearShortcuts()`.
|
||||
|
||||
## Plugin frontend globals available at runtime
|
||||
|
||||
- `window.playSong(filename, arrangementIdx)` — load and play a song
|
||||
- `window.showScreen(name)` — navigate between screens
|
||||
- `window.createHighway()` — factory for the highway renderer (used by main player and splitscreen panels)
|
||||
- `window.slopsmith` — event emitter (`emit`, `on`, `off`)
|
||||
- `window.slopsmith.audio` — audio mixer fader registry
|
||||
- `window.slopsmith.diagnostics` — diagnostics namespace (`contribute`, `snapshotConsole`, etc.)
|
||||
- `window.registerShortcut` / `window.unregisterShortcut` / `window.createShortcutPanel` — keyboard shortcuts API
|
||||
- `highway` global — set when the player is active. Getters: `getTime`, `getNotes`, `getChords`, `getChordTemplates`, `getSongInfo`, `getStringCount`, `getLefty`, `getInverted`, `getBeats`, `isDefaultRenderer`, …
|
||||
|
||||
## Plugin load order
|
||||
|
||||
Plugins load alphabetically by directory name. This determines the `playSong` wrapper chain order (last-loaded wrapper runs first; alphabetically earliest plugin runs closest to the original) and which plugin's UI elements appear first.
|
||||
|
||||
If your plugin depends on another's globals, **check at runtime** with `typeof window.X === 'function'`, not at load time. Plugins are independent — assume any other plugin may be missing or disabled.
|
||||
- Prefer native capability commands, events, and provider registration over private globals. If a domain you need is not active yet, document the gap in the PR instead of baking in a new private integration.
|
||||
|
||||
## Licensing for curated plugins
|
||||
|
||||
|
||||
Reference in New Issue
Block a user