aboutsummaryrefslogtreecommitdiff
path: root/src/server/headless.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-02 02:45:20 +0300
committerGitHub <noreply@github.com>2026-09-02 02:45:20 +0300
commitcc88b3b8e5bb9f7d9f23ed6ae85a52fd7b5b9ed6 (patch)
tree4d37c760099070f1a1488b61c7b7271875aafef8 /src/server/headless.rs
parent18e69891dca486d669a584facd80644bb51f54a2 (diff)
feat: add stable client endpoint compatibility (#3509)
* feat: add stable client endpoint compatibility * fix: keep portable-pty patch checks composable * ci: run maintenance checks in pull requests * fix: reject endpoint errors from terminal clients * feat: keep compatible servers running across updates
Diffstat (limited to 'src/server/headless.rs')
-rw-r--r--src/server/headless.rs35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/server/headless.rs b/src/server/headless.rs
index 6bae0a98..1cf8ebd4 100644
--- a/src/server/headless.rs
+++ b/src/server/headless.rs
@@ -1934,12 +1934,17 @@ impl HeadlessServer {
connection.shell_projection_revision,
config_diagnostic,
);
- connection.shell_snapshot = Some(snapshot.clone());
+ let snapshot_message = match crate::protocol::endpoint::snapshot_message(&snapshot)
+ {
+ Ok(message) => message,
+ Err(err) => {
+ warn!(client_id, err = %err, "failed to encode endpoint snapshot");
+ return false;
+ }
+ };
+ connection.shell_snapshot = Some(snapshot);
self.clients.insert(client_id, connection);
- self.send_to_client(
- client_id,
- ServerMessage::ClientShellSnapshot(Box::new(snapshot)),
- );
+ self.send_to_client(client_id, snapshot_message);
self.foreground_client_id = Some(client_id);
if first_app_client {
self.app.mark_git_status_refresh_due(Instant::now());
@@ -2374,6 +2379,26 @@ impl HeadlessServer {
}
foreground_changed || runtime.scroll_metrics() != scroll_before
}
+ ServerEvent::ClientShellEndpointRequestError {
+ client_id,
+ boot_id,
+ request_id,
+ code,
+ message,
+ } => {
+ let Some(client) = self.clients.get(&client_id) else {
+ return false;
+ };
+ if !matches!(client.mode, ClientConnectionMode::ClientShell) {
+ self.remove_client_and_resize_if_needed(client_id);
+ return true;
+ }
+ let message = crate::server::client_commands::error_message(
+ boot_id, request_id, code, message,
+ );
+ self.send_to_client(client_id, message);
+ false
+ }
ServerEvent::ClientShellEndpointRequest {
client_id,
boot_id,