Skip to content

feat(clipboard): implement GFN paste protocol - #583

Merged
zortos293 merged 2 commits into
devfrom
capy/feat-gfn-clipboard-paste
Jul 3, 2026
Merged

feat(clipboard): implement GFN paste protocol#583
zortos293 merged 2 commits into
devfrom
capy/feat-gfn-clipboard-paste

Conversation

@zortos293

@zortos293 zortos293 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

This PR implements official-style clipboard paste for OpenNOW using the GFN PASTE custom-message protocol over the data channel, with client-side availability advertisement and server request/response handling that mirrors the official JavaScript client's behavior.

  • Added src/renderer/src/gfn/clipboardProtocol.ts implementing the GFN PASTE custom-message envelope, CLIENT_ADDED_DATA/CLIENT_REMOVED_DATA/CLIENT_DATA_RESPONSE and SERVER_DATA_REQUEST message types, trace ID generation, and UTF-8 byte size clamping.
  • Added src/renderer/src/gfn/clipboardProtocol.test.ts with 3 test cases validating message construction and parsing.
  • Integrated clipboard availability advertisement in src/renderer/src/gfn/webrtcClient.ts via setClipboardPasteEnabled and refreshClipboardAvailability, and server data request handling in onControlChannelMessage, with control channel open/close lifecycle hooks.
  • Updated src/renderer/src/App.tsx to call client.pasteClipboardText() before falling back to sendText/sendPasteShortcut, and pass clipboardPaste/readClipboardText options to the client, with runtime setting changes propagated via setClipboardPasteEnabled.

Verification

  • npm test -- clipboardProtocol (3 tests pass, 148 total)
  • npm run typecheck (no errors)
  • npm run lint (0 errors, 35 pre-existing warnings unrelated to this change)

Open OPE-242 OPE-242


Note

Medium Risk
Changes streaming paste behavior and sends clipboard content over the control channel when enabled, though it remains behind the clipboardPaste setting with legacy fallbacks.

Overview
Adds official GFN clipboard paste over the WebRTC control_channel using the PASTE custom-message protocol, so paste can follow the same request/response flow as the official client instead of only injecting text or simulating shortcuts.

A new clipboardProtocol module builds and parses the PASTE envelope (CLIENT_ADDED_DATA / CLIENT_REMOVED_DATA / CLIENT_DATA_RESPONSE / SERVER_DATA_REQUEST), generates trace IDs, and clamps clipboard text by UTF-8 byte size (with unit tests).

GfnWebRtcClient advertises clipboard availability when the control channel opens and on window focus, answers server data requests with host clipboard text, and exposes pasteClipboardText() (refresh availability then trigger paste). The clipboardPaste setting is passed in at connect and can be toggled live via setClipboardPasteEnabled.

App routes paste through client.pasteClipboardText() first, then falls back to sendText / sendPasteShortcut. Paste shortcut detection now ignores Shift and treats Ctrl/Cmd consistently; fallback paste shortcut always uses Ctrl.

Reviewed by Cursor Bugbot for commit eba0fd1. Configure here.

… behavior

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
@zortos293 zortos293 added the capy Generated by capy.ai label Jul 3, 2026 — with Image Capy AI
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f845c444-c983-49e5-ba73-b960c8ba9665

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch capy/feat-gfn-clipboard-paste

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

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit eba0fd1. Configure here.

const sentOfficialPaste = await client.pasteClipboardText();
if (sentOfficialPaste) {
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Oversized clipboard skips sendText

Medium Severity

When the control channel is open, pasteClipboardText returns true after sending the paste shortcut even if clampClipboardText rejected the clipboard (for example over clipboardMaxBytes). sendStreamClipboardPaste then exits early and never uses sendText, which previously could still inject the full local clipboard via chunked text input.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eba0fd1. Configure here.


await this.refreshClipboardAvailability();
return this.sendPasteShortcut(false);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty clipboard sends paste shortcut

Medium Severity

With an open control channel, pasteClipboardText always calls sendPasteShortcut and reports success, even when local clipboard text is empty after clampClipboardText. The old sendStreamClipboardPaste path returned after a successful read without injecting Ctrl+V when there was no text.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eba0fd1. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eba0fd1fc0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1074 to +1075
await this.refreshClipboardAvailability();
return this.sendPasteShortcut(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor unavailable clipboard before sending paste

When the official paste path is available but refreshClipboardAvailability() returns false (for example the local clipboard is empty, unreadable, or exceeds clipboardMaxBytes), this still sends Ctrl+V and reports success to sendStreamClipboardPaste(). That suppresses the existing text-input fallback and can cause the remote session to paste stale remote clipboard contents even though the client just advertised CLIENT_REMOVED_DATA; return false or skip the shortcut when no clipboard data is available.

Useful? React with 👍 / 👎.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
@zortos293
zortos293 merged commit 6730316 into dev Jul 3, 2026
16 checks passed
Chizuui pushed a commit to Chizuui/OpenNOW-Modified that referenced this pull request Aug 11, 2026
* Implement GFN-style clipboard paste protocol to match official client behavior

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Fix clipboard paste no-op when unavailable

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capy Generated by capy.ai

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant