Skip to content

Add Lua plugin scripting#302

Merged
LargeModGames merged 5 commits into
mainfrom
lua-scripting
Jun 12, 2026
Merged

Add Lua plugin scripting#302
LargeModGames merged 5 commits into
mainfrom
lua-scripting

Conversation

@LargeModGames

Copy link
Copy Markdown
Owner

Adds an embedded Lua plugin system (phases 0-5) plus the ecosystem polish needed to ship it.

What plugins can do

  • React to playback events (track_change, playback_state_change, seek, volume_change, queue_change, start, quit)
  • Read playback/track/device snapshots and drive playback through a curated action API (same code paths as keybindings, including native-streaming fast paths)
  • Register named commands bound to keys via a plugin_commands map in config.yml
  • Extend the UI: persistent playbar segments, scrollable modal popups, runtime theme overrides
  • Make async HTTP requests and encode/decode JSON

Ecosystem

  • spotatui plugin add/list/remove/update git-based installer with a plugins.lock lockfile
  • spotatui plugin new <name> scaffolds a working directory plugin to start from
  • Directory plugins (plugins/<name>/main.lua) with require support for sibling modules
  • spotatui.require_api(n) lets a plugin declare its minimum API version and fail with a clear message instead of a cryptic nil-call error on older builds
  • Trust and safety docs (plugins are unsandboxed and run with full privileges)
  • 5 runnable example plugins, PLUGINS.md index, full docs/scripting.md reference, and a spotatui-plugin GitHub topic convention for discovery

Safety

  • Scripting is behind the scripting feature; the slim CI build stays mlua-free
  • A failing plugin is disabled with a status message and never crashes the app
  • Lua actions route through high-level App methods, never raw IoEvents

Verification

  • cargo clippy/cargo test green on both telemetry,scripting (343 tests) and slim telemetry (251 tests)
  • Manually TUI-tested end to end (events, commands, installer lifecycle, all examples)

Adds a plugin-facing domain facade (src/core/plugin_api.rs) with
serde-serializable snapshots (PlaybackState, TrackInfo, DeviceInfo,
PlaylistInfo); rspotify types never cross the plugin boundary.

Embeds a Lua 5.4 engine (mlua, vendored) behind the new `scripting`
default feature. Loads ~/.config/spotatui/init.lua and plugins/*.lua,
exposes a curated spotatui.* API (reads, actions, event hooks for
start/quit/track_change/playback_state_change/seek/volume_change/
queue_change). Actions route through the same App methods as
keybindings so native-streaming fast paths are honored. Plugin errors
are panic-safe, one-strike disabled, and surface as error-priority
status messages that normal notifications cannot clobber. Slim CI
build stays mlua-free.
spotatui.http_get/http_post spawn requests on the tokio runtime and
deliver results back to the engine over a channel drained each tick;
callbacks are one-shot, attributed to their plugin, and error-contained.
spotatui.json_decode/json_encode wrap serde. API version 2 -> 3.
- Load directory plugins (plugins/<name>/main.lua, fallback init.lua) with
  the plugin's own folder on package.path for require()
- Add 'spotatui plugin' CLI (add/list/remove/update) backed by a git clone
  and a plugins.lock lockfile; gated behind the scripting feature
- Ship example plugins under examples/plugins/ and a PLUGINS.md index
- Document install/authoring flow in docs/scripting.md
- spotatui.require_api(n) fails a plugin load with a clear "requires API vN"
  message when the build is too old, instead of a cryptic nil-call error
- Bump scripting API_VERSION 3 -> 4
- Add a Trust and safety section (plugins are unsandboxed) to the docs
- Add `spotatui plugin new <name>` to scaffold a working directory plugin
- Document the `spotatui-plugin` GitHub topic for discovery
@LargeModGames LargeModGames merged commit bf1bba3 into main Jun 12, 2026
9 checks passed
@LargeModGames LargeModGames deleted the lua-scripting branch June 12, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant