1023 Commits
Author SHA1 Message Date
Spark 7f06606300 feat: panneau Spark V3 — la console en surimpression pleine page #222 v2.77.0 2026-10-23 04:13:37 +00:00
Spark 985af3a294 docs: #221 livré (2.76.1) — statut Roadmap
CI / lint (push) Successful in 2m54s
CI / security (push) Failing after 1m40s
CI / test (push) Successful in 4m59s
CI / build (push) Failing after 11m14s
CI / e2e (push) Skipped
2026-10-22 21:21:27 +00:00
Spark 440cfdcc31 fix: bouton « Console ↗ » dans le panneau Spark #221
CI / lint (push) Successful in 2m53s
CI / security (push) Failing after 1m39s
CI / test (push) Successful in 5m3s
CI / build (push) Successful in 1m39s
CI / e2e (push) Successful in 18m1s
v2.76.1
2026-10-22 21:20:51 +00:00
Spark 0ca92c3723 docs: #220 livré (2.76.0) — statut Roadmap
CI / lint (push) Successful in 2m52s
CI / security (push) Failing after 1m38s
CI / test (push) Successful in 5m3s
CI / build (push) Successful in 1m29s
CI / e2e (push) Successful in 17m47s
2026-10-22 19:59:24 +00:00
Spark f434f30286 feat: émission d'événements vers le journal du service d'agents #220
CI / lint (push) Successful in 2m53s
CI / security (push) Failing after 1m46s
CI / test (push) Successful in 4m57s
CI / build (push) Successful in 1m36s
CI / e2e (push) Successful in 17m40s
v2.76.0
2026-10-22 19:58:25 +00:00
Spark f4b8935189 docs: #219 livré (2.75.0) — statut Roadmap
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
2026-10-22 12:07:49 -04:00
Spark 014df322e7 feat: panneau Spark v2 — Markdown, largeur, thème, discussions #219
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
v2.75.0
2026-10-22 12:06:12 -04:00
bruno 39f9cc16e4 fix(deploy): retirer DIR_1 Bruno — doublon avec le vault par défaut home-user (#194), surconsommation mémoire
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
v2.74.1
2026-10-22 10:10:18 -04:00
Spark b4b3032456 docs: #218 livré (2.74.0) — statut Roadmap
CI / lint (push) Successful in 2m49s
CI / security (push) Failing after 1m40s
CI / test (push) Successful in 5m4s
CI / build (push) Successful in 1m29s
CI / e2e (push) Successful in 18m6s
2026-10-22 03:43:24 +00:00
Spark edef1ea708 feat: panneau Spark intégré à la barre commune (Fusion) #218 v2.74.0 2026-10-22 03:43:17 +00:00
Spark 7523670949 fix: barre commune v0.1.4, palier mobile élargi à 900 px (suite BUG-118, #215)
CI / lint (push) Successful in 2m54s
CI / security (push) Failing after 1m34s
CI / test (push) Successful in 4m54s
CI / build (push) Successful in 1m28s
CI / e2e (push) Successful in 18m28s
v2.73.1
2026-10-21 12:47:16 -04:00
Spark d81f328859 feat: menu des applications par la marque ✦ de la barre commune (commons v0.1.3, #215)
CI / lint (push) Successful in 2m47s
CI / security (push) Successful in 1m34s
CI / test (push) Successful in 4m55s
CI / build (push) Successful in 1m28s
CI / e2e (push) Successful in 18m20s
v2.73.0
2026-10-21 12:27:12 -04:00
Spark 1a39d601de fix: barre d'apps mobile — CSS commune v0.1.2 et rail contextuel (BUG-118, #215)
CI / lint (push) Successful in 2m51s
CI / security (push) Successful in 1m33s
CI / test (push) Successful in 4m58s
CI / build (push) Successful in 1m27s
CI / e2e (push) Successful in 18m3s
v2.72.1
2026-10-21 11:36:35 -04:00
Spark 68d3dd85a9 feat: validation locale du jeton draco_session — repli SSO dans get_current_user (#217)
CI / lint (push) Successful in 3m34s
CI / security (push) Successful in 2m17s
CI / test (push) Successful in 5m38s
CI / build (push) Successful in 2m15s
CI / e2e (push) Successful in 18m31s
v2.72.0
2026-10-20 23:47:45 -04:00
Spark cb80b08f77 feat: émettrice SSO draco_session — cookie partagé .dracodev.net, renouvellement et révocation (#216)
CI / lint (push) Successful in 3m32s
CI / security (push) Successful in 2m18s
CI / test (push) Successful in 5m38s
CI / build (push) Successful in 3m52s
CI / e2e (push) Successful in 19m0s
v2.71.0
2026-10-20 23:33:52 -04:00
Spark e5577b9996 fix: planchers de sécurité des dépendances — pip-audit vierge (aiohttp, mcp, pillow, certifi)
CI / lint (push) Successful in 3m40s
CI / security (push) Successful in 2m23s
CI / test (push) Successful in 5m38s
CI / build (push) Successful in 3m16s
CI / e2e (push) Successful in 21m7s
v2.70.1
2026-10-20 23:10:34 -04:00
Spark 9bc31d069b feat: barre d'apps commune et références croisées des notes (#215)
CI / lint (push) Successful in 3m32s
CI / security (push) Failing after 2m27s
CI / test (push) Successful in 5m36s
CI / build (push) Successful in 2m12s
CI / e2e (push) Successful in 18m18s
v2.70.0
2026-10-20 22:20:48 -04:00
bruno 411667fd88 feat: menu contextuel Déplacer/Dupliquer sidebar + réparation drag & drop interne #201 #BUG-117
CI / lint (push) Successful in 3m13s
CI / security (push) Successful in 1m59s
CI / test (push) Successful in 5m16s
CI / build (push) Successful in 1m52s
CI / e2e (push) Successful in 18m2s
v2.69.0
2026-10-15 10:02:48 -04:00
bruno ed9029d760 fix: éditeur Forge — textarea qui ne grandit pas après insertion programmatique (tableau/code) #BUG-116
CI / lint (push) Successful in 3m17s
CI / security (push) Successful in 2m0s
CI / test (push) Successful in 5m14s
CI / build (push) Successful in 1m49s
CI / e2e (push) Successful in 17m57s
v2.68.6
2026-10-14 22:09:28 -04:00
bruno 1892062d88 fix: éditeur Forge — espace checkbox/texte aperçu, flash du preview, menus table/langue coupés #BUG-115
CI / lint (push) Successful in 3m11s
CI / security (push) Successful in 2m0s
CI / test (push) Successful in 5m16s
CI / build (push) Successful in 1m49s
CI / e2e (push) Successful in 17m47s
v2.68.5
2026-10-14 21:56:37 -04:00
bruno cbe3d9bc75 fix: popup currentPath is not defined après suppression/renommage de répertoire #BUG-114
CI / lint (push) Successful in 3m9s
CI / security (push) Successful in 1m59s
CI / test (push) Successful in 5m12s
CI / build (push) Successful in 1m49s
CI / e2e (push) Successful in 17m57s
v2.68.4
2026-10-14 21:20:08 -04:00
bruno 2ebfe74459 perf: suppression de répertoire incrémentale au lieu du re-scan complet #BUG-113
CI / lint (push) Successful in 3m9s
CI / security (push) Successful in 1m55s
CI / test (push) Successful in 5m25s
CI / build (push) Successful in 1m48s
CI / e2e (push) Successful in 17m56s
v2.68.3
2026-10-14 16:56:56 -04:00
bruno 6257adb46b fix: CI security — bandit B112 sur search_shared_notes (nosec, continue délibéré)
CI / lint (push) Successful in 3m9s
CI / security (push) Successful in 1m56s
CI / test (push) Successful in 5m13s
CI / build (push) Successful in 1m47s
CI / e2e (push) Successful in 18m17s
v2.68.2
2026-10-14 13:43:26 -04:00
bruno 31a0ab5b70 fix: config Clés API & MCP — wrap des champs de création au lieu du débordement desktop
CI / lint (push) Successful in 3m10s
CI / security (push) Failing after 1m51s
CI / test (push) Successful in 5m12s
CI / build (push) Successful in 1m48s
CI / e2e (push) Successful in 18m15s
v2.68.1
2026-10-14 12:09:08 -04:00
bruno f783394f09 feat: intégration TikTak #197-200 + scoped tokens, webhooks filtrés, listes mtime/size ; fix e2e-server BUG-112
CI / lint (push) Successful in 3m17s
CI / security (push) Failing after 1m51s
CI / test (push) Successful in 5m14s
CI / build (push) Successful in 1m50s
CI / e2e (push) Successful in 18m18s
v2.68.0
2026-10-14 11:42:53 -04:00
bruno 2be0b15bcf fix: partage dirigé — ACL court-circuitée après résolution Partage/ + chemin canonique au token #196
CI / lint (push) Successful in 3m0s
CI / security (push) Failing after 1m38s
CI / test (push) Successful in 4m58s
CI / build (push) Successful in 1m36s
CI / e2e (push) Successful in 19m55s
- le partage EST l'autorisation: plus de 403 'Accès refusé à la vault' pour un
  destinataire sans accès au vault émetteur (api_file, raw, download)
- chemin virtuel canonique Partage/<token>/<nom> — désambiguïse les homonymes,
  fallback par nom conservé
- 'reçu' = partagé_avec contient l'utilisateur: un admin ne voit plus les
  partages des autres comme reçus (fix File not found: Partage/…)
- +3 tests (14 total)
v2.67.2
2026-10-10 23:11:12 -04:00
bruno de6bde1613 fix: partage dirigé — dossier Partage virtuel + ouverture en onglet #196
CI / lint (push) Successful in 3m1s
CI / security (push) Failing after 1m58s
CI / test (push) Successful in 4m43s
CI / build (push) Successful in 1m39s
CI / e2e (push) Successful in 20m28s
- _resolve_shared_file: home-<user>/Partage/<f> -> fichier source (/api/file, raw, download)
- clic dossier Partage: dépliage sans navigation (fix Directory not found)
- fichiers reçus ouverts en onglet applicatif (arbre, recherche, dashboard)
- POST /api/share: path vide/null rejeté (400) — un share path:null cassait /api/shares
- +2 tests (13 total)
v2.67.1
2026-10-10 21:48:46 -04:00
bruno fdc9f47a0d feat: visibilité & recherche des partages dirigés #196
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
- icône share-2 bleue sur les fichiers partagés dans l'arborescence
- dossier virtuel Partage/ à la racine du home du destinataire (lecture seule /s/{token})
- recherche plein texte couvre les documents reçus (merge search_vaults, share_token)
- cache front invalidé à la création/révocation ; +2 tests non-fuite
v2.67.0
2026-10-10 21:23:00 -04:00
bruno 49c715199d feat: partage dirigé entre utilisateurs #196
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
CI / lint (push) Canceled after 1m29s
- create_share/shared_with + validation des destinataires
- gate auth sur /s/{token} (+pdf, raw) : 404 opaque hors créateur/admin/destinataires
- GET /api/shares scopé (non-admin = créés + reçus), révocation créateur/admin
- UI : dialogue dirigé/public + destinataires, dashboard « partagé par X »
- i18n FR/EN, tests test_directed_shares.py (9), fiche feature
v2.66.0
2026-10-10 20:14:29 -04:00
bruno fd192df036 fix: admin — icône fermeture modale utilisateurs + sections du dashboard affichées une à la fois BUG-111
CI / lint (push) Successful in 2m54s
CI / security (push) Successful in 1m41s
CI / test (push) Successful in 4m36s
CI / build (push) Successful in 1m34s
CI / e2e (push) Successful in 17m56s
v2.65.2
2026-10-10 17:17:14 -04:00
bruno 8662d23ec8 fix: un dossier perso n'est plus visible par les autres comptes #194
CI / lint (push) Successful in 2m57s
CI / security (push) Successful in 1m40s
CI / test (push) Successful in 4m39s
CI / build (push) Successful in 1m34s
CI / e2e (push) Successful in 17m44s
L'admin (vaults: ["*"]) voyait le home de chaque utilisateur dans sa
barre latérale : "*" ouvrait tous les vaults, home-* compris.

- backend/auth/middleware.py : check_vault_access exige un octroi
  explicite pour tout vault home-* (nouveau is_home_vault()).
- Filtres « * » en dur remplacés par check_vault_access : dashboard,
  conflits, liens retour, favoris, abonnements push.
- /api/search : search_vaults(is_allowed=…) filtre les bruts avant
  pagination (total et page restent justes).
- backend/user_home.py : _grant n'écarte plus les comptes « * » —
  l'admin reçoit son propre home-admin (auto-réparé au démarrage).
- Tests : test_user_home.py +2, assertion API inversée dans
  test_auth_api.py (admin ne voit plus home-alice).
v2.65.1
2026-10-10 16:42:00 -04:00
bruno 10453d8dfe feat: dossier perso (#194) — vaults home-* en tête de l'arborescence, icône maison, compose de test
CI / lint (push) Successful in 3m1s
CI / security (push) Successful in 1m41s
CI / test (push) Successful in 4m37s
CI / build (push) Successful in 1m34s
CI / e2e (push) Successful in 17m40s
- frontend/js/sidebar.js : tri stable _homeFirst appliqué à la source des
  deux listes de vaults (loadVaults + soft refresh) → les vaults home-<user>
  passent en premier, arborescence et sélecteurs cohérents.
- frontend/js/viewer.js : getVaultIcon renvoie l'icône lucide "home" pour
  home-* (même safeCreateIcons / stroke currentColor que les autres).
- docker-compose.test-win.yml : montage test_home:/vaults/Home +
  OBSIGATE_HOME_ROOT=/vaults/Home pour tester la feature en local ;
  test_home/ ajouté au .gitignore.
- Tests : sidebar-filters.test.mjs +2 (icône maison, gemme violette
  inchangée), vérifié live sur l'instance 2020 (ordre + svg.lucide-home).
v2.65.0
2026-10-10 16:09:59 -04:00
bruno 8235d632b8 feat: dossier personnel par utilisateur — vault home-<user> + registre de vaults persistant #194
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
- backend/user_home.py : ensure_user_home()/release_user_home() idempotents
  (mkdir, vault, watcher, octroi dans user.vaults), rappelés à la création
  d'un compte et au démarrage (migration + réparation + sweep des vaults
  home-* orphelins), dossier conservé à la suppression.
- backend/indexer.py : data/vaults.json, registre persistant des vaults
  ajoutés à la volée, fusionné par load_vault_config() — ils disparaissaient
  au premier reindex complet et au redémarrage. reload_single_vault remet
  vault_config[name] après remove_vault_from_index.
- backend/auth/router.py + routers/vaults.py : appels ensure/release +
  persistance à l'ajout/retrait d'un vault.
- docker-compose.yml : montage unique /NFS/OBSIDIAN_DOC/Home:/vaults/Home +
  OBSIGATE_HOME_ROOT (absente = fonctionnalité inactive).
- Tests : tests/test_user_home.py (12) + tests/test_auth_api.py::TestUserHome (2).
v2.64.0
2026-10-10 00:40:35 -04:00
bruno f4c8504c8d feat: chat — les posts affichent le markdown rendu comme un document, code coloré #193
CI / lint (push) Successful in 2m50s
CI / security (push) Successful in 1m37s
CI / test (push) Successful in 4m34s
CI / build (push) Successful in 1m31s
CI / e2e (push) Successful in 17m36s
v2.63.0
2026-10-09 15:48:04 -04:00
bruno 4fb7c43e06 feat: chat — boutons discrets sous l'image, image en onglet d'app, point de non-lus, notification OS, suppression annulable BUG-110
CI / lint (push) Successful in 2m50s
CI / security (push) Successful in 1m36s
CI / test (push) Successful in 4m28s
CI / build (push) Successful in 1m31s
CI / e2e (push) Successful in 17m30s
v2.62.0
2026-10-09 11:53:26 -04:00
bruno 54caa48d1f feat: chat — saisie auto-agrandissante, accusé de réception ✓✓, vignette de tuile #192 (BUG-109)
CI / lint (push) Successful in 2m52s
CI / security (push) Successful in 1m35s
CI / test (push) Successful in 4m27s
CI / build (push) Successful in 1m29s
CI / e2e (push) Successful in 17m1s
v2.61.0
2026-10-08 23:28:08 -04:00
bruno f00a8bea8f feat: chat — suppression de post, messages privés, boîte compacte, link preview #191
CI / lint (push) Successful in 2m50s
CI / security (push) Successful in 1m35s
CI / test (push) Successful in 4m28s
CI / build (push) Successful in 1m28s
CI / e2e (push) Successful in 17m11s
v2.60.0
2026-10-08 22:33:29 -04:00
bruno 55a9fcc0f4 fix: retirer -f de logs du build.sh (bloquait le lock de deploiement)
CI / lint (push) Successful in 2m48s
CI / security (push) Successful in 1m34s
CI / test (push) Successful in 4m31s
CI / build (push) Successful in 1m26s
CI / e2e (push) Successful in 17m16s
2026-10-08 21:06:18 -04:00
bruno 4cdea956d7 docs: spec Assistant V2 — second cerveau (mémoire, connecteurs, proactivité)
CI / lint (push) Successful in 2m48s
CI / security (push) Successful in 1m35s
CI / test (push) Successful in 4m27s
CI / build (push) Successful in 1m26s
CI / e2e (push) Successful in 16m41s
2026-10-08 21:01:45 -04:00
bruno ae06436f91 feat: chat — suivi du document, chat général en onglet sidebar, onglets au-dessus du filtre #190
CI / lint (push) Successful in 2m48s
CI / security (push) Successful in 1m34s
CI / test (push) Successful in 4m33s
CI / build (push) Successful in 1m30s
CI / e2e (push) Successful in 17m5s
- **A — Suivi du document** : l'en-tête du panneau chat affiche le document
  ciblé (titre + chemin) et `followFileChat()` appelé par `renderFile()`
  re-cible le panneau ouvert à chaque changement de document.
- **B — Chat général** : onglet « Chat » (dernier) dans la sidebar,
  conversation centrale stockée dans le store #169 via les sentinelles
  `__global__/general` (`GET/POST /api/chat`) ; pastille de messages non
  lus sur l'onglet ; pièces jointes image/vidéo (`POST /api/chat/upload` :
  allow-list d'extensions, 25 MB, nom UUID ; `GET /api/chat/attachment/{name}`
  résolu contre l'allow-list) ; URL cliquables au rendu ; date/heure d'envoi.
- **C — Ordre des onglets** : la barre de filtre passe sous les onglets et
  sert de recherche dans le chat (texte + auteur) quand l'onglet Chat est
  actif (`switchSidebarTab` + `routeFilter`).
- Transport : broadcast SSE `chat_message` réutilisé (`vault __global__`
  route vers la sidebar, sinon le panneau fichier) — pas de 2ᵉ WebSocket.
- i18n FR/EN (6 clés), CSS bloc #190, `initSidebarChat()` dans l'orchestrateur.
- Tests : pytest 27 chat (12 nouveaux) ; JSDOM `filechat.test.mjs` 11 (5
  nouveaux) ; suite 1655 passed, ruff/mypy 0, validate-imports 42 modules.
- Docs : CHANGELOG [Unreleased], ROADMAP #190 → index, fiche
  `file-chat-169.md` §#190, guide « Chat général », journal des interventions.
v2.58.0
2026-10-08 20:40:54 -04:00
bruno d0e10d4cc6 docs: journal des interventions AI #189/#169 + versions d'index resynchronisées
CI / lint (push) Successful in 2m47s
CI / security (push) Successful in 1m34s
CI / test (push) Successful in 4m24s
CI / build (push) Successful in 1m27s
CI / e2e (push) Successful in 17m37s
- `docs/ISSUES_TODOLIST.md` : deux lignes ajoutées au journal (features
  #189 mobile tableur et #169 chat par fichier, avec vérifications et
  résultats CI), exigées par le DoD pour tout passage d'IA modifiant du code.
- `docs/ROADMAP.md` : colonne version de l'index corrigée — #189 → 2.56.0,
  #169 → 2.57.0 (le hook de bump ne resynchronise pas ces rangées).
v2.57.1
2026-10-08 18:42:31 -04:00
bruno c94f065f80 feat: chat intégré par fichier — panneau latéral, historique, temps réel SSE #169
CI / lint (push) Successful in 2m46s
CI / security (push) Successful in 1m35s
CI / test (push) Successful in 4m28s
CI / build (push) Successful in 1m27s
CI / e2e (push) Successful in 17m11s
- Store backend `backend/file_chat.py` : messages JSON par (vault, path)
  sous `data/chats/` (nom hashé SHA-256 → traversal impossible), plafond
  500 messages, texte tronqué à 4000 caractères, écriture atomique.
- Routes `GET/POST /api/file/{vault}/chat` : auth + accès vault +
  `resolve_safe_path`, schémas Pydantic (`response_model`), broadcast SSE
  `chat_message` sur le transport existant (#62) — pas de second WebSocket.
- Panneau latéral `frontend/js/filechat.js` : bouton 💬 dans la toolbar
  fichier, historique chronologique, envoi optimiste + dédoublonnage par id,
  toast « Nouveau message » si le panneau est fermé/autre fichier.
- Relais SSE dans `sync.js` (import dynamique), CSS bloc #169 (plein écran
  ≤ 768 px, input 16 px anti-zoom), i18n FR/EN (10 clés `chat.*`).
- Tests : `tests/test_file_chat.py` (15) + `tests/frontend/filechat.test.mjs`
  (6, ajouté au pipeline CI), regex toolbar-order mise à jour.
- Docs : CHANGELOG [Unreleased], ROADMAP #169 → livré + index, fiche
  `docs/features/file-chat-169.md`, guide « Discuter d'un fichier ».
v2.57.0
2026-10-08 17:03:29 -04:00
bruno 36b4962efb feat: tableur mobile — barres repliées par défaut, bascule unique #189
CI / lint (push) Successful in 2m42s
CI / security (push) Successful in 1m38s
CI / test (push) Successful in 4m19s
CI / build (push) Successful in 1m27s
CI / e2e (push) Successful in 17m12s
Sous 768 px, la barre de menus, le ruban et le groupe Recherche sont
repliés par défaut : la barre de formule (fx), les onglets et Enregistrer
restent visibles et la grille récupère la hauteur d'écran. Un bouton
unique (#xlsx-tools-toggle) dans la barre des feuilles déplie/replie
l'ensemble (aria-expanded, état actif) ; desktop inchangé.

Ergonomie tactile : cibles ≥ 44 px, onglets en défilement horizontal,
champs de la barre de formule en 16 px (anti-zoom iOS), barre de formule
en 2 lignes quand les outils sont ouverts.

Tests : JSDOM xlsx-viewer.test.mjs (+2, 165/165), E2E mobile (repli par
défaut, dépliage, no-overflow ruban, cibles 44 px) ; openXlsx() déplie
automatiquement ≤ 768 px pour les tests desktop.
v2.56.0
2026-10-08 15:45:39 -04:00
bruno e01e837a2a feat: secrets masqués — couverture universelle clés API/mots de passe + clic pour copier (#188)
CI / lint (push) Successful in 2m40s
CI / security (push) Successful in 1m33s
CI / test (push) Successful in 4m19s
CI / build (push) Successful in 1m31s
CI / e2e (push) Successful in 16m56s
v2.55.0
2026-10-08 13:22:27 -04:00
bruno 634ba8a272 feat: éditeur tableur — grille A → Z par blocs, barre de menus Sheets, panneau de couleurs, création .xlsx (#180 → #186)
CI / lint (push) Successful in 2m43s
CI / security (push) Successful in 1m33s
CI / test (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
Restaure et termine le lot tableur resté non committé. Il n'existait que dans un
`git stash` (24 fichiers suivis) et en fichiers non suivis (menus.js, formula.js,
color-picker.js, tests, fiches) : la 2.53.3 livrée ne le contenait donc pas. Le
stash, créé avant le commit BUG-108, n'a jamais été restauré.

#180 Redimensionnement au curseur (en-tête de bord miroité + classe de repaint),
grille thémée sur les 15 thèmes et les modes contraste élevé / sépia, menu
Fichier au niveau des onglets, barre épinglée pleine largeur.

#181 Modèle de saisie Google Sheets : sélection ≠ édition (caret masqué sans
quitter contenteditable, double-clic / F2 / première frappe qui remplace,
Entrée contextuelle, Échap qui restaure) + inventaire priorisé des écarts.

#182 Désélection fiable (clic simple sans dépendre du focus), contours de plage
non empilés (sélecteur de classes sans point), couleurs texte/fond sur une
plage, clic droit qui préserve la sélection multiple.

#183 Panneau de couleurs façon Google Sheets : palette 8 × 10, STANDARD,
PERSONNALISÉ, coche selon la luminance, sortie `#rrggbb` (une valeur HSL était
rejetée par normHex).

#184 Peinture de format complète (toutes propriétés, source sans format =
réinitialisation), sélection multi-lignes/colonnes depuis les marges, grille
étendue : colonnes A → Z d'emblée, lignes ajoutées PAR BLOCS DE 100 au
défilement jusqu'à 1000 — matérialiser 1000 lignes d'un coup = ~26 000 cellules
câblées par feuille, ce qui épuisait le tas de la suite JSDOM ; index de
cellules `ref → td`, court-circuits formule/styles, marqueur data-wired.

#185 Barre de menus : les 10 menus Google Sheets (161 entrées, 125 câblées, 36
annoncées indisponibles), ruban façon Sheets, grille unie 1 px dérivée du thème.

#186 « Créer un fichier » propose .xlsx et construit un vrai classeur OPC
(openpyxl) au lieu d'une charge utile texte illisible.

Corrections trouvées en restaurant et en exerçant le lot :
- fuite mémoire : écouteur `click` anonyme posé sur #content-area à chaque
  rendu, jamais retiré — sa fermeture retenait la grille précédente en entier ;
- sorties Markdown / HTML / Imprimer de la barre de menus inertes
  (`data-xlsx-export` jamais réparti, seul `data-xlsx-action` l'était) ;
- collision de classe `.xlsx-structure-menu` entre la barre de menus et le menu
  Structure de la barre d'outils (toute requête tombait sur un nœud masqué) ;
- curseur col/row-resize absent quand le pointeur est sur la table elle-même ;
- l'export emportait les lignes et colonnes vides du quadrillage (CSV, Markdown,
  HTML, impression) ;
- clic extérieur avalé par la grâce de 250 ms du menu contextuel (destinée au
  seul appui long tactile) ;
- une entrée indisponible laissait la barre de menus ouverte.

Tests : pytest 1595 passés / 2 ignorés ; ruff et mypy 0 erreur ; bandit 0 ;
33 suites frontend vertes (xlsx-viewer 163/163, xlsx-menus 19/19,
xlsx-formula 14/14) ; E2E complet 132 passés / 12 ignorés ; E2E xlsx-viewer
19/19.
v2.54.0
2026-10-08 12:00:15 -04:00
bruno ce1944d437 fix: coller du menu contextuel tableur muet + planchers sécurité CI (BUG-108)
CI / lint (push) Successful in 3m6s
CI / security (push) Successful in 2m18s
CI / test (push) Successful in 4m55s
CI / build (push) Successful in 3m1s
CI / e2e (push) Successful in 19m27s
BUG-108 — closeContextMenu() retirait le nœud du menu AVANT de déférencer
_menu : le retrait émet focusout en synchrone (le menu tient le focus), qui
rappelle closeContextMenu() ; le second remove() sur un nœud démonté lève
NotFoundError et avorte le handler de l'action « Coller » du viewer — le
coller par menu contextuel était silencieusement mort (régression de la
fermeture au focus #179, reproduite par l'E2E « coller une plage », CI
#850→#854). Déférencement avant retrait.

Sécurité CI (job security, run #853) :
- plancher multidict>=6.9.1 (CVE-2026-104874 ; 6.7.x préinstallée dans la
  toolcache de l'image du runner, même piège « already satisfied » que pypdf
  BUG-093) + entrée dans le garde-fou TestDependencySecurityFloors ;
- exception documentée CVE-2026-85394 (python-jose, AUCUN correctif upstream) :
  non atteignable ici, jwt.decode passe toujours algorithms=["HS256"] avec un
  secret symétrique serveur — jamais de clé publique comme clé HMAC.

Vérifié : E2E -g « coller une plage » 1/1 ; xlsx-menus 11/11,
xlsx-formula 14/14, ai 100/100, ai-quick-actions 13/13 ; pytest 1586
passés ; ruff/mypy 0 erreur ; ISSUES_TODOLIST + CHANGELOG à jour.
v2.53.3
2026-10-07 16:49:31 -04:00
bruno 39bad990c0 test: ai-quick-actions suit #187 - plus de flag agent sur les actions
CI / lint (push) Successful in 3m1s
CI / security (push) Failing after 2m14s
CI / test (push) Successful in 4m58s
CI / build (push) Successful in 3m17s
CI / e2e (push) Failing after 16m56s
Le test assertait encore `agent: true` sur les quick actions frontmatter,
depuis la suppression du toggle mode agent (#187, v2.53.2). Job lint CI
(run 853) en échec. Commit rattaché à la livraison 2.53.2 déjà publiée :
pas de nouvel incrément (SKIP_VERSION_BUMP).
2026-10-07 08:29:57 -04:00
bruno 431d6e9338 docs: i18n et suivi #187 - assistant agent toujours actif
CI / lint (push) Failing after 2m51s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Failing after 2m14s
v2.53.2
2026-10-07 08:18:45 -04:00
bruno d453969708 docs: i18n et suivi #187 - assistant agent toujours actif 2026-10-07 08:17:59 -04:00
bruno 778fa65b4c fix: assistant IA toujours en mode agent, retrait du bouton toggle #187
- Bouton « mode agent » du panneau supprimé : l'assistant est toujours
  agent (toute requête texte part sur /api/ai/bookslm/agent, les images
  restent sur /chat multimodal). Les mutations gardent la confirmation
  two-step. Deep Research et les quick actions `agent: true` basculaient
  déjà le mode en silence : le toggle ne protégeait plus rien.
- /agent résout le provider comme /chat (req.provider brut transmis à
  l'adapter pouvait désigner un fournisseur indisponible et retomber
  silencieusement sur un autre que l'étiquette SSE affichée).
- Schémas des outils mis en cache par (scope, taille du registre) avec
  copies fraîches par appelant (~27 ms de pydantic économisées par
  requête agent/MCP).
- Aide in-app réécrite, i18n FR/EN (retrait de ai.agent_mode_*),
  tests frontend adaptés (ai.test.mjs 100/100) + non-régression pytest
  (provider résolu, cache sûr).
2026-10-07 08:16:56 -04:00