From 237071bd4865f0220c35c8c37895c8dba48aed84 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 21:25:52 -0300 Subject: Attach in a detached session is refused with words: bare is wrong #args, a name no session has is "no such session" A detached session's core has no frontend loop to take an Attach, so the word was asked and never answered: a ctl write of it succeeded and nothing happened. The core now knows it is a detached session's, and Attach there says why: bare names no session but itself, a name with no session behind it is said so, and one that is a session is told to be attached from a frontend. Co-Authored-By: Claude Opus 5.5 --- src/pardes.zig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/pardes.zig') diff --git a/src/pardes.zig b/src/pardes.zig index f479f44d..4472df8f 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -573,6 +573,20 @@ test "Attach asks for a session and tears nothing down" { try std.testing.expect(p.panes[0] != null); } +test "Attach in a detached session: bare is wrong #args, a name no session has says so, and nothing is asked" { + if (comptime !can_attach) return; + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .detached_session = true }); + defer p.deinit(); + while (p.nextEffect()) |_| {} + const pane = p.panes[0].?; + try std.testing.expect(p.executeBuiltinLine(0, "Attach")); + try std.testing.expect(drainForAttach(p) == null); + try std.testing.expectStringStartsWith(pane.msg[0..pane.msg_len], "wrong #args"); + try std.testing.expect(p.executeBuiltinLine(0, "Attach zz-no-such-session-qq")); + try std.testing.expect(drainForAttach(p) == null); + try std.testing.expectEqualStrings("Attach: zz-no-such-session-qq: no such session", pane.msg[0..pane.msg_len]); +} + test "Detach asks the frontend to leave, and says so when there is nothing to leave" { if (comptime !can_attach) return; // compiled out where nothing polls `takeAttach` — see `can_attach` const gpa = std.testing.allocator; @@ -4199,6 +4213,9 @@ pub const Options = struct { /// load a dump of another instance instead of spawning shells (acme -l) load_path: ?[]const u8 = null, nested: bool = false, + /// The core of a `--detach` session (detached/server.zig): it has no + /// terminal of its own, so Attach there is refused with why. + detached_session: bool = false, startup_config: ?[]const u8 = null, ninep_name: []const u8 = "", ninep_tcp: ?[]const u8 = null, -- cgit v1.3