Repository navigation
Description
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Problem
The web app (opencode pair → browser) file preview is view-only: there is no download action in the preview header, the file tree, or any tab menu. Files the agent generated on the server cannot be saved from the browser.
- Text files: select-all + copy is the only way out.
- Binary files (zip, pdf, docx, images, fonts, …): the preview shows the binary placeholder and there is no route to the bytes at all.
- The only built-in download I could find is
view.downloadin the legacy artifact toolbar (packages/gui-plugins/src/file/artifact-toolbar.tsx), and it only renders whileprops.text !== undefined. The V2 file preview (packages/session-ui/src/v2/components/session-review-file-preview-v2.tsx) exposes no toolbar actions, so in current V2 there is no download entry point at all. - API side: the
server.fsgroup only hasread,list,find(plus experimentalwrite/watch). 2.1.2's/openapi.jsonand currentdev(packages/server/src/handlers/fs.ts) both have no download route.
This matters most for remote / paired sessions: the person in the browser often has no shell on the server, so "just scp it" is not available.
Proposed solution
Add a download action (button and/or context-menu item) to the file preview and file tree that streams the raw bytes from fs.read:
- Server: add
GET /api/fs/download/*(or adownloadflag onfs.read) returningContent-Disposition: attachment; filename="…", with RFC 5987 encoding for non-ASCII names.serveFilealready streams with Range support, so large files should not be buffered in the app. - App: a Download item in the file preview header and in the file tree row menu that navigates to that URL. Using a navigation, not
fetch+ blob, keeps memory flat for large generated artifacts. - Keep it available when the preview falls back to the binary placeholder — that is the case that is impossible today.
Prior art
- [FEATURE]: file upload, download and delete in the file manager #39878 (upload/download/delete in the file manager) was closed automatically after 60 days of inactivity.
- feat(app): add file upload, download and delete to file manager #39879 ("feat(app): add file upload, download and delete to file manager") implemented this, including
fs.downloadwith sanitized filenames and a 2 GB upload limit, but was closed unmerged. - [FEATURE]: Add ability to download generated file from remote server in Desktop preview #58957 (desktop, remote preview download) was closed as a duplicate; app: the attachment card in a sent message is display-only — the uploaded file cannot be opened or downloaded #59896 covers message attachments, a different surface.
I am happy to rebase and re-submit #39879 against current dev, or to open a smaller PR that adds only the download endpoint plus the preview header item, whichever is preferred.
Workaround used today
A userscript that re-fetches /api/fs/read/<path>?location[directory]=<dir> and saves the blob through a[download]. It works, but no user should need one for a basic "save this generated file" action.
Environment
- opencode 2.1.2, Linux x64; the same gap exists in current
dev. - Web app accessed over
opencode pairin a desktop browser.
Activity
opencodejr commentedon Oct 29, 2026
Thanks for the detailed write-up, @xiaoqinxing! You're asking for a Download action in the web app's file preview and file tree, backed by a server route that streams the raw bytes as an attachment, and for it to work when the preview shows the binary placeholder too. Today generated files can't be saved from the browser, which hurts most in remote or paired sessions with no shell access.
The current V2 preview and the
fsAPI don't offer this, so it's a new feature rather than a bug. The maintainers will consider it, and your offer of a PR (either rebasing #39879 or the smaller endpoint-plus-header version) is noted.Related:
ArtifactToolbar. It overlaps with part of this but doesn't cover binary files, the file tree or a server route.