Obsidian plugin quality audit
SkillDocs & knowledgeAudit ZettelFlow against the official Obsidian plugin guidelines and the Community-hub automated review / quality score. Use before a release, when preparing a directory submission, or when the user asks to "check plugin quality", "raise the Obsidian score", "run the reviewer", or "prepare for submission". Runs the same rule set Obsidian's automated reviewer uses and reports concrete, file-anchored fixes.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Obsidian plugin quality audit skill
What this skill tells your AI
The instructions your AI receives, as published by rafaelgb/obsidian-zettelflow in .claude/skills/obsidian-plugin-quality/SKILL.md and read by ahel’s review.
Obsidian's Community hub (May 2026) runs an automated review on every plugin version
and publishes a 1–100 source-code quality score plus safety scorecards. The score is
essentially how clean the code is against eslint-plugin-obsidianmd + the developer
policies + the submission requirements. This skill reproduces that audit locally.
Background reference (keep it in sync): docs/development/obsidian-review-and-scoring.md.
When to use
- Before cutting a release or tagging a version.
- Before (re-)submitting to the community directory.
- When the user asks to improve the Obsidian score / pass the automated review.
How to run the audit
Work through the phases in order. Report findings grouped by category, most-severe first,
each anchored to file:line with a concrete fix. Do not auto-apply large refactors
without confirming scope with the user first.
Phase 1 — Run the official linter (the ground truth)
The project currently lints with oxlint and a legacy .eslintrc.js; neither encodes the
Obsidian rules. Add and run the official rule set:
npm i -D eslint eslint-plugin-obsidianmd @typescript-eslint/parser
# with an eslint.config.mjs using obsidianmd.configs.recommended (see the doc)
npx eslint "src/**/*.{ts,tsx}"
If the flat config is not yet present, create eslint.config.mjs as shown in
docs/development/obsidian-review-and-scoring.md §5. Treat every eslint-plugin-obsidianmd
error as a score deduction.
Phase 2 — Fast static audit (grep the known anti-patterns)
Run these and triage each hit:
| Check | Command (ripgrep) | Rule / guideline |
|---|---|---|
| HTML injection | `rg -n "innerHTML | outerHTML |
| Inline styles | `rg -n ".style. | setAttribute(['"]style" src` |
| Detach leaves on unload | rg -n "detachLeavesOfType" src | detach-leaves → remove from onunload. |
| Hardcoded config dir | rg -n "\.obsidian/" src | hardcoded-config-path → use vault.configDir. |
| Node/Electron on mobile | `rg -n "require( | from ['"](fs |
Global app | `rg -n "window.app | \bapp." src` |
var / Promise chains | `rg -n "\bvar\s | .then(" src` |
| Regex lookbehind | rg -n "\(\?<" src | regex-lookbehind → unsupported on some iOS. |
Direct activeLeaf | rg -n "workspace\.activeLeaf" src | Use getActiveViewOfType(). |
| Adapter over Vault | rg -n "\.adapter\." src | Prefer the Vault API. |
Phase 3 — Manifest & release hygiene
-
manifest.json: validid,name, semverversion,minAppVersion,description(≤250 chars, action verb, ends with., not starting "This is a plugin"),author. -
fundingUrlpresent only because donations are accepted (ZettelFlow: yes). -
versions.jsonexists and maps each version →minAppVersion. ⚠️ Currently missing — seedocs/development/obsidian-review-and-scoring.md§6. -
version-bump.mjsexists (referenced by theversionnpm script). ⚠️ Currently missing. - Release workflow attaches
main.js,manifest.json,styles.cssunder a git tag equal tomanifest.version(novprefix). Cross-check.github/workflows/releases.yml. -
LICENSEpresent with a valid copyright notice (validate-license).
Phase 4 — Commands, settings & UI text
- Command ids/names don't repeat the plugin id/name or the word "command".
- No default hotkeys shipped.
- Settings headings use
setHeading()(not manual HTML), no "settings" in the heading text. - All user-facing strings are Sentence case, not Title Case. (ZettelFlow has an
i18n layer at
src/architecture/lang/— auditen/eslocale strings too.)
Phase 5 — ZettelFlow-specific risk review
- Canvas monkey-patching (
src/architecture/plugin/canvas/extensions/CanvasPatcher.ts) patches internal Canvas APIs viamonkey-around. This is a manual-review flag: keep the patches defensive (they already register uninstallers viaplugin.register), guard every patched method behind existence checks, and document the risk. Verify against the currentminAppVersion. .jsextension registration (CodeView): already wrapped in try/catch — keep it.- Logger gating (
src/architecture/monitoring/Logger.ts):erroris silenced when the logger toggle is off. Consider always allowingerror. onunloadonly clears the action store; confirm no leaked resources (most are covered by Obsidian'sregister*auto-teardown).
Phase 6 — The transformation gate (constitution §XI)
Beyond the linter, judge the change against the design gate:
- Transformation. Ask "what knowledge transformation does this enable?" Flag surface that doesn't transform/connect/evaluate/discover/advance knowledge as secondary.
- No net complexity. The change removes/merges a command, view, setting or path, or hardens a boundary — it doesn't only add. Rising net surface is a finding.
- Boundaries. The Knowledge layer (
architecture/knowledge, futureknowledge/) imports noobsidianand makes no network/AI call; derived metrics are queries over the model, not new dashboard features. Existing.zftemplatesystems and saved settings still work; no command/view removed without an alias.
Output format
Produce a prioritized report: (1) blocking submission issues (missing versions.json,
manifest errors), (2) eslint-plugin-obsidianmd errors, (3) security (HTML injection),
(4) styling/inline-style migrations, (5) polish (sentence case, commands). For each: the
rule, the file:line, and the exact fix. Offer to apply the low-risk mechanical fixes
(innerHTML = "" → .empty(), adding the eslint config) in a follow-up.
Signals
- GitHub stars
- 168
- Forks
- 12
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
obsidian-plugin-quality- Source
- github.com/rafaelgb/obsidian-zettelflow