Commit Graph

741 Commits

Author SHA1 Message Date
780f91a211 chore(idea): bookkeeping tickets 202/207 + création #208 2026-08-15 08:50:42 +02:00
b855555c9d chore(idea): bookkeeping QA #206 verte + lancement QA transverse #207 2026-08-15 01:33:49 +02:00
b885f0c4de merge(web): UX mobile task-flow dédiée — #206 (QA verte) 2026-08-15 01:33:43 +02:00
a907586f41 feat(web): add mobile task flow shell — #206 2026-08-15 01:31:49 +02:00
dcf6a84dba chore(idea): bookkeeping QA #205 verte + préparation #206 2026-08-15 01:26:26 +02:00
9eb81689c6 merge(web): persistance session web desktop + synchro inter-onglets — #205 (QA verte) 2026-08-15 01:26:18 +02:00
3b8ce66e33 feat(web): persist workspace presentation across browser hosts — #205 2026-08-15 01:24:23 +02:00
723e2987ef chore(idea): bookkeeping QA #204 verte + préparation #205 2026-08-15 01:18:28 +02:00
1a8f548e3f merge(web): surfaces ouvrables ici/onglet/fenêtre — #204 (QA verte) 2026-08-15 01:18:22 +02:00
0d543fb298 feat(web): open project surfaces in browser targets — #204 2026-08-15 01:16:23 +02:00
7fea538d0d chore(idea): bookkeeping QA #203 verte + préparation #204 2026-08-15 01:10:18 +02:00
32a6c685c6 merge(web): shell desktop parity — #203 (QA verte) 2026-08-15 01:10:15 +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
4cbb4ee7c7 chore(idea): bookkeeping .ideai — tickets #184-#207, contexts agents, mémoire (préparation train refonte web #202) 2026-08-15 00:56:12 +02:00
715f0ededd merge(infra): temp IdeA pour tous les agents et purge managed-tmp à la fermeture — #200 (QA verte) 2026-08-15 00:14:25 +02:00
b5653b24b5 feat(infra): temp IdeA généralisé à tous les agents + purge du store managed-tmp au shutdown d'IdeA — #200 (QA verte) 2026-08-15 00:14:25 +02:00
e6f6eb5b1b merge(infra): temp IdeA launch-scoped géré pour les agents — #200 (QA verte) 2026-08-14 23:56:02 +02:00
1157de1dda feat(infra): temp IdeA launch-scoped alloué par lancement d'agent, injecté via TMPDIR/TMP/TEMP, writable_roots + release au stop, fail-closed — #200 (QA verte) 2026-08-14 23:55:54 +02:00
1d10a6ee80 merge(sandbox): writable roots Codex alignées sur les permissions du menu agent — #197 (QA verte) 2026-08-14 15:05:23 +02:00
a60fb3ed92 fix(sandbox): writable roots Codex dérivées des permissions effectives du menu agent — #197 (QA verte) 2026-08-14 15:05:15 +02:00
6a98752cb0 merge(ui): resize vertical du chat + colonne tags de versions dans le graph Git — #193 (QA verte) 2026-08-14 09:33:25 +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
d0521db6b6 merge(infra): tests d'intégration managed temp handlers/routage — #191 (QA verte) 2026-08-13 14:23:17 +02:00
24bcf80286 merge(infra): injection sandbox handles managed temp — #190 (QA verte) 2026-08-13 14:23:17 +02:00
cc5a324bf8 test(infra): intégration handlers Tauri managed_temp_* + routage idea_managed_temp_* — #191 2026-08-13 14:23:03 +02:00
4e9b205b40 feat(infra): injection sandbox des handles managed temp résolus dans les sessions agents — #190 2026-08-13 14:08:36 +02:00
1b7ff56419 merge(infra): tmp partagé inter-projets géré par IdeA — #189 (QA verte) 2026-08-13 13:34:40 +02:00
fdca55ecd4 feat(infra): tmp partagé inter-projets géré par IdeA (handles opaques, leases, GC, projection sandbox) — #189 (QA verte)
- Domaine: port ManagedTempStore + modèle (handle opaque, kind Directory/File, état Active/Released, allocation/lease, expiry).
- Application: use cases Allocate/Resolve/Release/GcManagedTemp, horodatés via Clock.
- Infrastructure: impl FS FsManagedTempStore sous app_data_dir/managed-tmp (root global inter-projets, métadonnées par handle, GC des leases expirés/libérés).
- Exposition MCP contrôlée (ManagedTempToolProvider, catalogue) + câblage sandbox: les agents résolvent un handle au lieu d'inventer un path libre.
- Tests: application/infrastructure managed_temp.
2026-08-13 13:34:33 +02:00
d7dfbcdfcb merge(cli): références d'attachments + zone chat redimensionnable — #188 (QA verte) 2026-08-13 13:01:12 +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
8b8468dacd merge(cli): progress live agent/tool + anti-duplication running/done — #187 (QA verte) 2026-08-13 12:45:44 +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
1d393ffd4f merge(sandbox): accès Git minimal pour Codex — roots writable restreints au .git résolu (#195, QA verte) 2026-08-12 16:41:35 +02:00
e2fc85b434 fix(sandbox): accès Git minimal pour Codex — writable roots restreints au .git résolu, sans blanket grant project (#195, QA verte)
Codex ne pouvait pas accéder aux métadonnées Git sous sandbox workspace-write.
À l'inverse, la factory relayait jusqu'ici le project_root entier en --add-dir,
soit un grant large non défendable.

Change pour n'accorder en écriture (Codex --add-dir ET SandboxPlan OS) que le
.git réellement résolu :
- resolve_git_dir gère .git/ directory ET fichier worktree 'gitdir: <path>'
  (absolu ou relatif au parent du marker), puis canonicalize.
- enrich_sandbox_plan_with_codex_git_roots ajoute/déduplique les roots en RW
  sur le SandboxPlan existant (préserve l'autorité EffectivePermissions).
- factory: défaut writable_roots = Vec::new() en l'absence de policy explicite.

Invariants conservés :
- project_root n'est jamais injecté comme writable root.
- aucun élargissement au parent commun (canonicalize + BTreeSet).
- permissions MCP/globales inchangées (seul le plan runtime est enrichi).

Tests (crates/application) :
- standard .git/ dir -> root unique.
- projet non-Git -> aucun root.
- worktree (.git file gitdir:) -> résolution + canonicalization.
- symlink -> dédup, pas de grant parent.
- factory: défaut sans policy n'émet plus --add-dir project_root.

Réserve QA: launch_conventionfile_injects_assigned_skills_in_order
(agent_lifecycle) arbitré hors-scope/non bloquant pour #195.
2026-08-12 16:41:25 +02:00
8a66ccbc07 merge(runtime): cancel en cascade des tasks filles — stop agent / cancel parent (#200, QA verte) 2026-08-12 16:02:27 +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
a3bda8ebc0 merge(ui): LED projet — exploite les signaux d'interaction CLI custom (#198, QA verte) 2026-08-12 15:44:41 +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
b38f5b6f14 merge(ui): cellule agent stoppé — état explicite + reopen from scratch (#197, QA verte) 2026-08-12 15:35:03 +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
7b7b2cec85 merge(runtime): cancel de background task immédiat et fiable depuis le workstate (#199, QA verte) 2026-08-12 15:18:50 +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
f5e2e302ba merge(runtime): stop/restart d'agent visible robuste — kill réel, état stopped, relance froide (#196, QA verte) 2026-08-12 14:56:15 +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
4e93fa2f20 merge(orchestrator): délégation simple vers UX renvoie son Final structuré (#207, QA verte) 2026-08-12 14:09:44 +02:00
646b9d9284 fix(orchestrator): la délégation simple vers UX renvoie son Final structuré (#207, QA verte)
Une demande idea_ask_agent vers UX échouait avec « finished without a structured Final response » alors qu'Architect répondait. Deux causes corrigées:

- session/process: un tour CLI terminé en code non nul SANS stdout (ex. erreur 401/auth) renvoyait une sortie vide au lieu du stderr réel; l'orchestrateur concluait alors à un « no Final ». On remonte désormais le stderr effectif (drain sync + async + helper process_exit_message + test dédié).

- orchestrator/service: la branche « ask waiting on background » masquait le premier Final structuré; la réponse synchrone redevient le premier Final (suppression de active_rendezvous_has_background_tasks / mark_rendezvous_task_waiting).

Nettoyage runtime corollaire (#204): arrêt du live runtime stale (PTY + structuré) d'un agent recréé afin que la délégation route vers l'agent courant (LiveSessions, stop_live_agent_runtime_in_project, wiring backend via DeleteAgent::with_runtime_cleanup, lifecycle, workstate cascade).
2026-08-12 14:09:06 +02:00
ba176e3cf2 merge(chat): déduplication des progress intermédiaires dans la timeline (#192, QA verte) 2026-08-11 20:37:37 +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