fix(ai+editeur): BUG-046 erreur lisible et vault réel pour l'ajout IA au document; BUG-045 fin de la double scrollbar
CI / lint (push) Failing after 1m26s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Successful in 57s

BUG-046: 'Ajouter du texte au document courant' échouait avec 'Échec de
l'action: [object Object]'. Trois causes corrigées:
- continuation de confirmation sans payload -> second Appliquer POSTait
  sans 'message' (422); le payload d'origine est désormais transmis
- detail 422 FastAPI (tableau d'objets) stringifié tel quel -> nouvelle
  _responseError() qui aplatit en message lisible
- prompt documents/dossier muet sur le vault -> le modèle inventait
  'vault: test' et append_to_file échouait en silence; build_system_prompt
  nomme le vault et enjoint les outils d'écriture de l'utiliser exactement

BUG-045: double barre de défilement dans l'éditeur Editer (fichiers
longs): #editor-body overflow:auto + cm-editor height:100% sous la barre
IA -> corps et scroller CodeMirror défilant tous les deux. Flex column,
seul le scroller défile; override global .cm-scroller retiré. SW v20.

Vérifié: pytest 1038, ruff backend 0, tests frontend AI 84/84,
editor-inline 25/25, validate-imports 38 modules; Playwright sur
l'instance de test (un seul conteneur scrollable) et flux agent complet
append_to_file ok=true sur fichier réel
This commit is contained in:
2026-09-16 08:53:01 -04:00
parent e3df4bbf00
commit 3a648cdc50
10 changed files with 212 additions and 20 deletions
+30 -3
View File
@@ -87,9 +87,13 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
lecture (bandeau, métadonnées, tags et contenu). L'overlay reste monté mais neutralisé
(transparent, sans capture des clics, `z-index` conservé) car le ruban d'édition mobile y est
ancré. Retour à la lecture par ✓ (sauvegarde), ✕, Échap ou l'ouverture d'un autre fichier —
un garde-fou dans `renderFile()` libère proprement la session (destruction CodeMirror/Yjs,
retrait de l'iframe Forge) ; l'overlay n'est conservé qu'en repli, quand la cible n'est pas le
document affiché (ex. fichier créé depuis la palette). Conséquence directe : l'éditeur ne
trois garde-fous libèrent proprement la session (destruction CodeMirror/Yjs, retrait de
l'iframe Forge) avant qu'un rendu concurrent n'efface son DOM : `renderFile()`, l'activation
d'onglet (`TabManager.activate`, `PaneTabManager.activate`, qui vident la zone avant de
rendre) et l'événement SSE `index_updated` (un fichier modifié hors de l'app recharge le
**tampon de l'éditeur** au lieu de re-rendre la vue lecture). L'overlay n'est conservé qu'en
repli, quand la cible n'est pas le document affiché (ex. fichier créé depuis la palette).
Conséquence directe : l'éditeur ne
recouvre plus le panneau de l'assistant IA, qui peut donc mettre le document à jour **sous
les yeux de l'utilisateur** — `app_context.editing` annonce au modèle le document en cours
d'édition (et sa surface), et toute écriture d'outil (`edit_file`, `append_to_file`,
@@ -102,6 +106,29 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Corrigé
- **BUG-045 — Double barre de défilement dans l'éditeur « Editer »** : sur les
documents longs, `#editor-body` (qui gardait `overflow:auto`) et le scroller
CodeMirror débordaient simultanément — la barre d'outils IA empilée sous un
`.cm-editor` en `height:100%` faisait déborder le corps, et un ancien override
global `.cm-scroller` forçait une seconde zone défilante. La surface
d'édition est passée en flex column : le corps ne défile plus (`overflow:
hidden`), l'éditeur remplit l'espace restant et **seul le scroller CodeMirror
défile**. Repli textarea (fallback) cohérent ; la règle mobile BUG-020 est
préservée.
- **BUG-046 — « Échec de l'action : [object Object] » (assistant IA, ajout de
texte au document courant)** : trois causes corrigées ensemble. (1) La carte
de confirmation « Appliquer » reprenait un payload dont le message était
absent après une première application échouée (continuation `payload:null`)
→ réponse 422 du backend. (2) Cette réponse 422 porte un `detail` **tableau
d'objets** (format validation FastAPI) que `new Error(detail)` réduisait en
`[object Object]` dans le toast — nouvelle méthode `_responseError()` qui
aplatit tableaux et objets en message lisible. (3) Le prompt des modes
documents/dossier ne nommait pas le vault : le modèle inventait parfois
`"vault":"test"` et l'outil d'écriture échouait silencieusement — le prompt
indique désormais le vault exact et enjoint les outils `edit_file` /
`append_to_file` / `create_file` de l'utiliser. Cache service worker
`SW_VERSION` v20.
# Changelog — ObsiGate
- **#91 — Bulle utilisateur trop étroite & ancre d'envoi retardée** : le plafond de
largeur était appliqué **deux fois** (wrapper 80 % × bulle 85 % ≈ 68 % du fil), d'où
des lignes très courtes ; le plafond est désormais porté par la seule bulle (90 %),