--- name: obsidian-plugin description: >- End-to-end playbook for building an Obsidian community plugin. Use when scaffolding, implementing, verifying, reviewing, or shipping any Obsidian plugin; for vault-as-markdown architecture, Selenium E2E, plugin-review lint, GitHub releases, community directory submission, or /obsidian-plugin. --- # Build an Obsidian community plugin Unofficial playbook. Not affiliated with, published by, or endorsed by Obsidian or Dynalist Inc. Obsidian loads three files from `.obsidian/plugins//`: `main.js`, `manifest.json`, and optional `styles.css`. Everything else is how you stay sane while shipping those three. Official docs stay canonical for API and directory rules: - [Build a plugin](https://docs.obsidian.md/Plugins/Getting+started/Build+a+plugin) - [Manifest](https://docs.obsidian.md/Reference/Manifest) - [Plugin guidelines](https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines) - [Submit your plugin](https://docs.obsidian.md/plugins/releasing/submit-plugin) ## Which skill to load | Situation | Skill | | --- | --- | | New repo / sample-plugin bootstrap | [obsidian-plugin-scaffold](../obsidian-plugin-scaffold/SKILL.md) | | Layers, vault-as-data, path safety | [obsidian-plugin-architecture](../obsidian-plugin-architecture/SKILL.md) | | DOM, settings UI, CSS, commands | [obsidian-plugin-ui](../obsidian-plugin-ui/SKILL.md) | | Unit tests, typecheck, build, Selenium E2E, Cloud VMs | [obsidian-plugin-verify](../obsidian-plugin-verify/SKILL.md) | | Version bump, GitHub Release, directory listing | [obsidian-plugin-ship](../obsidian-plugin-ship/SKILL.md) | Load this file for routing and gates, then **only** the phase skill you are in. Do not skip phases that produce proof. ## Hard stops Stop and fix before the next phase if any of these fail. How-to lives in the phase skill, not here. 1. Domain logic imports `obsidian`. Move it to a pure module. 2. A user-visible control has no stable `data-testid`. Add the hook and the Selenium assertion together. 3. Live DOM is built with `innerHTML`, `outerHTML`, or `insertAdjacentHTML`. Paint with `createDiv` / `createEl`. 4. `styles.css` uses `:has(`, `!important`, or `scrollbar-width`. Replace them. 5. A vault path from settings or user input is not validated. Run it through `normalizePath` and a folder-safety helper. 6. `npm test`, `npm run typecheck`, or `npm run build` fails. 7. Obsidian is installed and `npm run test:e2e` is skipped without recording why. 8. Release tag is `v1.2.3` or assets omit `main.js` / `manifest.json`. Computer-use is not the health check. `npm run test:e2e` is. Use computer-use only after Selenium fails and you have screenshots under the e2e artifact dir. ## Definition of done This is the only done-list. [obsidian-plugin-verify](../obsidian-plugin-verify/SKILL.md) owns how to run it; [obsidian-plugin-ship](../obsidian-plugin-ship/SKILL.md) must not tag a release that fails it. 1. `npm test`, `npm run typecheck`, and `npm run build` pass. 2. `npm run test:e2e` passed, or the summary states Obsidian could not be installed or launched after a real attempt. 3. New UI has `data-testid` hooks and Selenium coverage (or a source-level hook test if the flow is not yet in the health check). 4. Docs the user would hit are updated. HTML mockups do not replace E2E. 5. You did not commit an accidental `main.js` rebuild unless the release is supposed to include it.