Skip to content

fix: preserve existing EXIT trap from ides shellHook#2

Open
wanderer wants to merge 5 commits into
manic-systems:masterfrom
wanderer:fix/preserve-exit-trap
Open

fix: preserve existing EXIT trap from ides shellHook#2
wanderer wants to merge 5 commits into
manic-systems:masterfrom
wanderer:fix/preserve-exit-trap

Conversation

@wanderer

@wanderer wanderer commented Jun 20, 2026

Copy link
Copy Markdown

The ides shellHook sets trap _ides_leave EXIT which clobbers any existing EXIT trap. This breaks direnv (and potentially other tools that rely on EXIT traps) because direnv uses its EXIT trap to capture the environment state after .envrc finishes executing. With the trap overridden, direnv captures nothing — no PATH, no env vars — making the nix dev shell completely invisible to the shell.

Closes #1.

wanderer added 5 commits June 20, 2026 20:45
The ides shellHook sets `trap _ides_leave EXIT` which clobbers any
existing EXIT trap. This breaks direnv (and any other tool that relies
on EXIT traps) because direnv uses its EXIT trap to capture the
environment state after .envrc finishes. With the trap overridden,
direnv captures nothing — no PATH, no env vars — making the nix dev
shell invisible.

Fix: save the existing EXIT trap before setting ours, and chain to it
from a wrapper function.

Closes manic-systems#1
When ides' shellHook runs inside direnv, the bash subprocess that
evaluates .envrc exits immediately after evaluation. This causes the
EXIT trap to fire, releasing the lease and stopping all services.

Fix: detect direnv via DIRENV_DIR/DIRENV_DIFF env vars. When detected:
1. Walk up the process tree (bash → direnv → real shell) to find the
   user's actual shell PID for the lease, so the lease stays alive.
2. Skip the EXIT-trap lease cleanup — the daemon's prune_dead will
   release the lease and stop services when the real shell exits.
3. Still chain to any existing EXIT trap (e.g. direnv's env capture).

In normal (non-direnv) shells, behavior is unchanged.
ides enter can fail on first run when the daemon is still starting up
(connection reset). Add retry logic (5 attempts, 200ms apart).

Also, don't exit the shell if ides enter ultimately fails — just skip
lease management. The user can run `ides run` manually.
The daemon's serve() loop checks if active==0 && pruned>0 to detect
when all shells have exited (pruned dead leases → stop services → exit).
But on startup, stale lease files from previous runs would trigger this
condition immediately, causing the daemon to call systemd::down() and
exit before any client could connect.

Fix: skip the prune-and-exit check on the first iteration. The daemon
will still exit after 10 seconds of idle time if no leases are created.
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.

shellHook's trap _ides_leave EXIT breaks direnv environment capture

1 participant