Repository navigation
feat: paste an image or files into a native text area with desktop_insert, or leave the clipboard replaced on request - #99
Merged
Conversation
This was referenced Oct 17, 2026
iamnbutler
force-pushed
the
feat/insert-attachments
branch
from
October 17, 2026 08:15
3bb074b to
80194e3
Compare
…sert, or leave the clipboard replaced on request (#3)
iamnbutler
force-pushed
the
feat/insert-attachments
branch
from
October 17, 2026 08:48
80194e3 to
686170a
Compare
This was referenced Oct 17, 2026
Merged
iamnbutler
added a commit
that referenced
this pull request
Oct 20, 2026
… (#167) * native2: background paste preparation, and file-dialog path entry Pastes into an inactive app first make its window key with a SkyLight activation record and a routed title-bar click, as Peekaboo does; desktop_dialog_answer path enters a folder and name in an Open or Save panel. Why: native2/Sources/DesktopMac/BackgroundPreparation.swift | TextEdit and Finder drop a background Command-V unless the window is key; #99 passed earlier only because TextEdit happened to be frontmost Why: native2/Sources/DesktopMac/Dialogs.swift | a sheet (and Go to Folder inside it) holds keyboard focus itself, so the focused window can be a sheet inside the dialog's window * lane: sync finder-paste memory * lane: confirm the dialog prefix note
iamnbutler
added a commit
that referenced
this pull request
Oct 20, 2026
) * native2: select web text by text markers; refuse an unverifiable paste receiver before checking focus Why: native2/Sources/DesktopMac/WebText.swift | Safari on macOS 27 dropped AXStart/EndTextMarkerForTextMarkerRange; bounds(of:) reads both ends from the AXTextMarkerRange itself Why: native2/Sources/DesktopMac/Paste.swift | the receiver check comes before requireKeyboardFocus so a background web field gets PASTE_UNVERIFIABLE_RECEIVER, as on Node, not a focus refusal * lane: sync web-select memory * lane: notes
Merged
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.
Part of #3.
desktop_insertcan now paste an image or files through a temporary clipboard, with the same restore rules as text.Request
format: "image"with one absolutepath(PNG, JPEG or TIFF, at most 10 MiB and 64 MP; original bytes and type are kept), orformat: "files"with 1–32 absolutepaths.textorroutein that form.clipboard:"restore"(the default) or"replace".Route, fixed before any input
restore) pastes only into a focusedAXTextAreathat meets both conditions:TextInputRoute.resolve(container:) == .nativeAX, so not web content or Electron);PASTE_UNVERIFIABLE_RECEIVER. The hint offersclipboard: "replace", ordesktop_clipboard_writefollowed by Command-V.Observed consumption
AXAttributedStringForRangemarks any of those characters withAXAttachment, it must mark all of them (attachment_evidence: "attachment_attribute"). If it marks none, or can't be read, the replacement characters and caret decide ("replacement_characters"). A partly marked range does not count.clipboard: "replace"clipboard_cleanup: "left_replaced". The result iscompletedonly if the expected edit is observed; otherwise it isunknownwithINSERTION_UNVERIFIED. The hint says to inspect before the next clipboard write, because a pending Command-V pastes whatever the clipboard holds then.Native (
peekaboo-attachment-insert.patch, appended last)insertLiteralTextbecomes one caller ofpasteThroughClipboard(write, expectation, replace, …). Text insertion behaves exactly as before; its predicate is theattachments: 0case.attachmentInsertBridge op (131 ops). It reuses the literal-insert response and descriptor.handleGuardedPaste.ClipboardWriteRequest(fileURLs:)writes onepublic.file-urlitem per path through the claimed temporary write.ClipboardService.prepareReplacingWrite()is added.PASTE_UNVERIFIABLE_RECEIVERmapping. Its action input limit rises to 14 MiB, for image insertions only.Docs: the tool description, the
docs/tools.mdrow and paragraph (which links the Finder copy recipe), and the patches README entry.Checks
npm run checkandnpm testpass (56 tests, 4 new).ClipboardAttachmentWriteTests: 3 new;ClipboardTemporaryWriteTests,ClipboardWriteRequestTests,ClipboardReadAccessTestsandClipboardPasteTransactionGateTests;PeekabooBridgeRequestPlanTests,PeekabooBridgeOperationSemanticPlanTestsandPeekabooBridgeOperationResultSemanticsTests, with the counts at 131.Follow-up (not in this PR): pasting files into a Finder folder, with a host-side filesystem predicate. Until then, use
desktop_clipboard_writewith files, then Command-V.