dms_tailscalectl/skills/dms-plugin-dev/SKILL.md
vybe 01ac7e9041 feat: add dms-plugin-dev agent skill for Dank Material Shell plugin development
- Introduces a general-purpose opencode skill to help agents build, debug, and publish DMS plugins.
- Includes orientation, decision trees (plugin types), condensed cheat sheets, ecosystem map, and four generic vertical-slice starter templates (bar widget, popout widget, launcher, desktop widget).
- Skill is versioned here for this project while remaining available as a global opencode skill.
- Updated .gitignore to ignore globally-installed copies of the skill.

Written by AI agent working for @jtmorris. Model: grok-build-0.1.
2026-05-24 09:31:06 +00:00

5.9 KiB

name description license compatibility
dms-plugin-dev Guidance, decision trees, cheat sheets, ecosystem map, and generic vertical-slice starter templates for building plugins for Dank Material Shell (DMS / DankMaterialShell) using Quickshell QML. Use when the user asks to create, extend, debug, review, or publish a DMS plugin, or mentions plugin.json, PluginComponent, DankBar widgets, launcher plugins, desktop widgets, or the DMS plugin registry. MIT opencode

DMS Plugin Development

Mental Model (Read This First)

Dank Material Shell plugins are small, self-contained directories dropped into ~/.config/DankMaterialShell/plugins/<YourPluginId>/.

Each plugin declares what it is in plugin.json (type, capabilities, entry component, permissions, dependencies).

The shell discovers them, loads the QML components into its running context, and injects services (PluginService, Theme, ToastService, etc.).

Plugins do not run in isolation like a normal QML app. They participate in the larger DMS object tree.

There are four primary plugin types (see docs/plugin-types.md for the decision tree):

  • widget — Appears in the DankBar or Control Center (most common).
  • launcher — Extends the Spotlight-style launcher with searchable items (root is a QtObject, not an Item).
  • daemon — Background logic, no UI (react to events, run automation).
  • desktop — Free-floating, user-positionable and resizable widgets on the desktop layer (uses DesktopPluginComponent).

Development Loop (Fastest Feedback)

  1. Create your plugin directory anywhere (e.g. ~/src/my-dms-plugin).
  2. Symlink it: ln -s ~/src/my-dms-plugin ~/.config/DankMaterialShell/plugins/MyPlugin.
  3. Work in the source tree.
  4. After changes: dms ipc call plugins reload myPlugin (uses the id from plugin.json).
  5. For popout widgets, set layerNamespacePlugin: "something-unique" in your PluginComponent.
  6. Set up qmlls for autocomplete (see official docs; create .qmlls.ini in a DMS checkout).
  7. Use the Proc singleton (from qs.Common) for any external command whose output you need to capture. It handles debouncing and auto-cleanup.

Never restart the whole shell while iterating on a plugin unless absolutely necessary.

Must-Read Official Sources

This skill is deliberately a thin orientation + index + templates layer. The canonical, detailed, and up-to-date reference is the official documentation:

Always check the version notes at the top of those pages and match them to the DMS version the user is running.

High-Signal Cheat Sheets in This Skill

  • docs/plugin-types.md — Decision tree for choosing the right plugin shape.
  • docs/cheatsheets.md — Condensed surfaces for plugin.json, PluginComponent, PluginService, settings components, popouts, and permissions.
  • docs/ecosystem.md — Where to find real examples (first-party plugins, monorepo PLUGINS/, registry, community).

Generic Vertical-Slice Templates

Located in the templates/ directory of this skill. Each is a minimal, correct, modern starter for one plugin type.

How to use them:

  1. Copy the entire template folder to ~/.config/DankMaterialShell/plugins/YourPluginName/.
  2. Rename files and update plugin.json (especially id, name, author, paths).
  3. Run dms ipc call plugins reload <id> (or restart).
  4. Enable in DMS Settings → Plugins.

Current templates:

  • widget-bar/ — Simple DankBar widget with settings.
  • widget-popout/ — Bar widget that opens a nice popout (uses PopoutComponent + layer namespace).
  • launcher/ — Basic launcher extension (QtObject root + getItems/executeItem).
  • desktop/ — Minimal desktop layer widget (uses DesktopPluginComponent).

These templates follow current best practice (PluginSettings + *Setting components, proper permissions, Proc where relevant, etc.). They are intentionally small.

Common Agent Failure Modes Specific to DMS Plugins

  • Assuming the plugin is a standalone QML application (it lives inside DMS's context and singleton graph).
  • Writing settings UI without declaring "permissions": ["settings_write"] (the settings simply won't appear).
  • Using raw Process items for one-shot commands that need stdout (use the Proc singleton instead).
  • Forgetting that pluginData comes from the settings store and is not a general reactive property bag.
  • Neglecting layerNamespacePlugin on popout widgets (z-order and focus problems).
  • Treating launcher plugins like normal QML Items (they must be QtObject and export specific functions).
  • Over-caching or pre-computing things at load time that the shell can provide on demand.
  • Not testing the hot-reload path early.

Publishing & Distribution

How to Explore When Stuck

  1. Re-read the two official development pages for the exact DMS version in use.
  2. Look at the small example plugins inside the main DMS repo (quickshell/PLUGINS/).
  3. Study first-party plugins in https://github.com/AvengeMedia/dms-plugins (they are maintained to current standards).
  4. Browse the registry for real-world usage of the feature you need.
  5. Use dms ipc call plugins list and the logs from dms run for runtime diagnostics.

This skill exists to reduce uncertainty and variability when an agent is asked to work on a DMS plugin. It is intentionally lightweight and points at the official sources for depth.

Written by AI agent working for @jtmorris. Model: grok-build-0.1.