From b2e08f4ceda6133947bca0ed58d86b73cde0f336 Mon Sep 17 00:00:00 2001 From: tomymaritano Date: Fri, 24 Apr 2026 12:37:24 -0300 Subject: [PATCH 1/2] feat: allow disabling built-in plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously built-in plugins were hardcoded as always enabled with the toggle disabled. Now: - Toggle enabled for built-in plugins (removed disabled={isBuiltIn}) - Built-in enabled state loaded from plugin_registry DB table - onToggle handler wired for built-in plugins (same as community) - App.tsx filters built-in plugins by enabled state before passing to PluginHost — disabled plugins won't load at runtime - State re-checked on plugins:reload event The DB infrastructure (plugin_registry table) and IPC handlers (plugins:setEnabled/isEnabled) already existed but were unused. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/desktop/src/renderer/App.tsx | 30 ++++++++++++++++++- .../settings/sections/plugins/PluginCard.tsx | 1 - .../pages/settings/sections/plugins/index.tsx | 16 ++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/renderer/App.tsx b/apps/desktop/src/renderer/App.tsx index 78c096c4..8ed4acbf 100644 --- a/apps/desktop/src/renderer/App.tsx +++ b/apps/desktop/src/renderer/App.tsx @@ -438,12 +438,40 @@ function NotesApp() { // Plugin runtime: init once, React observes const discoveredPlugins = useStore(pluginRuntimeStore, s => s.plugins); const pluginErrors = useStore(pluginRuntimeStore, s => s.errors); + const [builtInEnabledMap, setBuiltInEnabledMap] = useState>({}); useEffect(() => { void pluginRuntimeStore.getState().init(); + // Load built-in plugin enabled states + void (async () => { + const stateList = await window.readied.plugins.listState(); + const map: Record = {}; + for (const s of stateList) { + map[s.pluginId] = s.enabled; + } + setBuiltInEnabledMap(map); + })(); + }, []); + + // Re-check built-in enabled state when plugins reload + useEffect(() => { + const handler = () => { + void (async () => { + const stateList = await window.readied.plugins.listState(); + const map: Record = {}; + for (const s of stateList) { + map[s.pluginId] = s.enabled; + } + setBuiltInEnabledMap(map); + })(); + }; + return window.readied.ipc.on('plugins:reload', handler); }, []); - const allPlugins = useMemo(() => [...builtInPlugins, ...discoveredPlugins], [discoveredPlugins]); + const allPlugins = useMemo(() => { + const enabledBuiltIn = builtInPlugins.filter(p => builtInEnabledMap[p.id] !== false); + return [...enabledBuiltIn, ...discoveredPlugins]; + }, [discoveredPlugins, builtInEnabledMap]); const configBridge = useMemo( () => ({ diff --git a/apps/desktop/src/renderer/pages/settings/sections/plugins/PluginCard.tsx b/apps/desktop/src/renderer/pages/settings/sections/plugins/PluginCard.tsx index 9bffbb85..51357077 100644 --- a/apps/desktop/src/renderer/pages/settings/sections/plugins/PluginCard.tsx +++ b/apps/desktop/src/renderer/pages/settings/sections/plugins/PluginCard.tsx @@ -59,7 +59,6 @@ export function PluginCard({ id={`plugin-${name.toLowerCase().replace(/\s+/g, '-')}`} checked={enabled} onChange={checked => onToggle?.(checked)} - disabled={isBuiltIn} /> {!isBuiltIn && onUninstall && (