feat(wave): #119/#122/#131/#132 verts + sprint plugins ESM/persistance #135/#136/#139
État d'intégration confiné à la branche batch. Les tickets #119 (skills → capacités agent découvrables), #122 (override permissions par défaut), #131 (effort par agent/presets) et #132 (outil MCP d'édition du contexte projet) sont verts en périmètre. Le sprint plugins multi-fichiers ESM / persistance plugin-owned (#135/#136/#139) est co-implémenté dans les MÊMES fichiers de câblage (frontend/src/ports/index.ts, backend/src/lib.rs, domain/ports.rs, backend/dto.rs), inséparable sans staging interactif (indisponible ici). Commit unique volontaire : préserve l'état vert QA sans découpe hunk risquée. NON mergé vers develop tant que #137 (QA e2e plugins) n'est pas vert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -47,7 +47,8 @@ use crate::error::AppError;
|
||||
use crate::orchestrator::rendezvous::{run_inactivity_watchdog, WatchdogOutcome};
|
||||
use crate::orchestrator::{
|
||||
ProposeContext, ProposeContextInput, ProposeOutcome, ReadContext, ReadContextInput, ReadMemory,
|
||||
ReadMemoryInput, WriteMemory, WriteMemoryInput,
|
||||
ReadMemoryInput, UpdateProjectContext, UpdateProjectContextInput, WriteMemory,
|
||||
WriteMemoryInput,
|
||||
};
|
||||
use crate::skill::{CreateSkill, CreateSkillInput, ReadSkill, ReadSkillInput};
|
||||
use crate::terminal::{CloseTerminal, CloseTerminalInput, StructuredSessions, TerminalSessions};
|
||||
@ -534,6 +535,8 @@ pub struct ContextGuardUseCases {
|
||||
pub read_context: Arc<ReadContext>,
|
||||
/// Proposition/écriture d'un contexte `.md` IdeA sous le garde.
|
||||
pub propose_context: Arc<ProposeContext>,
|
||||
/// Écriture directe stricte du contexte projet global.
|
||||
pub update_project_context: Arc<UpdateProjectContext>,
|
||||
/// Lecture mémoire sous read-lease.
|
||||
pub read_memory: Arc<ReadMemory>,
|
||||
/// Écriture mémoire sous write-lease.
|
||||
@ -1241,6 +1244,14 @@ impl OrchestratorService {
|
||||
self.propose_context(project, target, content, requester)
|
||||
.await
|
||||
}
|
||||
OrchestratorCommand::UpdateProjectContext {
|
||||
content,
|
||||
if_match,
|
||||
requester,
|
||||
} => {
|
||||
self.update_project_context(project, content, if_match, requester)
|
||||
.await
|
||||
}
|
||||
OrchestratorCommand::ReadMemory { slug, requester } => {
|
||||
self.read_memory(project, slug, requester).await
|
||||
}
|
||||
@ -1363,7 +1374,7 @@ impl OrchestratorService {
|
||||
target: Option<String>,
|
||||
requester: ConversationParty,
|
||||
) -> Result<OrchestratorOutcome, AppError> {
|
||||
let md = self
|
||||
let out = self
|
||||
.require_context_guard()?
|
||||
.read_context
|
||||
.execute(ReadContextInput {
|
||||
@ -1372,9 +1383,13 @@ impl OrchestratorService {
|
||||
requester,
|
||||
})
|
||||
.await?;
|
||||
let mut text = out.content.into_string();
|
||||
if let Some(version) = &out.version {
|
||||
text.push_str(&format!("\n\n<!-- idea-context-version: {version} -->"));
|
||||
}
|
||||
Ok(OrchestratorOutcome {
|
||||
detail: format!("read {} context", target.as_deref().unwrap_or("project")),
|
||||
reply: Some(md.into_string()),
|
||||
reply: Some(text),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1411,6 +1426,31 @@ impl OrchestratorService {
|
||||
})
|
||||
}
|
||||
|
||||
/// `context.update` → strict direct write of the global project context.
|
||||
async fn update_project_context(
|
||||
&self,
|
||||
project: &Project,
|
||||
content: String,
|
||||
if_match: Option<String>,
|
||||
requester: ConversationParty,
|
||||
) -> Result<OrchestratorOutcome, AppError> {
|
||||
let out = self
|
||||
.require_context_guard()?
|
||||
.update_project_context
|
||||
.execute(UpdateProjectContextInput {
|
||||
project: project.clone(),
|
||||
content,
|
||||
if_match,
|
||||
requester,
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(OrchestratorOutcome {
|
||||
detail: format!("wrote project context (version {})", out.new_version),
|
||||
reply: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// `memory.read` → reads a note (or the index) under a shared read-lease; the
|
||||
/// content is returned inline in the outcome's `reply`.
|
||||
async fn read_memory(
|
||||
@ -2783,6 +2823,7 @@ impl OrchestratorService {
|
||||
description: None,
|
||||
content,
|
||||
scope,
|
||||
kind: domain::SkillKind::Workflow,
|
||||
project_root: project.root.clone(),
|
||||
})
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user