Plugin development Explanation

Plugin overview

How Muxie's plugin system works: hot-loadable plugins, the hook and slot extension surfaces, and the core plugins built on them.

Muxie is extensible through plugins. A plugin can add command-palette commands, sidebar buttons, dock panels, per-pane banners, whole pane-tabs, and react to lifecycle events across the app — using the same machinery the built-in features are built on.

Everything is hot

There is no plugin build step you have to ship through and no restart to apply changes. Install, enable, disable, uninstall, and reload all happen live: the running app loads and unloads plugin code on the fly. You manage plugins in Settings → Plugins, which offers enable toggles, Install from folder…, and Reload / Uninstall for installed plugins.

This liveness is the central design constraint: any extension surface a plugin touches has to be safe to add and remove at runtime. That’s what shapes the three APIs below.

Core plugins use the same system

The features that ship with Muxie — Sprites, SSH, Agents, and Welcome & What’s New — are themselves plugins. They live under src/plugins/<id>/, register through the same plugin contexts, and the Plugins page can toggle them live just like a third-party plugin. There is no privileged “built-in” path that your plugins can’t reach; the core simply bundles its plugins instead of installing them from a folder.

The extension surfaces

A plugin extends Muxie through three kinds of API, plus pane surfaces:

  • Hooks — typed lifecycle events you subscribe to. A main-process hook fires on things like a session spawning or the GPU recovering; a renderer hook fires on UI moments like a tab activating or the theme changing. See the Hook catalog.
  • Slots — named places in the UI where you contribute interface: the rail, the command palette, settings, dock panels, pane banners, the terminal right-click menu, the + New dropdown, and more. See the Slot catalog.
  • Context APIs — everything else handed to your plugin on the ctx object: logging, IPC between your main and renderer halves, config and storage access, raw terminal byte streams, and the tab-close interceptor. See Main-process context and Renderer context.
  • Pane surfaces — render an entire workspace pane-tab that splits, moves, and persists like any other tab. See Pane surfaces & panels.

The hot-unload invariant

Because plugins load and unload at runtime, every registration a plugin makes through ctx (hooks, slots, commands, IPC handlers, surfaces, interceptors) is tracked and disposed automatically when the plugin deactivates. That is what makes live disable / uninstall / reload safe: nothing a plugin added lingers after it goes away. The rule for plugin authors is simple — register only through ctx, and wrap any ad-hoc cleanup of your own with ctx.track({ dispose }) so it’s torn down with the rest.

Security in one paragraph

Plugins are trusted code (the Obsidian / VS Code model). A plugin’s main-process entry runs with full Node access; its renderer entry runs inside the app’s CSP and is served only over the privileged muxie-plugin:// scheme, which keeps remote and eval’d code blocked and refuses paths outside the plugin’s own directory. Only install plugins you trust. See the Security model for the full picture.

Next steps

Start with the Plugin quickstart to build a working plugin in a few minutes, then use the reference pages — the Hook catalog, the Slot catalog, the context pages, and Pane surfaces & panels — as you grow it.