Skip to content

Open symlinked directories, and re-read ssh_config when asked - #14

Merged
ralyodio merged 1 commit into
mainfrom
fix/symlinks-and-host-refresh
Aug 30, 2026
Merged

Open symlinked directories, and re-read ssh_config when asked#14
ralyodio merged 1 commit into
mainfrom
fix/symlinks-and-host-refresh

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Two reports, both about a pane showing something other than what is there. A third report in the same batch turned out not to be a bug — see the end.

A symlinked directory could not be opened

~/data -> /mnt/vdb on a server was a row that swallowed every double-click. SFTP's readdir reports a link's type the way lstat does, so it arrives as symlink, and the pane only walked into rows typed directory.

The browser now follows each link with a stat — one per link, and only for links, since a listing is mostly ordinary files — and records what is behind it. A link to a directory opens, sorts with the directories, draws as a folder in the link colour rather than as a chain, and shows no byte size. A link whose target cannot be stat'd stays unopenable, which is the honest answer for a broken one.

Navigation goes to the link's own path, not the resolved target: the server resolves it when it lists, and the breadcrumbs keep saying where the user thinks they are.

Verified against a real server (seed2):

.tmux.conf  type=symlink  targetType=file       -> /home/anthony/.tmux/.tmux.conf
data        type=symlink  targetType=directory  -> /mnt/vdb

navigable by the pane's rule: true
listing data -> 1 entries: lost+found

The host list was read once at startup

sshConfigHosts() was fetched on mount and never again, so a host removed from ~/.ssh/config stayed in the picker for the life of the window — and one added to it never appeared at all. Opening the picker now re-reads both lists.

Checks

  • pnpm test — 323 passed, 30 files (9 new)
  • pnpm typecheck — clean
  • Rendered headless in both themes: the link row sorts among the directories, draws as a folder, and shows for size

The new SFTP test stubs a layer where readdir and stat disagree, which is the whole shape of the bug.

Not a bug: seed1

Reported alongside these as "can't connect to seed1". It is the host refusing our credentials, not the app failing to offer them:

seed1  ubuntu@seed1.h4kr.com:22  auth=agent
  connect -> [auth] SSH authentication was rejected by seed1.h4kr.com.

No code change here can help; that key needs to be authorised on the host.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GTQ3RzTAey9nT6r1kbGBCd

Two things reported together, both about a pane showing something other
than what is there.

**A symlinked directory could not be opened.** `~/data -> /mnt/vdb` on a
server is a row that swallowed every double-click. SFTP's readdir reports
a link's type the way lstat does, so it arrives as `symlink`, and the
pane only walked into rows typed `directory`. The browser now follows
each link with a stat — one per link, and only for links, since a listing
is mostly ordinary files — and records what is behind it. A link to a
directory opens, sorts with the directories, draws as a folder in the
link colour rather than as a chain, and shows no byte size. A link whose
target cannot be stat'd stays unopenable, which is the honest answer for
a broken one.

Navigation goes to the link's own path, not the resolved target: the
server resolves it when it lists, and the breadcrumbs keep saying where
the user thinks they are.

**The host list was read once at startup.** A host removed from
~/.ssh/config stayed in the picker for the life of the window, and one
added to it never appeared at all. Opening the picker now re-reads both
lists.

Verified against a real server: on seed2, `data` resolves to a directory
target, the pane's rule calls it navigable, and listing it returns its
contents; `.tmux.conf`, a link to a file, correctly stays unopenable.
Rendered headless in both themes to confirm the row sorts and draws as a
folder. 9 new tests, including a stubbed SFTP layer where readdir and
stat disagree, which is the whole shape of the bug.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTQ3RzTAey9nT6r1kbGBCd
@ralyodio
ralyodio merged commit 68fa4ae into main Aug 30, 2026
4 checks passed
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