fix: copy Studio agent prompts in Safari#536
Conversation
jrusso1020
left a comment
There was a problem hiding this comment.
LGTM — the structural fix is the actually-correct one.
Pre-loading agentPromptTagSnippet on selection (not on copy click) is the right shape — Safari's navigator.clipboard.writeText requires synchronous user activation, and the previous async fetch chain broke that even with the most permissive clipboard API. Race-safety on stale fetch via domEditSelectionRef.current !== selection guard is correct.
copyTextToClipboard has solid fallback ordering: Safari → execCommand textarea → async clipboard → execCommand. UA sniffing is fragile in principle, but the worst-case degradation is a Safari user falling back to async clipboard which usually works for direct-button-click flows. focus({ preventScroll: true }) is a nice detail. try/finally removes the textarea on error.
Test coverage in clipboard.test.ts exercises Safari path, non-Safari path, async-failure fallback, and both-paths-fail. @hyperframes/studio 278/278 pass locally.
— Review by Rames Jusso
vanceingalls
left a comment
There was a problem hiding this comment.
Staff review: approved.
Preloading the source snippet before submit is the important structural fix because it keeps Safari's copy operation tied to the user gesture. Routing the other copy affordances through the shared helper is also a good consolidation, and the error toast avoids the previous false-success behavior. I did not find any blocking issues.
d7e6a0c to
64d8b19
Compare
Problem
The Design panel's Ask agent flow could fail to copy prompts in Safari. The modal looked like it completed the action from the user's point of view, but Safari's clipboard permission is more tightly coupled to the original user gesture than Chromium's.
The submit handler was doing an async project-file fetch before calling
navigator.clipboard.writeText(). In Safari, that can lose the trusted click/key gesture by the time the copy runs, so the prompt never reaches the system clipboard.What this fixes
navigator.clipboard.writeText()first, avoiding the automation/system-clipboard mismatch from usingexecCommandtoo eagerly there.outerHTMLif the source snippet has not loaded yet.Root cause
The Design panel Ask agent submit path mixed two operations with different timing requirements: it fetched the project source asynchronously, then tried to copy the generated prompt. Safari can reject clipboard writes after that async boundary because the write is no longer directly attached to the user's click or
Cmd+Entergesture.The older fallback also only ran after
navigator.clipboard.writeText()failed, which is too late for Safari's stricter gesture handling in this flow. Moving source lookup ahead of the submit action and preferring a synchronous copy path in Safari keeps the actual copy inside the trusted interaction.Verification
Local checks
bun run --filter @hyperframes/studio test -- src/utils/clipboard.test.ts-> 4 tests passbun run --filter @hyperframes/studio test-> 23 files pass, 278 tests passbun run --filter @hyperframes/studio typecheckbun run --filter @hyperframes/studio buildbunx oxlint packages/studio/src/utils/clipboard.ts packages/studio/src/utils/clipboard.test.ts packages/studio/src/App.tsx packages/studio/src/components/LintModal.tsx packages/studio/src/player/components/EditModal.tsx packages/studio/src/components/sidebar/AssetsTab.tsx-> 0 warnings, 0 errorsbunx oxfmt --check packages/studio/src/utils/clipboard.ts packages/studio/src/utils/clipboard.test.ts packages/studio/src/App.tsx packages/studio/src/components/LintModal.tsx packages/studio/src/player/components/EditModal.tsx packages/studio/src/components/sidebar/AssetsTab.tsxgit diff --checkBrowser verification
safari-copy-agentproject.agent-browserto load Studio, select a layer from the preview into the Design panel, open Ask agent, enter an instruction, and run the copy flow.Make the headline larger, clickedCopy prompt, and verified the Design panel changed toPrompt copied.pbpaste; it contained the generated## HyperFrames element edit request v1prompt and the typed instruction.Notes
qa-artifacts/safari-copy-agent/and are intentionally not committed.pbpastefor clipboard verification. The agent-browser recording covers the same Studio flow in the required automation path.