fix(terminal): report the pane directory in the workspace's own spelling

tmux reads a pane's directory from the process cwd, which is always the
resolved path, while workingDir keeps the spelling the case was created
with. For a workspace reached through a symlink every reading looked
like it was outside the workspace, so the browser sent each relative
link through the attachment route instead of the workspace routes.

Each session now resolves workingDir once in the background, bounded by
probePathKind() and a timed realpath(), and setCwd() writes a reading at
or under the resolved path back in workingDir's spelling. Until that
settles only a reading lexically inside workingDir is taken. An unknown
probe or a failed realpath leaves readings untranslated and retries
after WORKSPACE_REALPATH_RETRY_MS.

Also corrects two comments: cwd is written to state.json but never read
back, and a blank pane path is usually a pane whose program exited.
This commit is contained in:
Aamer Akhter committed 2026-10-28 19:29:05 -04:00
1 parent 54c1692350
commit f23e18b1fc
6 files changed
+237 -9

No files matched your search

+4 -1
View File
@@ -974,9 +974,12 @@ unresolved) and survives a server restart.
Session state (`GET /api/v1/sessions`, the `session:updated` event) may carry `cwd`,
the directory the session's local tmux pane is in now (`#{pane_current_path}`), which
the web UI uses as the base for a relative path printed in the terminal. It is
runtime-only (never persisted, so a restart starts without it), absent for remote,
never restored after a restart (it is written to `state.json` with the rest of the
session state but not read back), absent for remote,
Docker, direct-PTY and rediscovered sessions and for a session split into several panes,
and never a confinement root: file routes stay confined to `workingDir`.
tmux reports the resolved directory, so for a workspace reached through a symlink a
directory at or under the resolved workspace is reported in `workingDir`'s spelling.
## Session model (`displayModel`)