feat(domain,application,backend,app-tauri,frontend): lot utilisateur #328 #329 #330 #331 — section plugins projet, erreurs menus plugin visibles, refresh auto des pages, droplist agents (QA verte)

Lot en un seul commit: les quatre tickets partagent les mêmes fichiers
(événements domaine/DTO, ProjectPluginsPanel, useProjectPlugins) — une
séparation par hunks aurait risqué des états intermédiaires non
compilables (convention lot des batches #310-#313, #315 et #325-#326).

#328 — section dédiée plugins dans Paramètres du projet:
- frontend: ProjectPluginsPanel intégré à ProjectSettingsPanel
  (Panneaux > Paramètres du projet) — activation/désactivation par
  plugin avec état actif/inactif explicite par projet, distinct de
  l'assignation agents/skills/tools
- domaine: événement ProjectPluginSettingsChanged publié par
  SetProjectPluginEnabled, MutateAgentPluginSkill et
  MutateAgentPluginTool après persistance de .ideai/project-plugins.json
  (application + backend + DTO camelCase, test dto.rs)

#329 — les menus plugin qui échouent ne sont plus muets:
- usePluginMenus: dispatcher strict (runCommandStrict) pour les
  commandes réellement enregistrées au lieu du dispatcher laxiste qui
  journalisait et avalait les rejets — rendait les échecs d'ouverture
  de fenêtres natifs invisibles pour l'hôte de menus
- le no-op SDK historique (commande déclarée sans handler) est préservé
- échec remonté à l'hôte via commandError/clearCommandError (journal
  console + état exposé); test window_usecases adapté à un plugin
  installé
- le correctif côté SDK/GitPlugin vit dans le projet GitPlugin (son
  commit/merge local y est fait, hors périmètre de ce dépôt)

#330 — refresh automatique des pages:
- frontend/domain: typage des événements pluginEnabled,
  pluginDisabled (restartRequired), pluginUninstalled
  (restartRequired), pluginLoadFailed et projectPluginSettingsChanged
- useProjectPlugins et PluginRuntimeProvider: souscription
  onDomainEvent — refresh sur changement catalogue global ou sur
  projectPluginSettingsChanged du projet courant; gardes
  révision/projet contre les réponses obsolètes
- useProjectAgents: refresh auto quand un agent est ajouté au projet;
  ProjectsView et AgentsPanel suivent (erreur de rafraîchissement
  affichée avec bouton Réessayer)

#331 — droplist agents des cellules:
- SmallDropdown: liste bg-overlay + bordure border-strong (plus de
  fond blanc hors thème), hover/focus bg-raised, sélection
  bg-primary/15, disabled text-faint opacity-60, role=combobox
- LayoutGrid: sélecteur d'agent des cellules migré du <select> natif
  vers SmallDropdown (mêmes libellés Terminal/visible
  ailleurs/arrière-plan)

QA verte réelle sur les quatre lots (tests ciblés + exécution).
sdk/IdeaSDK: contenu modifié non committable ici (pointeur inchangé).
Aucun push.
This commit is contained in:
2026-09-12 01:14:45 +02:00
parent 4f0457c08a
commit db67ecdf8f
24 changed files with 706 additions and 146 deletions

View File

@ -148,6 +148,12 @@ pub enum DomainEventDto {
/// Project id (UUID string).
project_id: String,
},
/// Project-scoped plugin activation or assignments changed.
#[serde(rename_all = "camelCase")]
ProjectPluginSettingsChanged {
/// Owning project id.
project_id: String,
},
/// A plugin was installed.
#[serde(rename_all = "camelCase")]
PluginInstalled {
@ -857,6 +863,11 @@ impl From<&DomainEvent> for DomainEventDto {
DomainEvent::ProjectCreated { project_id } => Self::ProjectCreated {
project_id: project_id.to_string(),
},
DomainEvent::ProjectPluginSettingsChanged { project_id } => {
Self::ProjectPluginSettingsChanged {
project_id: project_id.to_string(),
}
}
DomainEvent::PluginInstalled { plugin_id, version } => Self::PluginInstalled {
plugin_id: plugin_id.to_string(),
version: version.as_str().to_owned(),

View File

@ -3636,16 +3636,19 @@ impl BackendCore {
let set_project_plugin_enabled = Arc::new(SetProjectPluginEnabled::new(
Arc::clone(&project_plugin_settings_store),
Arc::clone(&plugin_package_store),
Arc::clone(&events_port),
));
let mutate_agent_plugin_skill = Arc::new(MutateAgentPluginSkill::new(
Arc::clone(&project_plugin_settings_store),
Arc::clone(&contexts_port),
Arc::clone(&project_plugin_resolver),
Arc::clone(&events_port),
));
let mutate_agent_plugin_tool = Arc::new(MutateAgentPluginTool::new(
Arc::clone(&project_plugin_settings_store),
Arc::clone(&contexts_port),
Arc::clone(&project_plugin_resolver),
Arc::clone(&events_port),
));
// --- Memory use cases (LOT A — §14.5.1) ---