Skip to content

feat(desktop): attach to a running local backend - #8115

Open
Pedro-Revez-Silva wants to merge 6 commits into
pingdotgg:mainfrom
Pedro-Revez-Silva:fix/desktop-attach-running-backend
Open

feat(desktop): attach to a running local backend#8115
Pedro-Revez-Silva wants to merge 6 commits into
pingdotgg:mainfrom
Pedro-Revez-Silva:fix/desktop-attach-running-backend

Conversation

@Pedro-Revez-Silva

@Pedro-Revez-Silva Pedro-Revez-Silva commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

What Changed

Packaged Desktop now discovers a live same-machine background service or t3 serve runtime and attaches to it instead of starting a second backend. The attachment uses a process-scoped grant to establish an administrative Desktop session while continuing to serve the renderer bundled with the installed app.

Desktop development remains isolated. Settings → Connections exposes an opt-out, reports the attached state, and leaves network-exposure controls with the server that owns them.

Attached backends are rediscovered after a restart or port change. Transient failures are retried silently; persistent secure-pairing failures offer Try Again, Start Separate Backend, Open in Browser, or Quit. Starting separately uses isolated state for that launch.

The background-service user documentation now covers Desktop attachment, ownership, recovery, and the escape hatch.

Why

A headless T3 Code server can be the durable environment used from web and mobile, but opening Desktop on the same machine currently creates a separate environment with different threads and settings. Desktop should be able to act as another client for the existing local environment without weakening development isolation or silently falling back when secure attachment fails.

Starting-point proposal: #8114

UI Changes

Before

Desktop manages its own backend, so Connections begins with its network controls and has no running-server attachment state.

Connections on main before running-server attachment

After

Desktop is attached to the disposable local server. The page shows the attachment control and makes network exposure read-only because the external server owns it.

Connections after attaching to a running local server

Service restart recovery

The attached server stops, Desktop retries and reloads its bundled renderer, and the same thread returns automatically without a decision dialog.

reconnect-recovery.mp4

Verification

  • Focused Desktop tests: 618 passed
  • Focused server tests: 55 passed
  • Focused web tests: 16 passed
  • Typechecks passed for Desktop, server, web, contracts, and shared
  • Targeted lint, formatting, and git diff --check passed
  • Production Desktop build passed
  • Packaged Desktop manually verified against a disposable background server: secure attachment, retained thread state, restart rediscovery, silent retry, automatic recovery, and persistent-failure UX

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Implemented and reviewed with GPT-5.6 through the Codex harness in T3 Code.


Note

High Risk
Changes desktop startup, OAuth pairing, and server auth grants for local attachment; mis-handling could spawn duplicate backends or fail secure reconnection in production.

Overview
Packaged Desktop can attach to an already-running local T3 Code server (background service or t3 serve) instead of always spawning its own backend, so the same environment can be used from Desktop without a duplicate process.

Discovery reads server-runtime.json (and systemd/launchd T3CODE_HOME hints), validates the server via /.well-known/t3/environment, and pairs with a new per-process desktopAttachToken exchanged for a bearer session. The server seeds that token in PairingGrantStore and persists it in runtime state; Desktop uses manageProcess: false with HTTP health watching, invalidates stale attachments on loss, and can reload the bundled renderer (local protocol handler) while API traffic goes to the attached origin. Development never auto-attaches; a new attachExistingLocalBackend setting (default on) plus IPC exposes attachment state and relaunches on toggle.

Bootstrap and runtime recovery add dialogs: retry pairing, start a separate backend (isolated desktop-independent home + port scan via extracted DesktopBackendPort), open in browser, or quit. The backend pool retries pairing silently before offering “start separate” on persistent failures.

Reviewed by Cursor Bugbot for commit ed06cc2. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add Desktop app support for attaching to a running local backend

  • Desktop boot discovers an existing local backend (systemd/launchd) and pairs with it using a desktopAttachToken, avoiding a second server spawn
  • New IPC channels getExistingLocalBackendState and setAttachExistingLocalBackend let the renderer query and toggle attachment; toggling relaunches the app
  • DesktopBackendManager gains an attached-runner mode (manageProcess: false) with health probes every 2s and callbacks for configuration failure and unexpected shutdown
  • Connections settings page renders an 'Attach to running server' switch; effective auth scopes stay administrative until an attached session resolves
  • ElectronProtocol serves the bundled renderer locally when rendererRoot is set, with MIME types, CSP, and path-traversal protection, instead of proxying from the attached server
  • PairingGrantStore seeds a reusable admin grant (100-year TTL) from the configured desktopAttachToken; server runtime state is persisted with file mode 0600
  • Auth layer (DesktopLocalEnvironmentAuth, desktopAuth) caches bearer tokens keyed by URL + token + authSessionKey and reuses the attached token without a bootstrap exchange
  • Recovery dialogs on pairing failure offer retry, start separate backend, open in browser, or quit; after 4 auto-retry attempts on ExistingLocalBackendPairingError the pool prompts the user
  • Risk: new DesktopBackendConfiguration interface members (resolveExistingLocalBackend, invalidateExistingLocalBackendAttachment, useIndependentBackendForLaunch) require all implementations and test mocks to provide them; DesktopSettings defaults attachExistingLocalBackend to true, so existing users without the key will begin attaching on next launch

Macroscope summarized ed06cc2.

Detect an already-running T3 Code server on this machine and connect
the desktop app to it instead of spawning a second environment.
The behavior is on by default and can be toggled in Settings →
Connections.
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9349159a-765e-4c5d-9284-813da4a94da7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 24, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new attach-to-running-backend Effect code against the service conventions. Three violations in the changed scope: a wrapped failure that loses its cause and rebuilds its message from cause.message, and two Effect.catchTag uses that should be Effect.catchTags. Dependency passing (fileSystem/path/httpClient in input objects) matches the established pattern in this package, so it is not flagged.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/desktop/src/backend/DesktopBackendConfiguration.ts Outdated
Comment thread apps/desktop/src/backend/DesktopExistingLocalBackend.ts Outdated
Comment thread apps/desktop/src/backend/DesktopBackendManager.ts Outdated
Comment thread apps/web/src/environments/primary/desktopAuth.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff0be38fb6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/backend/DesktopBackendConfiguration.ts Outdated
Comment thread apps/desktop/src/backend/DesktopExistingLocalBackend.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ff0be38. Configure here.

Comment thread apps/desktop/src/backend/DesktopBackendPool.ts
@macroscopeapp

macroscopeapp Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR introduces a default-on local-backend attachment workflow spanning Desktop startup, server authentication grants, bearer-session handling, IPC/contracts, recovery, and the Connections UI. Its cross-cutting runtime and security-sensitive behavior requires human review.

You can add or adjust custom eligibility rules. Learn more.

Comment thread apps/desktop/src/backend/DesktopExistingLocalBackend.ts Outdated
Comment thread apps/desktop/src/backend/DesktopExistingLocalBackend.ts

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

UI Consistency: 1 issue found

One concrete regression in the changed Connections settings scope: a failed attachment-state IPC call silently removes existing desktop backend controls instead of degrading to a visible, recoverable state.

Everything else in scope looks consistent — the new row uses the shared SettingsRow + Switch primitives with an aria-label, no primitive geometry/focus-ring overrides, and the search catalog entry is registered via searchableSetting with desktopOnly.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/ConnectionsSettings.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two compatibility re-export shims were introduced while moving declarations to their new canonical modules. Conventions ask that the moved declaration have a single canonical path with every consumer updated mechanically, rather than leaving a re-export behind.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/desktop/src/app/DesktopApp.ts Outdated
Comment thread apps/server/src/cloud/bootService.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding on the new Connections row: the attach toggle immediately relaunches Desktop, but nothing in the row says so and there is no confirmation, unlike the equally consequential "WSL only" switch in the same section.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/ConnectionsSettings.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding on the changed session-scope derivation in ConnectionsSettings.tsx. The rest of the new attach row (shared SettingsRow + Switch, searchableSetting title/anchor, restart wording, load-failure fallback) matches the existing Connections patterns.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/ConnectionsSettings.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant