Commit c0d157e
Eric Bower
·
2026-10-15 23:40:49 -0400 EDT
parent 2d23c0d
fix: replace has_had_client with clearing write_buf when is_terminal=false When a client connects, daemonLoop may broadcast raw PTY output into client.write_buf between accept() and handleInit(). Clearing write_buf avoids duplicating the initial output of forwarding already answered DA queries. This means we can always send terminal snapshot now.
1 files changed,
+6,
-10
+6,
-10
| ... | ... | @@ -598,7 +598,6 @@ pub const Daemon = struct { | |
| 598 | 598 | cwd_buf: [std.fs.max_path_bytes]u8 = undefined, | |
| 599 | 599 | cwd_path_buf: [std.fs.max_path_bytes]u8 = undefined, | |
| 600 | 600 | has_pty_output: bool = false, | |
| 601 | - | has_had_client: bool = false, | |
| 602 | 601 | created_at: u64, // unix timestamp (ns) | |
| 603 | 602 | is_task_mode: bool = false, // flag for when session is run as a task | |
| 604 | 603 | task_id: [4]u8 = undefined, |
| ... | ... | @@ -957,6 +956,10 @@ pub const Daemon = struct { | |
| 957 | 956 | ) !void { | |
| 958 | 957 | if (payload.len != @sizeOf(ipc.Resize)) return; | |
| 959 | 958 | ||
| 959 | + | if (!client.is_terminal) { | |
| 960 | + | client.write_buf.clearRetainingCapacity(); | |
| 961 | + | client.has_pending_output = false; | |
| 962 | + | } | |
| 960 | 963 | client.is_terminal = true; | |
| 961 | 964 | ||
| 962 | 965 | if (self.leader_client_fd == null) { |
| ... | ... | @@ -975,9 +978,7 @@ pub const Daemon = struct { | |
| 975 | 978 | try resizeTerm(gpa, term, resize.cols, resize.rows); | |
| 976 | 979 | } | |
| 977 | 980 | ||
| 978 | - | // Only serialize on re-attach (has_had_client), not first attach, to avoid | |
| 979 | - | // interfering with shell initialization (DA1 queries, etc.) | |
| 980 | - | if (self.has_pty_output and self.has_had_client) { | |
| 981 | + | if (self.has_pty_output) { | |
| 981 | 982 | const cursor = &term.screens.active.cursor; | |
| 982 | 983 | std.log.debug( | |
| 983 | 984 | "cursor before serialize: x={d} y={d} pending_wrap={}", |
| ... | ... | @@ -1009,16 +1010,13 @@ pub const Daemon = struct { | |
| 1009 | 1010 | // incremental renderers (Ink, Claude Code, etc.) know to repaint. | |
| 1010 | 1011 | // If the size changed, TIOCSWINSZ above already sent SIGWINCH; if the size | |
| 1011 | 1012 | // was unchanged, the kernel suppressed it, so signal the pgrp explicitly. | |
| 1012 | - | if (self.has_pty_output and self.has_had_client) { | |
| 1013 | + | if (self.has_pty_output) { | |
| 1013 | 1014 | var pgrp: lib_posix.pid_t = 0; | |
| 1014 | 1015 | if (cross.c.ioctl(pty_fd, cross.c.TIOCGPGRP, &pgrp) == 0 and pgrp > 0) { | |
| 1015 | 1016 | lib_posix.kill(-pgrp, .WINCH) catch {}; | |
| 1016 | 1017 | } | |
| 1017 | 1018 | } | |
| 1018 | 1019 | ||
| 1019 | - | // Mark that we've had a client init, so subsequent clients get terminal state | |
| 1020 | - | self.has_had_client = true; | |
| 1021 | - | ||
| 1022 | 1020 | std.log.debug("init resize rows={d} cols={d}", .{ resize.rows, resize.cols }); | |
| 1023 | 1021 | } | |
| 1024 | 1022 | } |
| ... | ... | @@ -1199,7 +1197,6 @@ pub const Daemon = struct { | |
| 1199 | 1197 | ||
| 1200 | 1198 | try ipc.appendMessage(gpa, &client.write_buf, .Ack, ""); | |
| 1201 | 1199 | client.has_pending_output = true; | |
| 1202 | - | self.has_had_client = true; | |
| 1203 | 1200 | std.log.debug("run command len={d}", .{payload.len}); | |
| 1204 | 1201 | } | |
| 1205 | 1202 |
| ... | ... | @@ -1306,7 +1303,6 @@ pub const Daemon = struct { | |
| 1306 | 1303 | ||
| 1307 | 1304 | try ipc.appendMessage(gpa, &client.write_buf, .Ack, ""); | |
| 1308 | 1305 | client.has_pending_output = true; | |
| 1309 | - | self.has_had_client = true; | |
| 1310 | 1306 | std.log.debug( | |
| 1311 | 1307 | "write command len={d} file_path={s}", | |
| 1312 | 1308 | .{ file_content.len, file_path }, |