obsidian-plugin/skills/dev-tools/SKILL.md
Obsidian plugin/theme dev: DevTools, CDP, JS eval, console/error buffers, CSS/DOM inspection, mobile emulation, screenshots. Use when debugging the app.
npx skillsauth add laurigates/claude-plugins dev-toolsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Use this skill when... | Use the alternative instead when... |
|---|---|
| Developing or debugging a community plugin / theme | Enabling or disabling plugins as a user — use plugins-themes |
| Running JavaScript against the live app API | Triggering an Obsidian command — use command-palette |
| Inspecting CSS or DOM in the running app | Switching themes or snippets in normal use — use plugins-themes |
| Capturing console errors during agent-run plugin tests | Reading note content — use vault-files |
These commands are for development and diagnostics. They expose the same surface as the in-app DevTools window plus a captured buffer of console output and JavaScript errors that survives between calls — the leverage point for agentic plugin testing.
dev:debug and dev:cdp: Chrome DevTools Protocol available
(Electron-based Obsidian — true on desktop)# Toggle the in-app DevTools panel
obsidian devtools
# Read state from the live app
obsidian eval code="app.vault.getFiles().length"
obsidian eval code="app.workspace.getActiveFile()?.path"
# Drive the app — anything you could type in the DevTools console
obsidian eval code="app.commands.executeCommandById('editor:toggle-bold')"
# Multi-statement: wrap in an IIFE
obsidian eval code="(()=>{const f=app.vault.getFiles();return f.filter(x=>x.extension==='md').length})()"
eval returns the expression's value (or last statement's value in an IIFE)
serialised to text. Use JSON.stringify(...) inside the expression for
structured output you can parse downstream.
The CLI maintains rolling buffers of console.* calls and JavaScript errors
from the running app — invaluable for agent-driven plugin testing where the
agent doesn't have the DevTools window open.
# Recent console messages (default limit 50)
obsidian dev:console
obsidian dev:console limit=200
obsidian dev:console level=error
obsidian dev:console level=warn
# Clear the console buffer (e.g. before a test run)
obsidian dev:console clear
# Captured JS errors
obsidian dev:errors
obsidian dev:errors clear
Typical agent loop:
obsidian dev:errors clear
obsidian dev:console clear
obsidian plugin:reload id=my-plugin
obsidian command id=my-plugin:run-test
obsidian dev:errors # any uncaught exceptions?
obsidian dev:console level=error
# All CSS rules matching a selector, with source location
obsidian dev:css selector=".workspace-leaf"
# Filter to one property
obsidian dev:css selector=".workspace-leaf" prop=background-color
Useful for tracking down which snippet or theme is winning a cascade.
# First match — full outerHTML
obsidian dev:dom selector=".nav-folder-title"
# Inner HTML only
obsidian dev:dom selector=".nav-folder-title" inner
# Just the text content
obsidian dev:dom selector=".nav-folder-title" text
# All matches (not just the first)
obsidian dev:dom selector=".nav-folder-title" all
# Element count
obsidian dev:dom selector=".nav-folder-title" total
# Read an attribute or computed CSS prop
obsidian dev:dom selector=".workspace-leaf.mod-active" attr=data-type
obsidian dev:dom selector=".workspace-leaf.mod-active" css=display
# Attach the CDP debugger
obsidian dev:debug on
obsidian dev:debug off
# Run an arbitrary CDP method
obsidian dev:cdp method=Page.captureScreenshot
obsidian dev:cdp method=Runtime.evaluate params='{"expression":"location.href"}'
CDP is the right tool when eval is too coarse — anything you'd reach for
in chrome://inspect.
# Capture the running window
obsidian dev:screenshot path=/tmp/state.png
# Toggle mobile emulation (responsive testing without leaving desktop)
obsidian dev:mobile on
obsidian dev:mobile off
obsidian dev:console clear
obsidian dev:errors clear
obsidian plugin:reload id=my-plugin
obsidian command id=my-plugin:run-tests
errors=$(obsidian dev:errors)
[ -z "$errors" ] && echo "PASS" || { echo "FAIL"; echo "$errors"; }
for theme in Default Minimal Things; do
obsidian theme:set name="$theme"
obsidian dev:screenshot path="/tmp/theme-$theme.png"
done
obsidian eval code="JSON.stringify({file: app.workspace.getActiveFile()?.path, view: app.workspace.activeLeaf?.view?.getViewType()})"
| Context | Command |
|---------|---------|
| Run JS, parseable output | obsidian eval code="JSON.stringify(...)" |
| Errors since last check | obsidian dev:errors |
| Reset error buffer | obsidian dev:errors clear |
| Console (errors only) | obsidian dev:console level=error |
| DOM element count | obsidian dev:dom selector=X total |
| Screenshot for diff | obsidian dev:screenshot path=/tmp/X.png |
| CSS source for property | obsidian dev:css selector=X prop=Y |
development
Debug HTTP APIs: trace requests, inspect headers. Use when a request fails: check status first.
documentation
Render architecture diagrams from text sources. Use when documenting system topology.
tools
Inspect JSON payloads and extract nested fields. Use when parsing API responses.
tools
--- name: no-description allowed-tools: Read --- # No Description This skill has no description and must be dropped with a warning.