diff --git a/.changeset/remote-file-access.md b/.changeset/remote-file-access.md new file mode 100644 index 000000000..bd399c099 --- /dev/null +++ b/.changeset/remote-file-access.md @@ -0,0 +1,34 @@ +--- +"aicodeman": patch +--- + +File previews, downloads and text reads now work in a **remote (SSH) case**. + +A remote case's working directory is an absolute path on the *remote* host, but the +file routes resolved it with local `fs` — so a clicked path (or the File Viewer) always +failed as "File not found" even though the file existed and the session was clearly +working in that directory. `GET /api/sessions/:id/file-raw`, `file-content`, +`file-preview` and `file-thumbnail` now resolve and read through the same +`buildSshConnectionArgs()` connection the launch uses (`src/remote-files.ts`, one +`realpath`+`stat` probe per request returning both the file and the workspace root). + +Clicked paths that point OUTSIDE the case directory (a remote `/tmp` scratchpad capture, +a screenshot elsewhere in the remote home) go through the attachment routes, which had +the same local-`fs` assumption: registration, the by-id `raw` stream, the metadata poll +and the attachment history list now resolve over ssh as well, so the click-path works +whether the file sits inside or outside the case. Which host a record is read from +follows the SESSION, never the path string — the same absolute path means a different +file on each host, and a remote session never falls back to a local file. + +The guards are unchanged in strength: the workspace boundary is still enforced (now +resolved on the host that can actually resolve it), the sensitive-path blocklist and +the size cap (`CODEMAN_MAX_DOWNLOAD_BYTES`) still apply before any bytes are read, and +`Range` requests keep working, so remote `