Imported from TheBestTvarynka/photo-tagging (
AGENTS.md). Install upstream withnpx skills add TheBestTvarynka/photo-tagging. Copyright stays with the author.
Obsidian community plugin
Project overview
- Target: Obsidian Community Plugin (TypeScript → bundled JavaScript).
- Entry point:
main.tscompiled tomain.jsand loaded by Obsidian. - Required release artifacts:
main.js,manifest.json, and optionalstyles.css.
To get familiar with the project purpose and development philosophy, read the README.md file.
Environment & tooling
- Node.js: use current LTS (Node 18+ recommended).
- Package manager: npm (required for this sample -
package.jsondefines npm scripts and dependencies). - Bundler: esbuild (required for this sample -
esbuild.config.mjsand build scripts depend on it). Alternative bundlers like Rollup or webpack are acceptable for other projects if they bundle all external dependencies intomain.js. - Types:
obsidiantype definitions.
Install dependencies
npm install
Dev (watch)
npm run dev
Production build
npm run build
Linting
After every change, run the linter and formatter:
npx eslint .
npx prettier . --write
File & folder conventions
- Organize code into multiple files: Split functionality across separate modules rather than putting everything in
main.ts. - Source lives in
src/. Keepmain.tssmall and focused on plugin lifecycle (loading, unloading, registering commands). - Keep the plugin small. Avoid large dependencies. Prefer browser-compatible packages.
- Generated output should be placed at the plugin root or
dist/depending on your build setup. Release artifacts must end up at the top level of the plugin folder in the vault (main.js,manifest.json,styles.css).
Commands & settings
- Any user-facing commands should be added via
this.addCommand(...). - If the plugin has configuration, provide a settings tab and sensible defaults.
- Persist settings using
this.loadData()/this.saveData(). - Use stable command IDs; avoid renaming once released.
Security, privacy, and compliance
Follow Obsidian's Developer Policies and Plugin Guidelines. In particular:
- Default to local/offline operation. Only make network requests when essential to the feature.
- No hidden telemetry. If you collect optional analytics or call third-party services, require explicit opt-in and document clearly in
README.mdand in settings. - Never execute remote code, fetch and eval scripts, or auto-update plugin code outside of normal releases.
- Minimize scope: read/write only what's necessary inside the vault. Do not access files outside the vault.
- Clearly disclose any external services used, data sent, and risks.
- Respect user privacy. Do not collect vault contents, filenames, or personal information unless absolutely necessary and explicitly consented.
- Avoid deceptive patterns, ads, or spammy notifications.
- Register and clean up all DOM, app, and interval listeners using the provided
register*helpers so the plugin unloads safely.
UX & copy guidelines (for UI text, commands, settings)
- Prefer sentence case for headings, buttons, and titles.
- Use clear, action-oriented imperatives in step-by-step copy.
- Use bold to indicate literal UI labels. Prefer "select" for interactions.
- Use arrow notation for navigation: Settings → Community plugins.
- Keep in-app strings short, consistent, and free of jargon.
Performance
- Keep startup light. Defer heavy work until needed.
- Avoid long-running tasks during
onload; use lazy initialization. - Batch disk access and avoid excessive vault scans.
- Debounce/throttle expensive operations in response to file system events.
Coding conventions
- TypeScript with
"strict": truepreferred. - Keep
main.tsminimal: Focus only on plugin lifecycle (onload, onunload, addCommand calls). Delegate all feature logic to separate modules. - Split large files: If any file exceeds ~200-300 lines, consider breaking it into smaller, focused modules.
- Use clear module boundaries: Each file should have a single, well-defined responsibility.
- Bundle everything into
main.js(no unbundled runtime deps). - Prefer
async/awaitover promise chains; handle errors gracefully.
Agent do/don't
Do
- Add commands with stable IDs (don't rename once released).
- Provide defaults and validation in settings.
- Write idempotent code paths so reload/unload doesn't leak listeners or intervals.
- Use
this.register*helpers for everything that needs cleanup.
Don't
- Introduce network calls without an obvious user-facing reason and documentation.
- Ship features that require cloud services without clear disclosure and explicit opt-in.
- Store or transmit vault contents unless essential and consented.
References
- Obsidian sample plugin: https://github.com/obsidianmd/obsidian-sample-plugin
- API documentation: https://docs.obsidian.md
- Developer policies: https://docs.obsidian.md/Developer+policies
- Plugin guidelines: https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines
- Style guide: https://help.obsidian.md/style-guide