Skip to content

[Feature]: Attach files by drag-and-drop and paste clipboard images into the chat composer on Orca Remote Server panes #12572

Open

Description

@mattbkiv

Problem or use case

Setup: Orca desktop 1.4.168 on Windows, paired to a headless orca serve runtime (v1.4.162) on a Linux VPS. Agent sessions run on the VPS; my files and screenshots are on the Windows machine.

In a runtime-owned (remote:) chat pane I cannot get local content to the agent:

  • Dragging a file from Windows Explorer onto the chat composer does not attach it.
  • Pasting a screenshot from the clipboard into the composer does nothing.

The only path is landing the file on the server out of band (scp, synced folder) and then typing the server-side path into the prompt. In practice that friction means the screenshot simply does not get sent and the agent works from a typed description instead. The cost is information loss, not keystrokes — I hit exactly this while diagnosing a rendering bug, where a re-typed fragment silently turned a newline into a space and sent the diagnosis down the wrong path for a while.

From the source this looks like a known, deliberate gap rather than a bug. resolveNativeChatAttachmentOwner in src/renderer/src/components/native-chat/native-chat-attachment-upload.ts returns { kind: 'runtime' } for runtime-owned panes, with the comment:

Runtime-owned (remote:) panes keep the composer's existing local-attachment block; runtime upload support is a separate seam.

The neighbouring transports are already handled: local panes attach directly, and SSH panes save the clipboard image on the remote host over SFTP (saveClipboardImageAsTempFile({ connectionId })) so the attached path names a file the remote agent can actually read.

Proposed solution

Implement that runtime upload seam for the desktop composer, so all three attach surfaces work on runtime-owned panes:

  • file drag-and-drop onto the composer,
  • the file picker,
  • clipboard image paste.

In each case: upload the bytes to the runtime over the existing pairing channel, write them to a temp location inside the workspace, and attach or insert the runtime-side path — the same end state the SSH path already produces.

The transport exists in at least one client already: Orca Mobile uploads images into a runtime-owned native chat session today (mobile/src/session/mobile-native-chat-image-attachment.ts, use-mobile-native-chat-image-attachments.ts). It is the desktop renderer that blocks.

Worth settling as part of this:

  • per-file and aggregate size limits for client-originated bytes,
  • what happens when the pairing connection drops mid-upload — a visible failure, not a silent no-op,
  • retention and cleanup of uploaded temp files,
  • whether arbitrary file types are inserted as @path references while images become attachment chips, matching local-pane behaviour.

Alternatives or additional context

Current workaround: paste the image into a GitHub comment box without submitting it — GitHub uploads on paste and hands back a URL — then give the agent that URL to fetch. It works from any machine and needs no file transfer, but it routes private screenshots through GitHub, so it is not usable for anything sensitive.

Related:

Activity

  1. mattbkiv commented on Aug 6, 2026

    @mattbkiv
    Author

    Two refinements to the report above, from a live 1.4.168 desktop ↔ 1.4.162 orca serve (Linux VPS) pairing.

    The runtime upload path already ships — for terminal panes

    Pasting a clipboard screenshot into a terminal view on a runtime-owned pane, from the Windows desktop client, uploads the image to the VPS and references it in the prompt as [Image #1] linked to the runtime-side file. Confirmed server-side: /tmp/orca-paste-<epoch-ms>-<uuid>.png, five such files present, most recent 2026-08-05 07:45:13 UTC.

    So this request is narrower than I originally framed it. The client→runtime image upload exists and works over this exact transport today. What is missing is the composer being wired to it.

    "Pasting does nothing" was imprecise — the two composer entry points fail differently

    • Drag-and-drop a file onto the composer → visible notice: "Local attachments are not available for remote sessions."
    • Clipboard image paste → no feedback at all.
    • Clipboard text paste into the same composer → works normally.

    Text ruling out the obvious: the composer is focused, enabled and receiving paste events. The failure is image-specific.

    In the v1.4.162 bundle both attach entry points converge on the same guard:

    attachResolvedPaths: (paths) => {
      const target = resolveTarget();
      if (!target || nativeChatComposerTargetIsRemote(target.ptyId)) {
        setNotice("Local attachments are not available for remote sessions.");
        return;
      }

    with nativeChatComposerTargetIsRemote(ptyId) = isRemoteRuntimePtyId(ptyId). Since drag-and-drop reaches that notice and paste does not, the paste path is bailing before the guard. Of the branches in useNativeChatComposerPaste.handlePaste, only two return without setting a notice: clipboardEventHasImage(event) === false, and saveClipboardImageForOwner returning { status: "empty" }. The "unsupported for this agent" branch and the thrown-error branch both do set one.

    The first of those two is also consistent with text working, since it returns without calling event.preventDefault() and lets the browser's default paste run.

    Caveat on that paragraph: the code is from the 1.4.162 bundle running on the server; the observations are from the 1.4.168 desktop client, which I can't inspect from here.

    Smallest fix for the main request

    Visible in the same paste handler:

    saveClipboardImageAsTempFile(owner.kind === "ssh" ? { connectionId: owner.connectionId } : undefined)

    SSH owners get a destination; runtime owners get undefined, so the image is saved client-local and the guard then correctly refuses it. Giving { kind: "runtime" } owners a runtime-side destination — the same one terminal paste already uses — and letting those resolved paths through the guard would cover the clipboard-image half of this issue.

    Worth fixing regardless of the feature: a composer paste that cannot attach should say so. The drag-and-drop string already exists.

  2. added a commit that references this issue on Sep 1, 2026
    b41a874
  3. OrcaWin commented on Oct 10, 2026

    @OrcaWin
    Collaborator

    Partly fixed: #25146 lets structured chats on a paired server take dropped and pasted files. Terminal-backed chats on a runtime-owned worktree still refuse them (src/renderer/src/components/native-chat/native-chat-attachment-upload.ts:59-62 and :121), since their agent can run on a host the server's attachment store can't reach. Leaving this open for that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions