Conversation
|
Hello, this is a pretty cool feature, but I think it would need to be implemented as a global plugin system. With such a system, you could not only use custom items, but also add new settings, change the menu layout, etc. That said, this is just my personal opinion. For a deeper analysis, you would need @Schneegans help. |
|
Hi @yar2000T , |
|
Thanks a ton for the initiative! Yet, overall, I am a bit hesitant. I think this adds something to Kando which is really not in it's scope. Kando is a pie menu, not a framework to build apps on top. Why should these plugins be part of Kando? Is there any benefit from being part of Kando (except for using the same technology stack, which is not really a good reason)? Because something can be done it does not necessarily should be done. I think, the functionality you suggest is 100% decoupled from Kando. Yet it introduces several thousands lines of code which need to maintained and which potentially bring bugs and security issues. In my opinion, it would be much better to put the functionality you are envisioning here into a separate (electron?) app. Then you could simply use ordinary run-command items in Kando to open this separate app. Something like That being said, I think Kando does indeed need a plugin system. Yet this should bring the possibility to augment the possibilities of the menu itself and not display websites on top. Kando Plugins (as I imagine them)Currently, we have a fixed set of menu items. In my opinion, the main purpose of plugins should be to add new menu-item types which are designed for a very specific purpose or which are platform-dependent. Like for instance a submenu which automatically lists all running applications on Windows. Or a submenu which shows all dock items on macOS. Or items which interact via some sort of IPC mechanism with some specific applications which can not easily be controlled via simulated keyboard shortcuts. We could even think about menu item types which are not only simple buttons. We should have checkbox-like items, sliders for numeric input, maybe color choosers or date pickers. But I'm not sure whether those should come in the form of plugins or rather in core Kando as they will need to be themed by menu themes. What do you think? Do you understand my point? |
Personally, I love idea about a plugins folder next to the menu themes folder, in which i can paste folders with code (typescript) and config file which defines properties of plugin (name, version, author, kando version). It will be loaded on start. I dont really know if its possible to side load code. |
|
It can be plugins like in flow launcher |
|
Hi @Schneegans , @yar2000T , Thank you very much for your feedback. I've started to develop some extensions to ease repetitive activities I'm doing at work and found out that the only way to add these additional functionalities was by creating a thin mini-apps in c++, compile them to exe and "run" them with Kando. A different ability I wanted to add is the ability to communicate with other web services via REST API commands, fetching information from external data sources and presenting them to the user. For example stock exchange information. I soon found out that creating separate exe for each functions didn't make sense, especially if I wanted the applications to have a nice and modern UI. Application size grew significantly, I had to suffer long loading times that resulted from loading the whole framework. The ability of Electron to run separate application on different threads while avoiding loading times as both chromium and the backend are already initialized seemed as a very interesting approach. While the first phase only loads html my final goal is to enable the Kando launch custom Electron applications on separate threads. I expect such functionality to be very attractive to many new users and will be happy to help on the definition, programming and testing. With regards to the exact implementation of the plugins I'm not sure that html plugins are indeed the optimal approach however this was just for me to be able to quickly test the infrastructures. To summarize, my main question is whether you be interested in enabling external plugins system to Kando allowing users to run Electron native mini-apps that will be able to communicate with external applications and databases ? Regards, |
|
Thank you so much for your elaborate response! Your vision is now much clearer to me. Yet I still think that these apps are not really plugins in the traditional sense, as they don't extend Kando itself, but rather run alongside it. In fact, I think the only reason to make them "plugins" is to leverage Kando's existing infrastructure (e.g. Electron runtime) which may reduce loading times and memory usage. But at the same time, this also means that these apps would be tightly coupled to Kando, and need to be updated when electron changes... Let's take a step back and consider the bigger picture, without focusing too much on the runtime. What if those apps were just standalone commandline tools that users drop into a "kando-apps" folder next to the "menu-themes" and "icon-themes"? We would define a metadata format (e.g. JSON) that describes the app's name, description, input parameters (like user-configurable options or context information like the clipboard content). Then Kando could be extended with a menu item that lists all discovered apps the same way it lists plugins in your current implementation. We could create a new repository called "Kando Apps" with some example apps. The awesome thing about this approach is that these apps would not be tied to Kando at all, and could potentially be used by other launchers or even run standalone! This could potentially widen the user base and attract more developers to create apps for Kando. And it would be even simpler to create them using AI :) Now back to the runtime question. I think it would be best to not force a specific runtime like Electron on these apps. Instead, the only requirement would be that they can be executed from the commandline. This way, developers could choose whatever technology they prefer (e.g. Python scripts, Node.js apps, compiled binaries, etc.). Kando would just need to handle launching them and passing the necessary input parameters. Either via commandline arguments or environment variables. Only problem I see with this approach is that showing a custom UI for the apps would be more challenging, but definitely not impossible. I guess in many cases, no UI would be needed at all. And a simple message dialog will be supportable by most scripting languages. What do you think about this idea? |
|
Hi Simon, Yar, Nevertheless we will need to have some kind of mechanism within Kando that will enable designers to write mini-apps that will be able to run efficiently. I'm not sure that the current "Run command" will be sufficient as many of the mini-apps will want to address content that is being shown on the active window. In the example above of an AI agent that helps rephrase text a user will need to copy the text and send it along with a prompt through RESTI API and present the respond in separate window. While it's easy to create a small app that will trigger the "clipboard copy" command and process it, the part that takes relatively long time is to initiate a modern user interface, especially if we would like to design a cross-platform app. We will probably need open text fields like "URI", "Auth Token", "Prompt" that can be defined on the json scheme. Would you like to add an option for running Kando app that will receive a json in the format that we will define and parse the parameters for the CLI app ? Another approach could be to ask the designer to just pack everything in one exe - maybe like a Tauri app that will be called through the "Run command" feature and ask him to take care of all the rest. The drawback on this approach is that it will be less flexible to configure. Regards, |
|
Hi Simon, I fully understood your first part and agree that each Kando-app should have it's own json manifest. For example: kando-plugin.json Nevertheless, even this approach doesn't really resolve the full use case we started discussing above of having a sufficiently flexible plugin engine to allow users to easily create an Ollama plugin. After selecting the Kando-Ollama app on the configuration menu the user will need to define the URI, then we will want to send a cmd like "Ollama list" to retrieve all the currently installed models and allow the user to select one for the current menu item along with a prompt open-text field. To summarize, I want to think of it a bit more... Regards, |
|
Thanks for your thoughts! I think we are mostly on the same page, but there are a few differences in our approaches. The most important one is that I hope that we can make these plugins powerful enough without adding the possibility to create custom windows with custom UI. In my opinion, this would go way beyond the original vision of Kando as a simple, fast, and efficient menu system. I fear that if we allow plugins to create custom windows, we would end up with a situation where every plugin creates its own UI and user experience, which could lead to a very inconsistent and fragmented user experience. And most importantly, efficiency and speed are core to Kando's vision. Kando actions should be things that you do dozens maybe even hundreds of times a day. So it's not a good idea if an action opens a new window where you have to press another button or to copy something to the clipboard. This is 100% against the idea of having a seamless and efficient workflow. So the ideal plugin in my vision would be something that you configure once, and then it just works with a single click in the menu. For instance, the Ollama plugin could be configured to take the currently selected text, send it to Ollama with a predefined prompt, and then automatically copy the result to the clipboard and show a notification once it's done. No additional windows, no additional clicks, just a seamless extension of the menu's functionality. Of course, there might be some use cases where some additional UI is necessary, but I think we should try to avoid this as much as possible. The architecture I proposed with the JSON manifest and environment variables should be powerful enough to open custom dialogs if really needed. But the main focus should be on creating plugins that work seamlessly within the existing menu structure without the need for additional windows or complex interactions. I think many use-cases could be addressed with the approach I outlined above. However, the model list which you mentioned for the Ollama plugin is indeed a tricky thing. I think the only solution would be a free-formed text field where the user can enter the model name. Alternatively we would need plugin code to generate the menu-item configuration UI dynamically and this would add a lot of complexity to the plugin system. So I would prefer to avoid this if possible. I think 90% of the use-cases will be covered with the JSON manifest listing predefined options. What do you think about this? Is my idea mostly clear? Else I could try to explain it in more detail. |
|
Hi Simon, I think that we're aligned regarding the JSON manifest functionality. By the way, it will be possible to implement the Ollama functionality above either with python support or worst case scenario I can create a small Tauri executable and just invoke it with the "Run" command. Let me know what you want to do, Regards, |


Kando Plugin System - Implementation Status
Live Documentation of All Changes
Overview
This document tracks all implementation changes made to integrate the Plugin System into Kando. It serves as a comprehensive guide for completing the fork and submitting a PR.

✅ Phase 1: Core Infrastructure (COMPLETE)
1. Plugin Manifest Parser
File:
src/common/plugin-manifest.tsStatus: ✅ Implemented
Provides TypeScript interfaces and validation:
IPluginManifest- Main manifest interfaceIPluginWindowConfig- BrowserWindow configurationIPluginParameter- Union type for all parameter typesIPluginParameterString,IPluginParameterNumber,IPluginParameterBoolean,IPluginParameterSelect,IPluginParameterFile,IPluginParameterFolder,IPluginParameterPasswordvalidateManifest(json)- Validates manifest structuregetWindowConfigWithDefaults()- Applies default window settingsDEFAULT_WINDOW_CONFIG- Sensible defaults for plugin windows2. Plugin Manager
File:
src/main/plugins/plugin-manager.tsStatus: ✅ Implemented
Core plugin management singleton:
getInstance()- Singleton accessgetPluginsDirectory()- Platform-specific path resolution%APPDATA%/kando/plugins/~/Library/Application Support/kando/plugins/~/.config/kando/plugins/scanPlugins()- Discovers and validates all plugin foldersvalidatePlugin(path)- Checks manifest and required filesgetPluginManifest(id)- Returns parsed manifestimportPluginFromZip(zipPath)- Extracts and validates ZIPremovePlugin(id)- Deletes plugin foldergetPluginConfig(id)- Loads user configurationsavePluginConfig(id, config)- Persists user configuration3. Plugin Config Storage
File:
src/main/plugins/plugin-config-store.tsStatus: ✅ Implemented
Stores user-defined parameter values:
~/.config/kando/plugin-configs/{plugin-id}.jsonloadConfig(pluginId)- Load with defaults from manifestsaveConfig(pluginId, config)- Persist configurationvalidateConfig(config, manifest)- Validate against schema4. ZIP Handler Utility
File:
src/main/plugins/zip-handler.tsStatus: ✅ Implemented
Dependency:
adm-zip(must be installed in Kando)ZIP file operations:
extractZip(zipPath, destFolder)- Extract ZIP contentsvalidateZipContents(zipPath)- Check for manifest before extractinglistZipContents(zipPath)- List all files in ZIPreadFileFromZip(zipPath, filePath)- Read specific file without extraction5. Plugin Item Type
File:
src/common/item-types/plugin-item-type.tsStatus: ✅ Implemented
Defines the "plugin" item type for Kando menus:
typeId:'plugin'defaultName:'Plugin'defaultIcon:'extension'defaultIconTheme:'material-symbols-rounded'PluginItemData:{ pluginId: string }6. Plugin Item Action
File:
src/main/item-actions/plugin-item-action.tsStatus: ✅ Implemented
Executes plugins when triggered from menu:
ItemActioninterfaceexecute(item)- Main execution methoddelayedExecution()- Returnsfalsefor immediate launchBrowserWindowwith manifest settingsadditionalArguments7. IPC Handlers
File:
src/main/plugins/ipc-handlers.tsStatus: ✅ Implemented
Bridges main process to renderer:
plugins:get-list- Returns list of installed pluginsplugins:import- Imports plugin from ZIP pathplugins:remove- Removes installed pluginplugins:get-config- Gets plugin configurationplugins:save-config- Saves plugin configurationregisterPluginIPCHandlers()- Registration function8. Module Exports
File:
src/main/plugins/index.tsStatus: ✅ Implemented
Exports all plugin system components:
File:
src/common/index.tsStatus: ✅ Implemented
Exports common types:
✅ Registration Changes (COMPLETE)
Item Type Registry
File:
src/common/item-type-registry.tsRequired Change:
Item Action Registry
File:
src/main/item-action-registry.tsRequired Change:
Main Process Initialization
File:
src/main/index.tsRequired Change:
✅ Phase 2: Settings UI (IN PROGRESS)
1. Settings Window API Extension
File:
src/settings-renderer/settings-window-api.tsRequired Addition to
SETTINGS_WINDOW_API:2. Plugin Item Config Component
File:
src/settings-renderer/components/menu-properties/item-configs/PluginItemConfig.tsxStatus: ✅ Implemented
Key Implementation Notes:
PluginTipwrapper to avoid crashes if nativeRandomTipfails3. Item Config Registry Update
File:
src/settings-renderer/components/menu-properties/item-configs/index.tsxRequired Change:
4. CSS Fix for Toolbar Alignment
File:
src/settings-renderer/components/menu-preview/PreviewFooter.module.scssStatus: ✅ Fix Identified
Problem: The 10th item (plugin icon) wraps to a new line due to fixed-width constraints.
Solution: Update
.newItemsto use Flexbox:✅ Localization (COMPLETE)
Translation Keys
File:
locales/en/translation.jsonRequired Addition:
{ "menu-items": { "plugin": { "name": "Plugin", "description": "Execute an external plugin application.", "placeholder": "Select a plugin...", "loading": "Loading plugins...", "no-plugins": "No plugins installed. Import a plugin ZIP file to get started.", "tip-1": "Plugins extend Kando with custom functionality.", "tip-2": "You can import plugins from ZIP files.", "tip-3": "Each plugin runs in its own isolated window." } } }Note: RandomTip component expects numbered keys (
tip-1,tip-2,tip-3), NOT atipsarray.📦 Dependencies
Required npm Packages
adm-zip@types/adm-zipInstall in Kando:
🧪 Test Plugin
Hello World Plugin
Location:
docs/test-plugins/hello-world/Files:
kando-plugin.json- Manifest with sample parametersindex.html- Simple test UIInstallation Path (Windows):
📁 File Summary
src/common/plugin-manifest.tssrc/common/item-types/plugin-item-type.tssrc/common/index.tssrc/main/plugins/plugin-manager.tssrc/main/plugins/plugin-config-store.tssrc/main/plugins/zip-handler.tssrc/main/plugins/ipc-handlers.tssrc/main/plugins/index.tssrc/main/item-actions/plugin-item-action.tssrc/common/item-type-registry.tssrc/main/item-action-registry.tssrc/main/index.tssrc/settings-renderer/settings-window-api.tssrc/settings-renderer/.../PluginItemConfig.tsxsrc/settings-renderer/.../item-configs/index.tsxsrc/settings-renderer/.../PreviewFooter.module.scsslocales/en/translation.json🔒 Security Model
nodeIntegration: falseby defaultcontextIsolation: trueby default🐛 Known Issues & Solutions
Issue: Settings window grey/blank screen
Cause: React hooks called conditionally, breaking Rules of Hooks
Solution: Move ALL useState/useEffect to top of component, before any conditional returns
Issue: Plugin icon not aligned in toolbar
Cause: CSS grid/inline-block constraints limiting to 9 items
Solution: Change
.newItemsto flexbox layoutIssue: RandomTip crashes with plugin tips
Cause: Component expects
tip-1,tip-2keys, not arraySolution: Use numbered keys in translation.json
🚀 Next Steps