# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview A lightweight web-based Markdown note-taking application with a Go backend and modern JavaScript frontend. Notes are stored as plain Markdown files with YAML front matter containing metadata (title, date, last_modified, tags). The system provides a sophisticated CodeMirror 6 editor with live preview, rich search capabilities, hierarchical organization, and automatic front matter management. **Recent Modernization**: The project has been migrated from a simple textarea editor to CodeMirror 6, with a Vite build system for frontend modules. The backend remains unchanged, maintaining the same Go architecture with htmx for dynamic interactions. ## Architecture ### Backend (Go) Three main packages under `internal/`: - **indexer**: Maintains an in-memory index mapping tags to note files. Parses YAML front matter from `.md` files to build the index. Thread-safe with RWMutex. - **watcher**: Uses `fsnotify` to monitor filesystem changes and trigger re-indexing with 200ms debounce. Recursively watches all subdirectories. - **api**: HTTP handlers that serve templates and handle CRUD operations on notes. Updates front matter automatically on save. The server (`cmd/server/main.go`) coordinates these components: 1. Loads initial index from notes directory 2. Starts filesystem watcher for automatic re-indexing 3. Pre-parses HTML templates from `templates/` 4. Serves routes: - `/` (main page) - `/api/v1/notes` and `/api/v1/notes/*` (REST API - JSON responses) - `/api/search` (HTML search results) - `/api/notes/*` (HTML editor for notes) - `/api/tree` (HTML file tree) - `/api/folders/create` (Folder management) - `/api/files/move` (File/folder moving) - `/api/home` (Home page) 5. Handles static files from `static/` directory ### Frontend The frontend uses a modern build system with Vite and CodeMirror 6: #### Architecture - **Build System**: Vite compiles frontend modules from `frontend/src/` to `static/dist/` - **Editor**: CodeMirror 6 with Markdown language support, One Dark theme, and syntax highlighting - **Templates**: `index.html`, `editor.html`, `file-tree.html`, `search-results.html`, `new-note-prompt.html` - **HTMX Integration**: Server returns HTML fragments that htmx swaps into the DOM - **Out-of-band swaps**: Update the file tree after saves/deletes without full page reload #### Frontend Source Structure ``` frontend/src/ ├── main.js # Entry point - imports all modules ├── editor.js # CodeMirror 6 editor implementation with slash commands ├── search.js # Search modal with Ctrl/Cmd+K keyboard shortcut ├── file-tree.js # Drag-and-drop file organization └── ui.js # Sidebar toggle functionality ``` #### CodeMirror 6 Editor Features - **Syntax Highlighting**: Full Markdown language support (`@codemirror/lang-markdown`) - **Theme**: One Dark theme (`@codemirror/theme-one-dark`) - VS Code-inspired dark theme - **Live Preview**: Debounced updates (150ms) synchronized with editor scroll position - **Auto-Save**: Triggers after 2 seconds of inactivity - **Keyboard Shortcuts**: - `Ctrl/Cmd+S` for manual save - `Tab` for proper indentation - Full keyboard navigation - **View Modes**: Toggle between split view, editor-only, and preview-only - **Slash Commands**: Type `/` to open command palette for quick Markdown insertion - **Front Matter Handling**: Automatically strips YAML front matter in preview #### File Tree Features - **Folder Management**: Expand/collapse folders with visual indicators (📁/📂) - **Drag & Drop**: Move files between folders with visual feedback - **Folder Creation**: Modal-based creation supporting nested paths - **Safe Validation**: Prevents dangerous path operations #### Rendering Pipeline - **marked.js**: Markdown to HTML conversion - **DOMPurify**: HTML sanitization to prevent XSS attacks - **Highlight.js**: Syntax highlighting for code blocks in preview - **Custom Theme**: Material Darker theme in `static/theme.css` with CSS custom properties ### Note Format Notes have YAML front matter with these fields: ```yaml --- title: "Note Title" date: "08-11-2025" last_modified: "08-11-2025:13:02" tags: [tag1, tag2] --- ``` The `indexer` package handles both single-value and array-format tags via custom `UnmarshalYAML`. ## Development Commands ### Building the Frontend **IMPORTANT**: The frontend must be built before running the application. The compiled JavaScript is required. ```bash cd frontend npm install # Install dependencies (first time only) npm run build # Compile frontend modules to static/dist/ ``` Output files (loaded by templates): - `static/dist/project-notes-frontend.es.js` (ES module) - `static/dist/project-notes-frontend.umd.js` (UMD format) Frontend dependencies (from `frontend/package.json`): - `@codemirror/basic-setup` - Base editor functionality - `@codemirror/lang-markdown` - Markdown language support - `@codemirror/state` - Editor state management - `@codemirror/view` - Editor view layer - `@codemirror/theme-one-dark` - Dark theme - `vite` - Build tool ### Running the Server ```bash go run ./cmd/server ``` Server starts on `http://localhost:8080`. Use flags to customize: - `-addr :PORT` - Change server address (default: `:8080`) - `-notes-dir PATH` - Change notes directory (default: `./notes`) ### Testing Run all tests: ```bash go test ./... ``` Run specific package tests: ```bash go test ./internal/indexer go test ./internal/api ``` Run tests with verbose output: ```bash go test -v ./... ``` ### Building the Server Binary ```bash go build ./cmd/server ``` ### Backend Dependencies Update Go dependencies: ```bash go mod tidy ``` Key backend dependencies: - `github.com/fsnotify/fsnotify` - Filesystem watcher - `gopkg.in/yaml.v3` - YAML parsing for front matter ### Vite Build System The frontend uses Vite (`frontend/vite.config.js`) for bundling JavaScript modules: **Configuration**: - **Entry Point**: `frontend/src/main.js` (imports editor.js, file-tree.js, ui.js) - **Output Directory**: `static/dist/` (served by Go server) - **Library Mode**: Builds as a library with both ES and UMD formats - **Single Bundle**: No code splitting - all dependencies bundled together - **Aliases**: Path aliases for `@codemirror/state` and `@codemirror/view` to ensure consistent versions **Build Process**: 1. Vite reads all source files from `frontend/src/` 2. Resolves npm dependencies (@codemirror packages) 3. Bundles everything into two formats: - ES module (`project-notes-frontend.es.js`) - 1.0 MB - UMD (`project-notes-frontend.umd.js`) - 679 KB 4. Outputs to `static/dist/` where Go server can serve them 5. Templates load the ES module version via `