feat(plugins): paramètres projet plugins + attribution skills/tools aux agents — #282 (manifeste accepte contributes.skills IdeA-native multi-harness; store .ideai/project-plugins.json v1: enable plugin par projet + assignments skills/tools par agent; refs + use cases settings/assign/unassign; resolver skills pour idea_skill_read et injection catalogue lancement agent; permissions MCP dynamiques projetées par harness Claude Code/Codex/OpenCode; tombstones uninstall, hot reload recalcule catalogue et marque assignments cassés; frontend: Settings projet Plugins, détail capabilities, attribution agent, catalogue permissions; bump pointeur IdeaSDK 6eb8db3; QA verte: cargo test -p application, project_plugin_settings 3/3, dto_plugins 2/2, structured_launch_d3 26/26, catalogue mcp 7/7, frontend 5 tests ProjectPluginSettings/plugin, npm build frontend)

This commit is contained in:
2026-09-08 15:48:57 +02:00
parent bdc20a134a
commit 86ed0aa00b
38 changed files with 2127 additions and 89 deletions

View File

@ -17,8 +17,20 @@ use crate::conversation::ConversationParty;
use crate::ids::{AgentId, NodeId, SkillId};
use crate::live_state::WorkStatus;
use crate::mailbox::TicketId;
use crate::plugin::{PluginId, PluginSkillId};
use crate::skill::{SkillKind, SkillScope};
/// Plugin origin for a resolved assigned skill. `None` on
/// [`AssignedSkillSnapshot::plugin`] denotes a native IdeA skill.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AssignedPluginSkillSource {
/// Owning plugin.
pub plugin_id: PluginId,
/// Manifest-local skill id.
pub skill_id: PluginSkillId,
}
/// Current schema version for orchestration capabilities injected into an
/// agent's effective runtime context.
pub const ORCHESTRATION_CAPABILITY_SNAPSHOT_VERSION: u32 = 1;
@ -35,6 +47,9 @@ pub struct AssignedSkillSnapshot {
pub skill_id: SkillId,
/// Store scope used to resolve the skill body.
pub scope: SkillScope,
/// Plugin origin. Absent for native IdeA skills.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub plugin: Option<AssignedPluginSkillSource>,
/// Display name shown to the model and accepted by `idea_skill_read`.
pub name: String,
/// One-line affordance description shown in the model context.