Add plugin system with sample plugin and settings UI

Introduces a plugin architecture, including a PluginManager, plugin loading in main and renderer processes, and a sample plugin demonstrating menu, IPC, and context menu contributions. Adds a Plugins tab to the settings UI for managing plugins (enable/disable, reload), and updates preload.js to load renderer preloads from plugins. Documentation for plugin development is included in README-PLUGINS.md.
This commit is contained in:
2025-09-08 19:10:05 +12:00
parent 62810fcb89
commit e228ca6317
11 changed files with 576 additions and 2 deletions
+43
View File
@@ -0,0 +1,43 @@
// Sample main-process side of a plugin
module.exports.activate = function(ctx) {
ctx.log('activating');
// Add a simple menu item under Help
try {
const template = ctx.Menu.getApplicationMenu()?.items?.map(mi => mi);
if (template) {
const help = template.find(i => /help/i.test(i.label || ''));
const insertInto = help || template[template.length - 1];
if (insertInto && insertInto.submenu) {
insertInto.submenu.append(new ctx.Menu.MenuItem({
label: 'Say Hello (Sample Plugin)',
click: () => {
const win = ctx.BrowserWindow.getFocusedWindow();
if (win) win.webContents.send('sample-hello', { msg: 'Hello from plugin!' });
}
}));
ctx.Menu.setApplicationMenu(ctx.Menu.getApplicationMenu());
}
}
} catch (e) { ctx.warn('menu injection skipped', e); }
// Simple IPC example
ctx.registerIPC('sample-hello:ping', async () => ({ pong: true }));
// Optional: intercept a request (no-op demo)
ctx.registerWebRequest({ urls: ['*://*/*'] }, (details) => {
// Could cancel or redirect here, but we let it pass through
return { cancel: false };
});
// Context menu contribution example
ctx.contributeContextMenu?.((template, params, sender) => {
template.push({ type: 'separator' });
template.push({
label: 'Sample: Greet Console',
click: () => {
try { (sender.hostWebContents || sender).executeJavaScript("console.log('[Sample Plugin] Hello from context menu')"); } catch {}
}
});
});
};
+9
View File
@@ -0,0 +1,9 @@
{
"id": "sample-hello",
"name": "Sample Hello Plugin",
"version": "0.1.0",
"description": "Demonstrates Nebula plugin basics: add menu item and renderer API.",
"main": "main.js",
"rendererPreload": "renderer-preload.js",
"enabled": false
}
+8
View File
@@ -0,0 +1,8 @@
// Renderer preload for sample plugin
// You can expose new APIs to the page
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('sampleHello', {
ping: () => ipcRenderer.invoke('sample-hello:ping'),
onHello: (handler) => ipcRenderer.on('sample-hello', (_e, payload) => handler(payload))
});