agentsclimarketplace

Obsidian plugin dev

Skill dustinkeeton/wafflestack/stacks/obsidian-dev/skills/obsidian-plugin-dev

πŸ§‡ One batter, every repo β€” reusable AI agent & skill definitions rendered into harness-native files (.claude/, .codex/, .agents/)

Install
npx -y skills add dustinkeeton/wafflestack --skill obsidian-plugin-dev

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Obsidian plugin development patterns, API usage, manifest configuration, settings management, testing, and build pipeline. Use when working on plugin architecture, lifecycle hooks, tests, or Obsidian API integration.

SKILL.md

4.5 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it

Obsidian Plugin Development Reference

Project Structure

plugin-root/
β”œβ”€β”€ src/
β”‚   └── main.ts           # Plugin class extending Plugin
β”œβ”€β”€ manifest.json          # Plugin metadata (id, name, version, minAppVersion)
β”œβ”€β”€ package.json           # npm dependencies
β”œβ”€β”€ tsconfig.json          # TypeScript config (ES6 target, strict mode)
β”œβ”€β”€ esbuild.config.mjs     # Bundler (main.ts β†’ main.js, obsidian external)
β”œβ”€β”€ styles.css             # Plugin styles
β”œβ”€β”€ versions.json          # Version-to-Obsidian compatibility
└── main.js                # Compiled output (generated)

manifest.json

{
  "id": "{{plugin.id}}",
  "name": "{{plugin.name}}",
  "version": "0.1.0",
  "minAppVersion": "0.15.0",
  "description": "{{plugin.description}}",
  "author": "{{plugin.author}}",
  "isDesktopOnly": false
}

Plugin Lifecycle

import { Plugin } from 'obsidian';

export default class {{plugin.classPrefix}}Plugin extends Plugin {
  async onload() {
    // Load settings, register UI, commands, events
    await this.loadSettings();
    this.addSettingTab(new {{plugin.classPrefix}}SettingTab(this.app, this));
    this.registerCommands();
  }

  onunload() {
    // Automatic cleanup for registered resources
  }
}

Feature Modules (scaling beyond main.ts)

Larger plugins split features into modules that mirror the plugin lifecycle:

class FeatureModule {
  constructor(plugin: Plugin, getSettings: () => {{plugin.classPrefix}}Settings) {}
  async onload(): Promise<void>;  // register commands, views, events
  onunload(): void;               // cleanup
}
  • Register everything through the Plugin instance (addCommand, registerEvent, registerDomEvent) inside the module's onload() so Obsidian's automatic cleanup covers it on unload.
  • Prefer zero runtime npm dependencies: use requestUrl/fetch for API calls and child_process for external tools β€” keeps the bundle lean and eases community-plugin review.

Key API Patterns

  • Commands: this.addCommand({ id, name, callback }) or editorCallback for editor context
  • Ribbon icons: this.addRibbonIcon(icon, title, callback)
  • Settings: this.loadData() / this.saveData() with Object.assign(DEFAULT_SETTINGS, loaded)
  • Events: this.registerEvent(this.app.vault.on('modify', callback))
  • DOM events: this.registerDomEvent(document, 'click', callback) (auto-cleanup)
  • File operations: this.app.vault.read(file), this.app.vault.modify(file, content)
  • Modals: Extend Modal class with onOpen() / onClose()
  • Setting tabs: Extend PluginSettingTab with display() method

Build Pipeline

  • npm install β†’ install deps (obsidian, @types/node, esbuild, typescript)
  • npm run dev β†’ esbuild watch mode (rebuilds on change)
  • npm run build β†’ production build with type checking (tsc -noEmit && esbuild)
  • Obsidian API is external (provided at runtime, not bundled)

Testing Obsidian Plugins

The obsidian package ships types only β€” the real module exists inside the app, so tests rely on a centralized mock:

  • Module mock: src/__mocks__/obsidian.ts, auto-loaded by the runner's module mocking, provides stub classes and helpers for TFile, TFolder, Plugin, Modal, Notice, normalizePath, requestUrl, etc.
  • No obsidian imports in test files β€” tests exercise the mock, never the real module.
  • Mock factories (central test-utils directory) keep fixtures uniform:
    • createMockApp() β€” fresh App with spy vault/metadataCache/workspace
    • createMockPlugin(settingsOverrides?) β€” a Plugin with pre-loaded settings
    • makeSettings(overrides?) β€” settings defaults deep-merged with overrides
    • mockFile(path) β€” a TFile instance for the given path
  • UI classes are exempt from unit tests β€” anything extending Modal, ItemView, or PluginSettingTab is tested indirectly through its callers; extract decision logic into pure functions instead.

Development Tips

  • Use a dedicated development vault, not your primary vault
  • Install Hot-Reload plugin for auto-reloading during dev
  • Use new Notice('message') for user-facing notifications
  • Settings persist to data.json in the plugin directory

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.