Skip to content

feat(desktop-gpui): native GPUI desktop client - #209

Draft
yordis wants to merge 14 commits into
mainfrom
yordis/feat-gpui-desktop
Draft

yordis wants to merge 14 commits into
mainfrom
yordis/feat-gpui-desktop

Conversation

@yordis

@yordis yordis commented Nov 5, 2026

Copy link
Copy Markdown
Member

Electron ships Node and Chromium with every desktop install. This adds apps/desktop-gpui, a native Rust client built on GPUI that is meant to replace apps/desktop over time without embedding either.

What it does so far:

  • Starts the T3 server as a child process with the same fd 3 bootstrap Electron uses, exchanges the bootstrap token for a session, and opens the RPC WebSocket with ping and reconnect. It can also attach to an already running server with a one-time pairing token (vp run dev:desktop-gpui).
  • Wire types are generated, not hand-written: packages/contracts/schema/rpc.schema.json is generated from the Effect schemas, and src/wire/generated.rs is generated from it with typify. A test fails when the committed file is stale.
  • Main screen skeleton from the live orchestration.subscribeShell stream: a sidebar with the web's sections and sort order (Working, Snoozed and Settled shelves), so rows no longer reorder on every status change.
  • Empty-state project picker that follows the web: grouping by repository, pinning, environment badges, "start without a project", tooltips and the combobox popup sizing.

Known gaps, tracked for follow-up: no openScratch RPC yet, no keybindings, the composer is static, and CI does not build the crate yet (GPUI needs a macOS runner or Linux system libraries). Reading the Electron app's saved credentials is a stopgap marked TODO(gpui-credentials) and must be replaced before this ships.

yordis added 12 commits November 4, 2026 22:49
… the server

A native client lets us replace Electron without shipping Chromium or a
Node runtime: the app launches the server with the user's Node, the same
bootstrap handshake Electron uses, so no pairing is needed.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Hand-porting 212 RPC methods to Rust would drift from the TypeScript
contracts. Export a JSON Schema from WsRpcGroup, check it for drift in CI,
and generate the Rust types from it so the native client decodes the
shell subscription with the same shapes the server sends.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…g token

Spawning a second server on a home that another server already owns would race it on the same database. Attaching with a pairing token lets the native client show a running server's data, and it is the same path remote and tunnel servers will need.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
A status line can't show whether the generated types hold up against real data. gpui-component supplies native inputs, buttons and theming, so the sidebar, empty state and composer render without a webview. That requires the crates.io gpui-pre build it targets.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Rows were a fixed 60px holding three lines, so the project name was cut off, and status tags pushed past the sidebar edge on long titles. The header also floated to the middle of the main area.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
The heading named a fixed project with no way to change it. Match the web empty state: the project name opens a picker, and the start-without-a-project link shows its shortcut.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
The hero picker lists projects the way the web does: pinned first, then by recent activity, with the active project leading, colored initials, and a search filter.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…eady

Hover a picker row to pin or unpin the project through projects.mutate, gated on the server's projectOrganization capability. The picker keeps its order while open and the default project no longer follows thread activity, so rows and the heading stop jumping. The project name is plain heading text that underlines on hover, and the composer gains the attach button.

Catalog icons beyond gpui-component's defaults rendered blank, so the app now embeds the extra icons it uses.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…ronments

The picker listed every project on its own and never showed which other machines had a project, so it disagreed with the web.

Projects now group by repository the way the web's default mode does, with the same label and icon rules, and pinning a group pins every member. Saved environments from the Electron app's connection catalog are read, so a project that also exists elsewhere gets the "Also on" badge. Reading Electron's catalog and DPoP key is a stopgap marked TODO(gpui-credentials) until this app has its own pairing.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Rows were sorted by updatedAt, which the server bumps on each status change, so the list jumped while agents worked.

The list now follows the web sidebar's default sections and anchors: pinned and active threads first, then collapsible Working, Snoozed and Settled shelves, each sorted the way the web sorts it.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Tooltips used gpui-component's default text-sm and a key chip, and the "or start without a project" link stayed muted on hover.

Tooltips now use the web TooltipPopup sizing with the shortcut as plain text, and the link is medium weight and turns foreground with an underline on hover, like the web's muted InlineButton.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis added the ignore label Nov 5, 2026
@github-actions github-actions Bot added size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Nov 5, 2026
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…er strip match the web

The desktop shell should feel identical to the web app, so the sidebar, composer and context strip follow the web's layout, breakpoints and data.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

This branch has not been deployed

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

Labels

ignore size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant