Skip to content

feat(chat): attach any file from the composer's button, not only images (#1101) - #1122

Merged
agegr merged 1 commit into
mainfrom
feat/attach-any-file
Oct 9, 2026
Merged

agegr merged 1 commit into
mainfrom
feat/attach-any-file

Conversation

@agegr

@agegr agegr commented Oct 8, 2026

Copy link
Copy Markdown
Owner

On a phone there is no drag and drop, so the only way to give the chat a PDF or a log was the attach button, which took images only (#1101). Approved scope: the button accepts any file; no staging area outside the project.

  • components/ChatInput.tsx: new optional onAttachFiles(files). With it, the hidden file input has no accept (and no capture, so phones still offer the photo library and camera) and hands the whole selection over; without it, the input stays accept="image/*" as before.
  • components/ChatWindow.tsx: onAttachFiles runs the picked files through the existing chat drop handler (feat(chat): drop files onto the chat to upload them and mention them #1094), so they behave exactly like a drop:
    • images attach to the prompt (same limits, compression, image-support warning);
    • other files upload into the working directory with conflict=skip and come back as @ mentions, with the same notices;
    • a mixed pick does both; with no working directory, images still attach and other files get the same warning as a drop.
  • i18n: chat.attachImage → chat.attachFiles ("Attach files" / "附加文件" / "附加檔案"); the no-directory notice says "adding" instead of "dropping" since it covers both.
  • docs/agents/files-and-access.md: one bullet.

Tests: components/ChatInput.test.mjs (accept/capture/label with and without the handler; the real handleFilePick routing), new components/ChatWindow.attach-files.test.mjs (real drop/upload path with a stubbed upload request: mixed pick, image-only pick, no working directory). tsc, eslint, npm test pass.

Not checked on a real phone. Per WebKit 267277, iOS converts HEIC to JPEG only when accept lists specific types that exclude HEIC, which image/* did not, so dropping accept should not change the format of picked photos.

Refs #1101

🤖 Generated with Claude Code

…es (#1101)

On a phone there is no drag and drop, so the only way to give the chat a
PDF or a log was the attach button, which took images only. The button's
file input now has no accept list and hands the whole selection to
ChatWindow, which runs it through the chat drop handler: images attach to
the prompt as before (limits, compression, the image-support warning),
other files are uploaded into the working directory with conflict=skip
and mentioned, with the same notices, including the one when there is no
working directory. No capture attribute, so phones still offer photos and
the camera.

The button reads "Attach files", and the no-directory notice says
"adding" rather than "dropping" since it now covers both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@agegr
agegr merged commit 3f6baa9 into main Oct 9, 2026
3 of 4 checks passed
agegr added a commit that referenced this pull request Oct 9, 2026
Scrolling up a long session could show a page of older messages twice.
The page lands, and loadingOlderRef clears, a moment before React renders
the next cursor; a sentinel report in between (a renewed observer's first
one) still held the old cursor and fetched the same page again. #1122's
e2e failed on it (before=e4850 requested twice). The cursor asked for is
now kept until another one renders, and the observer skips it; a page that
failed, or a cursor a reload brings back, can still be asked for.

Repeating the e2e's pagination steps in headless Chromium at 6x CPU
throttling: main requested a page twice and showed 50-150 duplicate rows
in 3 of 10 runs; this branch in 0 of 30.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@agegr
agegr deleted the feat/attach-any-file branch October 9, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant