Skip to content

fix(tui): attach files copied in Finder instead of their name or icon - #54845

Closed
lacherogwu wants to merge 2 commits into
anomalyco:devfrom
lacherogwu:finder-file-paste
Closed

lacherogwu wants to merge 2 commits into
anomalyco:devfrom
lacherogwu:finder-file-paste

Conversation

@lacherogwu

@lacherogwu lacherogwu commented Oct 12, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #54844

Type of change

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

What does this PR do?

OpenTUI's host clipboard only reads image/png and text/plain. For a Finder copy, those are the file icon and the bare file names. This adds readPasteboardFiles(), which reads the file URLs from NSPasteboard through osascript (macOS only), and uses it in two places:

  • clipboard.read() returns the copied files as a file:// URI list instead of the icon, so the existing path resolver attaches the real files (Ctrl+V).
  • When a bracketed paste is just bare attachment file names (no /, known image/PDF extension) that match the pasteboard's file URLs, they're resolved to those paths (Cmd+V). The pasteboard is only read for pastes that look like this, so normal text pastes don't spawn osascript.

How did you verify your code works?

  • Ran the TUI with bun run dev:live in the VS Code terminal: copying a screenshot in Finder and pasting with Cmd+V now attaches [Image 1] instead of inserting the file name
  • Against the real pasteboard, both a bare-name paste and clipboard.read() resolve to the full screenshot file (with the U+202F in its name)
  • New tests in clipboard.test.ts and local-attachment.test.ts, which fail without the change
  • bun typecheck passes. bun test in packages/tui: everything passes except the 2 dialog-shell-output timeouts, which also fail on dev

Screenshots / recordings

Not a visual change; the pasted file now shows up as [Image 1] like other image pastes.

Checklist

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

🤖 Generated with Claude Code


Added by the opencode bot (AI-generated).

Related: #48190

OpenTUI's host clipboard only reads image/png and text/plain, which for a
Finder copy are the file icon and the bare file names. Read the file URLs
from NSPasteboard on macOS and resolve pasted Finder names through them.

Fixes anomalyco#54844

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't verify this one: it needs macOS with Finder and the native pasteboard, and the review sandbox runs Linux. The new and existing tests in clipboard.test.ts and local-attachment.test.ts pass, and packages/tui type-checks. From reading the code, the approach looks right. Mapping public.file-url to a file:// list reuses the existing path resolver. Matching bare names against the pasteboard only for attachment-looking pastes keeps osascript off the normal paste path.

Public API: unchanged. readPasteboardFiles and the new optional parameters on createClipboardAdapter and resolvePastedAttachments are internal to packages/tui.

Two things worth fixing (see the inline comments):

  • readPasteboardFiles runs regardless of OpenTUI's remote handling. OpenTUI skips the process host clipboard when the session is remote, but this reads the local Mac's pasteboard and takes precedence over the clipboard result.
  • osascript now runs on every Ctrl+V on macOS, including plain-text pastes. It has no timeout, and a spawn error or hang fails or blocks the whole read.

A minor one: when Finder files that aren't attachments (a .txt, a folder) are copied, Ctrl+V now inserts file:///… URIs as text, where before it attached the icon. That is arguably better, but worth a conscious decision.

Related: #48190

Comment thread packages/tui/src/clipboard.ts Resolved
Comment thread packages/tui/src/clipboard.ts Resolved
Only read Finder file URLs when the clipboard holds a bitmap, since a Finder
copy always reads as its file icon. Time out a stuck osascript after 1s and
treat any failure as no files so it never breaks or blocks the paste.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@lacherogwu

Copy link
Copy Markdown
Author

Thanks for the review. Both inline points are addressed above (the timeout/gating fix is in 551aa13).

On non-attachment Finder copies: inserting the file:// URIs is intentional. The icon was never useful content, and the URIs give the model the real paths, matching how terminals deliver drag-and-dropped files as a URI list.

@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.

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.

Pasting an image file copied in Finder attaches the file name or its icon instead of the image (macOS)

1 participant