Commit Graph

192 Commits

Author SHA1 Message Date
c37638ff24 fix(domain,application,infrastructure,backend,app-tauri,frontend): Stop demande agent préserve la conversation ouverte — arrêt sans fermeture/clôture du chat, états cohérents après cancel sur les 3 adapters de session, cellule et workstate synchronisés — #343 (QA verte) 2026-09-13 10:03:36 +02:00
7b712f2b62 feat(infrastructure,backend,app-tauri,frontend): tools MCP workspace natifs read-only idea_workspace_map/list/read/search, activés par défaut et configurables dans les permissions MCP et les templates — #341 (QA verte) 2026-09-12 19:17:09 +02:00
1a1429f10e feat(domain,application,infrastructure,backend,web-server,app-tauri,frontend): lot utilisateur #325 #326 — icônes projet avec watermark CLI custom et localisation FR/EN (QA verte)
Lot en un seul commit: les deux features partagent les mêmes contrats
(domain/settings.rs, DTO, commandes Tauri/HTTP, web-server) et les mêmes
surfaces UI — la séparation par fichiers était impossible sans chirurgie
de hunks risquant des états intermédiaires non compilables (convention
lot des batches #310-#313 et #315).

#325 — icône configurable par projet, watermark CLI custom:
- domaine: ProjectIconSet (devicon, simple-icons, lucide, idea),
  ProjectIconRef validé (nom ASCII 1..=64, -_. internes), champ icon
  optionnel sur ProjectSettings; sérialisation camelCase et try_from
  strict
- application: UpdateProjectSettings.execute accepte un patch
  theme_color OU icon (absent = inchangé, null = défaut produit), tests
  in-dependants avec store mémoire
- backend/app-tauri/web-server: ProjectIconRefDto, UpdateProjectSettingsRequestDto
  avec icon optionnel (désérialisation additive), commandes
  update_project_settings alignées Tauri/HTTP, tests DTO et HTTP
  (défaut null, set, clear, nom invalide rejeté)
- frontend: catalogue projectIcons (recherche EN), ProjectIconPicker en
  grille multi-lignes dans Paramètres projet, affichage de l'icône dans
  ProjectTabs et watermark grand format à faible opacité en fond de CLI
  custom; ports ProjectSettings.icon, Partial<ProjectSettings>,
  adapters tauri/mock/http et tests alignés

#326 — localisation FR/EN et traduction des textes IdeA:
- domaine: IdeaLanguage (fr | en), champ language optionnel sur
  IdeaUserSettings (absence = défaut produit, série additive validée)
- backend/web-server: UserSettingsDto.language, update_user_settings
  accepte language, tests HTTP alignés; fixtures structured_launch_d3
  mises à jour
- frontend: i18n/ (catalogue FR/EN, I18nProvider, scan anti-régression
  des sources visibles), GeneralSettings avec sélecteur de langue dans
  les paramètres, setupI18n dans vitest; migration de l'ensemble des
  textes hardcodés vers le catalogue sur toutes les surfaces (agents,
  layout, projets, tickets, sprints, web, plugins, permissions, git,
  templates, skills, mémoire, model servers, embedder, first-run,
  devices, scheduled tasks, workstate, dialogs), FR conservé par défaut;
  recherche d'icônes #325 en anglais conformément au ticket

QA verte sur feature/batch-325-326-project-icons-localisation. Aucun push.
2026-09-11 21:53:56 +02:00
bf33e58508 feat(application,backend,infrastructure,app-tauri,frontend): contributions UI/runtime des plugins limitées aux projets liés — #321 (QA verte)
Les contributions runtime des plugins (menus, slash commands, layouts,
surfaces) ne sont exposées que dans les projets liés au plugin.

- Définition du lien: ProjectPluginSettingsStore par racine projet
  (domaine) — une contribution runtime-active n'entre dans le catalogue
  que si elle est explicitement activée pour le projet courant; hors
  projet focalisé, catalogue vide
- Application: ListPluginRuntimeContributions.execute prend un
  project_id optionnel, charge projet + settings et filtre le registre
  par activation projet; tests fake store/settings (catalogue vide sans
  projet, activation, layout, slash commands)
- Backend/app-tauri: plugin_list_runtime_contributions et slash
  commands list/execute acceptent projectId optionnel (DTO camelCase,
  défaut serde), BackendCore recâblé avec store_port et
  project_plugin_settings_store; test DTO de scope optionnel
- Frontend: PluginGateway.listRuntimeContributions(projectId) (ports,
  tauri, http/unsupported, mock alignés); PluginRuntimeProvider
  re-scope le catalogue au changement de focus projet (vidage du
  registre précédent, disposition des bundles, requêtes obsolètes
  ignorées par projectId/révision); PluginLayoutCellView ignore les
  références de layout devenues hors périmètre via onChooseAnotherLayout
  et ne rend rien pendant le rechargement (aucune fuite inter-projets)
- Tests: plugin_install_load (infrastructure), dto slash commands,
  plugin.test, PluginRuntimeProvider.test, PluginLayoutCellView.test

QA verte sur feature/321-plugin-contributions-linked-projects. Aucun push.
2026-09-11 17:46:03 +02:00
1316e87010 fix(application,domain,infrastructure,web-server,app-tauri,frontend): arrêt d'agent fiable avec cascade sur l'arbre de propriété et statut cohérent — #320 (QA verte)
Symptôme: stopper un agent (ex Main sur UnityPlugin) laissait des travaux
poursuivre, la cascade n'atteignait pas les agents lancés et la pastille
restait orange pendant que l'agent continuait à en appeler d'autres.

- barrière d'admission par génération d'exécution (ExecutionControl): un stop
  ferme l'admission de tout le sous-arbre propriété/attente AVANT toute
  annulation asynchrone — plus aucune nouvelle action inter-agents après stop
- arbre de propriété durable en-process (launched_by) + dépendances d'attente
  actives: la cascade couvre transitivement agents et travaux lancés
- commandes d'un agent arrêté rejetées (AppError::AgentStopped); stop
  lui-même admis pour rester idempotent; réactivation sur relance humaine
  (génération +1) et enregistrement du propriétaire au spawn
- admission exposée aux adaptateurs hors commandes cœur (tickets, templates,
  plugins) via ensure_agent_execution_active; MCP server/tools, web-server et
  commandes Tauri alignés
- cohérence live-state: statut Idle avec intent « Arrêté » ou
  « Arrêt incomplet — Certains travaux sont encore actifs » selon l'issue de
  la cascade; workstate et surfaces UI (AgentsPanel, LayoutGrid,
  ProjectWorkStatePanel) reflètent l'état réel, plus de pastille orange fantôme
- tests: orchestrator_service (cascade/générations/idempotence),
  workstate_actions, background_task_cancel, error_codes, agents, layout,
  workstate

QA verte sur fix/320-agent-stop-cascade. Aucun push.
2026-09-11 16:42:29 +02:00
7fb9d8bb86 feat(backend,application,frontend,domain,web-server,app-tauri): bouton Redémarrer l'agent dans la barre supérieure des cellules — #317 (QA verte)
La cellule expose un bouton Redémarrer l'agent valable pour les trois
modes de présentation (headless, TUI native, CLI custom), sans jamais
prendre la présentation pour vérité runtime.

- Application: use case RestartCellAgentRuntime validant le binding
  exact cellule/runtime via les snapshots live (RestartRuntimeNotFound,
  ConflictAgentVisibleElsewhere, AgentNotBoundToCell) puis déléguant au
  scheduler self-restart existant (schedule_cell); CellAgentPresentation
  purement informationnelle.
- Backend/app-tauri/web-server: commande restart_cell_agent sur contrat
  DTO identique Tauri/HTTP, stop borné par timeout typé
  (RestartStopTimeout), relance préservant routage TUI natif, géométrie
  de cellule (node/rows/cols) et conversation; évenements domaine
  enrichis.
- Frontend: bouton dans la barre de cellule avec confirmation,
  overlay d'état Redémarrage…/échec (libellés par code d'erreur, Fermer/
  Réessayer), gardes d'identité de cellule et de restarts externes,
  gateway/mock/http adapters et ports alignés.
- Tests: dto_agents, workstate_actions, contrats web-server,
  LayoutGrid.cellControlsLayering, adapters agent/mock/http.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 15:00:43 +02:00
bbe8c1d04b fix(frontend,application,backend,web-server,infrastructure): le set de couleurs projet s'applique à tous les projets — #316 (QA verte)
Cause: update_project_settings remplaçait tout ProjectSettings avec la
seule couleur fournie — champ absent et null indistinguables — et des
réponses de chargement/sauvegarde obsolètes d'un projet précédent
pouvaient réafficher/écraser la couleur lors d'un changement de projet
rapide, d'où l'impression que la couleur ne prenait pas sur tous les
projets.

- DTO tri-état (absent = inchangé, null = défaut produit) avec
  Deserialize manuel et use case de mise à jour partielle du champ
  theme_color; commandes Tauri et web-server alignées sur le même
  contrat.
- Garde-fous de course frontend: séquences load/save + révision thème
  par projet (pub/sub onProjectThemeChanged) dans ProjectSettingsPanel,
  garde de révision de focus dans ViewWindow.
- Tests: infrastructure settings, contrats web-server (inchangé/reset),
  ProjectSettingsPanel, ViewWindow, projects.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 13:01:05 +02:00
7007b2cc7e feat(backend,frontend): tâches planifiées projet — tool MCP idea_scheduled_task_* et menu utilisateur #305, fix transcript lié indisponible après reboot #314 (QA verte)
#305: nouvel agrégat durable ScheduledProjectTask dans domain (scheduled_task.rs, ids, ports ScheduledProjectTaskStore), source de vérité <app_data_dir>/scheduled-project-tasks/<projectId>.json, schedules bornés V1 interval/daily/weekly avec fuseau, cycle À approuver/Active/Suspendue avec approbation obligatoire des tâches demandées par agent; use cases application/scheduled_task (list/create/update/delete/run_now/reconcile/fire) réutilisant BackgroundTask pour les runs avec distinction planifié/manuel; store infrastructure dédié + scheduler reconcile au boot sans rattrapage en rafale, cwd confiné au projet; 7 tools MCP idea_scheduled_task_* (list/read lecture seule, create/update/delete/run_now/set_enabled write-actions soumises aux permissions natives); commandes Tauri + routes HTTP aux contrats DTO identiques (camelCase nextRunAtMs/lastRunAtMs/lastTaskId/createdBy/updatedBy); frontend: gateways Tauri/HTTP/mock + types ports/domain, surface projet 'Tâches planifiées' (liste utilisateur+agent unifiée, création/édition avec récapitulatif avant activation, approbation/refus, exécuter maintenant, suspendre/reprendre, suppression), catalogage surface web (webSurfaceCatalog/viewPlacement/ViewPanelBody/WebWorkspace); docs/scheduled-project-tasks.md et sdk docs/services.md (047c38b: pas un service plugin V1, pas d'émulation via cron système).

#314: correction de 'Conversation liée — transcript indisponible' après reboot: restauration du transcript lié côté application (orchestrator service, lifecycle, session_limit, background sink, terminal registry) et côté frontend (adapters agent/http frames/stream/requestResponse, workStateNormalization, CustomAgentChatView avec état et action utile), tests dto_chat/agent_lifecycle/structured_registry_d1/background_completion_sink étendus.

QA verte rapportée par QA sur feature/305-scheduled-project-tasks-mcp, sans bloquant, pour #305 et #314.

Hors périmètre worktree: tickets non liés, attachments/, scripts/; aucun push.
2026-09-11 10:32:01 +02:00
402a60f213 feat(backend,frontend): lot utilisateur #310 #311 #312 #313 — horodatage conversation, stop agent robuste, préférence terminal par défaut, paramètres projet (QA verte)
- #310: horodatage de tous les messages et événements de conversation visibles — composant partagé EntryTimestamp, timestamps propagés dans le transcript chat, les annonces inter-agent et le viewer de conversation, normalisation côté domain/adapters (conversation_log, paginate).
- #311: stop d'agent robuste pour PTY non monté, sessions headless et CLI custom — lifecycle/orchestrator durcis, ponts chat app-tauri/web-server alignés, arrêt fiable sans session orpheline.
- #312: préférence globale d'interface terminal par défaut — nouveau store settings (domain/application/infrastructure + tests), DTO et commandes backend, adapter frontend userSettings, panneau TerminalSettings dans les paramètres globaux.
- #313: Paramètres du projet — contexte de projet éditable et couleur de thème par projet (ProjectSettingsPanel + projectTheme), teinte des onglets projet, persistance via DTO projet.

QA verte (GO QA sur feature/batch-310-311-312-313-chat-stop-prefs-theme) — vérifications Git: git diff --cached --check OK; staging borné à crates/ et frontend/ (74 fichiers, +2105/-531), commit unique de lot conforme à la convention des lots (précédents batch-151/158/159, batch-210/211/212) car les fichiers partagés (dto.rs, commands.rs, CustomAgentChatView) entrelacent les 4 tickets.

fichiers .ideai/* (agents/test.md, chat-drafts.json, system-permissions.json, tickets/counter.json, tickets/index.json, tickets/308-313/), attachments/ et scripts/ hors périmètre et préservés en worktree ; aucun push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 21:26:16 +02:00
b9f8ed303e feat(backend,domain,infrastructure,application,app-tauri,web-server,frontend): suppression d'un projet du registre IdeA sans toucher son dossier disque — #308 (QA verte)
cause: l'utilisateur ne pouvait pas retirer un projet du registre IdeA (projects.json) ; la seule issue laissait l'entrée fantôme dans la liste des projets, sans capacité générique de retrait.

domain: port ProjectStore::remove_project(id) -> Option<Project> avec implémentation par défaut « not supported » pour ne pas casser les stores spécialisés.

infrastructure: FsProjectStore implémente remove_project — retire l'entrée du registre persisté et la renvoie, None si id inconnu, ordre relatif du registre préservé ; test store dédié.

application: use case RemoveProjectFromRegistry (remove.rs) — NotFound explicite si id absent, retourne le projet retiré + registre rafraîchi.

backend/app-tauri/web-server: DTO RemoveProjectRequestDto/RemoveProjectResponseDto (removed, projects, restore_state, was_open), adapter partagé remove_project_for_adapter réutilisé par la commande Tauri remove_project et la route HTTP — même contrat desktop/web ; remove_project_and_deactivate désactive le projet s'il était ouvert, purge l'entrée open-projects restore correspondante et renvoie was_open/restore_state ; test adapter vérifiant le contrat de bout en bout (entrée retirée, restore purgé, root intact).

frontend: DTO + ProjectGateway.removeProject (HTTP + mock), ProjectsView expose un menu d'actions projet (ProjectActionsMenu) avec entrée Retirer, RemoveProjectDialog — confirmation explicite précisant que le dossier disque n'est pas supprimé, invalidation/rechargement de la liste des projets après succès (useProjects), tests ProjectsView/projects/adapters/httpInvoker/services.

QA verte: cargo targeted tests/check OK (domain, application project_usecases, infrastructure project_store, backend, app-tauri, web-server), npm targeted/typecheck/build OK ; suite npm test complète rouge non bloquante hors #308 (échecs préexistants listProjectSettings/web). Vérifications Git: git diff --check OK, cargo fmt --all -- --check OK.

fichiers .ideai/tickets/308/, tickets/counter.json, tickets/index.json, attachments/ et scripts/ hors périmètre et préservés en worktree (sync store traité séparément) ; aucun push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 18:27:15 +02:00
8df80ae67e feat(domain,application,infrastructure,backend,app-tauri,web-server,frontend): restaurer les projets ouverts au redémarrage dans l'ordre mémorisé — #303 (état versionné OpenProjectRestoreState persisté sous <app_data_dir>/open-projects.json via port dédié OpenProjectRestoreStore, distinct du registre projects.json et sans recycler workspace.json; sept use cases cadrés: read/record opened/record closed/save order/restore/retry/remove, mutations sérialisées par mutex applicatif contre les lost updates, tombstones conservés à leur position avec lastFailure et codes stables notFound/inaccessible/store/invalid; prévalidation root par metadata+listing sans interrompre les autres restaurations; activation centralisée BackendCore::activate_project réutilisée par ouverture Tauri/HTTP, création, restore et retry: reconciliation layouts/live-state/background tasks, watcher orchestrateur + serveur MCP, réparation run dirs Claude; cinq commandes exposées Tauri et HTTP avec contrats DTO identiques: restore_open_projects, retry_open_project_restore, remove_project_from_restore, save_open_project_restore_order, read_open_project_restore_state; frontend: DTO de reprise + ProjectGateway étendu, useProjects initialise par listProjects+restoreOpenProjects et reconstruit openTabs dans l'ordre opened sans notification quand tout réussit, notification unique singulier/pluriel avec Voir les détails/Réessayer, détail par projet avec cause française et Retirer de la reprise, retry réussi réinséré à la position mémorisée, onglet conservé si closeProject échoué; saveOpenProjectRestoreOrder exposé non appelé car l'UI ne permet pas encore de réordonnancer; QA verte reconfirmée par Git: rustup run stable cargo fmt --all -- --check, git diff --check, cargo test -p backend open_project_restore_tests 1/1 couvrant absence initiale/ordre/fermeture/inaccessible/retry/notFound/remove/watcher+MCP, cargo test -p web-server authorized_open_project_restore_commands_share_the_tauri_contract 1/1, cargo test -p domain 311+ suites vertes, cargo check -p application -p infrastructure -p backend -p app-tauri -p web-server OK, npm run typecheck OK, npm test ciblé 3 fichiers/37 tests OK, npm run build OK; réserves hors périmètre documentées au carnet: application tests/layout_usecases.rs 2 échecs fixtures plugin package NotFound, infrastructure 1 timing test cancellation process, npm test large 32 échecs web shell/LS7/tickets web — préexistants sans lien avec #303; restant: rebuild AppImage demandé après validation puis validation live fermeture/relance; fichiers tickets/296/*, tickets/299-303/*, counter/index, attachments/ et scripts/ hors périmètre; aucun push) 2026-09-10 08:14:28 +02:00
e4622cd753 fix(app-tauri,frontend): le panneau MCP se détache en fenêtre OS — #299 (cause: enum Rust ViewPanel sans variante Mcp, open_view_window("mcp") rejetait INVALID et detachPanel ne touchait le placement qu'en cas de succès donc aucun effet visible ni message; fix: variante ViewPanel::Mcp avec parse/as_str/title "MCP" + contrat stable label view-mcp / url index.html?panel=mcp / decodage view_panel_from_window_label, identite persistee des fenetres view-mcp acceptee a la restauration #50, et ProjectsView surface desormais un echec de detachement via alerte role=alert avec bouton Reessayer au lieu de l'echec silencieux — placement conserve tant que la fenetre OS ne s'ouvre pas; QA verte reconfirmee par Git: rustup run stable cargo fmt --all -- --check, git diff --check, cargo test -p app-tauri view_window_tests 9/9 dont mcp_view_window_contract_is_stable, persisted_identity_accepts_mcp_view_label 1/1, npm test 22/22 sur ViewWindow/ProjectsView.detach/viewPlacement, npm run build tsc+vite OK; fichiers tickets/296/*, tickets/299/, scripts/ et sync counter/index hors perimetre; aucun push) 2026-09-09 21:41:41 +02:00
e283f4a9e4 feat(agents,plugins): surface unifiée Capacités de l'agent — skills et tools MCP natifs + plugins #296 (domain: PluginMcpToolMetadata dans PluginMcpServerContribution, validation hôte alignée SDK — name requis non vide, description optionnelle non vide, doublons rejetés; application: McpToolPermissionCatalogue.vue structurée additive tools {name, description, access read|writeAction} enrichie des descriptions canoniques infrastructure orchestrator mcp tools, use case SetAgentMcpToolAllowed — toggle atomique idempotente d'un tool natif dans l'allowlist explicite d'un agent, refus unknown tool sans mutation, overrides vides retirés; backend DTO: catalogue.tools additive + SetAgentMcpToolAllowedRequestDto, wire camelCase; app-tauri + web-server: commande set_agent_mcp_tool_allowed; frontend: AgentPluginCapabilities devient la surface unifiée — skills natifs assign/unassign, tools natifs via setAgentMcpToolAllowed (catalogue structuré avec fallback legacy), skills/tools plugins avec metadata statiques mcpServers[].tools et saisie manuelle fallback pour serveurs sans catalogue, tombstones indisponibles, bannière redémarrage requis si agent actif; AgentsPanel retire l'ancienne section Skills séparée au profit de la surface unifiée; ProjectPluginsPanel recentré enable/disable avec renvoi Capacités des agents; adapters Tauri/HTTP/mock + permission.test.ts; QA verte reconfirmée par Git: application mcp_tool_permissions 5/5 + plugin::tests 37/37, backend ciblés 3/3 + checks domain/application/backend, app-tauri dto 33/33 + dto_agents 30/30 + dto_plugins 2/2, check web-server, npm test 35/35 + 65/65, npm run build; suites complètes rouges classées non bloquantes par QA: web-server parallèle too many open files + 7 PTY série passant individuellement, frontend 32 échecs sur 6 fichiers web non modifiés reproduits isolément) 2026-09-09 19:52:38 +02:00
1b1476de52 fix(chat): le transcript s'affiche à nouveau après redémarrage automatique d'un agent — #295 (app-tauri ChatBridge: cartes successors/owners, rebind_session déplace sink+scrolloback du logical chat vers la session de remplacement et canonical_session résout les écritures avec l'ancien id sur toutes les opérations register/scrollback/detach/send_output; backend stream: ReplayOutputBridge::rekey prépare le scrollback source devant le destination et invalide les générations pré-rekey des deux pumps; commands: agent_send binde l'owner stable (projectId,agentId) au tour humain et rebind avant le flux de continuation au handoff restart; reattach_agent_chat résout le successeur du bridge puis fallback identité stable projectId/agentId explicite ou owner bindé, renvoie sessionId effectif + conversationId, NOT_FOUND sinon; web-server chat.attach même fallback stale→live par project/agent; DTO ReattachChatDto/ReattachResultDto documentent l'id effectif post-restart; frontend: ReattachAgentChatOptions, conversationId dans ChatAttachedPayload, CustomAgentChatView réattache sur agentRestartCompleted (dédupe par restartId, scrollback appliqué, tours restart préservés), retry identité stable sur NOT_FOUND dans openOrAttach avant fallback launch frais, publication sessionId effectif + conversationId, état vide «Conversation liée» quand une conversation/run/workstate lié existe; QA verte reconfirmée par Git: git diff --check, cargo fmt --all --check, app-tauri chat_bridge 34/34 dont 3 nouveaux restart_rebind + dto_chat 24/24, cargo check -p app-tauri, backend 91+7 ignored permissions socket, web-server websocket_chat_attach 3/3, npm test 77/77 CustomAgentChatView+agentGateway, npm run build; réserves non bloquantes: warnings Vite esbuild/oxc et chunk >500kB connus) 2026-09-09 18:44:01 +02:00
18c1b01afb fix(backend,orchestrator,chat): l'objectif suspendu guide le premier tour post-restart — #290 regression partielle (register_suspended_turn capture la demande utilisateur exacte au point d'entrée chat agent_send/chat.send avec source diagnostique, RestartRendezvousCoordinator conserve tour/objectif/restart_attempt_id, take_continuation consommable exactement une fois et seulement par la tentative courante: suspended_restart_continuation_prompt place l'objectif utilisateur avant toute consigne generique et StructuredHumanTurnTransition::Resume porte le prompt host-provided injecte au runtime de remplacement; nettoyage du tour suspendu sur succes, echec, annulation et abandon/expiration; diagnostics projet/agent/turn_id/restart_attempt_id/source; rendez-vous inter-agents #289 inchanges; QA verte reconfirmee par Git: cargo check --workspace, backend self_restart_contract_tests 3/3, orchestrator_service restart 10/10, workstate_actions 9/9, app-tauri chat_bridge 31/31, web-server websocket_chat_send 3/3, fmt --check, diff --check; restants: rebuild AppImage + validation live reprise objectif apres restart; carnet #290 iteration regression + passage store qa inclus; scripts/ hors périmètre; aucun push) 2026-09-09 09:17:36 +02:00
d03300a20f fix(backend,orchestrator,chat): tour humain agent_send survit au self-restart — #290 (le tour humain direct agent_send/ws chat.send s'enregistre au RestartRendezvousCoordinator via StructuredHumanTurnGuard: Final/Error de l'ancien provider devient transition de contrôle et non le Final logique; transition_after_provider_terminal_async attend Ready puis accept_ready acquitte le handoff et libère le scheduler, Resume => drain de la session de remplacement avec SELF_RESTART_CONTINUATION_PROMPT, seul le terminal du remplacement est transmis au chat; Failed/Cancelled surfacés explicitement avec libération Busy/FIFO; send_with_tap en erreur pendant restart actif traité comme teardown attendu (stream vide puis attente du remplacement, plus de Final prématuré ni chat bloqué); StopLiveAgent câblé with_restart_rendezvous: stop utilisateur annule le rendez-vous restart; RestartRendezvousRegistration rendu public (state/changed/accept_ready); QA verte: backend self_restart_contract_tests 3/3 dont 2 nouveaux (old terminal ignoré + handoff accepté, failure explicite + busy libéré), application orchestrator_service restart 8/8 dont registration directe du rendez-vous, workstate_actions 9/9, app-tauri chat_bridge 31/31, web-server websocket_chat_send 3/3, cargo check --workspace, fmt --check, diff --check — reconfirmés par Git avant commit; réserves hors périmètre préexistantes: 7 échecs fixture PTY web-server + 2 échecs plugin application; carnet #290 + clôture store #289 inclus; scripts/ hors périmètre; aucun push) 2026-09-09 08:38:29 +02:00
63537572b8 feat(mcp,orchestrator,frontend): tool idea_restart_self, redemarrage autonome d'un agent — #288 (tool core self-only via requester MCP handshake, retour immediat {restartId, status: scheduled} puis orchestration detachee: snapshot reprise, stop PTY/structured, liberation Busy/mailbox, relance LaunchAgent meme conversation_id fresh_start=false, injection interne invisible; events domain/wire agentRestartRequested/PhaseChanged/Completed/Failed phases stopping/releasingInput/launching/resuming; CLI custom: separateurs exacts redemarrage de l'agent + etat termine/echoue, deduplication (restartId, event), verrouillage composer; TUI native: overlay AgentRestartOverlay sans injection xterm, progress/annonces projetes jusqu'a idle; QA verte: mcp_server restart_self 1/1, restart-self 3/3, backend self_restart_contract + events wire 2/2, frontend 3 suites 92/92, npm build, cargo check --workspace, fmt --check, diff --check; reserves hors perimetre: web-server 103/110 fixture PTY preexistante, 34 echecs npm test globaux listProjectSettings/web hors #288; scripts/ hors perimetre) 2026-09-08 22:04:18 +02:00
86ed0aa00b feat(plugins): paramètres projet plugins + attribution skills/tools aux agents — #282 (manifeste accepte contributes.skills IdeA-native multi-harness; store .ideai/project-plugins.json v1: enable plugin par projet + assignments skills/tools par agent; refs + use cases settings/assign/unassign; resolver skills pour idea_skill_read et injection catalogue lancement agent; permissions MCP dynamiques projetées par harness Claude Code/Codex/OpenCode; tombstones uninstall, hot reload recalcule catalogue et marque assignments cassés; frontend: Settings projet Plugins, détail capabilities, attribution agent, catalogue permissions; bump pointeur IdeaSDK 6eb8db3; QA verte: cargo test -p application, project_plugin_settings 3/3, dto_plugins 2/2, structured_launch_d3 26/26, catalogue mcp 7/7, frontend 5 tests ProjectPluginSettings/plugin, npm build frontend) 2026-09-08 15:48:57 +02:00
cb5196fd69 feat(agents): role orchestrateur du contexte global expose et configurable par agent — isOrchestrator distinct des permissions MCP, DTO update_project_orchestrator (terminologie wire legacy conservee), refus idea_context_update explicite avec writer effectif + orientation idea_context_propose, surface AgentsPanel + adaptateurs frontend — #276 (QA verte: cargo fmt/check, tests cibles application/app-tauri/infrastructure/backend, npm typecheck, 69/69 tests frontend agents/adapters) 2026-09-07 22:49:12 +02:00
805b1b4d0d feat(plugins): hot reload des plugins sans relancer IdeA — use case ReloadPlugin (invalidation registry/catalogue, resultat hashes+changed), tools MCP d'administration plugin agent-facing (mcp/plugins.rs + PluginToolProvider), evenement domaine plugin_reloaded relaye sur le wire (dto/events), exposition openai_tools rafraichie, wiring app-tauri — #271/#269 (QA verte #273: application 32, mcp_server 38, openai_tools 10, plugin_install_load 5, plugin 10, wire 1 — 96 tests ciblés; app-tauri compile sans desktop runtime) 2026-09-07 19:29:25 +02:00
f6101a8249 fix(permissions): tools MCP inter-projets exposés (idea_project_*) + contactable agent/template persisté — update_agent_contactable (application/web-server/app-tauri), defaultContactable TemplateEditor save/reopen, groupes MCP 'IdeA inter-projets' avec fallback, permissions agent Contactable — #267 (QA verte) 2026-09-07 18:13:27 +02:00
3513e90101 fix(templates): default_contactable toujours sérialisé (idea_template_update retourne false au lieu de Null) + fixture app-tauri adaptée — #264 (QA verte) 2026-09-07 16:55:37 +02:00
98954986a7 feat(cross-project): découverte et contact inter-projets — tools MCP idea_project_{list,read_context,list_agents,ask_agent,cancel_agent}, permission contactable par agent + default_contactable persistée dans les templates, routage orchestrator par projectId+agentId — #260 (tests ciblés verts, QA en attente) 2026-09-07 16:31:14 +02:00
f1d85dfc5a fix(custom-cli): busy/progress/tools/chatbox bloqués après le premier appel — #245 (QA verte)
Backend : StructuredHumanTurnGuard pour partager la comptabilité busy/FIFO entre chat direct humain (agent_send, web chat.send) et asks inter-agents structurés, avec liveness mark_alive et retrait idempotent du tour. Web-server : tap d'événements sur chat.send pour le scrollback temps réel. Frontend : scoping des clés de progression par tour pour éviter la déduplication/ghosting des progress et outils entre appels.
2026-08-23 13:34:56 +02:00
0a7d7f844e fix(templates): open_project ne rétro-synchronise plus les permissions agents vers les templates — #244 (QA verte)
Suppression du backfill agent→template au open_project (cause racine de la non-persistance des permissions MCP/system des templates) et couverture de régression : create/read/update des default permissions + test dédié open_project sans backfill.
2026-08-23 13:03:07 +02:00
d6c80be56d feat(templates): nom d'agent par défaut + permissions système et MCP outils sur AgentTemplate — #242
AgentTemplate étendu (defaultAgentName, systemPermissions, mcpToolPermissions),
CreateTemplate/UpdateTemplate/CreateAgentFromTemplate projetés vers l'agent créé,
DTO/MCP tools et persistance store complétés. Correctif modèle par défaut:
UpdateTemplate ne persistait pas defaultProfileId (profil stale à la création
d'agent). Backfill best-effort des templates existants depuis les agents du
projet au open_project, overrides explicites uniquement.
2026-08-23 10:59:55 +02:00
3f3eb5938a fix(chat): capture du final et cause réelle des fins de tour « Le modèle n'a renvoyé aucune réponse. » — #231 2026-08-21 20:45:50 +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
d0521db6b6 merge(infra): tests d'intégration managed temp handlers/routage — #191 (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
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
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
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
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
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
fbaca9d5cc feat(plugins): seam slash-commands contribuées par plugin via callback — #165 (QA verte)
Permet à un plugin de contribuer des commandes slash adossées à une callback,
transitant par le registry/contrat unifié (#162) :

- sdk/IdeaSDK: manifeste contributes.slashCommands (déclaratif) — pointer bumpé.
- domain: source Plugin étendue + effet PluginCallback (la commande ne
  s'exécute pas directement : elle renvoie une référence à la callback du plugin).
- application: registration des commandes plugin dans le registry + exécution
  renvoyant l'effet PluginCallback ; métadonnées UI suffisantes pour l'autocomplete.
- backend + app-tauri: DTO + commandes Tauri listant/invoquant les commandes plugin.
- frontend (contrat): types adapters/domain/ports/mock pour pluginCallback et
  l'invocation avec arguments.

L'exécution effective de la callback côté runtime UI est livrée par #166.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:46:52 +02:00
6997138a71 feat(slash): fondation du système de commandes slash pour la CLI custom — #162 (QA verte)
Introduit le contrat unifié des commandes slash consommable par le frontend,
indépendant de la source (native, puis plugin plus tard) :

- domain: modèle pur SlashCommand / SlashCommandSource / SlashCommandAvailability,
  métadonnées UI (nom, description, disponibilité, confirmation requise) et
  validation des noms/préfixes.
- application: registry + list/filter par préfixe + plan d'exécution natif ;
  commandes natives /help et /clean (/clean = nettoyage de la vue de session
  courante ; pas de /reset distinct tant qu'aucune utilité produit ne le justifie).
- backend + app-tauri: exposition du contrat via DTO/transport + tests DTO.

Source neutre : les commandes contribuées par plugins (#165) transiteront par
le même registry sans changer le contrat frontend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:52:36 +02:00
918116664c feat(backend): modèle unifié streaming/progress/events provider-agnostic + pont app-tauri — foundation #156 (QA verte) 2026-08-06 13:13:17 +02:00
790c4755be feat(chat): #155 paste image depuis presse-papier dans le composer custom (QA verte)
- frontend: onPaste sur CustomAgentChatView, détection MIME image, chip/preview d'attachment, envoi via le contrat #154 (adapters/agent, ports)

- backend: import d'image par bytes dans le store attachments (commands, chat_attachments app+infra, dto, ports) + tests
2026-08-06 11:01:50 +02:00
1c80d08f92 feat(attachments): fondation pipeline durable d'attachments agent/chat + sandbox-safe (#154, QA verte)
Socle #154 : entité attachment, store, contrat DTO et routage session. Modules : domain/chat_attachment, application/chat_attachments, infrastructure/chat_attachments, app-tauri (commands/lib), backend dto.
2026-08-06 10:44:15 +02:00
c43f29b2f2 feat(chat): propage l'intention chat → require_structured dans le pipeline de lancement
- Ajoute le champ cell_kind dans LaunchAgentRequestDto pour distinguer les demandes chat (custom CLI) des lancements PTY historiques
- Convertit cellKind:Chat en require_structured:true dans commands.rs et web-server/src/lib.rs
- Implémente la logique de routing structuré dans LaunchAgent::execute :
  - valide que require_structured implique un profil avec structured_adapter
  - remplace une session PTY existante quand require_structured est vrai
  - route vers structured seulement quand wants_structured est vrai
- Met à jour tous les appels historiques avec require_structured:false pour préserver le contrat PTY
- Ajoute les tests unitaires human_launcher_with_chat_intent_routes_structured_profile_to_chat_session et chat_intent_replaces_existing_pty_instead_of_returning_pty_session
- Wire les ports structured dans BackendCore pour le launcher humain

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 23:39:35 +02:00
dcba76b871 feat(chat): livre la CLI custom de chat agent (#147) et corrige Cancel
Implémente la vue chat structurée par cellule agent (toggle TUI/CLI custom,
préférence persistée `preferred_view`, reattach live, composer + pièces
jointes) avec le socle backend AgentSession/ChatBridge (UserPrompt,
cancel_current_turn, routage interrupt_agent, commande cancel_agent_chat).

Corrige le bug bloquant relevé par QA : le bouton Cancel de
CustomAgentChatView interrompait tout le tour via closeAgentChat au lieu
de n'annuler que le tour courant via cancelAgentChat, ce qui tuait la
session contrairement au contrat produit validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 11:59:39 +02:00
551eb09ad2 feat(window): support des fenêtres plugin-hébergées (backend)
Étend le port/usecases window et layout.customPluginLayout pour ouvrir et
piloter des fenêtres OS hébergeant un layout plugin, en réutilisant
contributes.layouts plutôt qu'un système de fenêtres parallèle. Câble la
commande Tauri et l'état app-tauri correspondants.

Cargo test -p domain --test window : 5/5
Cargo test -p application --test window_usecases : 7/7
Cargo test -p infrastructure --test window_state_store : 1/1
Cargo test -p app-tauri view_window_tests : 8/8

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:39:42 +02:00