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:
@ -10,9 +10,9 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use application::{
|
||||
AppError, CreateProjectInput, CreateProjectOutput, GitGraphOutput, HealthInput, HealthReport,
|
||||
LayoutKind, ListProjectsOutput, OpenProjectOutput,
|
||||
LayoutKind, ListProjectsOutput, LiveSessionKind, OpenProjectOutput, ProjectWorkState,
|
||||
};
|
||||
use domain::{Project, ProjectId};
|
||||
use domain::{AgentBusyState, Project, ProjectId};
|
||||
|
||||
/// Request DTO for the `health` command.
|
||||
#[derive(Debug, Clone, Default, Deserialize)]
|
||||
@ -1472,6 +1472,83 @@ impl LiveAgentListDto {
|
||||
}
|
||||
}
|
||||
|
||||
/// Runtime family of a live work-state session.
|
||||
#[derive(Debug, Clone, Copy, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum LiveWorkSessionKindDto {
|
||||
/// Raw PTY-backed CLI session.
|
||||
Pty,
|
||||
/// Structured agent-session backend.
|
||||
Structured,
|
||||
}
|
||||
|
||||
impl From<LiveSessionKind> for LiveWorkSessionKindDto {
|
||||
fn from(kind: LiveSessionKind) -> Self {
|
||||
match kind {
|
||||
LiveSessionKind::Pty => Self::Pty,
|
||||
LiveSessionKind::Structured => Self::Structured,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Live session coordinates in the project work-state read model.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LiveWorkSessionDto {
|
||||
/// The layout node currently hosting the session view.
|
||||
pub node_id: String,
|
||||
/// The live session id.
|
||||
pub session_id: String,
|
||||
/// Runtime family that owns the session.
|
||||
pub kind: LiveWorkSessionKindDto,
|
||||
}
|
||||
|
||||
/// One manifest agent's current live/busy state.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AgentWorkStateDto {
|
||||
/// Agent id.
|
||||
pub agent_id: String,
|
||||
/// Agent display name.
|
||||
pub name: String,
|
||||
/// Runtime profile id assigned to the agent.
|
||||
pub profile_id: String,
|
||||
/// Live session, if any.
|
||||
pub live: Option<LiveWorkSessionDto>,
|
||||
/// Current mediated-input busy state.
|
||||
pub busy: AgentBusyState,
|
||||
}
|
||||
|
||||
/// Project-level read model for conversation/delegation UX.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ProjectWorkStateDto {
|
||||
/// Manifest agents in manifest order, enriched with live/busy state.
|
||||
pub agents: Vec<AgentWorkStateDto>,
|
||||
}
|
||||
|
||||
impl From<ProjectWorkState> for ProjectWorkStateDto {
|
||||
fn from(state: ProjectWorkState) -> Self {
|
||||
Self {
|
||||
agents: state
|
||||
.agents
|
||||
.into_iter()
|
||||
.map(|agent| AgentWorkStateDto {
|
||||
agent_id: agent.agent_id.to_string(),
|
||||
name: agent.name,
|
||||
profile_id: agent.profile_id.to_string(),
|
||||
live: agent.live.map(|live| LiveWorkSessionDto {
|
||||
node_id: live.node_id.to_string(),
|
||||
session_id: live.session_id.to_string(),
|
||||
kind: live.kind.into(),
|
||||
}),
|
||||
busy: agent.busy,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Request DTO for `attach_live_agent`: bind an already-running agent session to
|
||||
/// a visible layout cell without spawning a new process.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user