7.9 KiB
issueRef, version, updatedBy, updatedAt
| issueRef | version | updatedBy | updatedAt | ||||
|---|---|---|---|---|---|---|---|
| #279 | 8 |
|
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 IdeApar défaut. - Messages possibles :
Chargement du plugin…,Mise à jour de l’interface…, succès discretPlugin 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.ouPlugin 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_directoryagent-facing. - Réutiliser
InstallPluginFromDirectoryexistant 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_reloadreste 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
PluginRuntimeProviders’abonne aux événementspluginInstalled/pluginReloaded.- Sur événement, il relit
plugin.listRuntimeContributions()puis reconstruit le registry vialoadPlugins. - 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.rscrates/backend/src/lib.rscrates/infrastructure/src/orchestrator/mcp/plugins.rscrates/infrastructure/src/orchestrator/mcp/tools.rscrates/infrastructure/tests/mcp_server.rscrates/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
expectedPluginIdavant commit. - Tool classé
WriteAction, masqué/refusé sans permission explicite. - Installation avec
restartRequired: falseet publicationPluginInstalled. idea_plugin_reloadconservé comme tool canonique, publicationPluginReloaded.
Tests DevBackend :
cargo fmt --all -- --check— OKcargo check -p application -p infrastructure -p backend— OKcargo test -p application directory_install_ --lib -- --nocapture— 2 OKcargo test -p backend plugin_directory_resolution_ --lib -- --nocapture— 4 OKcargo test -p infrastructure --test mcp_server plugin_ -- --nocapture— 2 OKcargo test -p infrastructure --test plugin_install_load -- --nocapture— 5 OKcargo test -p application plugin::tests --lib -- --nocapture— 34 OKcargo test -p infrastructure --test mcp_server -- --nocapture— 39 OKgit diff --check -- <six fichiers>— OK
Implémentation frontend
Fichiers modifiés :
frontend/src/domain/index.tsfrontend/src/features/plugins/PluginRuntimeProvider.tsxfrontend/src/features/plugins/PluginRuntimeProvider.test.tsxfrontend/src/features/plugins/plugins.test.tsxfrontend/src/adapters/mock/index.tsfrontend/src/plugins/runtime/loader.ts
Résultat :
- Événements typés
pluginInstalledetpluginReloaded. - 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 messageRedémarrage requisquand non nécessaire.
Tests DevFrontend :
npm run typecheck— OKnpm 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 OKgit diff --check— OK
QA
Verdict QA : VERT sur feature/279-plugin-soft-refresh.
Commandes QA :
cargo fmt --all --check— OKgit diff --check— OKcargo test -p infrastructure --test mcp_server -- --nocapture— 39 OKcargo test -p infrastructure --test plugin_install_load -- --nocapture— 5 OKcargo test -p backend plugin_directory_resolution -- --nocapture— 4 OKcargo 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 OKcargo test -p application restore_open_windows -- --nocapture— 2 OKcd frontend && npm run typecheck— OKcd frontend && npm test -- --run src/features/plugins/PluginRuntimeProvider.test.tsx src/features/plugins/plugins.test.tsx— 2 fichiers, 13 OKcd 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-ffversdevelop.- 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.