# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Type This is an Obsidian community plugin written in TypeScript and bundled to JavaScript using esbuild. ## Build Commands ```bash # Install dependencies npm install # Development mode (watch mode, auto-recompiles on changes) npm run dev # Production build (type checks, then bundles with minification) npm run build # Lint code npm run lint ``` ## Architecture ### Entry Points & Build Process - Source code lives in `src/` - Main entry point: `src/main.ts` (plugin lifecycle management) - Build target: `main.js` (bundled output at root) - Bundler: **esbuild** (configured in `esbuild.config.mjs`) - Required release artifacts: `main.js`, `manifest.json`, `styles.css` (if present) ### Code Organization Pattern - **Keep `main.ts` minimal**: Only plugin lifecycle (onload, onunload, command registration) - Delegate feature logic to separate modules - Settings are defined in `src/settings.ts` - Organize larger features into subdirectories: - `commands/` for command implementations - `ui/` for modals, views, and UI components - `utils/` for helper functions ### Plugin Architecture - Extends `Plugin` class from `obsidian` package - Settings are loaded/saved using `this.loadData()` / `this.saveData()` - All event listeners, intervals, and DOM events must use `this.register*()` helpers for proper cleanup - Commands are registered via `this.addCommand()` with stable IDs ## Key Constraints ### Obsidian-Specific - **Bundle everything**: No external runtime dependencies (except `obsidian`, `electron`, CodeMirror packages) - **External packages**: Listed in `esbuild.config.mjs` external array; never bundle these - **Mobile compatibility**: Avoid Node/Electron APIs unless `isDesktopOnly: true` in manifest - **Network requests**: Default to offline; require explicit user consent for any external calls - **No remote code execution**: Never fetch/eval scripts or auto-update outside normal releases ### Manifest (`manifest.json`) - Never change `id` after initial release - Use semantic versioning for `version` - Keep `minAppVersion` accurate when using newer Obsidian APIs - Update both `manifest.json` and `versions.json` when bumping versions ## Development Workflow ### Testing Locally 1. Build the plugin: `npm run dev` or `npm run build` 2. Copy `main.js`, `manifest.json`, `styles.css` to: ``` /.obsidian/plugins// ``` 3. Reload Obsidian and enable plugin in Settings → Community plugins ### Type Checking - TypeScript strict mode enabled in `tsconfig.json` - Build command runs `tsc -noEmit -skipLibCheck` before bundling - Fix type errors before considering build successful ## Important Files - `src/main.ts` - Plugin class and lifecycle - `src/settings.ts` - Settings interface, defaults, and settings tab UI - `manifest.json` - Plugin metadata (never commit with wrong version) - `esbuild.config.mjs` - Build configuration - `eslint.config.mts` - ESLint configuration with Obsidian-specific rules - `styles.css` - Optional plugin styles ## Code Quality Guidelines From AGENTS.md and Obsidian best practices: - Split files when they exceed ~200-300 lines - Use clear module boundaries (single responsibility per file) - Prefer `async/await` over promise chains - Register all cleanup via `this.register*()` helpers to prevent memory leaks - Keep startup lightweight; defer heavy work until needed - Use stable command IDs (don't rename after release) - Provide sensible defaults for all settings