mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-13 02:08:31 +00:00
CLAUDE.md had grown to 545 lines / 50 KB — most of it plugin-author
content that other AI tools (Cursor, Copilot, Codex, Aider) and humans
without AI never reach. Extract the plugin surface into 10 focused
docs and a JSON Schema for plugin.json, then slim CLAUDE.md to a
156-line navigable index.
New docs (~999 lines total, all self-contained):
docs/PLUGIN_AUTHORING.md — entry point and quickstart
docs/plugin-manifest.md — plugin.json field reference
docs/plugin-visualization-contracts.md — setRenderer / overlay / note-state
docs/plugin-audio-mixer.md — fader registration
docs/plugin-logging.md — context["log"] + env vars
docs/plugin-diagnostics.md — server_files / callable
docs/plugin-keyboard-shortcuts.md — registerShortcut + scopes
docs/plugin-sibling-imports.md — load_sibling pattern
docs/websocket-protocol.md — /ws/highway message reference
docs/testing-plugins.md — pytest fixtures + Playwright
schema/plugin.schema.json — Draft 2020-12 schema for
plugin.json; license enum
mirrors CONTRIBUTING's curated
allowlist. Backs CI validation
and the plugin-validate skill.
CLAUDE.md slim (581 lines changed, -485):
- Removed ~300 lines of plugin-author prose (now in docs/).
- Kept architecture quick reference, running the app, testing,
git workflow, versioning, song formats, frontend/backend
conventions, plugin authoring INDEX (table → docs/), first-hour
pitfalls, "For AI agents" footer.
- Anchor stubs preserved next to the new index entries so deep
links from specs/001-slopsmith-platform/analyze.md still resolve.
Verification:
python -c "import json,glob,jsonschema; s=json.load(open('schema/plugin.schema.json')); [jsonschema.validate(json.load(open(p)), s) for p in sorted(glob.glob('plugins/*/plugin.json'))]"
# ok — validates highway_3d, app_tour_library, app_tour_settings
Signed-off-by: Miguel_LZPF <mgcdreamer@gmail.com>
74 lines
5.0 KiB
Markdown
74 lines
5.0 KiB
Markdown
# 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.
|
|
|
|
This guide is the entry point. Each topic below has a dedicated doc — read what's relevant to what you're building.
|
|
|
|
## Quickstart
|
|
|
|
```
|
|
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
|
|
└── 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.
|
|
|
|
```json
|
|
{
|
|
"id": "my_plugin",
|
|
"name": "My Plugin",
|
|
"version": "0.1.0"
|
|
}
|
|
```
|
|
|
|
## Topics
|
|
|
|
| Topic | Doc | When to read |
|
|
|---|---|---|
|
|
| **Manifest reference** | [plugin-manifest.md](plugin-manifest.md) | Field-by-field reference for `plugin.json`. Read first. |
|
|
| **Visualization contracts** | [plugin-visualization-contracts.md](plugin-visualization-contracts.md) | Building a highway renderer (setRenderer), an overlay layer, or a note-state provider. |
|
|
| **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. |
|
|
| **Diagnostics bundle spec** | [diagnostics-bundle-spec.md](diagnostics-bundle-spec.md) | Existing in-depth spec — what's inside a diagnostics export. |
|
|
| **Sloppak format spec** | [sloppak-spec.md](sloppak-spec.md) | Existing in-depth spec — for plugins that read/write sloppaks. |
|
|
|
|
## General guidelines
|
|
|
|
- Wrap your plugin code in an IIFE: `(function () { 'use strict'; ... })();`
|
|
- 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.
|
|
|
|
## Licensing for curated plugins
|
|
|
|
Plugins submitted for inclusion in the curated list must be AGPL-3.0 or AGPL-compatible (MIT, BSD, Apache-2.0). See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full policy. The `plugin.json` schema enforces this via the `license` field enum — see [plugin-manifest.md](plugin-manifest.md).
|