Skip to content

App share: the Share dialog opens only on the device whose page asked - #776

Merged
localrivet merged 1 commit into
mainfrom
fix/share-dialog-origin-device
Oct 9, 2026
Merged

localrivet merged 1 commit into
mainfrom
fix/share-dialog-origin-device

Conversation

@localrivet

Copy link
Copy Markdown
Contributor

The Share dialog for an app's file now opens only on the device whose page asked for it. Before this change, a share made in an app on the mobile app or the web app also opened the dialog on the desktop.

Root cause. POST /apps/{id}/share (nebo.share) sent app_share_requested to every client with no origin on it. Each client's listener then set shareRequest, focused its window, moved to the app's chat, and opened the dialog. The page's request carried no client id: the SDK sends only thread, and the desktop's neboapp:// proxy drops headers such as X-Nebo-Client. This was also the path an app's page uses to answer a #775 "Share a link" request. The other #775 path, where the reply hands over a file, was already local to the device that picked the entry (linkAsk).

Fix: one origin rule (EventOrigin / opensHere)

  • The app page is opened with ?client=<clientId> beside ?thread= (apps/launcher.ts, for both the Tauri window and the browser popup). A window left from before a reload of the main window is reopened, so its page names the current client.
  • nebo.share (app-sdk nebo.share names the device the page is open on app-sdk#10, bundle copied to app/static/sdk/nebo.global.js) sends client in the request body, beside thread. The body survives the neboapp:// proxy and the tunnel.
  • share_file stamps the event with EventOrigin { client_id, session_id: thread } through the new share_requested_event.
  • The desktop and web listener goes through shareRequestOf, which uses opensHere(data, 'nowhere'). Only the client whose page asked sets the request, focuses its window and opens the dialog. A share that no client claims opens nowhere; the file is still in Work. Other clients still see the thread as usual.
  • The SDK reference (sdk-more.md) now says where the dialog opens.

The mobile app has a matching change in NeboLoop/nebo-mobile: the app page carries the mobile app's client id, and the Share link screen opens only for its own client.

Tests

  • cargo test -p nebo-server --lib share_tests: the event names the client whose page asked (phone B or desktop A). A page that names no client gives client_id: null. A body from an older SDK still parses.
  • vitest stores/appShare.test.ts: a share started from client B (the phone) gives no request on A. A share started from A opens on A. An unclaimed share opens nowhere. A malformed event opens nothing.
  • vitest apps/launcher.test.ts: the page is opened with thread and client=<clientId>.
  • Also run: cargo test -p nebo-tools --lib app_studio, cargo build -p nebo-cli, pnpm check (0 errors), pnpm build.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HtFKzcuyNHcb9tJBW1tz3e

nebo.share broadcast app_share_requested to every client with no origin,
so the desktop came forward and opened the Share dialog for a share made in
the app on the phone or the web app (and for a #775 "Share a link" the page
answered there). The app page now opens with ?client=<clientId> beside
?thread=; the SDK sends it as `client` (NeboLoop/app-sdk#10; the body
survives the neboapp:// proxy and the tunnel); share_file stamps the event
with EventOrigin; the listener opens only through opensHere(data,
'nowhere'). An unclaimed share opens nowhere; the file is in Work either way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HtFKzcuyNHcb9tJBW1tz3e
@localrivet
localrivet merged commit 786750f into main Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant