ソース情報
- リポジトリ
- tomevault-io/tomes
- ソースの最終更新活動
- 2026年7月23日 21:48
- 検出された SKILL.md の言語
- 英語
- スター
- 1
- フォーク
- 0
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
メニュー
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/tomevault-io/tomes --skill dms-plugin-devコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
> Use when this capability is needed.
Use when writing kernel, account, or note MASM code that reads from or writes to the advice provider (advice stack / advice map) — validate advice data.
Use when writing a Rust test that exercises a failure path or a MASM test that expects a `panic` / `assert` — assert on the specific expected error variant or error code.
SOC 職業分類に基づく
SKILL.md を表示中
| name | dms-plugin-dev |
| description | > Use when this capability is needed. |
DMS plugins extend the desktop shell with custom widgets, background services, launcher
integrations, and desktop widgets. Plugins are QML components discovered from
~/.config/DankMaterialShell/plugins/.
Minimum plugin structure:
~/.config/DankMaterialShell/plugins/YourPlugin/
plugin.json # Required: manifest with metadata
YourComponent.qml # Required: main QML component
YourSettings.qml # Optional: settings UI
*.js # Optional: JavaScript utilities
Plugin registry: Community plugins are available at https://plugins.danklinux.com/
Four plugin types:
| Type | Purpose | Base Component | Bar pills | CC integration |
|---|---|---|---|---|
widget | Bar widget + popout | PluginComponent | Yes | Yes |
daemon | Background service | PluginComponent (no UI) | No | Optional |
launcher | Searchable items in launcher | Item | No | No |
desktop | Draggable desktop widget | DesktopPluginComponent | No | No |
Choose the type based on what the plugin does:
widget. Displays a pill in DankBar, optionally opens a popout,
optionally integrates with Control Center.daemon. No visible UI, reacts to events (wallpaper
changes, notifications, battery level, etc.).launcher. Items appear in the DMS launcher
with trigger-based filtering (e.g., type = for calculator, : for emoji).desktop. Draggable, resizable widget on the
desktop layer.Create plugin.json in your plugin directory. See plugin-manifest-reference.md for the full schema.
Minimal manifest:
{
"id": "yourPlugin",
"name": "Your Plugin Name",
"description": "Brief description of what your plugin does",
"version": "1.0.0",
"author": "Your Name",
"type": "widget",
"capabilities": ["your-capability"],
"component": "./YourWidget.qml"
}
With settings and permissions:
{
"id": "yourPlugin",
"name": "Your Plugin Name",
"description": "Brief description",
"version": "1.0.0",
"author": "Your Name",
"type": "widget",
"capabilities": ["your-capability"],
"component": "./YourWidget.qml",
"icon": "extension",
"settings": "./Settings.qml",
"requires_dms": ">=0.1.0",
"permissions": ["settings_read", "settings_write"]
}
Key rules:
id must be camelCase, matching pattern ^[a-zA-Z][a-zA-Z0-9]*$version must be semver (e.g., 1.0.0)component must start with ./ and end with .qmltype: "launcher" requires a trigger fieldsettings_write permission is required if the plugin has a settings componentimport QtQuick
import qs.Common
import qs.Widgets
import qs.Modules.Plugins
PluginComponent {
property var popoutService: null
horizontalBarPill: Component {
StyledRect {
width: label.implicitWidth + Theme.spacingM * 2
height: parent.widgetThickness
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
StyledText {
id: label
anchors.centerIn: parent
text: "Hello"
color: Theme.surfaceText
font.pixelSize: Theme.fontSizeMedium
}
}
}
verticalBarPill: Component {
StyledRect {
width: parent.widgetThickness
height: label.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
StyledText {
id: label
anchors.centerIn: parent
text: "Hi"
color: Theme.surfaceText
font.pixelSize: Theme.fontSizeSmall
rotation: 90
}
}
}
}
See widget-plugin-guide.md for popouts, CC integration, and advanced features.
import QtQuick
import qs.Services
Item {
id: root
property var pluginService: null
property string trigger: "#"
signal itemsChanged()
function getItems(query) {
const items = [
{ name: "Item One", icon: "material:star", comment: "Description",
action: "toast:Hello!", categories: ["MyPlugin"] }
]
if (!query) return items
const q = query.toLowerCase()
return items.filter(i => i.name.toLowerCase().includes(q))
}
function executeItem(item) {
const [type, ...rest] = item.action.split(":")
const data = rest.join(":")
if (type === "toast") ToastService?.showInfo(data)
else if (type === "copy") Quickshell.execDetached(["dms", "cl", "copy", data])
}
}
See launcher-plugin-guide.md for triggers, icon types, context menus, and image tiles.
import QtQuick
import qs.Common
Item {
id: root
property var pluginService: null
property string pluginId: ""
property bool editMode: false
property real widgetWidth: 200
property real widgetHeight: 200
property real minWidth: 150
property real minHeight: 150
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: Theme.surfaceContainer
opacity: 0.85
border.color: root.editMode ? Theme.primary : "transparent"
border.width: root.editMode ? 2 : 0
Text {
anchors.centerIn: parent
text: "Desktop Widget"
color: Theme.surfaceText
}
}
}
See desktop-plugin-guide.md for sizing, persistence, and edit mode.
import QtQuick
import qs.Common
import qs.Services
import qs.Modules.Plugins
PluginComponent {
property var popoutService: null
Connections {
target: SessionData
function onSomeSignal() {
console.log("Event received")
}
}
}
See daemon-plugin-guide.md for event-driven patterns and process execution.
Wrap settings in PluginSettings with your pluginId. All settings auto-save and auto-load.
import QtQuick
import qs.Common
import qs.Widgets
import qs.Modules.Plugins
PluginSettings {
pluginId: "yourPlugin"
StringSetting {
settingKey: "apiKey"
label: "API Key"
description: "Your API key"
placeholder: "sk-..."
}
ToggleSetting {
settingKey: "enabled"
label: "Enable Feature"
defaultValue: true
}
SelectionSetting {
settingKey: "interval"
label: "Refresh Interval"
options: [
{ label: "1 min", value: "60" },
{ label: "5 min", value: "300" }
]
defaultValue: "300"
}
}
Available setting components: StringSetting, ToggleSetting, SelectionSetting, SliderSetting, ColorSetting, ListSetting, ListSettingWithInput.
See settings-components-reference.md for full property lists.
Important: Your plugin must declare "permissions": ["settings_write"] in plugin.json, or the settings UI will show an error.
Three tiers of persistence:
| API | Persisted | Use case |
|---|---|---|
pluginService.savePluginData(id, key, val) / loadPluginData(id, key, default) | Yes (settings.json) | User preferences, config |
pluginService.savePluginState(id, key, val) / loadPluginState(id, key, default) | Yes (separate state file) | Runtime state, history, cache |
PluginGlobalVar { varName; defaultValue; value; set() } | No (runtime only) | Cross-instance shared state |
pluginData is a reactive property on PluginComponent, auto-loaded from settingsConnections { target: pluginService; function onPluginDataChanged(id) { ... } }See data-persistence-guide.md for details and examples.
Always use Theme.* properties from qs.Common - never hardcode colors or sizes.
Essential properties:
Theme.surfaceContainerHigh, Theme.surfaceText, Theme.primary, Theme.onPrimaryTheme.fontSizeSmall (12), Theme.fontSizeMedium (14), Theme.fontSizeLarge (16), Theme.fontSizeXLarge (20)Theme.spacingXS, Theme.spacingS, Theme.spacingM, Theme.spacingL, Theme.spacingXLTheme.cornerRadius, Theme.cornerRadiusSmall, Theme.cornerRadiusLargeTheme.iconSizeSmall (16), Theme.iconSize (24), Theme.iconSizeLarge (32)Common widgets from qs.Widgets: StyledText, StyledRect, DankIcon, DankButton, DankToggle, DankTextField, DankSlider, DankGridView, CachingImage.
See theme-reference.md for the complete property list.
Add a popout that opens when the bar pill is clicked:
PluginComponent {
popoutWidth: 400
popoutHeight: 300
popoutContent: Component {
PopoutComponent {
headerText: "My Plugin"
detailsText: "Optional subtitle"
showCloseButton: true
Column {
width: parent.width
spacing: Theme.spacingM
StyledText {
text: "Content here"
color: Theme.surfaceText
}
}
}
}
horizontalBarPill: Component { /* ... */ }
verticalBarPill: Component { /* ... */ }
}
PopoutComponent properties: headerText, detailsText, showCloseButton, closePopout() (auto-injected), headerHeight (readonly), detailsHeight (readonly).
Calculate available content height: popoutHeight - headerHeight - detailsHeight - spacing
Add your widget to the Control Center grid:
PluginComponent {
ccWidgetIcon: "toggle_on"
ccWidgetPrimaryText: "My Feature"
ccWidgetSecondaryText: isActive ? "On" : "Off"
ccWidgetIsActive: isActive
onCcWidgetToggled: {
isActive = !isActive
pluginService?.savePluginData(pluginId, "active", isActive)
}
// Optional: expandable detail panel (for CompoundPill)
ccDetailContent: Component {
Rectangle {
implicitHeight: 200
color: Theme.surfaceContainerHigh
radius: Theme.cornerRadius
}
}
}
CC sizing: 25% width = SmallToggleButton (icon only), 50% width = ToggleButton or CompoundPill (if ccDetailContent is defined).
Run commands and capture output:
import qs.Common
Proc.runCommand(
"myPlugin.fetch",
["curl", "-s", "https://api.example.com/data"],
(stdout, exitCode) => {
if (exitCode === 0) processData(stdout)
},
500 // debounce ms
)
Fire-and-forget (clipboard, notifications):
import Quickshell
Quickshell.execDetached(["dms", "cl", "copy", textToCopy])
Long-running processes: Use the Process QML component from Quickshell.Io with StdioCollector.
Shell commands with pipes: ["sh", "-c", "ps aux | grep foo"]
Do NOT use globalThis.clipboard or browser JavaScript APIs - they don't exist in the QML runtime.
plugin.json against the schema at assets/plugin-schema.jsonqs -v -p $CONFIGPATH/quickshell/dms/shell.qmlCommon issues:
jq . plugin.jsonsettings_write permission is declaredsettings_write permission - Settings UI shows error without itproperty var popoutService: null - Must declare for injection to workTheme.* properties, not hex valuesglobalThis.clipboard - Does not exist; use Quickshell.execDetached(["dms", "cl", "copy", text])Theme.fontSizeS does not exist, use Theme.fontSizeSmallimport Quickshell (not import QtQuick for execDetached)categories in launcher items - Items won't display without itPluginComponent for launchers - Launchers use plain Item, not PluginComponentWidget / Daemon:
import QtQuick
import qs.Common
import qs.Widgets
import qs.Modules.Plugins
Launcher:
import QtQuick
import qs.Services
Desktop:
import QtQuick
import qs.Common
For clipboard/exec: import Quickshell
For processes: import Quickshell.Io
For networking: import Quickshell.Networking
For toast notifications: access ToastService from qs.Services
MyAwesomePlugin/)myAwesomePlugin)MyWidget.qml, Settings.qml)./ prefix (e.g., "./MyWidget.qml")utils.js, apiAdapter.js)Load these on demand for detailed API documentation:
Source: AvengeMedia/DankMaterialShell — distributed by TomeVault.