Skip to content

fix: prefer foreground process during session resurrection - #1

Draft
bearmug wants to merge 3 commits into
mainfrom
fix/resurrect-prefer-foreground-process
Draft

fix: prefer foreground process during session resurrection#1
bearmug wants to merge 3 commits into
mainfrom
fix/resurrect-prefer-foreground-process

Conversation

@bearmug

@bearmug bearmug commented Mar 19, 2026

Copy link
Copy Markdown

Summary

  • Fix get_all_cmds_by_ppid silently overwriting when a parent PID has multiple children, causing session resurrection to capture a subprocess command instead of the user's foreground command
  • Use ps -ao ppid,stat,args (adding STAT column) to prefer the foreground process (marked with +) over background children
  • Apply the same overwrite fix to the non-unix (Windows) path using first-child heuristic

Problem

When tools like claude --resume run in a Zellij pane, they spawn child processes (MCP servers, LSP servers, etc.). The previous code used HashMap::insert in a loop over ps output, so whichever child appeared last would silently overwrite earlier entries sharing the same parent PID. On resurrection, Zellij would then run the wrong command (e.g. node /path/to/mcp-server instead of claude --resume my-session).

Relates to zellij-org#2925, zellij-org#4129

Approach

The STAT column from ps contains + for processes in the foreground process group. By collecting all children per parent PID and preferring the one marked as foreground, we reliably capture the command the user actually launched.

  • Return type and trait signature unchanged — all consumers work without modification
  • post_command_discovery_hook continues to work per-process; empty hook output now excludes that process from candidates
  • Fallback to first child when no foreground process is found (also fixes the overwrite bug for the no-foreground case)

Test plan

  • 6 new unit tests covering: foreground preference, background-first ordering, single child, multiple PPIDs, header line handling, no-foreground fallback
  • All 928 existing tests pass
  • Manual: build and run modified binary, open a pane with a command that spawns children, verify zellij action dump-session captures the correct command

When a parent process has multiple children (e.g. `claude --resume`
spawning MCP servers), `get_all_cmds_by_ppid` would store only the
last child from `ps` output due to HashMap::insert overwriting.
This caused session resurrection to capture a subprocess command
instead of the user's actual foreground command.

Fix by:
- Adding the STAT column to ps output (`ps -ao ppid,stat,args`)
- Collecting all children per parent PID
- Preferring the foreground process (STAT contains '+')
- Falling back to the first child when no foreground process exists

The non-unix (Windows) path receives the same fix for the overwrite
bug, using first-child as the heuristic since sysinfo does not
expose foreground process group information.

The return type and trait signature are unchanged, so all consumers
(populate_session_layout_metadata, get_pane_running_command) work
without modification.

Relates to zellij-org#2925, zellij-org#4129
@bearmug
bearmug force-pushed the fix/resurrect-prefer-foreground-process branch from 7813751 to 020d2b6 Compare March 19, 2026 22:36
- Negate empty if-branch in update_terminal_commands (match
  existing is_dirty pattern at line 124)
- Avoid unnecessary .clone() in select_best_candidates by using
  position() + into_iter().nth() to move instead of copy
The sticky command change (not clearing `run` when the default shell
is detected) caused a regression. The os_input_output fix alone
addresses the root cause — this clearing behavior is needed for
panes that legitimately return to the shell.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant