Verify in a separate development vault. Never use a primary vault as the first test surface for code that creates, modifies, renames, or deletes notes.
- Select commands from the repository
- Prepare a development vault
- Use the Obsidian CLI
- Fall back when live automation is unavailable
- Build a focused regression matrix
- Report evidence
Inspect package.json and the lockfile before running commands. Use the established package manager and scripts; do not assume every repository exposes the sample plugin's commands.
Typical source-project layers are:
- Install dependencies with the lockfile-compatible command.
- Run type checking and the production build, not only watch mode.
- Run linting, formatting checks, and tests for pure logic.
- Run the skill's static audit and
git diff --check. - Inspect
main.jswithnode --check; confirm release builds contain no source maps or development endpoints. - Install the production artifacts and perform live plugin verification.
The current official sample exposes dev, lint, and build, with build type-checking before an esbuild production bundle. Treat those names as a baseline only; follow the inspected repository scripts and lockfile.
For an artifact-only repository, run node --check main.js, JSON parsing, the static audit, and git diff --check. State that TypeScript and source-level tests were unavailable.
Install the plugin under:
<dev-vault>/<config-dir>/plugins/<manifest.id>/
Copy or link main.js, manifest.json, and optional styles.css. Do not hardcode .obsidian; use the vault's configured directory in instructions and Vault.configDir in plugin code.
Use development watch mode for iteration. Before release, run the production build, install those exact artifacts in a clean disposable vault, and repeat the affected checks. Include a fresh install and an upgrade from the previous release when settings or stored data changed.
Require Obsidian to be open. Run obsidian help first because the installed CLI is authoritative. Parameters use key=value; flags have no value. Target the intended vault explicitly when more than one vault may be open:
obsidian vault="Development Vault" plugin:reload id=my-plugin
obsidian vault="Development Vault" dev:errors
obsidian vault="Development Vault" dev:console level=errorUse this loop after each meaningful change:
-
If
manifest.jsonchanged, restart Obsidian before judging the result. Otherwise reload the plugin:obsidian plugin:reload id=my-plugin
-
Inspect uncaught errors:
obsidian dev:errors
-
Exercise the changed interaction. Use
obsidian evalonly for small, read-only inspection or deliberately scoped setup:obsidian eval code="app.plugins.enabledPlugins.has('my-plugin')"
-
Inspect error-level console output:
obsidian dev:console level=error
-
Verify the rendered result:
obsidian dev:dom selector=".my-plugin-view" text obsidian dev:screenshot path=/tmp/my-plugin-check.png -
For mobile-compatible plugins, toggle emulation and repeat the affected flow:
obsidian dev:mobile on
Turn mobile emulation off after verification if the CLI supports the corresponding command. Finish release-critical mobile flows on an actual device because emulation does not reproduce the mobile adapter, operating-system APIs, touch behavior, or software keyboard completely.
Do not expose secret values or private note text through eval, console capture, DOM output, or screenshots.
Restart or reload Obsidian, enable the installed plugin, and exercise the same checks manually.
Record the absence of a running Obsidian instance or CLI as an untested live path, not as a passed test.
Select rows that intersect the change:
| Area | Minimum checks |
|---|---|
| Lifecycle | Enable, reload, disable, re-enable, restart; verify no duplicate UI, listeners, or timers |
| Commands/ribbon | Command palette, ribbon, repeated invocation, unavailable-state behavior |
| Custom view | First open, restored workspace, close/reopen, split leaf, pop-out if supported |
| Deferred view | Query while deferred, reveal, restored layout, optional background load on supported versions |
| Settings | Fresh defaults, persistence, invalid stored/input values, migration, global settings search |
| Dual settings support | Declarative UI on 1.13+, imperative UI below 1.13, synchronized controls and persistence |
| Vault writes | New file, existing file, renamed/deleted target, concurrent edit, invalid path |
| Editor/Markdown | Selection/cursor/undo in edit mode, Live Preview decorations, Reading view processor, large viewport |
| Search/index | Empty vault, cache invalidation after change/delete/rename, large result set |
| Network | Missing secret, bad URL, authentication error, timeout, malformed response, retry |
| CSS/UI | Light/dark/community theme, narrow width, zoom, keyboard, focus, reduced motion, long text, RTL |
| Mobile | Touch, software keyboard, rotation/narrow view, platform-gated paths |
| Privacy | No secrets in data.json or logs; no unintended note content in requests |
For destructive paths, create disposable fixture notes, confirm trash behavior, and verify that unrelated files remain unchanged.
List exact commands and outcomes. Distinguish static validation, automated live checks, and manual checks. Mention warnings accepted with rationale and any path that could not be tested.
Official CLI reference: Obsidian CLI