chantier: durcissement reprise headless inter-projets + persistance profils Opencode

- Implémentation reprise de session Opencode headless (conversational_recovery)
- Persistance des profils IA Opencode dans .ideai/memory avec JSON Schema
- Gestion des permissions MCP pour agents externes
- Tests QA verts : structured_launch_d3, conversation_log, tickets_missing_carnet, agents, ProfilesSettings
This commit is contained in:
2026-07-28 12:23:34 +02:00
parent 78f7c8fe2d
commit 045e0984cc
15 changed files with 782 additions and 49 deletions

View File

@ -2025,7 +2025,11 @@ impl LaunchAgent {
// même entrée. Toute défaillance (provider absent, pair_conversation_id non-UUID,
// erreur du store) dégrade silencieusement — un lancement n'est **jamais** cassé
// par cette persistance (lot P8c lira ce store pour `--resume`).
if let Some(engine_id) = engine_session_id.as_deref() {
if let Some(engine_id) = engine_session_id
.as_deref()
.map(str::trim)
.filter(|id| !id.is_empty())
{
self.persist_provider_session(root, profile, &pair_conversation_id, engine_id)
.await;
}
@ -2127,11 +2131,20 @@ impl LaunchAgent {
// L'id de paire (UUID) → resumable moteur via providers.json.
Some(raw) => match uuid::Uuid::parse_str(raw) {
Ok(uuid) => match provider.provider_session_store_for(root) {
Some(store) => store
Some(store) => match store
.get(ConversationId::from_uuid(uuid), adapter.provider_key())
.await
.ok()
.flatten(),
{
Ok(Some(engine_id)) => {
let engine_id = engine_id.trim().to_owned();
if engine_id.is_empty() {
None
} else {
Some(engine_id)
}
}
Ok(None) | Err(_) => None,
},
None => None,
},
Err(_) => None,