10 KiB
GEMINI.md
This file provides guidance to Google's Gemini models when working with code in this repository.
Project Overview
A lightweight, web-based Markdown note-taking application with a Go backend and a 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.
The project uses a hybrid architecture combining a Go backend, htmx for dynamic interactions, and a modern JavaScript frontend built with Vite and CodeMirror 6.
Features
- File-based Notes: All notes are stored as plain Markdown files (
.md) on the filesystem. - Daily Notes: Quick daily journaling with interactive calendar, keyboard shortcuts (
Ctrl/Cmd+D), and structured templates. - Tag Indexing: Notes are indexed by tags specified in their YAML front matter, enabling quick search.
- CodeMirror 6 Editor: Modern, powerful Markdown editor with syntax highlighting and One Dark theme.
- Live Markdown Preview: Side-by-side editor and live preview pane with scroll synchronization.
- Automatic Front Matter: Automatically generates and updates
title,date(creation),last_modified, andtagsin YAML front matter. - Slash Commands: Insert common Markdown elements and dynamic content (like current date) using
/commands in the editor. - Search Modal: Press
Ctrl/Cmd+Kto open a powerful search modal with keyboard navigation and real-time results. - Interactive Calendar: Monthly calendar widget showing daily notes with visual indicators and one-click access.
- Dynamic File Tree: Automatically updating file tree in the sidebar to navigate notes.
- Hierarchical Organization: Organize notes in folders with drag-and-drop file management.
- Rich Search: Search by keywords, tags (
tag:projet), title (title:meeting), or path (path:backend). - REST API: Full REST API (
/api/v1/notes) for programmatic access - list, read, create, update, and delete notes via HTTP. - Lightweight Frontend: Built with htmx for dynamic interactions, minimizing JavaScript complexity.
- Go Backend: Fast and efficient Go server handles file operations, indexing, and serving the frontend.
Technologies Used
- Backend: Go
net/http: Standard library for the web server.github.com/fsnotify/fsnotify: For watching file system changes and re-indexing.gopkg.in/yaml.v3: For parsing and marshaling YAML front matter.
- Frontend: HTML, CSS, JavaScript
- htmx: For dynamic UI interactions without writing much JavaScript.
- CodeMirror 6: For the robust Markdown editor.
- Vite: For bundling frontend JavaScript modules.
- marked.js: For client-side Markdown parsing in the preview.
- DOMPurify: For sanitizing HTML output from Markdown to prevent XSS vulnerabilities.
- Highlight.js: For syntax highlighting in code blocks.
- Custom CSS theme with dark mode inspired by VS Code and GitHub Dark.
Architecture
The project uses a hybrid architecture that combines:
- Go Backend: Fast, type-safe server handling file operations and indexing.
- HTMX: "HTML over the wire" for dynamic interactions with minimal JavaScript.
- Modern JavaScript: For UI enhancements like the CodeMirror 6 editor, drag-and-drop, and animations.
- Vite: Modern build tool for efficient JavaScript bundling.
Backend (Go)
Located under internal/, the backend has three main packages:
indexer: Maintains an in-memory index of notes, parsing YAML front matter. It's thread-safe usingsync.RWMutex.watcher: Usesfsnotifyto monitor the notes directory for changes and triggers re-indexing (with a 200ms debounce).api: Contains HTTP handlers for serving HTML templates and handling CRUD operations on notes. It automatically manages front matter on save.
The server entrypoint is cmd/server/main.go.
Frontend
The frontend source is in frontend/src/ and is built using Vite.
main.js: The entry point that imports all other modules.editor.js: Implements the CodeMirror 6 editor, live preview, scroll sync, and slash commands.file-tree.js: Handles the interactive file tree, including drag-and-drop functionality.search.js: Implements theCtrl/Cmd+Ksearch modal.ui.js: Handles general UI interactions like toggling the sidebar.
HTMX + JavaScript Coordination
The core principle is that HTMX handles all server interactions and DOM updates, while JavaScript provides client-side UI enhancements.
- Flow: User Interaction → HTMX (AJAX) → Go Server (sends HTML) → HTMX (swaps DOM) → JS listens to
htmx:*events to enhance the new content. - Best Practice: Use
htmx.ajax()for JS-initiated requests and listen to HTMX events (htmx:afterSwap,htmx:oobAfterSwap) instead of usingMutationObserver. This creates a more performant and maintainable system. The server uses out-of-band (OOB) swaps to update multiple parts of the UI at once (e.g., updating the file tree after saving a note).
Development Workflow
Prerequisites
Frontend Build Process
IMPORTANT: The frontend JavaScript must be built before running the application. The compiled assets are required for the editor and other interactive features to work.
-
Install Node.js dependencies (first time only):
cd frontend npm install -
Build the frontend for production:
npm run buildThis command compiles, bundles, and minifies the source files from
frontend/src/into thestatic/dist/directory. -
Run in watch mode for development:
npm run build -- --watchThis will automatically rebuild the frontend assets when you make changes to the source files.
Running the Application
- Ensure the frontend has been built at least once.
- Start the Go backend server from the project root:
go run ./cmd/server - The application will be accessible at
http://localhost:8080.
Server Configuration
The server accepts the following command-line flags:
-addr :PORT- Change server address (default::8080)-notes-dir PATH- Change notes directory (default:./notes)
Example: go run ./cmd/server -addr :3000 -notes-dir ~/my-notes
Testing
Run all Go tests:
go test ./...
Key Implementation Details
CodeMirror 6 Editor
Implemented in frontend/src/editor.js, the editor features:
- Markdown Support: Full syntax highlighting via
@codemirror/lang-markdown. - Theme:
one-darktheme for a VS Code-like feel. - Live Preview: A preview pane that updates 150ms after you stop typing.
- Scroll Sync: The editor and preview scroll in unison.
- Auto-Save: Automatically saves the note 2 seconds after inactivity.
- Slash Commands: A command palette triggered by
/for inserting Markdown snippets.
Slash Commands
A productivity feature in the editor (frontend/src/editor.js).
- Trigger: Type
/at the start of a line. - Commands: Includes
h1,h2,h3,list,date,link,bold,italic,code,codeblock,quote,hr,table. - Interaction: Navigate with arrow keys, select with
EnterorTab.
Search
- Modal: A fast search modal is available via
Ctrl/Cmd+K. - Syntax: Supports general keywords,
tag:value,title:value,path:value, and"quoted phrases". - Ranking: Results are scored by relevance, with title matches scoring highest.
REST API
A full REST API is available under /api/v1/ for programmatic access. See API.md for detailed documentation.
- Endpoints:
GET /notes,GET /notes/{path},PUT /notes/{path},DELETE /notes/{path}. - Content Negotiation: Supports
application/jsonandtext/markdown.
Security
- Path Traversal: The backend validates all file paths to prevent access outside the notes directory.
- XSS:
DOMPurifyis used to sanitize HTML rendered from Markdown, preventing Cross-Site Scripting attacks. - API Security: The REST API has no authentication by default. It is recommended to place it behind a reverse proxy with authentication if exposing it publicly.
Recent Fixes
- Bulk Deletion 404 Error: The issue with bulk deletion returning a 404 error has been resolved. The
DELETE /api/files/delete-multipleendpoint now correctly processes requests. This involved:- Changing the HTTP method from
POSTtoDELETEin bothfrontend/src/file-tree.jsandinternal/api/handler.go. - Adapting the Go backend handler (
handleDeleteMultiple) to manually read and parse the URL-encoded request body forDELETErequests, asr.ParseForm()does not automatically process bodies for this method.
- Changing the HTTP method from
Project Structure
project-notes/
├── cmd/server/main.go # Server entry point
├── internal/ # Go backend packages (api, indexer, watcher)
│ ├── api/
│ ├── indexer/
│ └── watcher/
├── frontend/ # Frontend source and build configuration
│ ├── src/
│ │ ├── main.js # JS entry point
│ │ ├── editor.js # CodeMirror 6 editor
│ │ ├── file-tree.js # Drag-and-drop file tree
│ │ ├── search.js # Search modal
│ │ └── ui.js # Misc UI scripts
│ ├── package.json
│ └── vite.config.js
├── static/ # Served static assets
│ ├── dist/ # Compiled/bundled frontend assets (generated by Vite)
│ └── theme.css # Main stylesheet
├── templates/ # Go HTML templates
├── notes/ # Default directory for user's Markdown notes
├── go.mod
├── API.md # REST API documentation
├── ARCHITECTURE.md # Detailed architecture document
└── GEMINI.md # This file