|
|
|
|
@ -0,0 +1,180 @@
|
|
|
|
|
---
|
|
|
|
|
issueRef: "#291"
|
|
|
|
|
version: 5
|
|
|
|
|
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
|
|
|
|
updatedAt: 1788940207349
|
|
|
|
|
---
|
|
|
|
|
# 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.
|