- Add composite plugin type with multi-surface components field - Add startupCheck manifest field and dependency gating docs - Add IPC runtime plugin discovery commands (plugin-scan target) - Add getPluginPath() to data persistence reference - Document bar reveal visibility optimization for widget plugins - Sync plugin-schema.json with source, add dependencies field - Bump skill version to 1.1
6.7 KiB
Plugin Manifest Reference (plugin.json)
Required Fields
| Field | Type | Description | Validation |
|---|---|---|---|
id |
string | Unique plugin identifier | camelCase, pattern ^[a-zA-Z][a-zA-Z0-9]*$ |
name |
string | Human-readable name | Non-empty |
description |
string | Short description (shown in UI) | Non-empty |
version |
string | Semantic version | Pattern ^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$ |
author |
string | Creator name or email | Non-empty |
type |
string | Plugin type | One of: widget, daemon, launcher, desktop, composite |
capabilities |
array | Plugin capabilities | At least 1 string item |
One of component or components is required (not both):
| Field | Type | Description | Validation |
|---|---|---|---|
component |
string | Path to main QML file (single-surface plugins) | Must start with ./, end with .qml |
components |
object | Map of surface name to QML path (multi-surface plugins) | At least 1 entry; keys: widget, desktop, daemon, launcher |
Conditional Requirements
| Condition | Required Field | Description |
|---|---|---|
type: "launcher" |
trigger |
Trigger string for launcher activation (e.g., =, #, !) |
components has launcher key |
trigger |
Same requirement applies to composite plugins with a launcher surface |
Optional Fields
| Field | Type | Description |
|---|---|---|
icon |
string | Material Design icon name (displayed in plugin list UI) |
settings |
string | Path to settings QML file (must start with ./, end with .qml) |
startupCheck |
string | Path to a QtObject component that gates plugin activation via a check(done) function (must start with ./, end with .qml). See Startup Check section below. |
requires_dms |
string | Minimum DMS version (e.g., >=0.1.18), pattern ^(>=?|<=?|=|>|<)\d+\.\d+\.\d+$ |
dependencies |
array | System tool dependencies (e.g., ["curl", "jq"]). Registry metadata. |
requires |
array | Deprecated alias for dependencies |
permissions |
array | Required permissions |
trigger |
string | Launcher trigger string (required for launcher type) |
Permissions
| Permission | Description | Enforced |
|---|---|---|
settings_read |
Read plugin configuration | No (not currently enforced) |
settings_write |
Write plugin configuration / use PluginSettings | Yes |
process |
Execute system commands | No (not currently enforced) |
network |
Network access | No (not currently enforced) |
If your plugin has a settings component but does not declare settings_write, users will see an error instead of the settings UI.
Capabilities
Capabilities are free-form strings that describe what the plugin does. Common values:
dankbar-widget- general bar widgetcontrol-center- integrates with Control Centermonitoring- system/service monitoringlauncher- launcher search providerdesktop-widget- desktop background widgetai- AI/LLM integrationslideout- uses slideout panel
Startup Check
The startupCheck field points to a non-visual QtObject component that gates plugin activation on dependency checks. The component must expose a check(done) function:
import QtQuick
import qs.Common
QtObject {
function check(done) {
Proc.runCommand("myPlugin.depCheck", ["sh", "-c", "command -v mytool"], (stdout, exitCode) => {
if (exitCode === 0) {
done(null);
return;
}
done({
"title": I18n.tr("mytool is required"),
"details": I18n.tr("Install 'mytool' and re-enable this plugin.")
});
});
}
}
The done callback accepts:
null- allow activation- A string - block with a short error message
{ title, details }- block with a title and expandable details
A synchronous variant (no done parameter, return the result directly) is also supported.
Failed startup checks show a toast error and store the error in pluginService.pluginLoadErrors.
Components (Composite Plugins)
The components field maps surface names to QML paths, allowing a single plugin to register multiple surfaces:
{
"id": "myComposite",
"name": "My Composite Plugin",
"description": "Daemon + widget + desktop from one plugin",
"version": "1.0.0",
"author": "Developer Name",
"type": "composite",
"capabilities": ["daemon", "dankbar-widget", "desktop-widget"],
"icon": "extension",
"components": {
"daemon": "./MyDaemon.qml",
"widget": "./MyBarWidget.qml",
"desktop": "./MyDesktopWidget.qml"
},
"settings": "./Settings.qml",
"permissions": ["settings_read", "settings_write"]
}
Valid surface keys: widget, desktop, daemon, launcher. Provide any subset. Each surface is loaded independently in the appropriate registry.
Complete Example
{
"id": "myPlugin",
"name": "My Plugin",
"description": "A sample plugin demonstrating all fields",
"version": "1.0.0",
"author": "Developer Name",
"type": "widget",
"capabilities": ["dankbar-widget", "control-center"],
"component": "./MyWidget.qml",
"icon": "extension",
"settings": "./Settings.qml",
"startupCheck": "./StartupCheck.qml",
"requires_dms": ">=0.1.18",
"dependencies": ["curl", "jq"],
"permissions": ["settings_read", "settings_write", "process", "network"]
}
Launcher Example
{
"id": "myLauncher",
"name": "My Launcher",
"description": "Search and execute custom actions",
"version": "1.0.0",
"author": "Developer Name",
"type": "launcher",
"capabilities": ["launcher"],
"component": "./MyLauncher.qml",
"trigger": "#",
"icon": "search",
"settings": "./Settings.qml",
"requires_dms": ">=0.1.18",
"permissions": ["settings_read", "settings_write"]
}
JSON Schema
The complete JSON schema is available at assets/plugin-schema.json in this skill. Validate with:
# Using python
python3 -c "
import json, jsonschema
schema = json.load(open('path/to/plugin-schema.json'))
manifest = json.load(open('plugin.json'))
jsonschema.validate(manifest, schema)
print('Valid!')
"
# Using jq (syntax check only)
jq . plugin.json
Additional Properties
The schema allows additional properties ("additionalProperties": true), so plugins can include custom fields. Common custom fields seen in production plugins:
viewMode- launcher display mode ("tile"for image grids)viewModeEnforced- lock launcher to specific view mode (true/false)