Commit Graph

239 Commits

Author SHA1 Message Date
41a850f2e9 fix(chat): bulles d'erreur étiquetées par type de session structurée — #240
L'erreur « La réponse du modèle n'a pas pu être finalisée. » indique désormais
l'adapter en cause (Session Codex / Claude / OpenCode / HTTP) pour lever
l'ambiguïté constatée sur GameTime entre session Codex et Claude.
2026-08-22 17:27:16 +02:00
cbfdfeb356 fix(chat): le contenu partiel streamé n'est plus masqué par l'erreur terminale de finalisation — #239
assistantFailureText conserve le texte déjà streamé puis classe l'échec
(sans contenu, tronqué, fin non reçue, transitoire) avec conseil de reprise
adapté, au lieu d'écraser la bulle par « Échec — … finalisée. ».
2026-08-22 16:38:55 +02:00
da911d5a9b fix(chat): états vides explicites et reroutage vers le fil actif quand Work state signale un agent busy — #238
ConversationViewer remplace « Aucun tour pour le moment » par un diagnostic
differentié (agent actif sans tour affichable, transcript non synchronisé,
activité sur un autre fil) avec action « Ouvrir le fil actif ». Le panneau
Work state affiche le résumé du fil du ticket actif et ProjectsView/WebWorkspace
câblent onOpenConversation.
2026-08-22 11:30:38 +02:00
8deaa1fd6c fix(cli): store annonces inter-agent borné par projectId avec reset et réhydratation busy au changement de projet — #236 2026-08-22 10:02:41 +02:00
aa85d4dfc8 fix(cli): les annonces MCP/inter-agent restent affichées pendant qu'un agent est busy — #232 2026-08-21 19:40:13 +02:00
8760ade168 feat(workstate): panneau Work state simplifié — état + intitulé simples, détails et background tasks repliés par défaut — #235 2026-08-21 17:52:44 +02:00
aaf628f1ff fix(cli): préserve l'affichage des progress legacy sans progressId via clés d'occurrence dédiées — #236 2026-08-21 17:47:05 +02:00
e20182fa5e feat(web): messages progress et usages MCP dépliables/repliables, repliés par défaut — #233 2026-08-21 16:09:25 +02:00
023d483ba2 fix(web): émet chat.attached pour les sessions agents structurées au lieu de UNSUPPORTED — #229 2026-08-20 15:10:41 +02:00
5fff70d156 fix(web): passe le nodeId réel à la custom CLI au lieu d'un id fabriqué — #225 2026-08-20 13:22:23 +02:00
9a3ca51f6b fix(web): démarre le serveur MCP custom CLI via idea-serve au lieu de node — #224 2026-08-20 12:49:00 +02:00
c547b71d0c feat(web): passage en custom CLI sur version téléphone avec UI mobile adaptée — #224 2026-08-17 17:56:47 +02:00
6a4787e814 fix(cli): normalise les timestamps chat secondes/ms pour l'heure des messages — #221 2026-08-15 22:21:00 +02:00
581063cf96 fix(cli): restaure la conversation au retour de layout via cache conversationId+sessionId — #217 2026-08-15 19:32:56 +02:00
3582b252bb fix(cli): affiche les progress reçus après Final sans rouvrir le tour — #216 2026-08-15 18:58:08 +02:00
86f6c7ebf8 fix(web): route la famille layout dans /api/invoke + fallback UX restauration — #212
Le web-server ne routait pas load_layout (UNKNOWN_COMMAND a l'ouverture
d'un projet web PC). Alignement de l'adapter web sur les contrats Tauri:
load_layout, mutate_layout, list_layouts, create_layout, rename_layout,
delete_layout, set_active_layout. useLayout ne propage plus l'erreur
brute: message utilisateur + fallback singleLeafTree.
2026-08-15 11:40:00 +02:00
79fc3d184d feat(web): panneau Fichiers — navigation projet + téléchargements fichier/dossier ZIP — #211 2026-08-15 10:38:53 +02:00
7f671dff01 feat(web): heure de réception des messages custom CLI — #210 2026-08-15 09:49:46 +02:00
7cdb97ae89 feat(web): parité layout AppImage desktop + switch TUI naïf/CLI custom — #208 2026-08-15 09:08:42 +02:00
a907586f41 feat(web): add mobile task flow shell — #206 2026-08-15 01:31:49 +02:00
3b8ce66e33 feat(web): persist workspace presentation across browser hosts — #205 2026-08-15 01:24:23 +02:00
0d543fb298 feat(web): open project surfaces in browser targets — #204 2026-08-15 01:16:23 +02:00
93dab2d961 test(web): align agent contract expectations — #203 2026-08-15 01:08:30 +02:00
ee2ee037f9 feat(web): add desktop parity shell — #203 2026-08-15 01:03:29 +02:00
2bbe7f63b0 feat(ui): colonne tags de versions à gauche du graph Git — #193 2026-08-14 09:33:05 +02:00
2b2da223d5 feat(chat): resize vertical du composer avec poignée haut-droit (modèle carnet ticket) — #193 2026-08-14 09:33:05 +02:00
4f38e1c506 feat(cli): références d'attachments [file n]/[image n] dans le transcript + zone chat redimensionnable — #188 (QA verte)
- Attachments: projection canonique ChatPromptAttachmentDto (référence [file n]/[image n] par compteur de type, ordre d'import) insérée dans le prompt modèle et transportée par ReplyChunk::UserPrompt (attachmentRefs) ; rendu compact côté CustomAgentChatView.
- Resize: la zone chat (LeafView/LayoutGrid) est redimensionnable, taille actuelle conservée par défaut, préférence locale persistée.
- Tests: commands (projection des refs), dto_chat, chat_bridge, CustomAgentChatView, LayoutGrid.chat.
2026-08-13 13:01:03 +02:00
a3ee2814d6 fix(cli): progress agent_message émis en live + anti-doublon running/done par progressId — #187 (QA verte)
- Codex: les items agent_message sont désormais tapés en live comme progress (Message/Delta) dès item.completed, au lieu d'être bufferisés dans pending_final jusqu'à l'événement tool/MCP suivant.
- Corrélation stable progressId (codex:item:<id>) ajoutée sur ReplyProgress, propagée jusqu'au DTO (ReplyProgressDto.progressId) et au frontend ; le ProgressSettler et la vue procèdent par upsert running -> done au lieu d'empiler des lignes dupliquées.
- Tests: chat_bridge (settler par progressId), dto_chat, session codex, CustomAgentChatView (upsert par progressId).
2026-08-13 12:45:32 +02:00
803e9de093 fix(runtime): cancel en cascade des tasks filles — stop agent / cancel parent (#200, QA verte)
Cancel transitif, idempotent et ownership-aware sur le graphe parent→enfants des background tasks:

- domain/background_task + ports: modèle parent/enfant (parent_task_id, rejet du self-parent), index children_by_parent, traversal des descendants en largeur.

- application/background + infrastructure/store: cascade cancel (annule les descendants running/open, laisse les terminaux), idempotente face aux double-cancel et ordres de terminaison non déterministes; respect de l'ownership (parent_task_link).

- orchestrator/service: stop agent → cascade cancel des tasks lancées par cet agent (relatesTo #196); cancel task parent → cascade de ses sous-tasks (dependsOn #199). Refactor unifiant le chemin de cancel, sans sémantique #196/#199 regreffée (tests hérités verts).

- frontend: projection parentTaskId (workstate normalization/domain/services).

Tests QA verts: domain background_task, application background_task_cancel (cascades_background_task_subtree, cascades_to_running_child, cascades_to_open_descendants_and_leaves_terminal_child, parent_task_link_roundtrips_and_rejects_self_parent), orchestrator_service, workstate_actions, workstate.test.tsx.
2026-08-12 16:02:17 +02:00
b167226179 feat(ui): LED projet — exploite les signaux d'interaction CLI custom (#198, QA verte)
Projette l'état d'interaction agent→projet sur la LED via des signaux explicites de la CLI custom:

- projectCliInteractionActivity: modèle d'activité d'interaction (InteractionStarted/Finished/Stopped, interactionId/seq, version).

- useProjectActivity + ProjectTabs: projection live « interaction en cours » → LED, retour immédiat à l'état attendu au stop ou à la fin réelle de l'échange (pas d'état collant).

- CustomAgentChatView: émet les signaux d'interaction CLI custom (début d'envoi, fin de tour, stop) consommés par l'activité projet — sans dériver la LED du texte streamé ou d'heuristiques.

Tout côté frontend: aucun signal runtime manquant (les signaux proviennent de la CLI custom).

Tests QA verts: projectActivity.test.ts, ProjectTabs.test.tsx (+ useProjectActivity.test.tsx, CustomAgentChatView.test.tsx).
2026-08-12 15:44:30 +02:00
cdb395307b feat(ui): cellule agent stoppé — état explicite + reopen from scratch (#197, QA verte)
Surface UI du LayoutGrid pour un agent de cellule stoppé:

- Affichage d'un état explicite quand runtimeState vaut « stopped » ou « failedStart », avec actions refresh / reopen from scratch (freshStart) et état restarting pendant la relance.

- theme.css: styles .stopped-agent-cell (boutons primary/secondary, états disabled).

Consomme le contrat runtime issu de #196 (AgentRuntimeState stopped/failedStart, freshStart) déjà présent dans develop; aucune modification runtime ici.

Tests QA verts: LayoutGrid.test.tsx, LayoutGrid.chat.test.tsx (rejoué aussi: agent_lifecycle launch_fresh_start_ignores_existing_conversation_id_and_mints_new_one).
2026-08-12 15:34:53 +02:00
46103397de fix(runtime): cancel de background task immédiat et fiable depuis le workstate (#199, QA verte)
Transforme l'annulation d'une background task en contrat immédiat, observable et non-best-effort:

- domain/background_task: états Cancelling/Cancelled/CancelFailed et transitions idempotentes; un kill PTY qui échoue est surfacé en CancelFailed plutôt qu'en succès silencieux.

- infrastructure/runner + store: cancel effectif de la task ciblée, reconcile marque Cancelling même sans live handle, et départage CancelFailed des tâches pending au boot.

- application/background + workstate + orchestrator/wake: chemin de cancel initié depuis le workstate, projection synchronisée de l'état (pas d'attente d'un cycle ambigu).

- frontend: projection workstate de l'état cancelled/cancelling/cancelFailed (cancellingRow/cancelFailedRow/cancelButtons), normalization et services.

Tests QA verts: background_task_cancel, background_task_runner cancel_wins_even_if_output_is_still_available, background_task_store reconcile_marks_cancelling_without_live_handle_cancel_failed_and_pending, workstate.test.tsx.
2026-08-12 15:18:38 +02:00
bad7b4c2f3 fix(runtime): stop/restart d'agent visible robuste — kill réel, état stopped, relance froide (#196, QA verte)
Solidifie le cycle stop/restart d'un agent visible en cellule:

- terminal/registry: kill effectif de la TUI native et de la CLI custom, arrêt idempotent du live runtime (PTY + structuré), distinction nette « agent stoppé » vs « pas de session ».

- workstate + lifecycle: projection d'un état runtime explicite « stopped » (AgentRuntimeState: running/stopping/stopped/failedStart), réconcilié avec le live state; traitement des courses « agent not found ».

- relance froide via freshStart: repart de zéro sans réattacher une session morte et recharge la configuration courante de l'agent (y compris changement de modèle).

- contrat projeté côté adapters frontend (ports/domain/normalization/mock) pour la consommation UI future (#197/#198), sans surface UI ici.

Tests QA verts: workstate_actions, orchestrator_service stop_agent, agent_lifecycle (reopen/fresh_start), workstate stopped runtime state, vitest adapter stop_live_agent.
2026-08-12 14:56:02 +02:00
75635bdc8c fix(chat): déduplication des progress intermédiaires dans la timeline (#192)
Les progress « started » d'une même entité s'empilaient en plusieurs turns et
n'étaient dédupliqués qu'a posteriori par scan linéaire du tableau de turns,
d'où des doublons visibles et un affichage retardé (re-scan par chunk).

appendProgress opérait directement sur turns[] (chaque « started » y était poussé
puis retrouvé/remplacé par recherche séquentielle). Désormais:

- ChatViewState (turns + entityProgressMap): la Map indexée par « entité\0bucket »
  (started/completed) est l'unique source de vérité pour les progress en cours;
- les progress « started » ne deviennent des turns qu'au flush
  (completeChatViewProgress sur final/error), supprimant la duplication et
  rendant l'affichage immédiat;
- « completed » merge depuis l'entrée running de la Map puis la retire, au lieu
  de scanner le tableau;
- turnsIndicateBusy s'appuie sur la taille de la Map (état vivant) en plus du
  scan des turns.

Tests: déduplication des progress par entité (started répétés → une seule entrée,
flush au final), fusion « completed » depuis la Map, état busy reflété par la
Map, et rendu non dupliqué sur l'enchaînement started/completed/final.
2026-08-11 20:36:05 +02:00
ddecf9e0c5 fix(chat): reprise robuste au retour d'un layout non conversationnel (composer verrouillé selon l'état réel, replay complet du scrollback, plus de fausse terminaison 'no reply') (#190) 2026-08-11 19:50:35 +02:00
17b98e3d03 fix(tui): la bascule TUI native <-> CLI custom ne déclenche plus de faux conflit de visibilité (#189) 2026-08-11 19:27:15 +02:00
ee0ffd4e2d fix(chat): réattache persistante CLI custom et rendu tools/MCP/progress enrichi (#188)
Corrige la perte de session à la navigation: le démontage du CustomAgentChatView
appelait close_agent_session (destructeur) au lieu de simplement détacher le
transport. Désormais:

- nouvelle commande Tauri detach_agent_chat (+ ChatBridge::detach) qui libère le
  canal sans tuer la session ni le scrollback retenu; distinct de
  close_agent_session qui reste le close destructeur explicite;
- le frontend appelle detachAgentChat à l'unmount puis restore sa vue depuis un
  cache de session (turns + chunkCount) à la réattache;
- message « Reprise effectuée: N événements rattrapés… » quand la réattache
  rejoue plus de chunks que le cache local n'en avait conservé.

Enrichit le rendu tools/MCP/progress:

- ProgressSettler (chat bridge) émet un progress completed synthétique quand un
  spinner reste ouvert (nouvelle entité progress, chunk text/final/error): fini
  les spinners fantômes;
- les adapters claude/codex/opencode/openai_compat extraient un aperçu du
  payload (arguments/input/command/message/params) attaché au progress;
- bounded_reply_progress_preview (domain) garde les 4 premières lignes non
  vides, normalisation CR/LF;
- previewText (frontend) multiligne whitespace-pre-wrap, source/nativeEvent
  affichés sous le titre; suppression du flag settled et du Spinner inline
  devenus redondants (l'état est porté par le stage + le settler).

Tests: detach_agent_chat gateway (Tauri + mock), ProgressSettler, bornage
reply_progress, item_preview/tool_preview par adapter, réattache avec cache et
notice de rattrapage.
2026-08-11 18:49:12 +02:00
22ce2f62fd fix(chat): le bouton Stop de la CLI custom arrête l'agent en cascade (#187)
Le Stop du CustomAgentChatView n'annulait que le tour courant sans libérer la
session ni toucher aux tâches enfants ou appels MCP en cours. Il appelle
désormais stop_live_agent sur l'agent vivant, qui:

- ajoute le port StopAgentExecutionCascade (best-effort, idempotent), implémenté
  par OrchestratorService pour annuler les idea_run_in_background rattachés au
  rendez-vous actif (via BackgroundTaskRunner.cancel);
- cascade l'arrêt aux wait-dépendances (stop_turn_watch + preempt) pour
  interrompre les appels MCP et les attentes inter-agents;
- libère et supprime la session structurée.

UI: nouvel état "Arrêt en cours..." (bouton disabled + loading) pendant l'arrêt,
libération du sessionId, label expliquant la cascade demandée. La Tauri command
cancel_agent_chat est alignée sur stop_live_agent + stop_turn_watch agent et
dépendances.

Tests: SpyBackgroundRunner (cascade n'annule que les tâches rattachées),
workstate_actions cascade best-effort, CustomAgentChatView stop+cascade feedback
et fallback NOT_FOUND.
2026-08-11 18:14:47 +02:00
d9f949c0f2 fix(chat): restaure le collage des images dans le composer custom CLI (#184)
Le collage d'une image (ex. capture d'écran) échouait en environnement desktop : le presse-papier image n'est souvent pas exposé comme un File synchrone dans clipboardData.files, mais uniquement via l'Async Clipboard API. On ajoute donc un repli sur navigator.clipboard.read() (MIME image/*) quand l'événement de collage ne fournit aucun fichier. Le preventDefault() n'est émis que lorsqu'on a effectivement lu des fichiers issus de l'événement, afin de ne pas bloquer le collage texte quand le repli async ne remonte rien.

- refactor clipboardFiles(event) -> dataTransferFiles(DataTransfer) réutilisable
- dedupeKey robuste pour les images sans nom (mime + taille + contenu base64)
- ReplyChunk::UserPrompt porte désormais les labels d'attachments (DTO + accounting reply_chunk_bytes, skip_serializing_if Vec::is_empty)
- tests ciblés frontend (+219) et backend (chat_bridge/dto/attachments) verts

QA : tests ciblés verts. Réserve : environnement headless, pas de validation manuelle desktop — validation AppImage à confirmer en suivi.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 16:49:28 +02:00
94b4ce7e5f feat(chat): persistance bornee du brouillon custom chat par projet/layout (#182) 2026-08-11 16:24:20 +02:00
419987d890 feat(chat): colle les fichiers du presse-papiers via Ctrl+V dans le composer (#181) 2026-08-11 15:57:30 +02:00
5609c6a7a8 fix(slash-commands): route /clean et /help en commandes natives IdeA avant dispatch plugin (#183) 2026-08-11 15:46:59 +02:00
215bc16f21 refactor(ui): supprime le popup de reprise par cellule (#177)
Retire la surface utilisateur de reprise par cellule :
- supprime ResumeConversationPopup et son test (resumeConversationPopup.test.tsx)
- débranche l'appel dans LayoutGrid et retire l'export terminals/index
- ajuste les tests dépendants (libellé « Terminé » dans LayoutGrid.chat.test, refitEpoch)
- commentaire affiné dans ResumeProjectPanel

La reprise implicite éventuelle sera rediscutée ultérieurement (objectif immédiat : retirer la surface).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 12:24:57 +02:00
84fd3547a9 feat(cli): aligne les Final à droite, tools MCP « qui parle à qui », icône animée seulement pendant l'exécution (started→done), supprime le message de fin de tool redondant — #176 (QA verte) 2026-08-11 11:24:44 +02:00
ae3c55a13d feat(cli): repense la timeline de conversation (tools MCP centrés, progress à droite, tours compacts) — #174 (QA verte)
- ToolProgressCard: tools/MCP/délégations centrés, extrait succinct de la demande inter-agent

- ProgressBubble: progress non-outil alignés à droite, clamp 4 lignes (fourLineClamp)

- TurnMarker: marqueurs turn.started/turn.completed compacts et centrés

- Délégations explicites (« Demande à <target> », « Appel inter-agent ») + libellés FR (Terminé)
2026-08-11 10:28:04 +02:00
a943f0cf8b fix(projects): le viewer de conversation persiste au changement de layout/projet (#172)
Le viewer (CLI custom) se vidait au changement de layout/projet car l'etat viewerConversationId etait reset sur le changement de projet actif. Remplace par un etat viewerConversation {projectId, conversationId} lie a la conversation elle-meme, rendu contre le projectId de la conversation: la conversation persiste tant que la session headless existe, a l'instar de la TUI native.
2026-08-11 09:42:23 +02:00
9fe87a8664 fix(cli): déduplication métier des cartes progress + délégations rendues une fois (#157 #171)
appendProgress déduplique par entité (tool/mcp/delegation) + bucket de stage sur l'ensemble du tour, évitant le doublon entre tap live et flux autoritatif. idea_ask_agent/idea_ask_agents rendus comme Délégation. completeRunningProgress marque les entités complétées (settled) pour stopper l'animation. 2 nouveaux tests: ordre pre-MCP avant la première carte MCP, et dédup -> exactement 2 cartes Délégation pour 2 délégations.
2026-08-10 18:37:25 +02:00
a3d94d4d5e fix(layout): barre supérieure CLI custom cliquable — stacking context du corps de leaf
Le corps d'une leaf (layout-leaf-body) crée désormais son propre stacking context (z-index 0). Les vues CLI custom peuvent comporter des enfants à haut z local (toolbar z-20) qui restaient au-dessus des contrôles de cellule (CELL_Z 5) et captaient les clics ; ils restent désormais sous les contrôles. Test de layering dédié ajouté dans LayoutGrid.cellControlsLayering.test.tsx.
2026-08-06 21:57:48 +02:00
8e97da57c9 fix(cli): bouton Send↔Stop #168 + collage clipboard fichier générique #155 2026-08-06 20:00:36 +02:00
31976d6ed8 fix(cli): collage presse-papiers image/fichier via clipboardData.files — #155 (partiel : logique+tests verts, e2e AppImage clipboard en attente)
(cherry picked from commit 2f39a5ce17b9895e683c0d48f0d9e034e701ed19)
2026-08-06 19:40:46 +02:00