# Changelog — ObsiGate Toutes les modifications notables d'ObsiGate sont documentées dans ce fichier. Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > **En cours de développement** : les changements non publiés sont dans la section > [Unreleased](#unreleased). La dernière version publiée est **2.1.0**. --- ## [Unreleased] ### Ajouté - **#61 Plugins système au complet** — système de plugins permettant d'étendre ObsiGate (renderers personnalisés, filtres de recherche, actions d'éditeur), sandboxé pour la sécurité. - Backend `backend/plugins.py` : validation du manifest `plugin.json` (name regex lowercase, semver, hooks/permissions autorisés), stockage par vault `/.obsigate-plugins/`, lifecycle complet (install/uninstall/enable/disable via marker `.disabled`), validation ZIP à l'upload (anti path-traversal, max 100 fichiers, 500KB/fichier, 5MB upload), 9 endpoints `/api/plugins/*` (list/get/hooks/code/template + install/uninstall/enable/disable admin-gated), template API, scan au démarrage par vault (`get_plugin_registry().scan_vault`). - Frontend `frontend/js/plugins.js` : PluginManager (install/uninstall/enable/disable/view-code), sandbox d'exécution via Web Worker (code chargé par blob URL, protocole `postMessage` structuré, isolation DOM/localStorage/network selon permissions), hooks dispatch (`executeHook`, `onFileRender`, `onSearchFilter`, `onEditorAction`, `onSidebarItem`, `onFileCreate`, `onFileDelete`, `onVaultMount`), UI Settings > Plugins. - Sécurité : manifest de permissions (`read_files`, `write_files`, `network_request`, … restreint), CSP stricte sans `importScripts`, limites de taille. - Tests : `tests/test_plugins.py` (44 tests — validation manifest, lifecycle manager, validation ZIP/directory, démarrage scan) + `tests/frontend/plugins.test.mjs` (21 tests JSDOM — protocole sandbox Worker, isolation DOM, lifecycle mirror). - CI : job lint ajoute `node plugins.test.mjs` aux tests JSDOM. - Docs : `docs/PLUGINS.md` (manifest, hooks, permissions, modèle de sécurité, API, guide). --- ## [2.1.0] — 2026-09-08 ### Ajouté - **#74 Support PDF au complet** — `GET /api/file/{vault}/pdf/info` (métadonnées sans contenu), streaming avec HTTP Range / 206 Partial Content (rendu progressif des gros PDF), config `OBSIGATE_PDF_MAX_SIZE_MB` (50) + `OBSIGATE_PDF_EXTRACT_TIMEOUT` (30s). 16 tests supplémentaires (26 au total dans `test_pdf.py`). - **#64 MFA — WebAuthn** (second facteur en plus du TOTP) : enregistrement de clés de sécurité / biométrie (Windows Hello, Touch ID), assertion au login, gestion des clés dans « Sécurité du compte », codes de récupération émis à l'activation. Nouveau module `backend/auth/webauthn_mfa.py` (lib `webauthn==2.6.0`, challenges in-memory TTL 180s à usage unique). 10 tests avec authentificateur virtuel (CBOR réel, ECDSA P-256). i18n FR/EN (13 clés). Config : `OBSIGATE_WEBAUTHN_RP_ID` / `_RP_NAME` / `_ORIGINS`. - **#77 Desktop — port auto-increment** : `pick_free_port()` scanne 17890..17899 si le port est occupé (2 instances côte à côte possibles) + 3 tests Rust (19 au total côté desktop). - Docs : sections PDF README FR/EN (Range, /pdf/info), variables env, guide WebAuthn. - **#75 Split View — matrice E2E complète (37 tests)** : 16 tests `split-view.spec.js` (raccourcis, drag & drop, persistance, navigation clavier) + 21 tests `split-view-matrix.spec.js` couvrant 100% des cas d'ouverture/fermeture : boutons ⊞→/⊞↓, menu contextuel (diviser bas, fermer, fermer les autres/à droite/tout, fermer le panneau, flyout « Déplacer vers… »), palette (diviser, focus suivant/précédent, reset), fermeture par X/double-clic/molette/Ctrl+W, auto-collapse d'un panneau vidé, plafond 4 panneaux, drag-to-split bas, pas de doublon à la réouverture. - Fix `scripts/run-e2e-local.sh` : chemins Windows via `cygpath` (les env vars MSYS n'étaient pas converties → vaults vides, les 16 tests split-view échouaient en local alors qu'ils passaient en CI). ### Corrigé - **PDF stream 500** : `api_pdf_stream` plantait systématiquement (`NameError: current_user` non injecté — endpoint jamais couvert par un test). Désormais authentifié + testé. - **Indexation incrémentale des PDF** : le chemin watcher (`_index_single_file_sync`) lisait les PDFs en `read_text()` → contenu garbage indexé. Utilise maintenant `extract_pdf_text()` comme le scan complet. --- ## [2.0.0] — Unreleased > ObsiGate passe à **2.0.0** avec sa **version bureau native** et de nombreuses fonctionnalités > de productivité (branch main, 341 commits après le tag v1.8.0). ### Ajouté - **Application bureau native (Tauri 2)** — Porte d'entrée desktop pour vaults Obsidian (`desktop/`) - **Dashboard administrateur (#71, backend)** — 4 endpoints admin-gated pour monitoring serveur - `GET /api/admin/stats` — CPU/RAM/Disk/Uptime via psutil - `GET /api/admin/audit` — 500 dernières entrées d'audit avec filtres `user`/`action`/`limit`/`offset` - `GET /api/admin/backup-stats` — compte + taille + age par vault - `GET /api/admin/stream` — Server-Sent Events qui push les stats toutes les 5s - Nouveau module `backend/admin.py` + 13 tests pytest - **Tests JSDOM PaneManager (#75, sous-tâche I2)** — 9 tests d'intégration frontend via JSDOM 30 - Couvre : factory, init, open/activate/close, isolation entre panes, drag/drop smoke - Wired dans le CI Gitea (`.gitea/workflows/ci.yml`) - Shell Rust + Tauri 2 (tray icon, notifications OS, auto-update depuis Gitea) - Backend Python embarqué (python-embed) avec health check, démarrage ~2s - Sélecteur de dossiers natif, config persistante des vaults (type VAULT vs DIR) - Fenêtre console masquée, arrêt propre via tray, associations de fichiers `.md` - Packages : Windows MSI + NSIS, Linux .deb + AppImage - Pipeline CI/CD Desktop (`.gitea/workflows/desktop-build.yml`) - Thème système auto (clair/sombre) + RAM réduite (~80 MB au repos) - Écran de chargement inline (staging backend/frontend pour le bundle desktop) - **Internationalisation FR/EN complète** — 1357 clés i18n, préférence serveur, guide entièrement traduit - **Vue multi-panneaux (Split View #75)** — PaneManager + TabManager par panneau - Split droite/bas, drag & drop cross-pane, drag-to-split (bord droit/bas) - Boutons de split, navigation clavier, fermeture auto des panneaux vides - **Mermaid.js** — Rendu de diagrammes (22 templates, thème dark synchronisé) - Header bar Code/Preview, zoom, export SVG + PNG, plein écran / focus 480px - Pré-processeur Obsidian (`[[liens]]`, `![[img]]`, `==highlight==`) - **Gestionnaire de Backups complet** — Page, filtres, purge, restauration - Diff viewer (unifié + côte à côte), preview 100 Ko, compression gzip - Backup automatique, auto-nettoyage (max_backups_per_file) - **Support Excalidraw (#78)** — Fichiers `.excalidraw` / `.excalidraw.md` - Décompression lz-string, création depuis modale/menu contextuel - **Éditeur Forge + autocomplétion IA** — Auto-height, Mermaid QI, ghost text - Autocomplétion Ollama (qwen2.5-coder), Alt+/, auto-continuation listes/checkboxes - **Support PDF + multi-format** — PDF avec TOC, images/CSV/JSON/TXT - **15 thèmes clair/sombre (#65)** — Système de thèmes configurable - **Mode hors-ligne PWA (#59)** — Badge hors-ligne + gestion des conflits - **Tests E2E Playwright (#58)** — Suite desktop (44 tests) + CI ### Modifié - `desktop/` — Nouveau : application Tauri (Cargo.toml, build.rs, `src/main.rs`, scripts build) - `frontend/` — i18n, split view, Mermaid, Excalidraw, Forge, thèmes - `backend/` — Endpoints backups, Excalidraw, multi-format, versioning git - `docs/ROADMAP.md` — Feuille de route passée à 2.0.0-dev, items #75/#78 complétés --- ## [1.8.0] — 2026-06-04 ### Ajouté - **Palette de commandes** — Navigation rapide fichiers + commandes - Raccourcis : `Ctrl+P` fichiers, `Ctrl+Alt+Espace` commandes, `Ctrl+Shift+Espace` - Navigateur de dossiers : créer/supprimer fichiers/dossiers par sélection - Opérateurs `+include` / `-exclude` dans la recherche globale - 6 nouvelles commandes : créer/supprimer fichiers/dossiers, éditer, pop-out - **Barre d'outils mobile de bas de page** — Type Obsidian 📱 - Explorateur, recherche, palette, changement d'onglet - Indicateur de vault contextuel sous le header, pull-to-refresh - **Diff viewer des backups** — Comparaison unifiée + côte à côte, restauration - **Indicateur AI Actif** — Badge/statut IA dans le header (lecture runtime des clés) - **Page d'accueil de vault** — Liste récursive des fichiers par date - **Drag & drop de fichiers** dans l'arborescence - **Guide d'aide enrichi** — Recherche, scroll spy, slide-over mobile, section webhooks - **Indexation inversée non-bloquante** (`run_in_executor`) - **Infrastructure de tests** — Couverture pytest portée à 70% (+109 tests) ### Modifié - `frontend/` — Palette, mobile toolbar, aide, AI indicator, vault home - `backend/` — Indexation non-bloquante, statut IA, diff/restauration backups - `docs/` — Guide d'utilisation enrichi (navigation clavier), CHANGELOG/README/ROADMAP ### Corrigé - Correctifs UI mobile, palette, aide et AI toolbar (thème clair, menu clipping) --- ## [1.7.0] — 2026-05-30 ### Ajouté - **AI Editor Toolbar** — Barre d'outils IA intégrée à l'éditeur CodeMirror - Menus dropdown : Edit (improve, fix spelling, shorter, longer, simplify), Tone (professional, casual), Translate (multi-langue), Generate (explain, summarize, continue), Custom Rewrite, Toolbox (to list, to table, frontmatter, to canvas) - Multi-provider : DeepSeek / OpenRouter / Gemini, configurable via `.env` - 16 endpoints REST : `POST /api/ai/{edit|tone|translate|generate|rewrite|toolbox}` - Auto-save silencieux (2s debounce) avec feedback visuel toast - Cache toolbar si pas de clé API configurée - Messages d'erreur clairs (401→clé invalide, etc.) - **Graph view — Améliorations majeures** - Header flat design 2 lignes responsives (titre flexible + recherche dédiée + barre statut) - Navigation historique ← → + ↑ Parent - Sticky panels : tuile info (top-left/right) avec métadonnées, preview pleine hauteur (droite) - Ctrl+survol → aperçu contenu formaté (via `/raw`) dans tooltip - Filtre par tag dans la vue graphe - Boutons close ✕ sur les panneaux - Fond hover foncé unifié ### Modifié - **backends/ai.py** — Nouveau module IA backend - **backends/ai_routes.py** — Routes API pour l'éditeur IA - **frontend/js/ai.js** — Module frontend de la toolbar IA (404 lignes) - **frontend/js/graph.js** — Refonte complète : sticky panels, nav historique, aperçu markdown --- ## [1.6.0] — 2026-05-29 ### Ajouté - **Vue graphe des wikilinks** — Canvas force-directed - Phase 1 : Full-vault view, filtre par tag, backlinks entrants, métriques de nœud - Phase 2 : Recherche visuelle, tooltips survol, couleurs adaptatives, slider profondeur (0-3) - Phase 3 : Filtre par type (dossier/fichier/.md/autre), mode focus, plein écran, export PNG - Phase 4 : Barnes-Hut O(n log n), cache graphe - **sortedcontainers** → O(log n) insert/remove dans l'index inversé - **CI/CD Pipeline complet** — Gitea Actions - Ruff linting (0 erreur) - Mypy type checking (0 erreur) - Pytest — 175 tests, 49% coverage - Bandit SAST — scan de sécurité - Pip-audit — vulnérabilités dépendances - Docker build — vérification image - Coverage artifact — uploadé via `actions/upload-artifact@v3` - Runner Gitea auto-hébergé (`gitea/act_runner:0.2.11` sur Alpine/Proxmox) ### Modifié - `backend/search.py` — Remplacement bisect → SortedList pour le vocabulaire - `.gitea/workflows/ci.yml` — Pipeline CI/CD complet ### Corrigé - Résolution de 28 erreurs mypy pré-existantes - Fix lint ruff + faux positifs bandit + pip-audit non-bloquant --- ## [1.5.1] — 2026-05-28 ### Ajouté - **Split `app.js` (8 875 lignes) en 16 modules ES** - Modules : `state.js`, `utils.js`, `auth.js`, `ui.js` (76KB), `viewer.js` (47KB), `sidebar.js`, `search.js` (45KB), `config.js`, `dashboard.js`, `graph.js` (33KB), `sync.js`, `legacy.js`, `ai.js` - Import/export validator CI (`tests/frontend/validate-imports.mjs`) - Tests unitaires frontend (`tests/frontend/unit.test.mjs`) - **Stemming français** — `snowballstemmer` intégré au tokenizer - "manger" trouve "mangé", "mangeons", "mangeait" - Performance O(T) au lieu de O(S×T) — fix freeze 15min sur gros vaults - Crash guard : try/except snowballstemmer IndexError sur tokens exotiques ### Modifié - `frontend/js/app.js` → entrypoint ES module important les 16 modules - `backend/search.py` — tokenizer avec FrenchStemmer ### Corrigé - Nombreuses régressions post-split : imports manquants, exports oubliés, shadowing de variables - Réécriture state.js → mutable object (`export const state = {...}`) pour éviter les erreurs `assignment to constant` - Plus de 60 correctifs d'imports/exports validés par le validator CI - Tags de template `{{...}}` exclus du tag cloud via filtre configurable --- ## [1.5.0] — 2026-05-26 ### Ajouté - **Publication publique** — Génération de lien partageable avec token unique (64-char hex) - Expiration configurable, lecture seule, sans authentification - `backend/share.py` + endpoints CRUD + vue publique `/s/{token}` - Export PDF via WeasyPrint (lazy import) dans la vue publique - Support fichiers non-Markdown dans la vue publique - **Webhooks** — Notifications HTTP POST vers services externes - Signature HMAC-SHA256 optionnelle - `backend/webhooks.py` + CRUD endpoints + UI dans Configuration - **Dashboard statistiques** — Métriques agrégées par vault - Widget `DashboardStatsWidget` avec 4 cartes (fichiers, tags, taille, vaults) - Widget "Derniers fichiers ouverts" avec timestamps - **Documentation OpenAPI enrichie** — Tous les modèles Pydantic documentés (`Field(description=...)`) - Visible dans `/docs` (Swagger UI) et `/redoc` - **Documentation complète** — `ANALYSE_REVIEW.md`, `AUDIT_TECHNIQUE.md`, `ROADMAP.md` ### Modifié - `frontend/js/app.js` — Nouveau système d'onglets (TabManager), dashboard - `frontend/style.css` — Dashboard, share view, webhooks UI - `backend/main.py` — Nouveaux endpoints share/webhooks/dashboard - `backend/search.py` — Index inversé incrémental (hook pattern) --- ## [1.4.0] — 2026-05-25 ### Ajouté - **Rate limiting** — IP-based (10 tentatives/15min) + lockout par compte (5 tentatives) - `backend/ratelimit.py` — RateLimiter thread-safe avec nettoyage périodique - Intégré à `backend/auth/router.py` - **Secret redactor** — Masquage automatique des secrets dans les aperçus - `backend/secret_redactor.py` — JWT, API keys, tokens GitHub, clés privées, connection strings - **Audit log** — Traçage des écritures/suppressions/changements de config - `backend/audit.py` — JSON lines dans `data/audit.log`, rotation 10MB - **Backup automatique avant écriture** - Sauvegarde du contenu original dans `.obsigate-backup/` avant PUT/DELETE - **Backlinks panel** — Fichiers avec wikilinks pointant vers le fichier courant - `GET /api/file/{vault}/backlinks` + index inversé dans `indexer.py` - **Gestion des conflits Syncthing** - Détection automatique des fichiers `.sync-conflict-*` - Résolution : garder local, garder conflit - `GET /api/conflicts`, `POST /api/conflicts/resolve` - **Syncthing conflicts dashboard** — Vue dédiée dans l'UI - **IGNORED_DIRS configurable** — `OBSIGATE_IGNORED_DIRS` (liste séparée par virgules) - **Timeout de session configurable** — `OBSIGATE_ACCESS_TOKEN_TTL` / `OBSIGATE_REFRESH_TOKEN_TTL` ### Modifié - `backend/main.py` — +audit, +backup, +redaction, +backlinks endpoint, +conflicts endpoint - `backend/indexer.py` — +backlink index, +IGNORED_DIRS - `backend/auth/router.py` — +IP rate limiting - `backend/auth/jwt_handler.py` — +configurable TTL - `backend/watcher.py` — +configurable IGNORED_DIRS --- ## [1.3.0] — 2026-05-23 ### Ajouté - **Authentification complète** — JWT + Argon2id - Login/logout, refresh tokens, cookies httpOnly - Contrôle d'accès par vault - Interface d'administration : création/modification/suppression d'utilisateurs - "Se souvenir de moi", sessions persistantes - `backend/auth/` — 5 modules (~600 lignes) - **CodeMirror 6** — Éditeur de fichiers intégré - Syntax highlighting multi-langage - Sauvegarde, annulation, fallback textarea si CM6 échoue - Auto-sync frontmatter YAML - Find-in-page (Ctrl+F) avec regex, barre de navigation - **PWA complet** — `manifest.json`, `sw.js`, icônes multi-tailles - Installation via bouton "Installer l'application" - Thème synchronisé entre fenêtres popout - Service Worker avec mise en cache - **Synchronisation temps réel** — Watchdog + SSE - Surveillance automatique des fichiers - Mise à jour incrémentale de l'index - SSE Manager avec reconnexion automatique - `backend/watcher.py` — watchdog observer avec debounce 2s - **Drag & drop / rename** — Menu contextuel arborescence - Création fichier/dossier, rename inline, suppression - Boutons d'action toujours visibles, support mobile long-press ### Modifié - `frontend/app.js` — Refonte majeure : authentication flows, code editor, PWA, sync - `frontend/style.css` — CodeMirror themes, auth forms, PWA UI, responsive - `docker-compose.yml` — auth env vars, data volume, non-root user - `backend/main.py` — auth middleware, file CRUD, code editor API, SSE, PWA - `requirements.txt` — argon2-cffi, python-jose, python-multipart --- ## [1.2.0] — 2026-05-18 ### Ajouté - **Rendu d'images Obsidian** — Support complet de toutes les syntaxes - Standard Markdown avec attributs HTML - Wiki-link embed (`![[path/to/image.png]]`) - Markdown standard (`![alt](path)`) - Résolution multi-stratégies (7 niveaux) - Indexation des attachements au démarrage - Cache de résolution pour performance - **Système de fichiers cachés** — Configuration par vault - `includeHidden`, `hiddenWhitelist` — UI + env vars - Filtrage côté client (hideHiddenFiles) ### Modifié - `backend/attachment_indexer.py` — Scan et indexation d'images - `backend/image_processor.py` — Prétraitement Markdown pour les syntaxes d'images - `GET /api/image/{vault}?path=` — Serve images avec MIME types - `POST /api/attachments/rescan/{vault}` — Rescan manuel - `HIDDEN_FILES_GUIDE.md`, `IMAGE_RENDERING_GUIDE.md` --- ## [1.1.0] — 2026-05-15 ### Ajouté - **Recherche TF-IDF avancée** — Moteur complet avec index inversé - Opérateurs : `tag:`, `vault:`, `title:`, `path:`, `ext:` - Autocomplétion intelligente (fichiers, tags, historique) - Facettes, pagination, tri par pertinence - Snippets surlignés ``, accent-insensitive - Search history (localStorage, max 50, LIFO, dédupliqué) - **Recherche regex** — `extractRegexSnippet()` avec surlignage - **Recherches sauvegardées** — CRUD API + sidebar UI - Sauvegarde/chargement/suppression de requêtes - **Filtres de recherche** — toggles (case, mot entier, regex), chemins - **Onglets sidebar** — vaults, tags, récents, saved searches - **Auto-expand vault** dans le filtre sidebar - **Tree search** — Filtrage temps réel de l'arborescence avec surlignage ### Modifié - `backend/search.py` — Nouveau : InvertedIndex, TF-IDF, autocomplete - `frontend/app.js` — Refonte recherche : nouveau système de requêtes, facettes, pagination, autocomplete - `frontend/style.css` — Search results cards, autocomplete dropdown, tags --- ## [1.0.0] — 2026-05-10 ### Ajouté - **Première version stable** — Porte d'entrée web pour vaults Obsidian - **Multi-vault** — Visualisation de plusieurs vaults simultanément - **Arborescence** — Navigation hiérarchique avec lazy-loading - **Rendu Markdown** — Conversion HTML via mistune (tables, task lists, footnotes, strikethrough) - **Extraction YAML frontmatter** — Tous les champs parsés avec carte pliable, badges, tags - **Vue Source (raw)** — Toggle markdown brut + frontmatter - **Édition** — PUT/DELETE fichiers via API - **Breadcrumbs** — Navigation avec auto-expand et highlight - **TOC** — Table des matières avec scroll spy et barre de progression - **Thème clair/sombre** — Toggle localStorage + synchronisé fenêtres popout - **Popout** — Fenêtre détachée pour affichage standalone - **Configuration UI** — Paramètres persistants par vault - **Docker multi-stage** — Image ~180MB, linux/amd64 + arm64 + arm/v7 + i386 - **Healthcheck** — Endpoint `/api/health` - **Headers sécurité** — CSP, X-Frame-Options, XSS-Protection, Referrer-Policy - **Path traversal protection** — `_resolve_safe_path()` symlink-aware - **Security hardening** — Utilisateur non-root (UID 1000) - **Compression GZip** (SSE-safe), **Cache-Control immutable** - **build.sh** — Script de build automatisé ### Architecture - **Backend** : FastAPI 0.110.3, uvicorn 0.30.0, Python 3.11+ - **Frontend** : Vanilla JS SPA (0 dépendances npm), CSS custom properties - **Indexation** : In-memory, mise à jour incrémentale, watcher watchdog - **Recherche** : TF-IDF inversé, sans I/O disque