feat(workstate): read-model live-state minimal des conversations/délégations (Lot A backend)

Introduit le module application `workstate` (modèle de read-model live + snapshots
des conversations/délégations en cours) et l'expose via la couche terminal
(exports mod/registry). Câble la surface Tauri : DTO, commande et state pour
exposer le live-state au frontend (lib + state + commands), avec tests.

QA verte. Réserve environnementale non bloquante : tests loopback socket Unix
réels non exécutables en sandbox (UnixListener::bind PermissionDenied),
alternatives avec skips vertes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 18:06:22 +02:00
parent 6cfa0b04c6
commit aae18499a9
10 changed files with 663 additions and 28 deletions

View File

@ -28,7 +28,10 @@
mod registry;
mod usecases;
pub use registry::{LiveAgentRegistry, LiveSessions, StructuredSessions, TerminalSessions};
pub use registry::{
LiveAgentRegistry, LiveSessionKind, LiveSessionSnapshot, LiveSessions, StructuredSessions,
TerminalSessions,
};
pub use usecases::{
CloseTerminal, CloseTerminalInput, CloseTerminalOutput, OpenTerminal, OpenTerminalInput,
OpenTerminalOutput, ResizeTerminal, ResizeTerminalInput, WriteToTerminal, WriteToTerminalInput,

View File

@ -13,6 +13,28 @@ use domain::conversation::ConversationId;
use domain::ports::{AgentSession, PtyHandle};
use domain::{AgentId, NodeId, SessionId, SessionKind, TerminalSession};
/// Runtime family of a live agent session.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LiveSessionKind {
/// Raw PTY-backed CLI session.
Pty,
/// Structured agent-session backend.
Structured,
}
/// Read-only coordinates of one live agent session.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LiveSessionSnapshot {
/// The agent owning the live session.
pub agent_id: AgentId,
/// The layout node currently hosting the session view.
pub node_id: NodeId,
/// The live session id.
pub session_id: SessionId,
/// Which runtime registry owns the session.
pub kind: LiveSessionKind,
}
/// A registered, live terminal: its PTY handle plus the domain snapshot.
#[derive(Debug, Clone)]
struct Entry {
@ -516,6 +538,31 @@ impl LiveSessions {
all.extend(self.structured.live_agents());
all
}
/// Tous les agents vivants avec le type de registre source (PTY puis structuré).
#[must_use]
pub fn live_agent_snapshots(&self) -> Vec<LiveSessionSnapshot> {
let mut all: Vec<LiveSessionSnapshot> = self
.pty
.live_agents()
.into_iter()
.map(|(agent_id, node_id, session_id)| LiveSessionSnapshot {
agent_id,
node_id,
session_id,
kind: LiveSessionKind::Pty,
})
.collect();
all.extend(self.structured.live_agents().into_iter().map(
|(agent_id, node_id, session_id)| LiveSessionSnapshot {
agent_id,
node_id,
session_id,
kind: LiveSessionKind::Structured,
},
));
all
}
}
impl LiveAgentRegistry for LiveSessions {