clawmates-node --selftest + server terminal tracing (diagnose blank terminal)
ci / gates (push) Failing after 5s
ci / rust (push) Has been skipped
ci / sandbox-k8s (push) Has been skipped
ci / frontend (push) Has been skipped
ci / e2e (push) Has been skipped

- Daemon: factor the terminal command into terminal_command(); add `--selftest`
  which opens the host terminal PTY locally and prints ~2.5s of raw output, so
  you can confirm tmux/zsh actually draws on a given node without the browser.
  (Verified locally: tmux spawns zsh + draws its status bar.)
- cm-api: temporary [fleet-term] eprintln tracing in open_terminal, the pty_out
  router, and the browser bridge (byte counts + sink presence) to locate where
  output stops between daemon→server→browser. To be removed once diagnosed.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-24 21:28:26 -07:00
co-authored by Claude Opus 4.8
parent 6e81eaa52b
commit c2a0309ad7
3 changed files with 89 additions and 21 deletions
+6
View File
@@ -212,15 +212,21 @@ struct TermCtrl {
async fn bridge_terminal(hub: Arc<NodeHub>, node_id: NodeId, socket: WebSocket) {
let Some((sid, mut rx)) = hub.open_terminal(node_id, 80, 24).await else {
eprintln!("[fleet-term] bridge: open_terminal None (node offline?) node={node_id}");
return;
};
eprintln!("[fleet-term] bridge start node={node_id} sid={sid}");
let (mut ws_tx, mut ws_rx) = socket.split();
let to_browser = async {
let mut sent = 0usize;
while let Some(bytes) = rx.recv().await {
sent += bytes.len();
if ws_tx.send(Message::Binary(bytes.into())).await.is_err() {
eprintln!("[fleet-term] bridge: browser send failed after {sent} bytes");
break;
}
}
eprintln!("[fleet-term] bridge to_browser ended, {sent} bytes total");
};
let to_node = async {
while let Some(Ok(msg)) = ws_rx.next().await {