Files
IdeA/.ideai/tickets/279/carnet.md

7.9 KiB
Raw Blame History

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#279 8
kind agent_id
agent a6c6ea12-bfc6-4bdc-8031-324102dfa34d
1788865967900

Ticket #279 — Plugins sans restart + refresh UI + tools MCP

Demande utilisateur

  • Quand un plugin est ajouté à IdeA, ne plus demander de redémarrer si un reload d’interface suffit.
  • Déclencher automatiquement ce refresh après le load du plugin.
  • Après refresh, restaurer le même état : projets ouverts, projet actif, fenêtres/layouts, panneaux/onglets, agents visibles, conversations sélectionnées, état UI raisonnablement restaurable.
  • Ne pas couper les agents en cours.
  • Ajouter un tool MCP permettant à un agent d’installer un plugin dans IdeA depuis un dossier.
  • Ajouter un tool MCP permettant à un agent de hot reload l’affichage après modifications dans le dossier d’un plugin déjà installé.
  • Puis rebuild AppImage.

Mémoire pertinente

plugin-hot-reload-agent-facing-delivered : un use case backend ReloadPlugin et un tool agent-facing idea_plugin_reload({ pluginId, expectedContentHash? }) existent déjà. Limite V1 : les contributions UI React chargées par PluginRuntimeProvider ne sont pas rafraîchies après PluginReloaded.

Cadrage UX

  • Comportement attendu : soft refresh UI discret, déclenché après confirmation que le plugin est chargé côté système.
  • Ne plus afficher de demande générique Redémarrez IdeA par défaut.
  • Messages possibles : Chargement du plugin…, Mise à jour de l’interface…, succès discret Plugin chargé. Interface mise à jour. / Plugin rechargé. Affichage mis à jour.
  • Fallback seulement si nécessaire : Plugin chargé, mais l’interface n’a pas pu être mise à jour automatiquement. Rechargez l’affichage pour voir les changements. ou Plugin chargé. Un redémarrage d’IdeA est nécessaire pour appliquer tous les changements.
  • Préserver projets ouverts, fenêtres flottantes, layouts, tailles, onglets, panneaux, sélection, scroll/filtres raisonnables.
  • Les agents en cours ne doivent pas être arrêtés, relancés, masqués durablement ou marqués perdus.

Cadrage Architecture

Verdict : faisable sans restart IdeA. Contrat = soft refresh du runtime plugin UI, pas restart process ni window.location.reload().

Backend/MCP

  • Ajouter idea_plugin_install_from_directory agent-facing.
  • Réutiliser InstallPluginFromDirectory existant côté application.
  • Paramètres : { path: string, expectedPluginId?: string }.
  • Chemin relatif au project root requester accepté ; chemin absolu hors project root rejeté sauf règle explicite future.
  • Rejeter fichiers, archives, symlinks échappants, manifest absent/id invalide, mismatch expectedPluginId.
  • Retourner le même shape que l’install UI : plugin, review, restartRequired, warnings si disponibles.
  • idea_plugin_reload reste tool canonique pour le reload depuis la source enregistrée ; ne pas créer de doublon si son contrat/description couvre bien le refresh UI via event.
  • Les deux tools sont WriteAction.

Frontend

  • PluginRuntimeProvider s’abonne aux événements pluginInstalled/pluginReloaded.
  • Sur événement, il relit plugin.listRuntimeContributions() puis reconstruit le registry via loadPlugins.
  • Le contexte plugin est remplacé sans window.location.reload() ni remount de l’app/workspace.
  • Les layouts plugin existants restent en place ; fallback existant si contribution absente/invalide.

Implémentation backend

Fichiers modifiés :

  • crates/application/src/plugin/mod.rs
  • crates/backend/src/lib.rs
  • crates/infrastructure/src/orchestrator/mcp/plugins.rs
  • crates/infrastructure/src/orchestrator/mcp/tools.rs
  • crates/infrastructure/tests/mcp_server.rs
  • crates/infrastructure/tests/plugin_install_load.rs

Résultat :

  • Nouveau tool idea_plugin_install_from_directory({ path, expectedPluginId? }).
  • Chemin canonique confiné au project root du demandeur ; fichiers et symlinks sortants rejetés.
  • Validation expectedPluginId avant commit.
  • Tool classé WriteAction, masqué/refusé sans permission explicite.
  • Installation avec restartRequired: false et publication PluginInstalled.
  • idea_plugin_reload conservé comme tool canonique, publication PluginReloaded.

Tests DevBackend :

  • cargo fmt --all -- --check — OK
  • cargo check -p application -p infrastructure -p backend — OK
  • cargo test -p application directory_install_ --lib -- --nocapture — 2 OK
  • cargo test -p backend plugin_directory_resolution_ --lib -- --nocapture — 4 OK
  • cargo test -p infrastructure --test mcp_server plugin_ -- --nocapture — 2 OK
  • cargo test -p infrastructure --test plugin_install_load -- --nocapture — 5 OK
  • cargo test -p application plugin::tests --lib -- --nocapture — 34 OK
  • cargo test -p infrastructure --test mcp_server -- --nocapture — 39 OK
  • git diff --check -- <six fichiers> — OK

Implémentation frontend

Fichiers modifiés :

  • frontend/src/domain/index.ts
  • frontend/src/features/plugins/PluginRuntimeProvider.tsx
  • frontend/src/features/plugins/PluginRuntimeProvider.test.tsx
  • frontend/src/features/plugins/plugins.test.tsx
  • frontend/src/adapters/mock/index.ts
  • frontend/src/plugins/runtime/loader.ts

Résultat :

  • Événements typés pluginInstalled et pluginReloaded.
  • Rechargement atomique du registre plugin sur ces événements.
  • Aucun remount workspace ni reload WebView.
  • État enfant préservé.
  • Contributions absentes/invalides : fallback existant, cellule conservée.
  • Fenêtres secondaires couvertes via leur propre provider.
  • Installation mock alignée sur restartRequired: false; plus de message Redémarrage requis quand non nécessaire.

Tests DevFrontend :

  • npm run typecheck — OK
  • npm test -- --run src/features/plugins/PluginRuntimeProvider.test.tsx src/features/plugins/plugins.test.tsx src/features/plugins/PluginLayoutCellView.test.tsx src/app/ViewWindow.test.tsx — 4 fichiers, 24 OK
  • git diff --check — OK

QA

Verdict QA : VERT sur feature/279-plugin-soft-refresh.

Commandes QA :

  • cargo fmt --all --check — OK
  • git diff --check — OK
  • cargo test -p infrastructure --test mcp_server -- --nocapture — 39 OK
  • cargo test -p infrastructure --test plugin_install_load -- --nocapture — 5 OK
  • cargo test -p backend plugin_directory_resolution -- --nocapture — 4 OK
  • cargo test -p application plugin -- --nocapture — global vert, incluant install soft-refresh, mismatch expectedPluginId, reload/hash/reconcile.
  • cargo test -p application open_plugin_layout_window -- --nocapture — 2 OK
  • cargo test -p application restore_open_windows -- --nocapture — 2 OK
  • cd frontend && npm run typecheck — OK
  • cd frontend && npm test -- --run src/features/plugins/PluginRuntimeProvider.test.tsx src/features/plugins/plugins.test.tsx — 2 fichiers, 13 OK
  • cd frontend && npm test -- --run src/features/plugins/PluginLayoutCellView.test.tsx src/features/projects/pluginGitRepository.test.tsx src/features/layout/layoutTabsGitGraph.test.tsx src/features/agents/CustomAgentChatView.test.tsx — 4 fichiers, 78 OK

Git

  • 979965a — backend #279.
  • 44dc677 — frontend #279.
  • 0b709b9 — merge local --no-ff vers develop.
  • Aucun push distant.

Rebuild AppImage

Skill utilisé : build-appimage. Commandes :

  • npm --prefix frontend run build — OK.
  • Depuis crates/app-tauri : mkdir -p /tmp/idea-cargo-home && CARGO_HOME=/tmp/idea-cargo-home APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage — OK.

Artefact : /home/anthony/Documents/Projects/IdeA/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage. Vérification : -rwxr-xr-x, 114M, Sep 8 13:11.

Limite d’application live

L’AppImage installée n’a pas été remplacée et IdeA n’a pas été relancé. Pour rendre le correctif actif dans l’application en cours, il faudra remplacer l’AppImage installée puis relancer IdeA quand l’utilisateur est prêt.