<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotfiles/dot_config/zsh/dot_zprofile, branch master</title>
<subtitle>My linux config and rc files</subtitle>
<id>https://git.sommerfeld.dev/dotfiles/atom/dot_config/zsh/dot_zprofile?h=master</id>
<link rel='self' href='https://git.sommerfeld.dev/dotfiles/atom/dot_config/zsh/dot_zprofile?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/'/>
<updated>2026-05-29T10:18:15Z</updated>
<entry>
<title>refactor(suspend): drop SSH session inhibit; AC rule handles it</title>
<updated>2026-05-29T10:18:15Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:15Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=45ce3902227fdfe4380d7b956ed89274e04b6ba5'/>
<id>urn:sha1:45ce3902227fdfe4380d7b956ed89274e04b6ba5</id>
<content type='text'>
Same rationale as the previous commit: the new policy is "if you don't
want the machine to sleep, plug it in." An SSH-only inhibit in zprofile
is redundant on AC (logind already ignores the lid) and inconsistent on
battery (it would hold the lock for an SSH-attached idle session,
defeating the schedule).

Also removes a stale doc reference to zellij-inhibit-suspend.path which
no longer exists.
</content>
</entry>
<entry>
<title>feat(suspend): hold inhibit lock while any zellij session exists</title>
<updated>2026-05-29T10:18:13Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:13Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=01df321e907b6c8568bb8622eb44a5c1486a0631'/>
<id>urn:sha1:01df321e907b6c8568bb8622eb44a5c1486a0631</id>
<content type='text'>
The SSH-shell inhibitor in dot_zprofile is bound to the lifetime of the
login shell, so it disappears the moment the user detaches a zellij
session and disconnects — defeating the whole point of using zellij for
persistent remote work.

Add a user-scope path+service+watcher trio that ties the inhibit lock
to the existence of zellij sessions instead:

  - dot_local/bin/executable_zellij-inhibit-watcher
      Polls `zellij list-sessions --short` every 15s, exits when none
      remain. Override poll interval via $ZELLIJ_INHIBIT_POLL.

  - dot_config/systemd/user/zellij-inhibit-suspend.service
      Wraps the watcher in `systemd-inhibit --what=sleep:idle:handle-lid-switch
      --mode=block`. When the watcher exits, the service stops and the
      lock is released.

  - dot_config/systemd/user/zellij-inhibit-suspend.path
      Activates the service whenever $XDG_RUNTIME_DIR/zellij becomes
      non-empty (i.e. zellij creates its first session socket). Re-fires
      on every empty→non-empty transition.

Enable via systemd-units/user.txt (the .path unit; the service is
on-demand).

The existing SSH-shell inhibitor is kept as a backstop for non-zellij
remote sessions and is now documented as such.

VM (nix/vm.nix) deliberately not updated: the Ubuntu remote-dev VM
never suspends, so the inhibit machinery would be inert there.
</content>
</entry>
<entry>
<title>feat(zsh): inhibit suspend while an SSH session is active</title>
<updated>2026-05-29T10:18:13Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:13Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=263f39704ae5e8f44a79d64dce2be048009b4df6'/>
<id>urn:sha1:263f39704ae5e8f44a79d64dce2be048009b4df6</id>
<content type='text'>
A remote session is useless if the laptop suspends mid-command, but
logind doesn't suppress lid-close or idle-suspend for SSH sessions on
its own — you have to hold an explicit inhibitor lock.

When $SSH_CONNECTION is set, re-exec the login shell under
`systemd-inhibit --what=sleep:idle:handle-lid-switch --mode=block`
so the lock is bound to the shell's lifetime: it covers swayidle,
logind's HandleLidSwitch, and any other consumer that respects
inhibit locks, and it's released the moment the SSH session ends.

A guard env var prevents recursion if the user nests a login shell
inside the wrapped one (e.g. `exec zsh -l`).
</content>
</entry>
<entry>
<title>fix(ssh): make agent.sock symlink concurrent-connection-safe</title>
<updated>2026-05-22T09:41:24Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-22T09:41:24Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=982d180f9b9a2f8a90d454816474dce8d4b4b8e2'/>
<id>urn:sha1:982d180f9b9a2f8a90d454816474dce8d4b4b8e2</id>
<content type='text'>
Previously every new login retargeted ~/.ssh/agent.sock to its own
per-connection forwarded socket. That broke a multi-connection setup
when the most-recent connection (which 'won' the symlink) dropped:
all surviving connections' panes would point at a dead socket until a
fresh login from a surviving connection re-ran zprofile.

zprofile: only retarget when the existing symlink target is dead
(sshd unlinks the per-connection socket on disconnect, so [[ -S ]] on
the resolved path is a reliable liveness probe). First connection
seeds the symlink, subsequent logins keep using it.

ssh-agent-refresh: scan /tmp/ssh-*/agent.* for any live forwarded
socket and retarget to the first that responds to ssh-add. Lets the
surviving connection recover without waiting for a new login shell.
</content>
</entry>
<entry>
<title>fix(nix,zsh): tuicr flake schema + restore XDG_DATA_DIRS</title>
<updated>2026-05-22T09:41:23Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-22T09:41:23Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=a97634f5062088f8d4e6d3c06fdf82a87c157167'/>
<id>urn:sha1:a97634f5062088f8d4e6d3c06fdf82a87c157167</id>
<content type='text'>
tuicr's upstream flake uses the legacy 'defaultPackage.&lt;system&gt;' output
schema, not 'packages.&lt;system&gt;.default' — fixes the home-manager switch
error 'attribute packages missing' at nix/flake.nix:28.

zsh: removing the system zsh package took /etc/zsh/zprofile with it,
which used to 'source /etc/profile' and pull in /etc/profile.d/*.sh
(flatpak.sh, nix.sh, etc.). Reconstruct XDG_DATA_DIRS in dot_zprofile
defensively, including per-user + system flatpak exports + nix-profile
share, so 'flatpak update' stops warning and desktop entries from
flatpak/nix-installed apps work in launchers (fuzzel).
</content>
</entry>
<entry>
<title>fix(ssh): stabilise forwarded ssh-agent socket across reconnects</title>
<updated>2026-05-22T09:41:23Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-22T09:41:23Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=159d69ddd122cfdb55d087d754d7472d42fa73ae'/>
<id>urn:sha1:159d69ddd122cfdb55d087d754d7472d42fa73ae</id>
<content type='text'>
Forwarded SSH_AUTH_SOCK lives at /tmp/ssh-XXX/agent.NNN — a
per-connection path that disappears on disconnect, leaving every
long-running zellij pane (and its children: claude-code, nvim, …)
pointing at a dead socket. Reattaching after reconnect doesn't help:
the env was captured when zellij first started.

Fix: maintain ~/.ssh/agent.sock as a symlink, re-aimed at the live
forwarded socket on every login (zprofile). Export the stable path so
processes inherit a value that survives reconnects — git fetch /
commit signing keep working in re-attached zellij panes with zero
per-pane re-export.

Adds 'ssh-agent-refresh' helper for transitional panes still holding
the dead per-connection path: re-exports SSH_AUTH_SOCK to the stable
symlink and validates with ssh-add -l. Already-running children
(claude-code) must still be restarted since env is inherited, not
observed.
</content>
</entry>
<entry>
<title>refactor(zsh): drop FIRECRAWL_API_KEY export</title>
<updated>2026-05-20T13:01:04Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-20T13:01:04Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=5f5abfb453191c2bd3d1fb6de3a7aa7cc3ad6109'/>
<id>urn:sha1:5f5abfb453191c2bd3d1fb6de3a7aa7cc3ad6109</id>
<content type='text'>
Unused; the pass entry doesn't exist on most machines, so login emitted
'Error: copilot/firecrawl-api-key is not in the password store' on every
shell start. Easier to drop than to gate.
</content>
</entry>
<entry>
<title>drop residual Mason references after p6 migration</title>
<updated>2026-05-20T12:56:11Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-20T12:56:11Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=ea3e273d4221720f932d401a64d0881c7b23263b'/>
<id>urn:sha1:ea3e273d4221720f932d401a64d0881c7b23263b</id>
<content type='text'>
- zsh: remove ~/.local/share/nvim/mason/bin from PATH
- justfile: update comments to reflect Mason removal
</content>
</entry>
<entry>
<title>feat(zsh): prepend ~/.nix-profile/bin to PATH</title>
<updated>2026-05-20T12:56:09Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-20T12:56:09Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=1f7215ebdcfed2ccdb63abf0e3561d50e719fc63'/>
<id>urn:sha1:1f7215ebdcfed2ccdb63abf0e3561d50e719fc63</id>
<content type='text'>
So Home-Manager-provisioned tools shadow pacman/apt across host and VM,
delivering identical tool versions from the same flake.lock. Mason bin
stays for now; phase p6 of the nix migration removes it together with
the Mason plugins.

Phase 3 of the nix-on-host migration plan.
</content>
</entry>
<entry>
<title>fix(zsh): preserve forwarded SSH_AUTH_SOCK in SSH sessions</title>
<updated>2026-05-14T11:53:48Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-14T11:53:48Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=26616fced56d7d4b18ec4f3157a65366be35f90f'/>
<id>urn:sha1:26616fced56d7d4b18ec4f3157a65366be35f90f</id>
<content type='text'>
zprofile unconditionally pointed SSH_AUTH_SOCK at the local
gpg-agent's ssh socket. On remote machines (e.g. remote-dev VM)
that clobbers ssh-agent forwarding — `ssh-add -L` reports no
identities because the VM's gpg-agent has no keys.

Only override when there's no forwarded socket (no $SSH_CONNECTION
or no $SSH_AUTH_SOCK from sshd).
</content>
</entry>
</feed>
