fix: name the pane directory field paneCwd and apply the review items for #740

`cwd` beside the fixed `workingDir` reads ambiguously on a public API surface, and
`paneCwd` says where the value comes from, like `paneExit`. Also pin the field on
the payload the browser really receives (getSessionStateWithRespawn), and give the
pane-directory text its own architecture-invariants paragraph.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-04 16:59:16 +01:00
1 parent 4f50af6a9f
commit 91d157cae4
9 files changed
+83 -70

No files matched your search

+6 -6
View File
@@ -2431,23 +2431,23 @@ function resolveLinkedFilePath(filePath, workingDir) {
*
* `workingDir` is recorded once at create time and never follows a `cd`, so it
* stops describing where a shell (or an agent that changed directory) really
* is. `session.cwd` is the pane's live `#{pane_current_path}`, published by the
* is. `session.paneCwd` is the pane's live `#{pane_current_path}`, published by the
* server from its pane read. It only changes which BASE a relative path joins;
* the result is then routed like any other path, so a target outside the
* workspace still goes through the attachment routes.
*
* Remote and Docker sessions are excluded (the server never sends them a cwd,
* Remote and Docker sessions are excluded (the server never sends them a paneCwd,
* and this checks again): their local pane runs the ssh / docker-exec CLIENT,
* so its directory says nothing about the agent. An unknown cwd falls back to
* so its directory says nothing about the agent. An unknown paneCwd falls back to
* `workingDir`.
*
* @param {{workingDir?: string, cwd?: string, remote?: unknown, docker?: unknown}} [session]
* @param {{workingDir?: string, paneCwd?: string, remote?: unknown, docker?: unknown}} [session]
* @returns {string|undefined}
*/
function relativeResolutionBase(session) {
if (!session) return undefined;
const cwd = session.cwd;
if (!session.remote && !session.docker && typeof cwd === 'string' && cwd.startsWith('/')) return cwd;
const paneCwd = session.paneCwd;
if (!session.remote && !session.docker && typeof paneCwd === 'string' && paneCwd.startsWith('/')) return paneCwd;
return session.workingDir;
}
+2 -2
View File
@@ -2866,10 +2866,10 @@ export class WebServer extends EventEmitter {
// or empty read and carries a blank `#{pane_current_path}` forward, so an
// `undefined` here means an authoritative read listed no single directory
// for the session (split into several panes, or gone from the socket).
const cwdChanged = getPaneCurrentPath ? session.setCwd(getPaneCurrentPath(muxName)) : false;
const paneCwdChanged = getPaneCurrentPath ? session.setPaneCwd(getPaneCurrentPath(muxName)) : false;
if (session.setPaneExit(getPaneExit(muxName))) {
this.persistSessionState(session);
} else if (!cwdChanged) {
} else if (!paneCwdChanged) {
continue;
}
this.broadcastSessionStateDebounced(session.id);