Files
ObsiGate/CHANGELOG.md
T

43 KiB
Raw Blame History

Changelog — ObsiGate

Toutes les modifications notables d'ObsiGate sont documentées dans ce fichier.

Format basé sur Keep a Changelog, et Semantic Versioning.

En cours de développement : les changements non publiés sont dans la section Unreleased. La dernière version publiée est 2.2.1.


[Unreleased]

Ajouté

  • #70 Recherche sémantique — Embeddings vectoriels — la recherche comprend désormais le sens de la requête en plus des mots-clés. Embeddings : chaque document est découpé en chunks de 512 mots (recouvrement 64) puis vectorisé (384 dim) via all-MiniLM-L6-v2 (sentence-transformers), un endpoint /embeddings compatible OpenAI, ou un provider de repli sans dépendance (hachage déterministe). Stockage vectoriel : numpy/faiss (IndexFlatIP) si disponibles, sinon cosinus pur Python. Recherche hybride : fusion du classement TF-IDF et du classement sémantique par RRF (Reciprocal Rank Fusion), avec semantic_score par résultat. Indexation incrémentale branchée sur le watcher (un fichier modifié régénère son embedding). UI : toggle « Recherche sémantique » (~, raccourci Alt+S) dans la barre de résultats + affichage du score de similarité, clés i18n FR/EN. Nouveau module backend/semantic_search.py, paramètre semantic sur /api/search/advanced, dépendances optionnelles dans backend/requirements-semantic.txt. Tests : tests/test_semantic_search.py (27) + tests/frontend/semantic-search.test.mjs (4). Détail : docs/features/semantic-search.md.

  • #69 Éditeur mobile natif — Interface tactile optimisée — refonte de l'expérience d'édition sur téléphone/tablette. Barre d'outils flottante dans l'éditeur (gras, italique, code, liste à puces, lien) opérant directement sur la sélection CodeMirror (ou le textarea de secours), avec toggle (re-appui pour dé-formater) ; bouton « Coller » persistant qui contourne la restriction presse-papiers d'iOS (repli sur un message d'aide si l'accès est refusé). Adaptation CodeMirror : zoom par pincement à deux doigts, boutons A−/A+ et hauteur ajustable via une poignée (valeurs persistées en localStorage). Côté lecture : raccourcis swipe (gauche → liens entrants, droite → table des matières) et mode lecture plein écran (masquage de l'en-tête, des barres latérales et de la barre mobile, API Fullscreen, swipe horizontal pour passer au fichier suivant/précédent du même dossier). Nouveau module frontend/js/mobile-editor.js, styles frontend/style.css, clés i18n FR/EN. Tests : tests/frontend/mobile-editor.test.mjs (22 tests). Détail : docs/features/mobile-editor.md.

  • #62 Collaboration temps réel — Édition simultanée — plusieurs utilisateurs peuvent éditer le même document markdown en même temps, façon Google Docs. WebSocket : nouvel endpoint /ws/collab/{vault}/{path} (une room par fichier) qui relaie les changements instantanément ; authentification manuelle (cookie access_token ou paramètre token) + check_vault_access et resolve_safe_path par connexion. Yjs/CRDT côté client : Y.Doc/Y.Text fusionnent les modifications concurrentes sans conflit ni perte. Awareness : curseurs distants colorés et sélections dans CodeMirror, indicateur de présence (avatars + statut) dans l'en-tête de l'éditeur. Persistance serveur : le dernier texte reçu est écrit sur disque avec un debounce de 2 s (backend/collab.py). Reconnexion automatique avec backoff exponentiel et merge de l'état au retour. Nouveau module frontend frontend/js/collab.js (provider + liaison Y.Text↔CodeMirror + curseurs distants) et backend/collab.py (CollabManager). Tests : tests/test_collab.py (17 tests, dont 5 clients simultanés) et tests/frontend/collab.test.mjs. Détail : docs/features/collaboration.md.

  • #79 Phase F — Durcissement & documentation (rate limiting, redaction, OpenAPI/MCP, E2E) — clôture de la feature #79. Rate limiting par jeton et par outil (backend/tools/ratelimit.py, fenêtre glissante ; identité = JTI du jeton sinon id/username ; OBSIGATE_TOOL_RATE_LIMIT, OBSIGATE_TOOL_RATE_LIMIT_PER_TOOL, OBSIGATE_TOOL_RATE_WINDOW ; erreur rate_limited). Quotas BOOKSLM_MAX_* : BOOKSLM_MAX_TOOL_CALLS plafonne les appels d'outils par run d'agent (stopped="quota_exceeded") et BOOKSLM_MAX_TOOL_READ_BYTES plafonne read_file. Redaction systématique de tout résultat d'outil avant retour au LLM (backend/tools/redaction.py, récursif : diffs, extraits de recherche, lectures). OpenAPI : tag MCP + injection du path /mcp (Streamable HTTP) dans le schéma ; nouveau docs/MCP_GUIDE.md (config Claude Desktop/Cursor, tools/resources/prompts, sécurité, variables, dépannage). Tests E2E : tests/test_ai_e2e.py (agent read→confirm→write, quota, rate limit, redaction, flux MCP read→propose→apply→resources/read).

  • #79 Phase E — Serveur MCP (Streamable HTTP) — nouvel endpoint /mcp exposant ObsiGate à des clients MCP externes (Claude Desktop, Cursor…) via le SDK Python mcp==1.9.4. Les deux fronts (assistant in-app et MCP) consomment la même couche d'outils. Tools : outils de lecture/recherche directs ; outils d'écriture/destructifs en two-step propose_<tool> / apply_<tool> avec jeton JWT signé, usage unique et TTL (OBSIGATE_MCP_CONFIRMATION_TTL, défaut 300 s) et blacklist de JTI persistée (data/mcp_used_tokens.json, anti-rejeu). Resources : vault://<name> et vault://<name>/<path> (lecture seule, secrets redactés). Prompts : summarize-directory, generate-note, find-related. Auth Authorization: Bearer <JWT> → get_current_user ; permissions et toggle destructif par vault (aiDestructiveTools) appliqués. Nouveaux modules backend/mcp/server.py et backend/mcp/confirmations.py ; dépendances mcp==1.9.4 + sse-starlette==2.1.3 (compatibles FastAPI 0.110 / starlette 0.37). Tests : tests/test_mcp.py (13 tests).

  • #79 Phase D — Catalogue d'outils mutations + confirmations two-step — 11 nouveaux outils IA destructifs ou d'écriture exposés par la couche partagée (backend/tools/service.py) : create_file, create_directory, edit_file, append_to_file, rename_file, rename_directory, move_path, replace_in_files, delete_file, delete_directory, restore_backup. Nouveau service réutilisable backend/services/mutations.py (anti path-traversal, garde lecture seule, backup automatique avant écriture/suppression/restauration) ; les routes /api/file/{vault} (POST/PATCH/DELETE), /api/file/{vault}/save, /api/directory/{vault} (POST/PATCH/DELETE), /api/move/{vault}, /api/file/{vault}/restore et /api/search/replace délèguent désormais à cette couche. backend/services/backups.py expose create_backup (source unique, réutilisée par main._backup_file). Confirmations two-step : tout outil WRITE/DANGEROUS déclenche ToolConfirmationRequired (carte Apply in-app, propose/apply côté MCP en phase E). Toggle par vault aiDestructiveTools (défaut : activés) pour désactiver delete/rename/move/replace. Tests : tests/test_tools_mutations.py (40 tests).

  • #79 Phase C — Catalogue d'outils lecture & recherche — 10 nouveaux outils IA exposés par la couche partagée (backend/tools/service.py) : list_all_files, read_file_raw, get_backlinks, list_backups, diff_backup, get_graph, search_advanced, search_paths, suggest_tags, list_recent. Nouveaux services réutilisables backend/services/backups.py, graph.py, recent.py et extensions de vaults.py (list_all_files) / search.py (advanced_search_vaults, search_paths). Les routes /api/recent, /api/vault/{vault}/files, /api/file/{vault}/backups, /api/file/{vault}/diff, /api/graph/{vault}, /api/tree-search et /api/search/advanced délèguent désormais à ces services (source unique de vérité). Filtrage systématique par permissions vault ; secrets redactés sur read_file/read_file_raw. Tests : tests/test_tools.py (+17 tests).

  • #79 Assistant IA — Outils (function calling) & serveur MCP — Phase 0 (couche d'outils partagée) — nouveau paquet backend/tools/ : context.py (ToolContext), registry.py (décorateur @tool

    • schéma JSON), schemas.py, service.py, audit.py (journalisation JSONL des appels), façade backend/tools/api.py. Services lecture/recherche livrés (list_vaults, list_directory, read_file, search_fulltext, list_tags) ; permissions check_vault_access + resolve_safe_path appliquées par outil. Tests : tests/test_tools.py (30 tests).
  • #79 Phase B (partielle) — function calling in-app — abstraction tool-calling provider-agnostique backend/ai_chat.py (chat_completion, ToolCall, LLMResponse, OpenAI-compat

    • Gemini) ; agent loop backend/agent/loop.py (boucle tool→résultat→tool, limite 10 itérations, truncation) ; endpoint opt-in POST /api/ai/bookslm/agent (events SSE tool/message/confirmation) ; fallback automatique en chat simple si le provider rejette les tools. Tests : tests/test_agent_loop.py, tests/test_ai_chat.py, tests/test_bookslm.py.
  • #79 A2/B4/B5 — services partagés, SSE streaming & confirmations UI — extraction de la logique lecture/recherche dans backend/services/ (errors.py, paths.py, vaults.py, files.py, search.py) : routes REST et outils IA consomment la même source ; ServiceError mappée vers HTTPException (routes) et ToolError (outils). /api/ai/bookslm/chat streame réellement les tokens (stream_completion, OpenAI-compat + Gemini ; GZip ignoré pour les SSE BooksLM). Mode agent côté UI (toggle, événements tool/confirmation, carte Apply + aperçu diff LCS) et reprise confirm/confirm_messages de l'agent loop (confirmation one-shot). Tests : tests/test_services.py, tests/test_ai_chat.py, tests/test_agent_loop.py, tests/test_bookslm.py.

  • #79 G — Sélection fournisseur/modèle par défaut — ai_default_provider + ai_default_models persistés dans data/config.json, rechargement à chaud dans backend/ai.py, sélecteurs « Fournisseur par défaut » / « Modèle par défaut » dans #cfg-ai, i18n FR/EN.

  • #80 Assistant IA — Rendu Markdown, liens fichiers/paths & sessions — réponses de l'assistant rendues en Markdown formaté (titres, listes, tableaux, citations, code, emphase) via un renderer auto-contenu ; les fichiers et chemins mentionnés deviennent des liens cliquables (clic fichier → ouverture dans le viewer, clic répertoire → révélation/surlignage dans l'arborescence, outils open_file/reveal_in_tree côté in-app) ; gestion des sessions par contexte (historique consultable, rechargeable, supprimable) avec migration de l'ancienne conversation unique. Tests : tests/frontend/ai.test.mjs.

Modifié

  • Assistant IA (frontend/js/bookslm.js) — l'ancien rendu Markdown minimal est remplacé par un renderer bloc/inline complet ; l'en-tête expose un bouton « Historique des sessions » ; les badges de sources ouvrent désormais réellement le fichier (événement obsigate:open-file).

  • Assistant IA (frontend/js/bookslm.js) — bouton « mode agent » dans l'en-tête (persisté en localStorage) : l'envoi bascule vers /api/ai/bookslm/agent, affiche la trace des appels d'outils et les cartes de confirmation (Apply + aperçu diff) ; /chat reste le défaut. i18n FR/EN.

Corrigé

  • BUG-005 — Chargement mobile incomplet derrière Cloudflare (og.dracodev.net) — le service worker utilisait une stratégie cache-first avec un nom de cache fixe (obsigate-v1) et un précache de chemins erronés (/frontend/js/…) : le Cache Storage du SW (distinct du cache navigateur/Cloudflare) servait un ancien build indéfiniment, même après purge. Le middleware renvoyait en plus Cache-Control: public, max-age=31536000, immutable sur des assets non fingerprintés. Correctifs : frontend/sw.js réécrit (network-first pour HTML/JS/CSS, caches versionnés SW_VERSION, précache corrigé /static/js/…, skipWaiting/clients.claim) ; migration ponctuelle localStorage (suppression des anciens caches) en remplacement du kill-switch de session ; en-têtes no-cache sur /static, index.html, manifest.json et pages HTML ; rechargement unique sur controllerchange. Tests : tests/frontend/sw.test.mjs + TestStaticCaching. Guide Cloudflare : docs/PWA_GUIDE.md.

  • Typage backend (mypy) — 33 erreurs corrigées (backend/main.py, indexer.py, auth/router.py, pdf_reader.py, export.py, bookslm_routes.py) : annotations de types, gardes None sur get_user(), PdfReader: Any et import PROVIDERS manquant dans main.py (bug latent : le modèle par défaut n'était jamais prépendé à la liste des modèles live). L'étape mypy du CI devient bloquante (elle était en mode advisory).

  • README — lien « Contributing » corrigé vers docs/CONTRIBUTING.md (était cassé vers la racine) ; arbre du projet mis à jour.

  • #79 façade backend/tools/api.py — gestion des namespace packages et du __init__ ignoré lors du chargement des modules d'outils.

Documentation

  • Guide d'architecture IA — docs/AI_ARCHITECTURE_GUIDE.md (architecture, catalogue d'outils, sécurité, phases).

  • Refonte de la documentation — la Roadmap ne contient plus que le travail à venir + un index compact ; les fonctionnalités livrées sont archivées dans docs/archive/COMPLETED_v1-v2.md et documentées par feature dans docs/features/.

  • Méthode de livraison unifiée — nouveau docs/DELIVERY_WORKFLOW.md (Definition of Done : tests, documentation, commit, push, CI) et AGENTS.md (instructions obligatoires lues à chaque session). Référencés depuis la Roadmap, CONTRIBUTING et ISSUES_TODOLIST.


[2.2.1] — 2026-09-11

Ajouté

  • Mobile — assistant AI central — bouton assistant dans la barre du bas (commit 50b823e).

Corrigé

  • Version affichée dans l'UI — affichait 2.1.0 au lieu de 2.2.0 (commit 84bda90).
  • Mobile — boîte d'édition de l'assistant relevée au-dessus de la barre du bas (commit f307ecb).

[2.2.0] — 2026-09-11

Ajouté

  • Assistant AI contextuel (sidebar) — l'assistant s'adapte désormais au contexte d'ouverture :

    • Répertoire (directory) : ouvert depuis le menu contextuel d'un dossier — le contexte est le dossier et son contenu (mode historique BooksLM).
    • Documents (documents) : ouvert via le bouton flottant quand un ou plusieurs documents sont ouverts — le contexte est la liste des fichiers ouverts (tous onglets/panneaux).
    • Général (general) : ouvert via le bouton flottant quand aucun document n'est ouvert — l'assistant répond sur l'application et peut proposer des actions (créer un fichier/dossier) via un bloc obsigate-action rendu en carte avec bouton « Appliquer » (aucune exécution automatique).
    • Le contexte est affiché dans le header de la sidebar (icône, titre, sous-titre) et les suggestions de questions s'adaptent au mode.
    • Backend : /api/ai/bookslm/context et /chat acceptent mode (directory/documents/ general) et context_files ; collect_files_context(), empty_context() et build_general_system_prompt() dans backend/bookslm.py ; le mode documents dégrade proprement vers le mode général si aucun fichier n'est lisible.
    • Tests : tests/test_bookslm.py (+13 tests modes/documents/général) et tests/frontend/ai.test.mjs (+8 tests détection de contexte, clavier, actions, header).
  • #72 API publique documentée — OpenAPI 3.1 enrichie — documentation interactive complète de l'API REST, générée automatiquement et enrichie.

    • Backend backend/openapi_docs.py : métadonnées de tags (18 catégories : System, Auth, Files, PDF, Vaults, Search, Bookmarks, Backups, Export, AI, BooksLM, Sharing, Webhooks, Conflicts, Admin, Plugins, Push, Frontend), assignation automatique des tags par préfixe de route (normalisation des tags des routeurs), schémas de sécurité (bearerAuth, cookieAuth), exemples de requête/réponse sur les endpoints clés, réponses d'erreur documentées (401/403/404/422/500), serveur et externalDocs.
    • backend/schemas.py : nouveaux response_model Pydantic pour les endpoints qui n'en avaient pas (recent, bookmarks, saved searches, backups, diff/restore/backlinks, pdf/info, replace, vaults, attachments, settings, config, AI keys/models, diagnostics, dashboard, webhooks, shares, conflicts, BooksLM context, AI status).
    • backend/main.py : FastAPI(...) enrichi (description Markdown, contact, licence, tags) et override app.openapi pour post-traiter le schéma ; page de documentation /api (HTML autonome listant les endpoints groupés par catégorie, liens vers /docs, /redoc, /openapi.json).
    • Frontend : entrée « API » dans le menu d'options (i18n FR/EN) ouvrant Swagger UI.
    • Tests : tests/test_openapi.py (58 tests — version 3.1, tags, sécurité, erreurs, exemples, schémas de réponse, pages /api, /docs, /redoc, /openapi.json).
  • #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 <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).
  • #78 Excalidraw — finitions : décompression lz-string du format plugin Obsidian, création depuis la modale et le menu contextuel, extraction du texte pour la recherche (B5), support .excalidraw.md (commit ac16fc1 + correctifs associés).

  • #67 Notifications web (Push API) : backend/push.py, POST /api/push/subscribe, clés VAPID dans config.json, toggle par vault, payload (fichier/vault/action) et ouverture du fichier au clic (commit ac16fc1).

  • #68 Health check enrichi : GET /api/health/detailed (admin-gated) exposant index, mémoire (RSS/heap), uptime, connexions SSE, backups et espace disque (commit ac16fc1).

  • #77 Desktop — jumplist vaults récents dans le menu Démarrer (commit ac16fc1).

  • #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.

Documentation

  • #78 Excalidraw — doc utilisateur finalisée : .excalidraw / .excalidraw.md ajoutés aux formats supportés (README FR/EN), nouvelle section « Diagrammes Excalidraw » dans le guide intégré (i18n FR/EN) et note de compatibilité avec le plugin Obsidian Excalidraw.
  • Roadmap : #78 marqué terminé (B5 extraction texte, C8 menu contextuel, F3 E2E tests/e2e/excalidraw.spec.js, H1-H3 docs) ; F2 non retenu. Points optionnels #61 (dépôt communautaire de plugins) et #74 (D2/E4/H2/I2) explicitement marqués non retenus.

Corrigé

  • Assistant AI — sidebar qui ne s'ouvrait plus & erreur de contexte :

    • Le bouton flottant passait le chemin d'un fichier comme répertoire de contexte, d'où l'erreur « Aucun fichier markdown trouvé dans ce dossier » à l'ouverture sur un document. Le contexte est maintenant détecté automatiquement (documents ouverts → mode documents, sinon mode général).
    • Un panneau précédemment masqué (obsigate-bookslm-hidden=true persisté en localStorage) restait caché lors d'une ouverture explicite → l'ouverture force désormais l'affichage.
    • Ergonomie du header : le sélecteur fournisseur/modèle était sur la même ligne que les actions et masquait ces dernières ; il est déplacé sur une seconde ligne dédiée (toolbar) pour que « nouvelle conversation / export / plein écran / fermer » restent toujours visibles.
    • Clavier de la boîte de chat : Entrée envoie la requête, Ctrl+Entrée insère un saut de ligne (au lieu de l'inverse), avec un texte d'aide sous le champ.
  • Outil AI de l'UI — fiabilisation :

    • BooksLM (chat IA par répertoire) : les requêtes context/chat n'envoyaient pas le jeton d'authentification (échec 401 quand l'auth est activée) et la réponse SSE était mal parsée (le backend émet {token: ...}, le front lisait data.content) → les réponses n'apparaissaient jamais. Le message utilisateur envoyé était le placeholder assistant vide au lieu du texte saisi. Corrigé : requêtes authentifiées via AuthManager (retry 401), parsing SSE event:/data: avec support token/error, historique construit avant l'ajout du message courant, barre de progression basée sur max_total_chars.
    • AI Editor : le raccourci Ctrl/Cmd+J (complétion inline) était re-lié à chaque ouverture de l'éditeur (N listeners → N requêtes) ; un seul listener global est désormais posé. Les libellés de la barre d'outils AI étaient codés en dur (FR/EN mélangés) → i18n complet. La réécriture personnalisée utilisait window.prompt() → remplacée par une modale accessible (Échap annule, Ctrl/Cmd+Entrée valide).
  • Recherche cassée (régression plugins) : onSearchFilter() était appelée avec 2 arguments au lieu de 3 (frontend/js/search.js), renvoyait undefined, faisait échouer le rendu des résultats et basculait silencieusement sur la recherche hors-ligne (0 résultat). Corrigé → la recherche full-text et l'autocomplétion refonctionnent (20 tests E2E).

  • .excalidraw.md corrompu à l'ouverture : Excalidraw émet onChange au montage, ce qui déclenchait un auto-save 2 s plus tard réécrivant le fichier au format JSON brut et détruisant le format plugin Obsidian (frontend/excalidraw-editor.html + frontend/js/excalidraw-viewer.js). Les changements initiaux sont désormais ignorés et le format frontmatter + compressed-json est préservé à la sauvegarde.

  • Splash / tests E2E : window.__OBSIGATE_BOOTED était posé avant la fin de init() — le splash disparaissait trop tôt et les tests E2E interagissaient avant que les handlers soient liés. Le flag est maintenant posé après résolution de init() (frontend/js/app.js), et goHome()/login() attendent ce signal.

  • Tests E2E Excalidraw : réécriture de tests/e2e/excalidraw.spec.js avec les sélecteurs réels (modale .obsigate-modal + #file-ext-select/#file-name-input, menu contextuel, canvas.first() pour les deux couches canvas).


[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] — 2026-08-25

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 <mark>, 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