Skip to content

fix(extension): route clipboard image reading through extension host - #559

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix/image-paste-webview
Aug 25, 2026
Merged

fix(extension): route clipboard image reading through extension host#559
jeonghun-jj-lee merged 1 commit into
mainfrom
fix/image-paste-webview

Conversation

@jeonghun-jj-lee

@jeonghun-jj-lee jeonghun-jj-lee commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

The outer webview's navigator.clipboard.read() requires user activation (a keystroke on THAT document), but the user types inside the sandboxed iframe — so the async Clipboard API throws silently in newer Chromium/Electron, causing image paste to do nothing.

Fix

Forward clipboard-image-request to the extension host, which reads the clipboard image using platform-native tools:

Platform File manager copy Screenshot/browser copy
macOS public.file-url → resolve path → read file osascript + NSPasteboard (PNG/TIFF)
Linux text/uri-list via xclip → read file xclip image/png
Windows PowerShell GetFileDropList → read file PowerShell GetImage → PNG

Changes

  • chat_bridge.ts: new clipboard-image-read handler with native readers
  • chat_panel.ts: forward to extension host (both webview variants)
  • deck/shell.ts: same forwarding for deck shell
  • Tests for bridge handler and panel relay

Companion: harmoniqs/opencode#254

Summary by CodeRabbit

  • New Features

    • Added support for inserting images from the system clipboard into chat across macOS, Linux, and Windows.
    • Clipboard images are handled through the extension for improved compatibility, including PNG and TIFF images and copied file images.
    • Image requests are processed only for visible panels, helping prevent unintended responses from hidden views.
  • Bug Fixes

    • Improved clipboard image handling when browser-based clipboard access is unavailable or unsupported.

The outer webview's navigator.clipboard.read() requires user activation
(a keystroke on THAT document), but the user types inside the sandboxed
iframe — so the async Clipboard API throws silently in newer Chromium/
Electron, causing image paste to do nothing.

Fix: forward clipboard-image-request to the extension host, which reads
the clipboard image using platform-native tools:

- macOS: osascript + NSPasteboard (PNG/TIFF), with file-URL priority
  so Finder-copied images paste the actual file, not the Finder icon
- Linux: xclip with text/uri-list priority for file manager copies,
  then raw image/png data
- Windows: PowerShell with GetFileDropList priority for Explorer copies,
  then GetImage for screenshots

Changes:
- chat_bridge.ts: add clipboard-image-read handler with native readers
- chat_panel.ts: replace client-side navigator.clipboard.read() with
  forwarding to extension host (both splash and non-splash variants)
- deck/shell.ts: same forwarding for the deck shell webview
- Tests: bridge test, panel relay test
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 60a9b516-7cec-4012-9c2a-3740bc7d02cb

📥 Commits

Reviewing files that changed from the base of the PR and between 5cf69b6 and 663ef81.

📒 Files selected for processing (5)
  • packages/extension/src/chat_bridge.ts
  • packages/extension/src/chat_panel.ts
  • packages/extension/src/deck/shell.ts
  • packages/extension/test/chat_bridge.test.ts
  • packages/extension/test/chat_panel.test.ts

📝 Walkthrough

Walkthrough

The extension adds a visibility-gated clipboard-image-read bridge. Chat and shell webviews forward image requests to the extension host, which reads clipboard images through macOS, Linux, or Windows native tools and returns image metadata.

Changes

Clipboard image flow

Layer / File(s) Summary
Native clipboard reading and bridge response
packages/extension/src/chat_bridge.ts, packages/extension/test/chat_bridge.test.ts
The bridge validates panel visibility, reads clipboard images with platform-specific tools, and returns nullable image metadata. Tests cover visible and hidden panels, asynchronous replies, and data URL validation.
Webview request forwarding
packages/extension/src/chat_panel.ts, packages/extension/src/deck/shell.ts, packages/extension/test/chat_panel.test.ts
Chat and shell webviews send clipboard-image-read requests to the extension host. Client-side navigator.clipboard.read handling was removed. Tests verify the relay behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ChatWebview
  participant ExtensionHost
  participant NativeClipboard
  ChatWebview->>ExtensionHost: Send clipboard-image-read
  ExtensionHost->>NativeClipboard: Read image with platform tools
  NativeClipboard-->>ExtensionHost: Return image data or null
  ExtensionHost-->>ChatWebview: Send clipboard-image metadata
Loading

Suggested reviewers: aarontrowbridge, gennadiryan

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/image-paste-webview

Comment @coderabbitai help to get the list of available commands.

@jeonghun-jj-lee
jeonghun-jj-lee merged commit c54fd47 into main Aug 25, 2026
5 of 8 checks passed
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