fix(permissions): tools MCP inter-projets exposés (idea_project_*) + contactable agent/template persisté — update_agent_contactable (application/web-server/app-tauri), defaultContactable TemplateEditor save/reopen, groupes MCP 'IdeA inter-projets' avec fallback, permissions agent Contactable — #267 (QA verte)

This commit is contained in:
2026-09-07 18:13:27 +02:00
parent 9266d121cd
commit f6101a8249
30 changed files with 632 additions and 89 deletions

View File

@ -522,6 +522,72 @@ pub struct UpdateAgentEffortOutput {
pub agent: Agent,
}
// ---------------------------------------------------------------------------
// UpdateAgentContactable
// ---------------------------------------------------------------------------
/// Input for [`UpdateAgentContactable::execute`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UpdateAgentContactableInput {
/// The owning project.
pub project: Project,
/// The agent whose cross-project contactability changes.
pub agent_id: AgentId,
/// Whether agents from other IdeA projects may contact this agent.
pub contactable: bool,
}
/// Output of [`UpdateAgentContactable::execute`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UpdateAgentContactableOutput {
/// The updated agent.
pub agent: Agent,
}
/// Updates an agent's cross-project contactability in the project manifest.
pub struct UpdateAgentContactable {
contexts: Arc<dyn AgentContextStore>,
}
impl UpdateAgentContactable {
/// Builds the use case.
#[must_use]
pub fn new(contexts: Arc<dyn AgentContextStore>) -> Self {
Self { contexts }
}
/// Executes the update.
///
/// # Errors
/// - [`AppError::NotFound`] if the agent is unknown to the project,
/// - [`AppError::Invalid`] if the resulting manifest is invalid,
/// - [`AppError::Store`] on persistence failure.
pub async fn execute(
&self,
input: UpdateAgentContactableInput,
) -> Result<UpdateAgentContactableOutput, AppError> {
let mut manifest = self.contexts.load_manifest(&input.project).await?;
let entry = manifest
.entries
.iter_mut()
.find(|entry| entry.agent_id == input.agent_id)
.ok_or_else(|| AppError::NotFound(format!("agent {}", input.agent_id)))?;
let agent = entry
.to_agent()
.map_err(|err| AppError::Invalid(err.to_string()))?
.with_contactable(input.contactable);
*entry = ManifestEntry::from_agent(&agent);
let manifest = AgentManifest::new(manifest.version, manifest.entries)
.map_err(|err| AppError::Invalid(err.to_string()))?;
self.contexts
.save_manifest(&input.project, &manifest)
.await?;
Ok(UpdateAgentContactableOutput { agent })
}
}
/// Sets or clears an agent's per-agent effort override in the manifest.
///
/// The change applies at the agent's next launch; live sessions are not mutated.

View File

@ -37,7 +37,8 @@ pub use lifecycle::{
LaunchAgentOutput, ListAgents, ListAgentsInput, ListAgentsOutput, ListedAgentCapabilities,
LiveStateLeanProvider, ManagedTempExposureRequest, McpRuntime, PermissionProjectorRegistry,
ProviderSessionProvider, ReadAgentContext, ReadAgentContextInput, ReadAgentContextOutput,
StructuredRoutingMode, StructuredSessionDescriptor, UpdateAgentContext,
StructuredRoutingMode, StructuredSessionDescriptor, UpdateAgentContactable,
UpdateAgentContactableInput, UpdateAgentContactableOutput, UpdateAgentContext,
UpdateAgentContextInput, UpdateAgentEffort, UpdateAgentEffortInput, UpdateAgentEffortOutput,
AGENT_MEMORY_RECALL_BUDGET, DEFAULT_OPENCODE_MCP_TIMEOUT_MS, LIVE_STATE_INJECT_MAX,
};

View File

@ -66,8 +66,9 @@ pub use agent::{
ReferenceProfiles, ReferenceProfilesOutput, ResumableAgent, SaveOpenCodeProviderProfile,
SaveOpenCodeProviderProfileInput, SaveOpenCodeProviderProfileOutput, SaveProfile,
SaveProfileInput, SaveProfileOutput, SessionLimitService, StructuredRoutingMode,
StructuredSessionDescriptor, TurnOutcome, UpdateAgentContext, UpdateAgentContextInput,
UpdateAgentEffort, UpdateAgentEffortInput, UpdateAgentEffortOutput, AGENT_MEMORY_RECALL_BUDGET,
StructuredSessionDescriptor, TurnOutcome, UpdateAgentContactable, UpdateAgentContactableInput,
UpdateAgentContactableOutput, UpdateAgentContext, UpdateAgentContextInput, UpdateAgentEffort,
UpdateAgentEffortInput, UpdateAgentEffortOutput, AGENT_MEMORY_RECALL_BUDGET,
CODEX_SUBMIT_DELAY_MS, LIVE_STATE_INJECT_MAX, RESUME_PROMPT,
};
pub use background::{