fix(supervisor): use better error message when sandbox connect is not available (#3572)

* fix(supervisor): explain unavailable main terminal attachments

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(supervisor): reset cursor after terminal attachment errors

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(supervisor): format read-only warnings for terminal clients

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* docs: drop terminal attachment documentation additions

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(supervisor): exit read-only viewers on Ctrl-C

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* docs: simplify read-only viewer Ctrl-C guidance

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

---------

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
This commit is contained in:
Piotr Mlocek
2026-09-23 17:31:13 +00:00
committed by GitHub
parent f3e097d6c1
commit bed9e5eafc
6 changed files with 361 additions and 29 deletions
+35 -2
View File
@@ -652,10 +652,43 @@ async fn canonical_main_disconnect_reconnect_replays_history_for_same_process()
"read-only attachment should observe output: {observer_output_line}"
);
observer
.stdin
.as_mut()
.expect("observer stdin")
.write_all(b"\x03")
.await
.expect("send Ctrl-C to viewer");
let observer_status = tokio::time::timeout(Duration::from_secs(30), observer.wait())
.await
.expect("Ctrl-C should exit viewer")
.expect("wait for viewer");
assert!(observer_status.success(), "viewer should exit successfully");
owner
.stdin
.as_mut()
.expect("owner stdin")
.write_all(b"owner-after-viewer-exit\n")
.await
.expect("send input after viewer exits");
tokio::time::timeout(Duration::from_secs(30), async {
loop {
let line = owner_lines
.next_line()
.await
.expect("read owner output after viewer exits")
.expect("main process should remain running");
if line.contains("input=owner-after-viewer-exit") {
break;
}
}
})
.await
.expect("owner should retain working stdin after viewer exits");
owner.kill().await.expect("disconnect input owner");
owner.wait().await.expect("wait for input owner disconnect");
observer.kill().await.expect("disconnect observer");
observer.wait().await.expect("wait for observer disconnect");
let (mut reconnect, replay) = reconnect_with_input_ownership(&sandbox.name).await;