--- issueRef: "#291" version: 7 updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} updatedAt: 1788940935288 --- # Carnet #291 ## Signalement utilisateur Le redémarrage agent est fonctionnel et l'affichage initial après redémarrage est correct. Régression restante: après un changement de projet puis retour sur le projet courant, la conversation s'efface si un redémarrage de l'agent a eu lieu. ## Attendu produit La conversation doit rester visible et rechargée comme si aucun redémarrage agent n'avait eu lieu. ## Reproduction cible 1. Projet A ouvert, conversation agent visible. 2. Redémarrer l'agent. 3. Vérifier que la conversation reste visible. 4. Basculer vers un autre projet. 5. Revenir au projet A. 6. Vérifier que la conversation est toujours présente. ## Cadrage UX - Le transcript persisté est source de vérité après changement de projet, redémarrage app ou réhydratation de surface. - Le live buffer ne complète que la session active; un buffer vide ne doit jamais écraser un transcript persisté non vide. - Pendant la réhydratation, ne pas afficher prématurément `Aucun message`; garder l'ancien contenu si disponible ou afficher un chargement transitoire. - En erreur réelle de lecture: afficher `Impossible de recharger la conversation. Réessayer` sans remplacer un contenu ancien disponible. ## Cadrage architecture - Frontière probable: frontend project switching / reconnect et reconstruction du viewer, pas persistance backend en première intention. - Invariant: `conversationId` stable à travers restart agent, changement de projet, reconnect/refresh; contenu lu via `Gateways.conversation.readPage` / `read_conversation_page`. - Le live-state peut porter un pointeur mais ne doit pas devenir source de vérité du transcript. - Inspecter notamment `ProjectsView.tsx`, `WebWorkspace.tsx`, `ConversationViewer.tsx`, `useConversationThread.ts`, adapters conversation, source de `conversationId` dans ports/workstate/layout. - Backend à vérifier seulement si perte de projection `conversationId` après restart/open_project. ## Critères QA - Scénario restart agent + changement projet + retour projet: messages pré et post restart visibles, ordre conservé, sans duplication. - Test automatisé frontend attendu: `conversationId` stable, switch projet puis retour, `ConversationGateway.readPage` relancé avec le même id. - Test backend de projection workstate seulement si l'inspection révèle une perte côté backend. ## Orchestration - Ticket créé par Main le 2026-09-09. - UX et Architect consultés. - Prochaine étape: Git pour branche locale, puis DevFrontend en première intention. ## Livraison DevFrontend — 2026-09-09 ### Diagnostic - `ProjectsView` conservait bien `{ projectId, conversationId }`, mais rendait le viewer du projet source même lorsqu'un autre projet devenait actif. Le composant ne se démontait donc pas pendant l'aller-retour et `useConversationThread` ne relançait pas `ConversationGateway.readPage` au retour, puisque ses identifiants n'avaient jamais changé. - `WebWorkspace` avait l'écart symétrique: il supprimait entièrement le pointeur du viewer à chaque changement de projet, empêchant toute réhydratation au retour. - Les adapters Tauri et HTTP transmettent déjà correctement le même `projectId` / `conversationId` à `read_conversation_page`; aucune preuve de perte backend du pointeur n'a été trouvée. ### Correctif - Le viewer conservé n'est rendu que si son `projectId` correspond au projet actif. Le projet intermédiaire affiche sa propre surface; le retour au projet source remonte le viewer et relance la lecture persistée avec le même `conversationId`. - Même règle appliquée au shell web; son pointeur n'est plus effacé au switch. - `useConversationThread` ne vide plus préventivement un buffer existant avant la relecture. Le premier montage affiche toujours `Chargement du fil…`; un contenu déjà disponible reste visible pendant une relecture ou en cas d'échec. - L'erreur de lecture affiche `Impossible de recharger la conversation.` et l'action `Réessayer`, sans retirer les tours déjà visibles. ### Fichiers modifiés - `frontend/src/features/projects/ProjectsView.tsx` - `frontend/src/features/web/WebWorkspace.tsx` - `frontend/src/features/conversations/useConversationThread.ts` - `frontend/src/features/conversations/ConversationViewer.tsx` - `frontend/src/features/projects/ProjectsView.ls7.test.tsx` - `frontend/src/features/conversations/ConversationViewer.test.tsx` ### Preuves exécutées - `npm --prefix frontend test -- --run src/features/projects/ProjectsView.ls7.test.tsx -t "rehydrates the same conversation"` — OK, 1 test passé (8 ignorés par le filtre). Le test simule le restart, A→B→A, vérifie le contenu et deux appels `readPage` strictement identiques sur `{ projectId, conversationId }`. - `npm --prefix frontend test -- --run src/features/conversations/ConversationViewer.test.tsx src/features/conversations/useConversationThread.test.tsx` — OK, 2 fichiers / 19 tests passés. - `npm --prefix frontend run build` — OK (`tsc --noEmit` puis build Vite, 515 modules). - `git diff --check` — OK. ### Gaps observés hors lot - Le fichier complet `ProjectsView.ls7.test.tsx` conserve 4 scénarios historiques KO car leur helper ne parvient plus à ouvrir le panneau Work et ne trouve pas `open conversation …`; le nouveau scénario #291 passe isolément et ouvre le viewer via l'événement de complétion persistant. - `WebDesktopWorkspace.test.tsx` a 1 test historique KO sur un libellé attendu en anglais (`Project context`) alors que l'UI expose désormais `Contexte projet`; 2 autres tests passent. Aucun de ces échecs ne touche le chemin #291. - Aucun gap backend détecté. ## Validation QA indépendante — 2026-09-09 ### Verdict VERT pour le périmètre #291 sur `fix/291-keep-conversation-after-restart-project-roundtrip`. ### Inspection - Diff vérifié sur `ProjectsView.tsx`: le viewer conserve son pointeur global, mais n'est rendu que lorsque `viewerConversation.projectId === active.id`; le switch vers un autre projet démonte donc la surface et le retour remonte le viewer avec la même clé `{projectId, conversationId}`. - Diff vérifié sur `WebWorkspace.tsx`: même règle côté web, sans remise à `null` du pointeur au changement de projet. - Diff vérifié sur `useConversationThread.ts`: suppression du `setBuffer([])` au changement/rechargement; le buffer existant n'est plus vidé pendant une relecture. - Diff vérifié sur `ConversationViewer.tsx`: l'erreur de lecture expose un état de retry sans remplacer explicitement un contenu déjà présent. - Test #291 ajouté dans `ProjectsView.ls7.test.tsx`: simule restart agent, switch alpha -> beta -> alpha, vérifie le contenu et deux appels `readPage` identiques sur `{ projectId, conversationId }`. ### Commandes exécutées ```bash git status --short --branch ``` ```text ## fix/291-keep-conversation-after-restart-project-roundtrip M .ideai/tickets/290/carnet.md M .ideai/tickets/290/issue.md M .ideai/tickets/counter.json M .ideai/tickets/index.json M frontend/src/features/conversations/ConversationViewer.test.tsx M frontend/src/features/conversations/ConversationViewer.tsx M frontend/src/features/conversations/useConversationThread.ts M frontend/src/features/projects/ProjectsView.ls7.test.tsx M frontend/src/features/projects/ProjectsView.tsx M frontend/src/features/web/WebWorkspace.tsx ?? .ideai/tickets/291/ ?? scripts/ ``` ```bash npm --prefix frontend test -- --run src/features/projects/ProjectsView.ls7.test.tsx -t "rehydrates the same conversation" ``` ```text Test Files 1 passed (1) Tests 1 passed | 8 skipped (9) Duration 2.38s ``` ```bash npm --prefix frontend test -- --run src/features/conversations/ConversationViewer.test.tsx src/features/conversations/useConversationThread.test.tsx ``` ```text Test Files 2 passed (2) Tests 19 passed (19) Duration 1.34s ``` ```bash npm --prefix frontend run build ``` ```text > idea-frontend@0.3.0 build > tsc --noEmit && vite build ✓ 515 modules transformed. ✓ built in 2.60s ``` ```bash git diff --check ``` ```text OK (aucune sortie) ``` ### Test additionnel ```bash npm --prefix frontend test -- --run src/features/projects/ProjectsView.ls7.test.tsx ``` ```text Test Files 1 failed (1) Tests 3 failed | 6 passed (9) ``` Tests rouges observés dans ce fichier complet: - `opens the viewer on a conversation click and returns to the grid on back` - `keeps the viewer open when the active layout changes` - `does not close an open viewer when a background-task toast has no conversation` Ces trois échecs cherchent encore `open conversation ...` via l'ancien helper/panneau Work et correspondent aux rouges historiques déjà mentionnés hors lot. Le nouveau scénario #291 `rehydrates the same conversation after an agent restart and a project roundtrip` passe dans ce run complet. ### Risques résiduels - Validation effectuée par tests frontend et build local, pas par AppImage/runtime desktop réel. - Le worktree contient des modifications non liées à #291 (`.ideai/tickets/290/*`, index/counter tickets, `scripts/`) que QA n'a pas modifiées ni qualifiées. ## Git — 2026-09-09 - Branche: `fix/291-keep-conversation-after-restart-project-roundtrip` créée depuis `develop`. - Commit fix: `2c72205` (6 fichiers frontend uniquement). - QA reconfirmée par Git avant commit: ConversationViewer + useConversationThread 19/19, scénario #291 `rehydrates the same conversation` isolé vert, `git diff --check` OK. - Store de tickets synchronisé dans un `chore(tickets)` séparé (inclut carnet #290 v12 sections Git + build AppImage du merge `162de27`). - Merge local no-ff vers `develop`, aucun push. - Restants: rebuild AppImage + validation live du scénario exact (restart agent puis aller-retour projet). - `scripts/` non suivi maintenu hors périmètre. ## Rebuild AppImage — 2026-09-09 ### Commandes exécutées ```bash npm --prefix frontend run build ``` Résultat: OK (`tsc --noEmit && vite build`, 515 modules). Avertissement Vite habituel sur chunk > 500 kB. ```bash cd crates/app-tauri mkdir -p /tmp/idea-cargo-home CARGO_HOME=/tmp/idea-cargo-home APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage ``` Résultat: OK. Le `beforeBuildCommand` a reconstruit `frontend/dist` et `frontend/dist-web`, puis Rust release a compilé et le bundle AppImage a été produit. ### Artefact - Chemin: `target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage` - Taille: 114M - SHA-256: `8629ffef8939a08ff2b1008be515e778004cc34413a988cbf37ad71c2e3083dc` ### Reste manuel Pour rendre le correctif actif dans l'application installée, remplacer l'AppImage utilisée (`/home/anthony/Documents/IdeA_0.1.0_amd64.AppImage`) par l'artefact ci-dessus puis relancer IdeA. Cette étape n'a pas été automatisée car elle tue l'orchestrateur courant.