cmux NEXT New Tab: paste and drop images and files, sent with the first prompt

Merged
TE
17d ago
+622-304

Leo, 2026-10-19: "i cant paste in pictures in the new tab area but it works in the existing chats...?"

Cause

The New Tab page's prompt is its own <textarea> (newtab/NewTabScreen.tsx), not the chat composer (Composer.tsx). The chat composer's paste listener, document-level file drop (installFileDropLifecycle) and attachment chips all lived inside Composer, so on the New Tab page:

  • a pasted image or copied file did nothing;
  • a dropped file did nothing;
  • even with a way to stage attachments, the page's first send (screenActions.onAsk → chat.send { text }) carried only text.

Fix

  • The chat composer's attachment code moves to composer/attachmentIntake.tsx, and both composers use it:
    • useAttachmentIntake covers paste on the composer's field, file drop anywhere on the page, the moved-chat upload fallback and refusal notes.
    • AttachmentStrip / AttachmentChip / PdfAttachmentChip render the chips. They are moved, not changed.
    • Composer.tsx is 257 lines shorter.
  • The New Tab page stages a pasted image, a copied file, a screenshot or a dropped file under the same chips, with the same remove and preview.
  • onAsk passes the staged attachments. The chat's first chat.send carries { text, attachments }, and attachments alone are a prompt, as in a chat. A plain prompt sends exactly as before.

Tests

  • test/new-tab-paste-attachments.test.ts (browser lane, Chromium + WebKit, the pane's dev entry as a New Tab page on the mock transport):
    • case 1: paste a PNG on the field → chip → Return → the chat's first message shows the text and the image (data:image/png);
    • case 2: drop a file on the page → chip → × removes it; a pasted image with no text → Return → the first message has the image.
    • All 4 cases fail at base dde0ebbee3 (no chip appears) and pass with the fix.
  • test/new-tab-ask-attachments.test.ts: onAsk sends { text, attachments }, attachments alone, and a plain prompt unchanged. 2 of 3 fail at base.
  • Chat composer regressions, on Huge Blue:
    • agent-pane-attach-typing (3/3) and agent-pane-sent-images (1/1) pass;
    • all new-tab-* and composer* jsdom tests pass (139/0);
    • lint, fmt and typecheck are clean.

The classic New Tab layout (NewTabPage, Debug Settings layout "a") is unchanged.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes the New Tab page so pasted or dropped images and files stage as chips and are sent with the first prompt, matching the chat composer.

  • Moves the chat composer's attachment intake (paste, document-level drop, upload fallback, refusal notes) and its chips into composer/attachmentIntake.tsx, shared by Composer and the New Tab field.
  • onAsk now passes staged attachments to the chat's first chat.send; attachments alone act as a prompt. Plain prompts send exactly as before, and the classic New Tab layout is unchanged.
  • With attachments staged, Return starts a chat with the text and attachments instead of opening a suggested page, tab, or workspace; in shell mode a paste stays text.

Covered by browser tests (Chromium + WebKit) for paste and drop, and jsdom tests for onAsk sending attachments.