From 66c4c97c9db6e2bd4f70b01c185fca3dbf82f722 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 11 Jun 2026 10:10:13 -0400 Subject: [PATCH] Use fresh implicit sessions and raw live terminal output --- src/bin/dosh-client.rs | 21 +++++++-------------- src/bin/dosh-server.rs | 14 +++----------- tests/integration_smoke.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/bin/dosh-client.rs b/src/bin/dosh-client.rs index 07259e6..59769bb 100644 --- a/src/bin/dosh-client.rs +++ b/src/bin/dosh-client.rs @@ -80,7 +80,7 @@ async fn main() -> Result<()> { return run_update(&config); } let server = args.server.unwrap_or(config.server); - let session = select_session(args.session.as_deref(), args.new, &config.default_session); + let session = select_session(args.session.as_deref(), args.new); let mode = if args.view_only || config.view_only { "view-only" } else { @@ -288,14 +288,11 @@ fn log_debug(verbose: u8, level: u8, message: &str) { } } -fn select_session(requested: Option<&str>, force_new: bool, configured_default: &str) -> String { +fn select_session(requested: Option<&str>, _force_new: bool) -> String { if let Some(session) = requested { return session.to_string(); } - if force_new || configured_default == "new" || configured_default.is_empty() { - return unique_session_name(); - } - configured_default.to_string() + unique_session_name() } fn unique_session_name() -> String { @@ -342,14 +339,10 @@ fn ssh_bootstrap( .arg(ssh_auth_command) .arg("--protocol") .arg("1") - .arg("--nonce") - .arg(nonce_b64) - .arg("--session") - .arg(session) - .arg("--mode") - .arg(mode) - .arg("--size") - .arg(size) + .arg(format!("--nonce={nonce_b64}")) + .arg(format!("--session={session}")) + .arg(format!("--mode={mode}")) + .arg(format!("--size={size}")) .output() .context("run ssh dosh-auth")?; if !output.status.success() { diff --git a/src/bin/dosh-server.rs b/src/bin/dosh-server.rs index 88b1fb3..a7fda72 100644 --- a/src/bin/dosh-server.rs +++ b/src/bin/dosh-server.rs @@ -638,20 +638,12 @@ async fn broadcast_output( for (client_id, client) in session.clients.iter_mut() { client.send_seq += 1; let current_screen = session.parser.screen().clone(); - let mut snapshot = false; - let mut bytes = if client.pending.len() >= retransmit_window { + let (bytes, snapshot) = if client.pending.len() >= retransmit_window { client.pending.clear(); - snapshot = true; - current_screen.state_formatted() - } else if let Some(prev) = &client.last_screen { - current_screen.state_diff(prev) + (current_screen.state_formatted(), true) } else { - snapshot = true; - current_screen.state_formatted() + (output.bytes.clone(), false) }; - if bytes.is_empty() { - bytes = output.bytes.clone(); - } let frame = Frame { session: output.session.clone(), output_seq, diff --git a/tests/integration_smoke.rs b/tests/integration_smoke.rs index 211b4bb..250cca3 100644 --- a/tests/integration_smoke.rs +++ b/tests/integration_smoke.rs @@ -462,6 +462,38 @@ fn pty_sets_terminal_environment() { ); } +#[test] +fn live_output_forwards_terminal_control_sequences() { + let dir = tempfile::tempdir().unwrap(); + let port = free_udp_port(); + let config = write_server_config(&dir, port); + let mut server = start_server(&dir, &config); + let (socket, bootstrap, ok) = direct_attach(&config, port, "read-write"); + + let input = Input { + bytes: b"printf '\\033[?1049hDOSH_ALT_SCREEN\\033[?1049l\\n'\n".to_vec(), + }; + send_encrypted( + &socket, + port, + PacketKind::Input, + ok.client_id, + 2, + 0, + &bootstrap.session_key, + &protocol::to_body(&input).unwrap(), + ); + let text = collect_frame_text(&socket, &bootstrap.session_key, 2000); + + let _ = server.kill(); + let _ = server.wait(); + + assert!( + text.contains("\x1b[?1049h") && text.contains("\x1b[?1049l"), + "expected raw alternate-screen control sequences, got {text:?}" + ); +} + #[test] fn resume_updates_udp_endpoint_for_roaming() { let dir = tempfile::tempdir().unwrap();