Files
personotes/GEMINI.md

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, and tags in 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+K to 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 using sync.RWMutex.
  • watcher: Uses fsnotify to 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 the Ctrl/Cmd+K search 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 using MutationObserver. 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

  • Go (version 1.22 or higher)
  • Node.js (for the frontend build process)

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.

  1. Install Node.js dependencies (first time only):

    cd frontend
    npm install
    
  2. Build the frontend for production:

    npm run build
    

    This command compiles, bundles, and minifies the source files from frontend/src/ into the static/dist/ directory.

  3. Run in watch mode for development:

    npm run build -- --watch
    

    This will automatically rebuild the frontend assets when you make changes to the source files.

Running the Application

  1. Ensure the frontend has been built at least once.
  2. Start the Go backend server from the project root:
    go run ./cmd/server
    
  3. 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-dark theme 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 Enter or Tab.
  • 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/json and text/markdown.

Security

  • Path Traversal: The backend validates all file paths to prevent access outside the notes directory.
  • XSS: DOMPurify is 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-multiple endpoint now correctly processes requests. This involved:
    • Changing the HTTP method from POST to DELETE in both frontend/src/file-tree.js and internal/api/handler.go.
    • Adapting the Go backend handler (handleDeleteMultiple) to manually read and parse the URL-encoded request body for DELETE requests, as r.ParseForm() does not automatically process bodies for this method.

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