Skip to content

feat(app): add file upload, download and delete to file manager - #39879

Closed
valyc0 wants to merge 4 commits into
anomalyco:devfrom
valyc0:file-manager-upload
Closed

valyc0 wants to merge 4 commits into
anomalyco:devfrom
valyc0:file-manager-upload

Conversation

@valyc0

@valyc0 valyc0 commented Jul 31, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #39878

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Completes the file manager in the web app by adding the three actions that were missing: upload, download and delete. The panel could already read, list and search files, but you could not add or remove files from the UI.

  • Upload via picker or drag & drop, with a real progress bar (XMLHttpRequest-based, since fetch has no upload-progress event)
  • Download streams raw bytes with a sanitized filename
  • Delete with a confirmation dialog, followed by a tree refresh
  • Refresh re-syncs the file list

The actions are available consistently across the session header, file tree, search results and the file manager panel.

Server: new fs.upload, fs.delete and fs.download endpoints in the server.fs group, all with server-side path containment (including symlink resolution via realPath). The upload handler consumes the multipart file content inside the stream fold - the parser can only emit the next part once the current part's content is drained, so before this change uploads larger than the parser's initial buffer (~85 KB) would hang the request. The per-file limit is raised to 2 GB with a Content-Length guard that rejects oversized bodies with 413 before reading them, and any partial file from a rejected upload is cleaned up from disk.

App: shared helper packages/app/src/utils/file-transfer.ts for upload/download with Basic auth; upload timeout scales with file size (60 s base + 1 s/MiB, capped at 1 h); ConfirmDialog + useConfirm() for delete confirmation; i18n session.files.* keys added across all locales.

How did you verify your code works?

  • Typecheck passes in app, core, server, protocol and desktop.
  • Tests green: file-transfer (incl. timeout scaling), core filesystem, protocol fs-path.
  • End-to-end via curl: uploads from 85 KB to 200 MB succeed with byte-identical content (md5 verified); a >2 GB upload is rejected with no file left on disk.
  • Merged with the latest dev - no conflicts.
  • Note: the i18n parity test fails locally on packages/app for a pre-existing upstream reason (en.ts gained new export-session keys not yet translated in any locale - dev itself fails, and the test is CI-skipped). Not introduced by this PR.

Screenshots / recordings

Uploading with the progress bar:

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@valyc0
valyc0 requested review from Brendonovich and Hona as code owners July 31, 2026 13:43
@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

valyc0 added 2 commits August 6, 2026 16:36
Server: consume multipart file content inside the fold to avoid a parser deadlock on files larger than the parser initial buffer (uploads above ~85 KB previously hung); reject oversized bodies with 413 before reading them and remove orphaned files on rejected uploads. Client: upload via XMLHttpRequest with a real progress bar (fetch has no upload progress), timeout scaled to file size, and a 2 GB per-file limit. Adds file-transfer tests, core writeStream cleanup tests, and i18n keys across all locales.
# Conflicts:
#	packages/app/src/components/file-tree-v2.tsx
#	packages/app/src/i18n/es.ts
#	packages/app/src/i18n/uk.ts
@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@BongHwi

BongHwi commented Aug 11, 2026

Copy link
Copy Markdown

Hi @valyc0 — I tested this PR locally against the current dev branch in a remote OpenCode Web setup, and the upload/download foundation works well. Thank you for putting this together.

I also built a small downstream prototype on top of your work for presenting generated image and PDF artifacts directly in session messages. It uses the download endpoint from this PR, keeps only file metadata in the session, and fetches the actual bytes when previewing or downloading.

I preserved your original commits and authorship in my local prototype. I noticed the PR is currently no longer mergeable against the latest dev, and I have a small compatibility commit resolving the conflicts I encountered.

I don’t want to supersede or duplicate your PR. Would you prefer that I:

  1. share the compatibility patch with you,
  2. help rebase this branch, or
  3. wait and contribute the artifact UI as a follow-up after this PR lands?

The prototype currently supports:

  • inline generated image previews
  • image pan, pinch zoom, and mouse zoom
  • image and PDF downloads
  • browser-native PDF preview
  • project-contained file validation
  • no base64 or file bytes stored in session messages

Happy to adapt the follow-up to whichever direction you and the maintainers prefer.

@valyc0

valyc0 commented Aug 11, 2026

Copy link
Copy Markdown
Author

Hi @BongHwi,

Thank you very much for testing the PR locally and for building the downstream prototype on top of the upload/download foundation. I really appreciate the effort, and I'm glad the endpoints held up in a real-world scenario.

I especially like the approach of keeping only file metadata in the session and fetching the actual bytes only when previewing or downloading — combined with the inline image previews, pan/pinch/mouse zoom, and native PDF preview, it sounds like a solid foundation for the artifact UI. I also appreciate you preserving the original commits and authorship.

On the mergeability point, I re-checked against the latest dev today: GitHub currently reports the PR as mergeable (all required checks are green; the merge state is only "blocked" pending a maintainer review), and a local merge against current dev is clean as well. My guess is the conflicts you hit were on rebase rather than merge — the i18n locale files are the usual friction point there. Either way, I'll keep the branch in sync with dev as it moves, so this shouldn't cause further trouble.

Given that, I'd prefer option 3: land the artifact UI as a follow-up after this PR merges. Keeping the foundation PR focused makes it easier for the maintainers to review and merge, and your UI can then build cleanly on the merged endpoints. If it's convenient, you're welcome to share the compatibility patch anyway so I can verify it against the current tree — but there's no rush on my side.

Thanks again for the collaboration. Happy to coordinate on the follow-up whenever the time comes.

Best regards,
valyc0

@BongHwi

BongHwi commented Aug 11, 2026

Copy link
Copy Markdown

Thanks for checking, and option 3 sounds good to me.

You’re right about the mergeability distinction. I re-checked my local compatibility commit, and the issue came from applying the commits onto my prototype branch rather than from merging the current PR into dev. The commit only removes duplicate i18n entries introduced in that synthetic history, so there isn’t a generally useful patch for your branch to apply.

I’ll keep the artifact work separate and wait for #39879 to land before preparing the implementation PR. In the meantime, I’ll open a focused feature issue for the artifact presentation behavior so the scope and UI direction can be discussed independently.

Thanks again for coordinating and for keeping the foundation PR focused.

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

@onichandame

Copy link
Copy Markdown

sorry to bother. i lost track of the progress here. Which PRs are we waiting to land before we can move on with the download functionality?

@xiaoqinxing

Copy link
Copy Markdown

Opened #60180 to track the remaining gap.

Is this still something you would take? The gap is unchanged on current dev: the server.fs group only exposes read / list / find (plus experimental write / watch), and the V2 file preview has no download action, so binary files still cannot be saved from the web UI at all. #39878 was auto-closed after 60 days of inactivity, and #58957 was closed as a duplicate.

If the direction is acceptable, I can rebase this branch onto dev and open a fresh PR, or split it down to just the fs.download endpoint plus one item in the file preview header — whichever is easier to review. Happy to do either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: file upload, download and delete in the file manager

4 participants