feat(agent): conversation par paire + entrée médiée + pivot terminal/MCP

Coeur inter-agents consolidé et surface front réalignée sur la décision
"terminal natif PTY, pas d'UI chat" (Option 1).

Domaine
- nouveaux modules conversation, mailbox, input, fileguard (ports + types)
- orchestrator/profile/events étendus (conversation par paire, FIFO)

Application / Infrastructure
- orchestrator/service + context_guard : sérialisation FIFO par agent,
  garde RW mémoire/contexte, dispatch ask/reply
- adapters in-memory conversation / mailbox / input / fileguard
- registry session + lifecycle agent durcis (1 agent = 1 session vivante)
- outils MCP idea_* alignés sur le nouveau dispatch

Frontend
- MediatedInput + useAgentBusy : entrée utilisateur médiée par IdeA,
  terminal = vue sortie inchangée
- suppression de la vue chat structurée (AgentChatView) — abandonnée
- adapter input + ports mis à jour

Divers
- .ideai/ : mémoire projet + briefs de cadrage versionnés ;
  requests/ runtime ignoré ; agents projet réels (DevBackend/DevFrontend/QA)

Tests : Rust (domain/application/infrastructure/app-tauri) + front (346) verts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 07:33:04 +02:00
parent 5f45c22941
commit eca2ba95c4
61 changed files with 9491 additions and 2512 deletions

View File

@ -0,0 +1,33 @@
/**
* Tauri adapter for {@link InputGateway} (lot F1, cadrage §4.2).
*
* `submit` → `submit_agent_input` (enqueue), `interrupt` → `interrupt_agent`
* (preempt). These app-tauri commands land with lot C4; this adapter is complete
* on the frontend side and the mock covers tests/offline dev meanwhile.
*
* Commands use snake_case (Tauri convention); payload keys are camelCase
* (matching the backend DTO `#[serde(rename_all = "camelCase")]`), consistent
* with the other adapters in this directory.
*/
import { invoke } from "@tauri-apps/api/core";
import type { InputGateway } from "@/ports";
export class TauriInputGateway implements InputGateway {
async submit(
projectId: string,
agentId: string,
text: string,
): Promise<void> {
await invoke("submit_agent_input", {
request: { projectId, agentId, text },
});
}
async interrupt(projectId: string, agentId: string): Promise<void> {
await invoke("interrupt_agent", {
request: { projectId, agentId },
});
}
}