feat(plugins): wire plugin system into app initialization

- Add plugin system bootstrap in renderer.js after sidebar/commands init
- Wire status bar DOM insertion, editor API, and IPC adapters
- Add plugin-settings:get/set IPC channels to preload allowlist
- Add IPC handlers in main process using existing settings store
- Fix eqeqeq warning in EventBus.hasHandler

Amit Haridas
This commit is contained in:
2026-04-23 22:55:12 +05:30
parent b5771dd914
commit 539502d7ff
4 changed files with 66 additions and 2 deletions
+8
View File
@@ -283,6 +283,14 @@ const store = {
}
};
// Plugin settings IPC handlers
ipcMain.handle('plugin-settings:get', (_event, key) => {
return store.get(key);
});
ipcMain.handle('plugin-settings:set', (_event, { key, value }) => {
store.set(key, value);
});
let mainWindow;
let currentFile = null; // This will now represent the active tab's file
let pandocAvailable = null; // Cache pandoc availability check
+1 -1
View File
@@ -36,7 +36,7 @@ class EventBus {
hasHandler(event) {
const handlers = this.listeners.get(event);
return handlers != null && handlers.length > 0;
return handlers !== undefined && handlers !== null && handlers.length > 0;
}
}
+5 -1
View File
@@ -135,7 +135,11 @@ const ALLOWED_SEND_CHANNELS = [
'export',
// Git diff
'git-diff'
'git-diff',
// Plugin settings
'plugin-settings:get',
'plugin-settings:set'
];
const ALLOWED_RECEIVE_CHANNELS = [
+52
View File
@@ -1545,6 +1545,58 @@ document.addEventListener('DOMContentLoaded', () => {
}
});
// --- Plugin System ---
const { PluginLoader } = require('./plugins/plugin-loader');
const { PluginRegistry } = require('./plugins/plugin-registry');
const { EventBus } = require('./plugins/event-bus');
const { SettingsStore } = require('./plugins/settings-store');
const pluginPath = require('path');
const pluginEventBus = new EventBus();
const pluginSettings = new SettingsStore({
get: (key) => window.electronAPI.invoke('plugin-settings:get', key),
set: (key, value) => window.electronAPI.invoke('plugin-settings:set', { key, value })
});
const statusBarRight = document.querySelector('.status-bar-right');
const pluginRegistry = new PluginRegistry({
sidebar: sidebarManager,
commands: commandPalette,
statusBar: {
registerIndicator: (id, opts) => {
const el = document.createElement('span');
el.className = 'status-item';
el.id = `plugin-status-${id}`;
if (opts.tooltip) el.title = opts.tooltip;
el.textContent = opts.text || '';
const sep = document.createElement('span');
sep.className = 'status-separator';
sep.textContent = '|';
if (statusBarRight) {
statusBarRight.appendChild(sep);
statusBarRight.appendChild(el);
}
}
},
eventBus: pluginEventBus,
settings: pluginSettings,
editor: {
getContent: () => tabManager.getCurrentContent(),
getSelection: () => tabManager.getSelection(),
insertAtCursor: (text) => tabManager.insertAtCursor(text),
onContentChanged: (cb) => pluginEventBus.on('document:changed', cb)
},
ipc: {
invoke: (ch, data) => window.electronAPI.invoke(ch, data),
on: (ch, cb) => window.electronAPI.on(ch, cb)
}
});
const builtInDir = pluginPath.join(__dirname, 'plugins', 'built-in');
const loader = new PluginLoader([builtInDir]);
const discovered = loader.discoverPlugins();
discovered.forEach(p => pluginRegistry.register(p));
// Initialize Zen Mode
const ZenModeClass = getZenMode();
const zenMode = new ZenModeClass(tabManager);