fix: worktree hook race + FocusActiveProject keybinding#86
Merged
Conversation
…nning Two race conditions caused worktrees to be removed before the before_worktree_remove hook finished: 1. The WorktreeSyncWatcher (30s periodic cleanup) ignored lifecycle state and would auto-remove projects whose directories were temporarily missing while a hook was running. 2. Hook terminals with keep_alive=false went through the dtach session backend, decoupling the hook process from the PTY lifecycle. The dtach client could exit independently of the hook command, causing Okena to think the hook had finished. Fix: Add ShellType::OneShot variant that bypasses the session backend for one-shot hook commands, and guard the sync watcher against projects in closing/creating/removing state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Cmd+Shift+0 / Ctrl+Shift+0 to zoom into the project containing the active terminal (inverse of ClearFocus). When exiting project zoom, the scroll now centers on the previously-focused project instead of leaving it at the left edge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3b8a6af to
19097a5
Compare
matej21
reviewed
Mar 27, 2026
Member
matej21
left a comment
There was a problem hiding this comment.
Nice root cause analysis on both race conditions. The OneShot shell type is a clean solution for bypassing session backend decoupling. A few things to address:
ShellType::OneShotappears to be missing fromto_command_string()inshell_config.rs— this will likely cause a compile error or exhaustiveness panic. Please add the match arm.- The
OneShotconstruction uses-icflag with$SHELL//bin/shfallback.-iis unnecessary for a non-interactive hook command and non-standard with/bin/sh. Consider using just-c. - On Windows,
$SHELLis unset and/bin/shdoesn't exist. The existingShellType::for_commandhandles this withcmd /C—OneShotneeds similar platform branching.
… centering - Remove ShellType::OneShot variant — all hook terminals now go through the session backend like regular terminals - Make FocusActiveProject a toggle: pressing again clears focus - Defer center-scroll to next layout pass so scroll handle has correct max_offset after unfocusing - Merge new default keybindings into existing saved config on load Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
neumie
commented
Mar 27, 2026
Contributor
Author
neumie
left a comment
There was a problem hiding this comment.
Thanks for the review! All three points are moot now — we reverted ShellType::OneShot entirely in d4160f3. Hook terminals now use ShellType::for_command() which already handles all platforms correctly. The actual race condition fix (guarding closing_projects/creating_projects in the sync watcher) stands on its own without needing to bypass the session backend.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WorktreeSyncWatchercould remove projects whilebefore_worktree_removehooks were still running — now checksclosing_projectsandcreating_projectsguardsFocusActiveProjecttoggle keybinding (Cmd+Shift+0 / Ctrl+Shift+0) to zoom into/out of the active terminal's projectShellType::OneShot— all hook terminals go through the session backendTest plan
FocusActiveProjectappears in keybindings settings panel🤖 Generated with Claude Code