Skip to content

fix(desktop): claim the t3code:// scheme default on Linux at startup - #5054

Open
juliusmarminge wants to merge 3 commits into
mainfrom
fix/linux-default-scheme-handler
Open

fix(desktop): claim the t3code:// scheme default on Linux at startup#5054
juliusmarminge wants to merge 3 commits into
mainfrom
fix/linux-default-scheme-handler

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary

Follow-up to #5015. Linux users still get the "Choose an application to open 't3code'" prompt on every OAuth callback (and Firefox flows keep failing), even though the scheme registration from #5015 shipped — the app now appears in the chooser but is never recorded as the default handler for x-scheme-handler/t3code.

Why the OS keeps prompting

Linux ships as an AppImage, so the integrated .desktop entry's filename is decided by whatever integration tool the user runs (AppImageLauncher names it appimagekit_<hash>-….desktop). Electron's app.setAsDefaultProtocolClient resolves the desktop id from setDesktopName (t3code.desktop), which can never match those files — so there is no reliable built-in way to claim the default.

The fix

On packaged Linux startup, the new DesktopLinuxUrlHandler service:

  1. Writes a dedicated t3code-url-handler.desktop into $XDG_DATA_HOME/applications (default ~/.local/share/applications) with Exec="$APPIMAGE" %U, MimeType=x-scheme-handler/t3code;, and NoDisplay=true. Pointing at $APPIMAGE matters: process.execPath lives in the transient /tmp/.mount_* squashfs (it is used only as a fallback outside an AppImage). Exec values use freedesktop quoting (% doubled, " ` $ \ escaped).
  2. Claims the scheme default via xdg-mime default t3code-url-handler.desktop x-scheme-handler/t3code — the same association the file manager's "set as default app" checkbox records in mimeapps.list.

Registration is best-effort: any failure (missing xdg-utils, read-only home) logs a warning and never blocks startup; the OS chooser remains as fallback. Re-running on every launch keeps the Exec path current when the AppImage moves, and lets whichever channel (stable/nightly) launched last own the scheme — matching macOS semantics.

Supporting changes: DesktopConfig reads XDG_DATA_HOME, and DesktopEnvironment exposes linuxApplicationsDir + appImagePath (already parsed from $APPIMAGE).

User impact

After updating and launching the app once, browser OAuth redirects open T3 Code directly — no chooser dialog in Chrome/Chromium, and Firefox shows its standard one-time confirmation with T3 Code preselected instead of failing.

Test plan

  • New DesktopLinuxUrlHandler.test.ts: desktop-entry rendering incl. Exec quoting, AppImage vs. executable fallback, xdg-mime invocation, platform/packaged gating, and that write/xdg-mime failures never fail startup
  • Full desktop suite passes (411 tests), typecheck clean

🤖 Generated with Claude Code


Note

Low Risk
Linux-only, packaged-only startup side effect with swallowed errors; no auth or shared-backend changes, though it modifies user mimeapps associations for the custom scheme.

Overview
Packaged Linux builds now register the custom t3code:// scheme as the OS default so OAuth redirects stop opening the “choose an application” dialog on every callback.

A new DesktopLinuxUrlHandler service runs during startup (after Electron is ready): it writes a hidden t3code-url-handler.desktop under the XDG applications dir (from XDG_DATA_HOME, default ~/.local/share/applications) with Exec pointing at $APPIMAGE (not the transient /tmp/.mount_* process.execPath), then runs xdg-mime default for x-scheme-handler/t3code. This sidesteps Electron’s setAsDefaultProtocolClient, which cannot match AppImageLauncher-generated desktop entry names.

Registration is best-effort—write or xdg-mime failures log structured warnings and never block startup. DesktopEnvironment now exposes linuxApplicationsDir and appImagePath; tests cover Exec quoting, platform gating, and failure paths.

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

Note

Claim the t3code:// URL scheme on Linux at startup by registering a .desktop handler

  • Adds DesktopLinuxUrlHandler which writes a t3code-url-handler.desktop file and runs xdg-mime default to register the app as the default handler for the t3code:// scheme.
  • Uses appImagePath when available as the Exec target, falling back to process.execPath; resolves the output directory from XDG_DATA_HOME, defaulting to ~/.local/share/applications.
  • Registration runs during startup but failures are non-fatal — errors are logged as warnings and do not abort the app.
  • No-ops on non-Linux platforms and unpackaged builds.

Macroscope summarized be4a826.

The AppImage's integrated .desktop entry now advertises
MimeType=x-scheme-handler/t3code, so the app shows up in the browser's
"Choose an application" dialog — but nothing records it as the default
handler, so every OAuth callback prompts the user again (and the entry's
filename is decided by the integration tool, e.g. AppImageLauncher's
appimagekit_<hash>-….desktop, so Electron's setAsDefaultProtocolClient
cannot claim it via setDesktopName).

Write a dedicated t3code-url-handler.desktop into
$XDG_DATA_HOME/applications pointing at the current $APPIMAGE and set it
as the scheme default via xdg-mime — the same association the file
manager's "set as default" checkbox records. Registration is best-effort
and never blocks startup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 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: 58764337-8234-4709-b194-92d4d28edb50

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

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

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Jul 30, 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 DesktopLinuxUrlHandler service against the Effect service conventions. The service/tag/make/layer shape, namespace imports, dependency acquisition (yield* Foo.Foo), and Effect.catch on a fully-handled channel all look right. Two error-modeling issues below.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/desktop/src/app/DesktopLinuxUrlHandler.ts
Comment thread apps/desktop/src/app/DesktopLinuxUrlHandler.ts Outdated
…on errors

Add desktopEntryPath and exitCode fields to
DesktopLinuxUrlHandlerRegistrationError so failures log the resolved
entry path and the xdg-mime exit status instead of burying them in a
synthetic Error cause; cause is now optional for the domain failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/desktop/src/app/DesktopLinuxUrlHandler.ts Outdated
Implementations unescape a desktop entry's Exec value twice: the general
string-value rules first, then the Exec quoting rules. Writing therefore
has to apply Exec quoting first and general string escaping on top, so a
literal backslash in the AppImage path lands as four backslashes in the
file, a double quote as \\" and a dollar sign as \\$. The previous
single-layer escaping produced a malformed command for paths containing
those characters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@macroscopeapp

macroscopeapp Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new Linux-specific feature that writes .desktop files and executes xdg-mime commands at startup to claim URL scheme defaults. While well-scoped and defensive (failures don't block startup), new features with filesystem/process interactions warrant human review.

You can customize Macroscope's approvability policy. Learn more.

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

Labels

size:L 100-499 changed lines (additions + deletions). 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