Skip to content

feat: use crossAppIPC to coordinate update ownership between apps#307675

Draft
deepak1556 wants to merge 3 commits intomainfrom
robo/cross_app_update
Draft

feat: use crossAppIPC to coordinate update ownership between apps#307675
deepak1556 wants to merge 3 commits intomainfrom
robo/cross_app_update

Conversation

@deepak1556
Copy link
Copy Markdown
Collaborator

Introduce CrossAppUpdateCoordinator that uses Electron's crossAppIPC
module to ensure only one update client runs at a time. Whichever app
(VS Code or Agents) launches first becomes the IPC server and owns the
update client. The second app becomes the IPC client, suspends its local
update service, and proxies all update operations to the server.

When the server app quits, the client detects the disconnect, resumes
its local update service, and takes over update ownership. Both apps
show synchronized update UI at all times. "Restart to Update" signals
the peer to quit before applying the update.

- Add crossAppIPC type definitions for custom Electron build
- Add CrossAppUpdateCoordinator (symmetric, role-based coordination)
- Add suspend()/resume() to AbstractUpdateService
- Simplify Agents update UI to use direct update actions

@deepak1556 deepak1556 added this to the 1.116.0 milestone Apr 3, 2026
@deepak1556 deepak1556 self-assigned this Apr 3, 2026
Copilot AI review requested due to automatic review settings April 3, 2026 17:10
@deepak1556
Copy link
Copy Markdown
Collaborator Author

flowchart TD
    subgraph "App A (launched first)"
        A_LOCAL["Platform Update Service<br/>(Darwin / Win32)"]
        A_COORD["CrossAppUpdateCoordinator<br/>mode: server ∣ standalone"]
        A_CHANNEL["UpdateChannel<br/>(to renderer)"]
        A_UI["Update UI"]

        A_LOCAL -- "onStateChange" --> A_COORD
        A_COORD -- "onStateChange" --> A_CHANNEL
        A_CHANNEL --> A_UI
        A_UI -- "downloadUpdate / quitAndInstall" --> A_COORD
        A_COORD -- "direct call" --> A_LOCAL
    end

    subgraph "App B (launched second)"
        B_LOCAL["Platform Update Service<br/>(Darwin / Win32)<br/>⏸ suspended"]
        B_COORD["CrossAppUpdateCoordinator<br/>mode: client"]
        B_CHANNEL["UpdateChannel<br/>(to renderer)"]
        B_UI["Update UI"]

        B_COORD -- "onStateChange" --> B_CHANNEL
        B_CHANNEL --> B_UI
        B_UI -- "downloadUpdate / quitAndInstall" --> B_COORD
    end

    A_COORD -- "StateChange /<br/>InitialState /<br/>QuitForUpdate" --> IPC
    IPC -- "CheckForUpdates /<br/>DownloadUpdate /<br/>QuitAndInstall" --> A_COORD
    B_COORD -- "CheckForUpdates /<br/>DownloadUpdate /<br/>QuitAndInstall" --> IPC
    IPC -- "StateChange /<br/>InitialState /<br/>QuitForUpdate" --> B_COORD

    IPC["crossAppIPC<br/>(Mach ports / named pipes)"]

    style B_LOCAL stroke-dasharray: 5 5, opacity: 0.5
    style IPC fill:#f9f,stroke:#333
    ```
Loading

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces cross-application coordination for update ownership between the VS Code app and the Agents app by adding a main-process coordinator that uses Electron’s custom crossAppIPC to ensure only one update client performs checks/downloads while both apps stay UI-synchronized.

Changes:

  • Added CrossAppUpdateCoordinator (new crossAppUpdateIpc.ts) to proxy update operations/state between two running apps via crossAppIPC.
  • Added suspend()/resume() to AbstractUpdateService and removed prior “embedded app” update special-casing from win32/darwin update services.
  • Simplified Agents (Sessions) update UI action handling and added Electron cross-app IPC type definitions.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/vs/sessions/contrib/accountMenu/browser/account.contribution.ts Removes the “open VS Code to update” flow; uses direct update actions (download/apply/restart).
src/vs/platform/update/electron-main/updateService.win32.ts Removes embedded-app branching for update detection/download state.
src/vs/platform/update/electron-main/updateService.darwin.ts Removes embedded-app branching and simplifies “no auto-download” check path.
src/vs/platform/update/electron-main/crossAppUpdateIpc.ts Adds the cross-app IPC coordinator implementing IUpdateService.
src/vs/platform/update/electron-main/abstractUpdateService.ts Adds suspend()/resume() gating to prevent checks when another app owns updates.
src/vs/code/electron-main/app.ts Wraps the main-process update channel with CrossAppUpdateCoordinator.
src/typings/electron-cross-app-ipc.d.ts Adds typings for the custom Electron crossAppIPC feature.
build/lib/electron.ts Changes Electron build config tag to a hard-coded value (problematic).

@deepak1556
Copy link
Copy Markdown
Collaborator Author

Sequence where both apps are active and primary update owner remains the same

sequenceDiagram
    participant A as App A (first)
    participant IPC as crossAppIPC
    participant B as App B (second)

    Note right of A: Launches and calls ipc.connect()
    Note right of A: Standalone mode

    B->>IPC: ipc.connect()
    IPC-->>A: connected (isServer=true)
    IPC-->>B: connected (isServer=false)
    Note right of A: Becomes server
    Note left of B: Becomes client
    Note left of B: localService.suspend()
    A->>IPC: InitialState(currentState)
    IPC-->>B: updateState()

    Note over A,B: Both apps show same update UI

    B->>IPC: CheckForUpdates(explicit)
    IPC-->>A: localService.checkForUpdates()
    A->>IPC: StateChange(Downloading)
    IPC-->>B: updateState(Downloading)
    A->>IPC: StateChange(Ready)
    IPC-->>B: updateState(Ready)

    Note over A,B: User clicks Restart to Update

    alt Clicked in App A (server)
        A->>IPC: QuitForUpdate
        IPC-->>B: lifecycleMainService.quit()
        Note right of A: localService.quitAndInstall()
    else Clicked in App B (client)
        B->>IPC: QuitAndInstall
        Note left of B: lifecycleMainService.quit()
        IPC-->>A: localService.quitAndInstall()
    end
  
Loading

@deepak1556
Copy link
Copy Markdown
Collaborator Author

Sequence where ownership changes while being active

sequenceDiagram
    participant A as App A (server)
    participant IPC as crossAppIPC
    participant B as App B (client)

    Note over A,B: Ownership handoff when server quits normally

    Note right of A: User closes App A
    A->>IPC: disconnect
    IPC-->>B: disconnected (peer-disconnected)
    Note left of B: localService.resume()
    Note left of B: Now owns update client
    Note left of B: Reconnects to wait for peer

    Note left of B: App B is now standalone

    rect rgb(240, 240, 255)
        Note left of B: Later App A relaunches
        A->>IPC: ipc.connect()
        IPC-->>B: connected (isServer=true)
        IPC-->>A: connected (isServer=false)
        Note left of B: Stays server
        Note right of A: Becomes client
    end
   
Loading

Introduce CrossAppUpdateCoordinator that uses Electron's crossAppIPC
module to ensure only one update client runs at a time. Whichever app
(VS Code or Agents) launches first becomes the IPC server and owns the
update client. The second app becomes the IPC client, suspends its local
update service, and proxies all update operations to the server.

When the server app quits, the client detects the disconnect, resumes
its local update service, and takes over update ownership. Both apps
show synchronized update UI at all times. "Restart to Update" signals
the peer to quit before applying the update.

- Add crossAppIPC type definitions for custom Electron build
- Add CrossAppUpdateCoordinator (symmetric, role-based coordination)
- Add suspend()/resume() to AbstractUpdateService
- Simplify Agents update UI to use direct update actions
@deepak1556 deepak1556 force-pushed the robo/cross_app_update branch from e479068 to 406aea3 Compare April 3, 2026 17:36
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.

2 participants