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:
@ -20,6 +20,253 @@ use domain::{AgentBusyState, PageCursor, PageDirection, Project, ProjectId, Turn
|
||||
|
||||
pub use crate::ticket_dto::*;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Plugins (#43)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Plugin contribution summary DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginContributionSummaryDto {
|
||||
/// Top-level menus count.
|
||||
pub top_level_menus: usize,
|
||||
/// Menu items count.
|
||||
pub menu_items: usize,
|
||||
/// Layouts count.
|
||||
pub layouts: usize,
|
||||
/// MCP servers count.
|
||||
pub mcp_servers: usize,
|
||||
}
|
||||
|
||||
impl From<application::PluginContributionSummary> for PluginContributionSummaryDto {
|
||||
fn from(value: application::PluginContributionSummary) -> Self {
|
||||
Self {
|
||||
top_level_menus: value.top_level_menus,
|
||||
menu_items: value.menu_items,
|
||||
layouts: value.layouts,
|
||||
mcp_servers: value.mcp_servers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Admin plugin DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginAdminDto {
|
||||
/// Plugin id.
|
||||
pub id: String,
|
||||
/// Display name.
|
||||
pub display_name: String,
|
||||
/// Publisher.
|
||||
pub publisher: Option<String>,
|
||||
/// Version.
|
||||
pub version: String,
|
||||
/// Description.
|
||||
pub description: Option<String>,
|
||||
/// Icon URL.
|
||||
pub icon_url: Option<String>,
|
||||
/// Source kind.
|
||||
pub source_kind: String,
|
||||
/// Source label.
|
||||
pub source_label: Option<String>,
|
||||
/// Lifecycle state.
|
||||
pub lifecycle_state: domain::PluginLifecycleState,
|
||||
/// Enabled flag.
|
||||
pub enabled: bool,
|
||||
/// Pending enable state.
|
||||
pub pending_enable_state: Option<bool>,
|
||||
/// Pending uninstall flag.
|
||||
pub pending_uninstall: bool,
|
||||
/// Restart required flag.
|
||||
pub restart_required: bool,
|
||||
/// Trust level.
|
||||
pub trust_level: domain::PluginTrustLevel,
|
||||
/// Contribution summary.
|
||||
pub contribution_summary: PluginContributionSummaryDto,
|
||||
/// Optional error.
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl From<application::PluginAdmin> for PluginAdminDto {
|
||||
fn from(value: application::PluginAdmin) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
display_name: value.display_name,
|
||||
publisher: value.publisher,
|
||||
version: value.version,
|
||||
description: value.description,
|
||||
icon_url: value.icon_url,
|
||||
source_kind: value.source_kind,
|
||||
source_label: value.source_label,
|
||||
lifecycle_state: value.lifecycle_state,
|
||||
enabled: value.enabled,
|
||||
pending_enable_state: value.pending_enable_state,
|
||||
pending_uninstall: value.pending_uninstall,
|
||||
restart_required: value.restart_required,
|
||||
trust_level: value.trust_level,
|
||||
contribution_summary: value.contribution_summary.into(),
|
||||
error: value.error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Review request DTO.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ReviewPluginPackageDto {
|
||||
/// Source kind: `archive` or `directory`.
|
||||
pub source_kind: String,
|
||||
/// Local source path.
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
/// Plugin review DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginReviewDto {
|
||||
/// Manifest id.
|
||||
pub id: String,
|
||||
/// Display name.
|
||||
pub display_name: String,
|
||||
/// Publisher.
|
||||
pub publisher: Option<String>,
|
||||
/// Version.
|
||||
pub version: String,
|
||||
/// Description.
|
||||
pub description: Option<String>,
|
||||
/// Source kind.
|
||||
pub source_kind: String,
|
||||
/// Source label.
|
||||
pub source_label: Option<String>,
|
||||
/// Content hash.
|
||||
pub content_hash: String,
|
||||
/// Trust level.
|
||||
pub trust_level: domain::PluginTrustLevel,
|
||||
/// Summary.
|
||||
pub contribution_summary: PluginContributionSummaryDto,
|
||||
/// Manifest contributions.
|
||||
pub contributes: domain::PluginContributionSet,
|
||||
}
|
||||
|
||||
impl From<application::PluginReview> for PluginReviewDto {
|
||||
fn from(value: application::PluginReview) -> Self {
|
||||
Self {
|
||||
id: value.manifest.id.as_str().to_owned(),
|
||||
display_name: value.manifest.display_name,
|
||||
publisher: value.manifest.publisher,
|
||||
version: value.manifest.version.as_str().to_owned(),
|
||||
description: value.manifest.description,
|
||||
source_kind: value.source.kind().to_owned(),
|
||||
source_label: Some(value.source.label().to_owned()),
|
||||
content_hash: value.content_hash,
|
||||
trust_level: value.trust_level,
|
||||
contribution_summary: value.contribution_summary.into(),
|
||||
contributes: value.manifest.contributes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Plugin install result DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginInstallResultDto {
|
||||
/// Installed plugin.
|
||||
pub plugin: PluginAdminDto,
|
||||
/// Review.
|
||||
pub review: PluginReviewDto,
|
||||
/// Restart required.
|
||||
pub restart_required: bool,
|
||||
}
|
||||
|
||||
impl From<application::PluginInstallResult> for PluginInstallResultDto {
|
||||
fn from(value: application::PluginInstallResult) -> Self {
|
||||
Self {
|
||||
plugin: value.plugin.into(),
|
||||
review: value.review.into(),
|
||||
restart_required: value.restart_required,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Plugin uninstall result DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginUninstallResultDto {
|
||||
/// Plugin id.
|
||||
pub plugin_id: String,
|
||||
/// Removal outcome.
|
||||
pub removal_outcome: domain::RemovalOutcome,
|
||||
/// Restart required.
|
||||
pub restart_required: bool,
|
||||
}
|
||||
|
||||
impl From<application::UninstallPluginResult> for PluginUninstallResultDto {
|
||||
fn from(value: application::UninstallPluginResult) -> Self {
|
||||
Self {
|
||||
plugin_id: value.plugin_id,
|
||||
removal_outcome: value.removal_outcome,
|
||||
restart_required: value.restart_required,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Runtime catalog DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginRuntimeContributionCatalogDto {
|
||||
/// Runtime plugins.
|
||||
pub plugins: Vec<PluginRuntimePluginDto>,
|
||||
}
|
||||
|
||||
/// Runtime plugin DTO.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PluginRuntimePluginDto {
|
||||
/// Plugin id.
|
||||
pub id: String,
|
||||
/// Display name.
|
||||
pub display_name: String,
|
||||
/// Publisher.
|
||||
pub publisher: Option<String>,
|
||||
/// Version.
|
||||
pub version: String,
|
||||
/// Bundle URL.
|
||||
pub bundle_url: String,
|
||||
/// Icon URL.
|
||||
pub icon_url: Option<String>,
|
||||
/// Content hash.
|
||||
pub content_hash: String,
|
||||
/// Contributions.
|
||||
pub contributes: domain::PluginContributionSet,
|
||||
}
|
||||
|
||||
impl From<application::PluginRuntimeCatalog> for PluginRuntimeContributionCatalogDto {
|
||||
fn from(value: application::PluginRuntimeCatalog) -> Self {
|
||||
Self {
|
||||
plugins: value
|
||||
.plugins
|
||||
.into_iter()
|
||||
.map(PluginRuntimePluginDto::from)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<application::PluginRuntimePlugin> for PluginRuntimePluginDto {
|
||||
fn from(value: application::PluginRuntimePlugin) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
display_name: value.display_name,
|
||||
publisher: value.publisher,
|
||||
version: value.version,
|
||||
bundle_url: value.bundle_url,
|
||||
icon_url: value.icon_url,
|
||||
content_hash: value.content_hash,
|
||||
contributes: value.contributes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Request DTO for the `health` command.
|
||||
#[derive(Debug, Clone, Default, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -24,27 +24,30 @@ use application::{
|
||||
EnsureLocalModelServer, FirstRunState, GetAppExitWorkGuardState, GetLiveStateLean, GetMemory,
|
||||
GetProjectPermissions, GetProjectWorkState, GitBranches, GitCheckout, GitCommit, GitGraph,
|
||||
GitInit, GitLog, GitStage, GitStatus, GitUnstage, HarvestMemoryFromTurn, HealthUseCase,
|
||||
InspectConversation, LaunchAgent, LaunchAgentInput, LinkIssues, ListAgents, ListAgentsInput,
|
||||
ListDevices, ListEmbedderProfiles, ListIssues, ListLayouts, ListMemories, ListModelServers,
|
||||
ListProfiles, ListProjects, ListResumableAgents, ListSkills, ListSprints, ListTemplates,
|
||||
LiveAgentRegistry, LiveSessions, LiveStateLeanProvider, LiveStateProvider,
|
||||
LiveStateReadProvider, LoadLayout, McpRuntime, McpToolPermissionCatalogue, MoveTabToNewWindow,
|
||||
MutateLayout, OnnxModelView, OpenProject, OpenTerminal, OpenTicketAssistant,
|
||||
OrchestratorService, PairAttemptLimiter, PairDevice, PermissionProjectorRegistry,
|
||||
ProposeContext, ReadAgentContext, ReadContext, ReadConversationPage, ReadIssue,
|
||||
ReadIssueCarnet, ReadMcpToolPermissions, ReadMemory, ReadMemoryIndex, ReadProjectContext,
|
||||
ReadSkill, ReadTemplate, RecallMemory, ReconcileLayouts, ReconcileLiveState,
|
||||
ReconcileLiveStateInput, RecordTurn, RecordTurnProvider, ReferenceProfiles, RenameDevice,
|
||||
RenameLayout, RenameSprint, ReorderSprints, ResizeTerminal, ResolveAgentPermissions,
|
||||
ResolveMemoryLinks, RestoreOpenWindows, RetryBackgroundTask, RevokeAllDevices, RevokeDevice,
|
||||
InspectConversation, InstallPluginFromArchive, InstallPluginFromDirectory,
|
||||
JsonPluginManifestValidator, LaunchAgent, LaunchAgentInput, LinkIssues, ListAgents,
|
||||
ListAgentsInput, ListDevices, ListEmbedderProfiles, ListIssues, ListLayouts, ListMemories,
|
||||
ListModelServers, ListPluginRuntimeContributions, ListPlugins, ListProfiles, ListProjects,
|
||||
ListResumableAgents, ListSkills, ListSprints, ListTemplates, LiveAgentRegistry, LiveSessions,
|
||||
LiveStateLeanProvider, LiveStateProvider, LiveStateReadProvider, LoadLayout, McpRuntime,
|
||||
McpToolPermissionCatalogue, MoveTabToNewWindow, MutateLayout, OnnxModelView, OpenProject,
|
||||
OpenTerminal, OpenTicketAssistant, OrchestratorService, PairAttemptLimiter, PairDevice,
|
||||
PermissionProjectorRegistry, ProposeContext, ReadAgentContext, ReadContext,
|
||||
ReadConversationPage, ReadIssue, ReadIssueCarnet, ReadMcpToolPermissions, ReadMemory,
|
||||
ReadMemoryIndex, ReadProjectContext, ReadSkill, ReadTemplate, RecallMemory, ReconcileLayouts,
|
||||
ReconcileLiveState, ReconcileLiveStateInput, ReconcilePluginMcpServers, RecordTurn,
|
||||
RecordTurnProvider, ReferenceProfiles, RenameDevice, RenameLayout, RenameSprint,
|
||||
ReorderSprints, ResizeTerminal, ResolveAgentPermissions, ResolveMemoryLinks,
|
||||
RestoreOpenWindows, RetryBackgroundTask, ReviewPluginPackage, RevokeAllDevices, RevokeDevice,
|
||||
RotateConversationLog, SaveEmbedderProfile, SaveModelServer, SaveProfile, SessionLimitService,
|
||||
SetActiveLayout, SnapshotOpenWindows, SnapshotRunningAgents, SpawnBackgroundCommand,
|
||||
StopLiveAgent, StructuredRoutingMode, StructuredSessions, SuggestedThisSession,
|
||||
SyncAgentWithTemplate, TerminalSessions, TouchDevice, UnassignSkillFromAgent,
|
||||
UnassignTicketFromSprint, UnlinkIssues, UpdateAgentContext, UpdateAgentMcpToolPermissions,
|
||||
UpdateAgentPermissions, UpdateIssue, UpdateIssueCarnet, UpdateLiveState, UpdateMemory,
|
||||
UpdateProjectContext, UpdateProjectMcpToolPermissions, UpdateProjectPermissions, UpdateSkill,
|
||||
UpdateTemplate, WakeSessionProvider, WriteMemory, WriteToTerminal, AGENT_MEMORY_RECALL_BUDGET,
|
||||
SetActiveLayout, SetPluginEnabled, SnapshotOpenWindows, SnapshotRunningAgents,
|
||||
SpawnBackgroundCommand, StopLiveAgent, StructuredRoutingMode, StructuredSessions,
|
||||
SuggestedThisSession, SyncAgentWithTemplate, TerminalSessions, TouchDevice,
|
||||
UnassignSkillFromAgent, UnassignTicketFromSprint, UninstallPlugin, UnlinkIssues,
|
||||
UpdateAgentContext, UpdateAgentMcpToolPermissions, UpdateAgentPermissions, UpdateIssue,
|
||||
UpdateIssueCarnet, UpdateLiveState, UpdateMemory, UpdateProjectContext,
|
||||
UpdateProjectMcpToolPermissions, UpdateProjectPermissions, UpdateSkill, UpdateTemplate,
|
||||
WakeSessionProvider, WriteMemory, WriteToTerminal, AGENT_MEMORY_RECALL_BUDGET,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use domain::ports::{
|
||||
@ -53,9 +56,10 @@ use domain::ports::{
|
||||
BackgroundTaskStore, Clock, DeviceSessionStore, Embedder, EmbedderEnvInspector,
|
||||
EmbedderProfileStore, EmbedderPromptStore, EventBus, FileSystem, GitPort, IdGenerator,
|
||||
IssueNumberAllocator, IssueStore, McpToolPermissionStore, MemoryRecall, MemoryStore,
|
||||
PermissionStore, ProcessSpawner, ProfileStore, ProjectStore, PtyPort, ScheduledTask, Scheduler,
|
||||
SkillStore, SprintStore, StructuredSessionEnvironmentPreparer, TemplateStore, ToolInvoker,
|
||||
WakeError, WakeReason, WindowStateStore,
|
||||
PermissionStore, PluginManifestValidator, PluginMcpSupervisor, PluginPackageStore,
|
||||
PluginRegistryStore, ProcessSpawner, ProfileStore, ProjectStore, PtyPort, ScheduledTask,
|
||||
Scheduler, SkillStore, SprintStore, StructuredSessionEnvironmentPreparer, TemplateStore,
|
||||
ToolInvoker, WakeError, WakeReason, WindowStateStore,
|
||||
};
|
||||
use domain::profile::{
|
||||
AgentProfile, ContextInjection, McpConfigStrategy, McpTransport, StructuredAdapter,
|
||||
@ -73,10 +77,11 @@ use infrastructure::{
|
||||
embedder_from_profile, AdaptiveMemoryRecall, BackgroundCompletionSink,
|
||||
BackgroundTaskReadyToDeliver, ClaudePermissionProjector, ClaudeTranscriptInspector,
|
||||
CliAgentRuntime, CodexPermissionProjector, CommandBackgroundRunner, EmbedderEnvProbe,
|
||||
FsAssistantContextStore, FsBackgroundTaskStore, FsConversationLog, FsDeviceSessionStore,
|
||||
FsEmbedderProfileStore, FsEmbedderPromptStore, FsHandoffStore, FsIssueNumberAllocator,
|
||||
FsIssueStore, FsLiveStateStore, FsMcpToolPermissionStore, FsMemoryStore, FsModelServerRegistry,
|
||||
FsOrchestratorWatcher, FsPermissionStore, FsProfileStore, FsProjectStore,
|
||||
ExternalMcpPluginSupervisor, FsAssistantContextStore, FsBackgroundTaskStore, FsConversationLog,
|
||||
FsDeviceSessionStore, FsEmbedderProfileStore, FsEmbedderPromptStore, FsHandoffStore,
|
||||
FsIssueNumberAllocator, FsIssueStore, FsLiveStateStore, FsMcpToolPermissionStore,
|
||||
FsMemoryStore, FsModelServerRegistry, FsOrchestratorWatcher, FsPermissionStore,
|
||||
FsPluginPackageStore, FsPluginRegistryStore, FsProfileStore, FsProjectStore,
|
||||
FsProviderSessionStore, FsSkillStore, FsSprintStore, FsTemplateStore, FsWindowStateStore,
|
||||
Git2Repository, HeuristicHandoffSummarizer, HfModelArtifactDownloader,
|
||||
HttpOpenAiCompatibleProbe, IdeaiContextStore, InMemoryConversationRegistry, InMemoryMailbox,
|
||||
@ -1062,6 +1067,29 @@ pub struct BackendCore {
|
||||
pub retry_background_task: Arc<RetryBackgroundTask>,
|
||||
/// Store handle used by `list_background_tasks` to read the task read-model.
|
||||
pub background_task_store: Arc<dyn BackgroundTaskStore>,
|
||||
// --- Plugins (#43) ---
|
||||
/// Review a local plugin package before install.
|
||||
pub review_plugin_package: Arc<ReviewPluginPackage>,
|
||||
/// Install a plugin archive.
|
||||
pub install_plugin_from_archive: Arc<InstallPluginFromArchive>,
|
||||
/// Install a plugin directory snapshot.
|
||||
pub install_plugin_from_directory: Arc<InstallPluginFromDirectory>,
|
||||
/// List installed plugins for admin UI.
|
||||
pub list_plugins: Arc<ListPlugins>,
|
||||
/// Enable or disable a plugin.
|
||||
pub set_plugin_enabled: Arc<SetPluginEnabled>,
|
||||
/// Uninstall a plugin.
|
||||
pub uninstall_plugin: Arc<UninstallPlugin>,
|
||||
/// List runtime contributions for UI bootstrap.
|
||||
pub list_plugin_runtime_contributions: Arc<ListPluginRuntimeContributions>,
|
||||
/// Reconcile external MCP plugin servers.
|
||||
pub reconcile_plugin_mcp_servers: Arc<ReconcilePluginMcpServers>,
|
||||
/// Package store exposed for the Tauri asset protocol adapter.
|
||||
pub plugin_package_store: Arc<FsPluginPackageStore>,
|
||||
/// Registry store exposed for the Tauri asset protocol adapter.
|
||||
pub plugin_registry_store: Arc<dyn PluginRegistryStore>,
|
||||
/// Manifest validator exposed for the Tauri asset protocol adapter.
|
||||
pub plugin_manifest_validator: Arc<dyn PluginManifestValidator>,
|
||||
// --- Templates & sync (L7) ---
|
||||
/// Create a template in the global store.
|
||||
pub create_template: Arc<CreateTemplate>,
|
||||
@ -1233,6 +1261,17 @@ impl BackendCore {
|
||||
let pair_attempt_limiter_port =
|
||||
Arc::clone(&pair_attempt_limiter) as Arc<dyn PairAttemptLimiter>;
|
||||
let events_port = Arc::clone(&event_bus) as Arc<dyn EventBus>;
|
||||
let plugin_packages = Arc::new(FsPluginPackageStore::new(app_data_dir.clone()));
|
||||
let plugin_registry = Arc::new(FsPluginRegistryStore::new(app_data_dir.clone()));
|
||||
let plugin_validator =
|
||||
Arc::new(JsonPluginManifestValidator::new(env!("CARGO_PKG_VERSION")));
|
||||
let plugin_mcp_supervisor = Arc::new(ExternalMcpPluginSupervisor::new());
|
||||
let plugin_package_store = Arc::clone(&plugin_packages) as Arc<dyn PluginPackageStore>;
|
||||
let plugin_registry_store = Arc::clone(&plugin_registry) as Arc<dyn PluginRegistryStore>;
|
||||
let plugin_manifest_validator =
|
||||
Arc::clone(&plugin_validator) as Arc<dyn PluginManifestValidator>;
|
||||
let plugin_mcp_supervisor_port =
|
||||
Arc::clone(&plugin_mcp_supervisor) as Arc<dyn PluginMcpSupervisor>;
|
||||
|
||||
// --- Use cases (ports injected as Arc<dyn Port>) ---
|
||||
let health = Arc::new(HealthUseCase::new(
|
||||
@ -2089,6 +2128,53 @@ impl BackendCore {
|
||||
Arc::clone(&background_runner) as Arc<dyn BackgroundCommandArchive>,
|
||||
Arc::clone(&spawn_background_command),
|
||||
));
|
||||
let review_plugin_package = Arc::new(ReviewPluginPackage::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
));
|
||||
let list_plugins = Arc::new(ListPlugins::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
));
|
||||
let install_plugin_from_archive = Arc::new(InstallPluginFromArchive::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
Arc::clone(&events_port),
|
||||
Arc::clone(&plugin_mcp_supervisor_port),
|
||||
));
|
||||
let install_plugin_from_directory = Arc::new(InstallPluginFromDirectory::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
Arc::clone(&events_port),
|
||||
Arc::clone(&plugin_mcp_supervisor_port),
|
||||
));
|
||||
let set_plugin_enabled = Arc::new(SetPluginEnabled::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
Arc::clone(&events_port),
|
||||
Arc::clone(&plugin_mcp_supervisor_port),
|
||||
));
|
||||
let uninstall_plugin = Arc::new(UninstallPlugin::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&events_port),
|
||||
Arc::clone(&plugin_mcp_supervisor_port),
|
||||
));
|
||||
let list_plugin_runtime_contributions = Arc::new(ListPluginRuntimeContributions::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
));
|
||||
let reconcile_plugin_mcp_servers = Arc::new(ReconcilePluginMcpServers::new(
|
||||
Arc::clone(&plugin_package_store),
|
||||
Arc::clone(&plugin_registry_store),
|
||||
Arc::clone(&plugin_manifest_validator),
|
||||
Arc::clone(&plugin_mcp_supervisor_port),
|
||||
));
|
||||
let background_wake = Arc::new(AgentWakeService::new(
|
||||
Arc::clone(&mediated_inbox) as Arc<dyn AgentInbox>,
|
||||
Arc::clone(&input_mediator),
|
||||
@ -2613,6 +2699,17 @@ impl BackendCore {
|
||||
cancel_background_task,
|
||||
retry_background_task,
|
||||
background_task_store: Arc::clone(&background_tasks_port),
|
||||
review_plugin_package,
|
||||
install_plugin_from_archive,
|
||||
install_plugin_from_directory,
|
||||
list_plugins,
|
||||
set_plugin_enabled,
|
||||
uninstall_plugin,
|
||||
list_plugin_runtime_contributions,
|
||||
reconcile_plugin_mcp_servers,
|
||||
plugin_package_store: Arc::clone(&plugin_packages),
|
||||
plugin_registry_store: Arc::clone(&plugin_registry_store),
|
||||
plugin_manifest_validator: Arc::clone(&plugin_manifest_validator),
|
||||
ticket_tool_binder,
|
||||
template_tool_binder,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user