fix(input): fiabilise la livraison de délégation et journalise le submit

Durcit le portail d'écriture de délégation et son acheminement bout-en-bout
(commande Tauri → orchestrateur → file d'entrée infrastructure → portail
frontend), avec une journalisation du submit pour diagnostiquer les cas où la
délégation n'était pas remise. Couvre le portail d'écriture côté front
(useWritePortal) avec ses tests.

QA : checks application/front/infrastructure/app-tauri verts. Les tests loopback
socket Unix réels ne sont pas 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 10:57:20 +02:00
parent befff76de8
commit 018eb1a25e
8 changed files with 352 additions and 23 deletions

View File

@ -364,7 +364,46 @@ pub fn write_terminal(
state: State<'_, AppState>,
) -> Result<(), ErrorDto> {
let input = request.into_input()?;
state.write_terminal.execute(input).map_err(ErrorDto::from)
let session_id = input.session_id;
let bytes = input.data.len();
let control = describe_terminal_write(&input.data);
application::diag!(
"[pty-write] write_terminal start: session={session_id} bytes={bytes} control={control}"
);
match state.write_terminal.execute(input) {
Ok(()) => {
application::diag!(
"[pty-write] write_terminal ok: session={session_id} bytes={bytes} control={control}"
);
Ok(())
}
Err(e) => {
application::diag!(
"[pty-write] write_terminal failed: session={session_id} bytes={bytes} \
control={control} error={e}"
);
Err(ErrorDto::from(e))
}
}
}
fn describe_terminal_write(data: &[u8]) -> String {
if data.is_empty() {
return "<empty>".to_owned();
}
if data.len() > 16 {
return "<bulk>".to_owned();
}
data.iter()
.map(|byte| match *byte {
b'\r' => "\\r".to_owned(),
b'\n' => "\\n".to_owned(),
0x7f => "\\x7f".to_owned(),
byte if byte < 0x20 => format!("\\x{byte:02x}"),
byte => char::from(byte).to_string(),
})
.collect::<Vec<_>>()
.join("")
}
/// `resize_terminal` — resize a live PTY.
@ -1479,6 +1518,10 @@ pub async fn delegation_delivered(
let project = resolve_project(&request.project_id, &state).await?;
let agent_id = parse_agent_id(&request.agent_id)?;
let ticket = parse_ticket_id(&request.ticket)?;
application::diag!(
"[delivery] delegation_delivered command: project={} agent={agent_id} ticket={ticket}",
project.id
);
state
.orchestrator_service
.note_delegation_delivered(&project, agent_id, ticket);
@ -1502,6 +1545,10 @@ pub async fn set_front_attached(
state: State<'_, AppState>,
) -> Result<(), ErrorDto> {
let agent_id = parse_agent_id(&request.agent_id)?;
application::diag!(
"[delivery] set_front_attached command: agent={agent_id} attached={}",
request.attached
);
state
.orchestrator_service
.set_agent_front_attached(agent_id, request.attached);