Commit d469b2e
Eric Bower
·
2026-06-12 20:07:58 -0400 EDT
parent d4d5f2a
chore(ci): cleanup
7 files changed,
+11,
-38
+1,
-0
1@@ -3,6 +3,7 @@
2 .zig-cache/
3 zig-cache/
4 zig-out/
5+zig-pkg/
6 Session*.*vim
7 commit_msg
8 *.sw?
+2,
-3
1@@ -12,9 +12,8 @@ Use spec: https://common-changelog.org/
2
3 ### Changed
4
5-- *BREAKING* `zmx run` when creating session it runs `/bin/bash` instead of `$SHELL`
6- - There are just too many edge cases with tracking exit status in other shells which makes
7- `zmx run` much less useful for task management.
8+- *BREAKING* `zmx run` when creating session it runs `bash` instead of `$SHELL`
9+ - There are just too many edge cases with tracking exit status in other shells which makes `zmx run` much less useful for task management.
10 - This means when using `zmx run` the target shell must have support for `$?` exit code tracking
11 - *BREAKING* `zmx tail` now strips ansi escape codes
12
+1,
-3
1@@ -15,8 +15,6 @@ WORKDIR /app
2
3 COPY . /app/
4
5-RUN rm ./mise.toml
6-
7 RUN zig build
8
9-CMD ["zig", "build", "-Doptimize=ReleaseSafe"]
10+CMD ["zig", "build"]
+0,
-7
1@@ -1,7 +0,0 @@
2-[tools]
3-zig = "0.15.2"
4-zls = "0.15.1"
5-bats = "1.13.0"
6-
7-[tasks.test_int]
8-run = "bats test/session.bats"
M
pico.sh
+0,
-7
1@@ -6,13 +6,6 @@ EVENT_TYPE="${PICO_CI_EVENT_TYPE:-manual}"
2
3 echo "running ci event=${EVENT_TYPE} session=${ZMX_SESSION_PREFIX}"
4
5-if ! command -v mise &> /dev/null; then
6- echo "ERR: mise is required"
7- exit 1
8-fi
9-
10-zmx run install bash -c "mise trust && mise install"
11-
12 zmx run build docker build -t zig-zmx .
13 zmx run fmt -d docker run --rm -t zig-zmx:latest zig fmt --check .
14 zmx run test -d docker run --rm -t zig-zmx:latest zig build test
+5,
-17
1@@ -1140,30 +1140,14 @@ const Daemon = struct {
2
3 const cmd = payload;
4
5- // Prefix the command with environment variables to prevent it from
6- // blocking. Commands run in a PTY where stdout looks like a TTY,
7- // so programs like git/man/less will open a pager and hang. We set
8- // pager-related env vars to force non-interactive behavior:
9- // PAGER=cat — default pager fallback
10- // GIT_PAGER=cat — git ignores PAGER, uses its own
11- // LESS=-F — auto-exit if content fits (catches edge cases)
12- // MANPAGER=cat — man overrides PAGER with MANPAGER
13- // COLORTERM= — disable color (avoid ANSI in output)
14- // Plus < /dev/null to prevent programs that read stdin from blocking.
15- //
16- // Commands that legitimately need stdin should use `zmx send`
17- // instead, or pipe data directly: `echo data | zmx run dev cat`.
18- const cmd_prefix = "PAGER=cat GIT_PAGER=cat LESS=-F MANPAGER=cat COLORTERM= < /dev/null ";
19-
20 // Chain the exit marker with `;` on the same line. `$?` captures the
21 // exit code of the command (not the `;`). The sole exception is when
22- // the command contains a heredoc (`<<`) — the delimiter must be alone
23+ // the command contains a heredoc (`<<`), the delimiter must be alone
24 // on its line, so the marker goes on the next line instead.
25 const single_line_marker = "; echo ZMX_TASK_COMPLETED:$?\r";
26 const heredoc_marker = "\r\necho ZMX_TASK_COMPLETED:$?\r";
27 const uses_heredoc = std.mem.indexOf(u8, cmd, "<<") != null;
28
29- self.queuePtyInput(cmd_prefix);
30 if (cmd.len > 0 and cmd[cmd.len - 1] == '\r') {
31 self.queuePtyInput(cmd[0 .. cmd.len - 1]);
32 } else {
33@@ -1316,6 +1300,10 @@ fn help() !void {
34 \\ zmx run dev git log --oneline # pager won't block
35 \\ echo "hello" | zmx run dev cat # piped stdin still works
36 \\
37+ \\ # heredoc
38+ \\ printf "cat << 'EOF'\r\nHello $USER\r\nToday is $(date).\r\nEOF" | zmx run dev
39+ \\
40+ \\ # non-blocking
41 \\ zmx run dev -d sleep 10
42 \\ zmx wait dev
43 \\
+2,
-1
1@@ -352,7 +352,8 @@ pub fn findTaskExitMarker(output: []const u8) ?u8 {
2
3 /// Strip ANSI escape sequences from data, returning only printable characters
4 /// and essential whitespace (CR, LF, tab, backspace). Uses the ghostty VT
5-/// parser to correctly handle multi-byte sequences (CSI, OSC, DCS, etc.).n/// The returned slice is owned by the caller and must be freed.
6+/// parser to correctly handle multi-byte sequences (CSI, OSC, DCS, etc.).
7+/// The returned slice is owned by the caller and must be freed.
8 pub fn stripAnsi(alloc: std.mem.Allocator, data: []const u8) ![]const u8 {
9 var result = std.ArrayList(u8).initCapacity(alloc, data.len) catch unreachable;
10 defer result.deinit(alloc);