- commit
- 15c4a9c
- parent
- fbcec11
- author
- Eric Bower
- date
- 2026-02-17 08:55:28 -0500 EST
feat: env var `ZMX_SESSION_PREFIX` This change will allow users to set an environment variable that prefixes all session names with the value provided in the env var. This should help with some automation tasks relying on zmx since you can now "group" sessions together under a common prefix.
2 files changed,
+25,
-8
+1,
-0
1@@ -7,6 +7,7 @@ Use spec: https://common-changelog.org/
2 ### Added
3
4 - `zmx version` now returns the socket and log directory locations
5+- New environment variable `ZMX_SESSION_PREFIX` which will be applied to every session name provided
6
7 ## v0.3.0 - 2026-02-01
8
+24,
-8
1@@ -376,7 +376,9 @@ pub fn main() !void {
2 const session_name = args.next() orelse {
3 return error.SessionNameRequired;
4 };
5- return kill(&cfg, session_name);
6+ const sesh = try getSeshName(alloc, session_name);
7+ defer alloc.free(sesh);
8+ return kill(&cfg, sesh);
9 } else if (std.mem.eql(u8, cmd, "history") or std.mem.eql(u8, cmd, "hi")) {
10 var session_name: ?[]const u8 = null;
11 var format: HistoryFormat = .plain;
12@@ -392,7 +394,9 @@ pub fn main() !void {
13 if (session_name == null) {
14 return error.SessionNameRequired;
15 }
16- return history(&cfg, session_name.?, format);
17+ const sesh = try getSeshName(alloc, session_name.?);
18+ defer alloc.free(sesh);
19+ return history(&cfg, sesh, format);
20 } else if (std.mem.eql(u8, cmd, "attach") or std.mem.eql(u8, cmd, "a")) {
21 const session_name = args.next() orelse {
22 return error.SessionNameRequired;
23@@ -413,19 +417,21 @@ pub fn main() !void {
24 var cwd_buf: [std.fs.max_path_bytes]u8 = undefined;
25 const cwd = std.posix.getcwd(&cwd_buf) catch "";
26
27+ const sesh = try getSeshName(alloc, session_name);
28+ defer alloc.free(sesh);
29 var daemon = Daemon{
30 .running = true,
31 .cfg = &cfg,
32 .alloc = alloc,
33 .clients = clients,
34- .session_name = session_name,
35+ .session_name = sesh,
36 .socket_path = undefined,
37 .pid = undefined,
38 .command = command,
39 .cwd = cwd,
40 .created_at = @intCast(std.time.nanoTimestamp()),
41 };
42- daemon.socket_path = try getSocketPath(alloc, cfg.socket_dir, session_name);
43+ daemon.socket_path = try getSocketPath(alloc, cfg.socket_dir, sesh);
44 std.log.info("socket path={s}", .{daemon.socket_path});
45 return attach(&daemon);
46 } else if (std.mem.eql(u8, cmd, "run") or std.mem.eql(u8, cmd, "r")) {
47@@ -455,12 +461,14 @@ pub fn main() !void {
48 var cwd_buf: [std.fs.max_path_bytes]u8 = undefined;
49 const cwd = std.posix.getcwd(&cwd_buf) catch "";
50
51+ const sesh = try getSeshName(alloc, session_name);
52+ defer alloc.free(sesh);
53 var daemon = Daemon{
54 .running = true,
55 .cfg = &cfg,
56 .alloc = alloc,
57 .clients = clients,
58- .session_name = session_name,
59+ .session_name = sesh,
60 .socket_path = undefined,
61 .pid = undefined,
62 .command = null,
63@@ -469,7 +477,7 @@ pub fn main() !void {
64 .is_task_mode = true,
65 .task_command = cmd_args_raw.items,
66 };
67- daemon.socket_path = try getSocketPath(alloc, cfg.socket_dir, session_name);
68+ daemon.socket_path = try getSocketPath(alloc, cfg.socket_dir, sesh);
69 std.log.info("socket path={s}", .{daemon.socket_path});
70 return run(&daemon, cmd_args.items);
71 } else {
72@@ -1414,8 +1422,16 @@ fn detectShell() [:0]const u8 {
73 return std.posix.getenv("SHELL") orelse "/bin/sh";
74 }
75
76-fn sessionConnect(fname: []const u8) !i32 {
77- var unix_addr = try std.net.Address.initUnix(fname);
78+fn seshPrefix() []const u8 {
79+ return std.posix.getenv("ZMX_SESSION_PREFIX") orelse "";
80+}
81+
82+fn getSeshName(alloc: std.mem.Allocator, sesh: []const u8) ![]const u8 {
83+ return std.fmt.allocPrint(alloc, "{s}{s}", .{ seshPrefix(), sesh });
84+}
85+
86+fn sessionConnect(sesh: []const u8) !i32 {
87+ var unix_addr = try std.net.Address.initUnix(sesh);
88 const socket_fd = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
89 errdefer posix.close(socket_fd);
90 try posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen());