feat(backend): système de plugins — domaine, application, infrastructure (#43)

Lots B1-B4 : modèle de domaine des plugins (manifeste, capacités menus/layouts/MCP),
port et registre applicatif, chargement/validation en infrastructure, exposition DTO
et commandes Tauri. Tests cargo verts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 07:37:03 +02:00
parent 47aacc6da9
commit bb35641715
24 changed files with 4304 additions and 41 deletions

View File

@ -119,6 +119,60 @@ pub enum DomainEventDto {
/// Project id (UUID string).
project_id: String,
},
/// A plugin was installed.
#[serde(rename_all = "camelCase")]
PluginInstalled {
/// Plugin id.
plugin_id: String,
/// Installed version.
version: String,
},
/// A plugin was enabled.
#[serde(rename_all = "camelCase")]
PluginEnabled {
/// Plugin id.
plugin_id: String,
},
/// A plugin was disabled.
#[serde(rename_all = "camelCase")]
PluginDisabled {
/// Plugin id.
plugin_id: String,
/// Whether a restart is needed for full JS purge.
restart_required: bool,
},
/// A plugin was uninstalled.
#[serde(rename_all = "camelCase")]
PluginUninstalled {
/// Plugin id.
plugin_id: String,
/// Whether a restart is needed for full JS purge.
restart_required: bool,
},
/// A plugin failed to load.
#[serde(rename_all = "camelCase")]
PluginLoadFailed {
/// Plugin id.
plugin_id: String,
/// Failure reason.
reason: String,
},
/// A plugin MCP server started.
#[serde(rename_all = "camelCase")]
PluginMcpServerStarted {
/// Plugin id.
plugin_id: String,
/// Server id.
server_id: String,
},
/// A plugin MCP server stopped.
#[serde(rename_all = "camelCase")]
PluginMcpServerStopped {
/// Plugin id.
plugin_id: String,
/// Server id.
server_id: String,
},
/// An agent was launched.
#[serde(rename_all = "camelCase")]
AgentLaunched {
@ -677,6 +731,45 @@ impl From<&DomainEvent> for DomainEventDto {
DomainEvent::ProjectCreated { project_id } => Self::ProjectCreated {
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(),
},
DomainEvent::PluginEnabled { plugin_id } => Self::PluginEnabled {
plugin_id: plugin_id.to_string(),
},
DomainEvent::PluginDisabled {
plugin_id,
restart_required,
} => Self::PluginDisabled {
plugin_id: plugin_id.to_string(),
restart_required: *restart_required,
},
DomainEvent::PluginUninstalled {
plugin_id,
restart_required,
} => Self::PluginUninstalled {
plugin_id: plugin_id.to_string(),
restart_required: *restart_required,
},
DomainEvent::PluginLoadFailed { plugin_id, reason } => Self::PluginLoadFailed {
plugin_id: plugin_id.to_string(),
reason: reason.clone(),
},
DomainEvent::PluginMcpServerStarted {
plugin_id,
server_id,
} => Self::PluginMcpServerStarted {
plugin_id: plugin_id.to_string(),
server_id: server_id.as_str().to_owned(),
},
DomainEvent::PluginMcpServerStopped {
plugin_id,
server_id,
} => Self::PluginMcpServerStopped {
plugin_id: plugin_id.to_string(),
server_id: server_id.as_str().to_owned(),
},
DomainEvent::AgentLaunched {
agent_id,
session_id,