Repository navigation
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
My-Denia
force-pushed
the
fix/738-copy-message-windows-clipboard
branch
2 times, most recently
from
September 25, 2026 15:41
f701ab6 to
f74e0ad
Compare
…dows Electron denies the renderer's navigator.clipboard.writeText (NotAllowedError: Write permission denied — the renderer never holds clipboard-sanitized-write), so the chat panel's Copy message button always fell to its error toast and the clipboard kept its old content, in dev and packaged builds alike (issue getopenscreen#738). Route the write through a narrow preload bridge into main's clipboard module, which has no such permission gate: ipcMain.handle receives the text (string-checked), the preload exposes copyToClipboard, and the panel prefers the bridge while keeping the navigator path for shim/web contexts without one. Toasts and message content are unchanged. The regression test pins the distinguishing case: a navigator clipboard that rejects exactly the way Electron's does, with the bridge available — the old handler fails it, the new one copies the full message and reports success.
My-Denia
force-pushed
the
fix/738-copy-message-windows-clipboard
branch
from
September 25, 2026 16:37
f74e0ad to
a129322
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes getopenscreen#738. The AI chat panel's Copy message button always reported "Couldn't copy" on Windows: Electron denies the renderer's
navigator.clipboard.writeText(the renderer never holds theclipboard-sanitized-writepermission), so the write was rejected withNotAllowedError: Write permission deniedand the handler mapped every rejection to the generic error toast while the clipboard kept its old content. The behavior is identical in dev and packaged builds; on the packaged build the reporter saw the same failure.The fix
A narrow clipboard-write bridge following the repo's existing preload/IPC patterns:
electron/ipc/handlers.ts:ipcMain.handle("clipboard:write-text", …)— string-checked, writes with Electron's main-processclipboardmodule (no permission gate there;main.tsalready uses this API for the update dialog).electron/preload.ts:copyToClipboard(text)exposed through the existingelectronAPIbridge.electron/electron-env.d.ts: optionalcopyToClipboard?declaration, mirroringbenchFinished?.src/components/ai-edition/LeftPanel.tsx: the copy handler prefers the bridge and keeps thenavigator.clipboard.writeTextfallback for shim/web contexts without it. Toasts and semantics are unchanged.No clipboard framework, no chat data-model change, no UI redesign. The only other clipboard paths (Edit-menu roles, the update-dialog copy) are untouched.
Regression evidence (old FAIL / new PASS)
src/components/ai-edition/LeftPanel.copyMessage.test.tsxstubs the navigator clipboard to reject exactly the way Electron's does, with the bridge available, and asserts the bridge receives the exact message content plus the success toast:upstream/main(commit cef9be0): the distinguishing test fails — the click routes to the denied navigator and shows the error toast;Checks on the branch:
npx tsc --noEmitandnpx tsc -p tsconfig.test.json --noEmitboth clean; Biome clean on the touched files (repo-rootnpm run linthits a pre-existing nested-root configuration error on this machine, reproducible on pristinemain); the full unit suite shows exactly the same set of pre-existing local-environment failures with and without this change — the branch adds the regression test and zero new failures.Real-machine verification (Windows 11, computer-use driven)
main(dev build): Copy message click → the localized "Couldn't copy" error toast, clipboard unchanged (sentinel read-back), root cause captured as theNotAllowedErrorabove via a temporary uncommitted diagnostic.electron-builder --win --dir,Openscreen.exe,file://renderer): provider connected through the settings UI, chat turn completed, Copy message → "Copied to clipboard" toast and byte-exact clipboard for both messages.One honest limit: an assistant message with empty content renders a zero-height bubble whose footer buttons are not exposed to the accessibility tree, so the empty-content case could not be clicked end to end. Its semantics ride the same unconditional write path (no content-dependent branch) and the unit test pins exact content pass-through; the baseline has the identical rendering behavior.
Intent
Opened against the fork for review; ready for an owner decision before any upstream submission (per the standing rule, no upstream PR will be created without explicit approval).