Summary
Clicking an absolute file path printed by an agent (or opening it in the File Viewer) in a remote (SSH) case does not open the file — the file simply isn't found, even though it exists on the remote host and the session is clearly working in that directory.
Repro
- Create a Remote Case (
New Case → Remote) pointing at a directory on a remote SSH host.
- Run any agent mode (I used
pi) that writes a file into that directory (e.g. a generated image in an output/ subfolder).
- Click the absolute path the agent prints (or open the same path via the File Viewer panel).
Expected: image/file preview loads, same as for a local case.
Actual: the preview fails to open (behaves as if the file doesn't exist).
Root cause (from reading the source)
/api/sessions/:id/file-raw resolves purely against the local filesystem of the machine running the Codeman server:
const validated = validateSessionFilePath(session.workingDir, filePath);
...
const stat = await fs.stat(resolvedPath);
For a remote case, session.workingDir is a path that only exists on the remote host — there's no SSH-aware branch here, unlike the tmux/launch code path (buildSshConnectionArgs, buildRemoteLaunchCommand etc.), which is fully SSH-aware. A plain fs.stat against a remote-only path on the local server obviously fails.
I'd guess the sibling routes (file-content, file-preview, file-thumbnail, filesystem/browse, filesystem/preview) have the same gap, since they follow the same local-fs pattern — I didn't check all of them individually.
Suggested directions
- Proxy file reads for remote sessions through SSH (e.g.
cat/sftp) reusing the existing buildSshConnectionArgs helper, gated behind the same size caps already used for local previews.
- At minimum, surface a clear "file preview isn't available for remote cases yet" state instead of a generic not-found, which currently looks like user/agent error rather than a known limitation.
Workaround in use
SSHFS-mounting the remote directory onto the identical absolute path on the Codeman-server host, so the existing local fs calls transparently succeed. Works, but obviously not a general solution (extra moving part, doesn't help anyone without root/mount access).
Environment
- Codeman installed via the official install script, self-hosted (not Docker case — a Remote/SSH case)
- Remote host: Linux, reached via a saved Remote Host + Remote Case
- Agent mode:
pi
- Files: PNGs written by a process running on the remote host, in a subdirectory of the case's
remotePath
Summary
Clicking an absolute file path printed by an agent (or opening it in the File Viewer) in a remote (SSH) case does not open the file — the file simply isn't found, even though it exists on the remote host and the session is clearly working in that directory.
Repro
New Case → Remote) pointing at a directory on a remote SSH host.pi) that writes a file into that directory (e.g. a generated image in anoutput/subfolder).Expected: image/file preview loads, same as for a local case.
Actual: the preview fails to open (behaves as if the file doesn't exist).
Root cause (from reading the source)
/api/sessions/:id/file-rawresolves purely against the local filesystem of the machine running the Codeman server:For a remote case,
session.workingDiris a path that only exists on the remote host — there's no SSH-aware branch here, unlike the tmux/launch code path (buildSshConnectionArgs,buildRemoteLaunchCommandetc.), which is fully SSH-aware. A plainfs.statagainst a remote-only path on the local server obviously fails.I'd guess the sibling routes (
file-content,file-preview,file-thumbnail,filesystem/browse,filesystem/preview) have the same gap, since they follow the same local-fs pattern — I didn't check all of them individually.Suggested directions
cat/sftp) reusing the existingbuildSshConnectionArgshelper, gated behind the same size caps already used for local previews.Workaround in use
SSHFS-mounting the remote directory onto the identical absolute path on the Codeman-server host, so the existing local
fscalls transparently succeed. Works, but obviously not a general solution (extra moving part, doesn't help anyone without root/mount access).Environment
piremotePath