Skip to content

Support deep-link protocol registration for AppImage builds#2743

Merged
charlesvien merged 6 commits into
mainfrom
claude/blissful-brahmagupta-b9pwa3
Jun 18, 2026
Merged

Support deep-link protocol registration for AppImage builds#2743
charlesvien merged 6 commits into
mainfrom
claude/blissful-brahmagupta-b9pwa3

Conversation

@gantoine

Copy link
Copy Markdown
Member

Problem

AppImage builds lack an installed .desktop file, so app.setAsDefaultProtocolClient() (which points xdg at one) is a no-op. This breaks OAuth callbacks: the browser cannot hand posthog-code://callback?... back to the app after authentication.

Changes

Added AppImage-specific protocol registration that mirrors manual xdg-mime default setup:

  1. New module linux-appimage-protocol.ts: Detects AppImage runtime (APPIMAGE env var), builds freedesktop .desktop entries pointing at the stable $APPIMAGE path, stages the app icon to a persistent location, and registers URL schemes via xdg-mime.

  2. Updated DeepLinkService: Collects all schemes (dev/prod, legacy) and calls registerAppImageSchemes() on AppImage builds. Failures are best-effort and do not block startup.

  3. Updated forge.config.ts: Declared x-scheme-handler/posthog-code in the bundled .desktop entry so AppImage integrators (e.g., AppImageLauncher) register the handler at install time.

The solution is defensive: it only runs on Linux with APPIMAGE set, handles missing xdg utilities gracefully, and does not interfere with non-AppImage builds.

How did you test this?

  • Added comprehensive unit tests (linux-appimage-protocol.test.ts) covering:
    • isAppImage() detection on Linux with/without APPIMAGE
    • .desktop entry generation with correct Exec path and MIME types
    • Icon staging and fallback
    • Desktop database update and xdg-mime default registration
    • Graceful handling when not running as AppImage
  • Tests mock filesystem and execFile to verify correct paths and command sequences without side effects

https://claude.ai/code/session_014aMsqBjTdturnFTpnTsD1f

claude added 3 commits June 17, 2026 19:42
…ork stack

OAuth token exchange and refresh run in the Electron main process, where the
global `fetch` is Node's undici. undici ignores the system proxy and
certificate configuration that Chromium honours, so on some Linux setups
(e.g. behind a proxy or with a custom trust store) token exchange failed with
a bare "fetch failed" even though the renderer's API calls — which already go
through Chromium — succeeded.

Add an `IHttpClient` platform port backed by Electron's `net.fetch`
(Chromium networking) and inject it into `OAuthService`, so main-process
requests behave like the renderer's.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aMsqBjTdturnFTpnTsD1f
The AppImage build never registered the posthog-code:// protocol handler, so
after OAuth at us.posthog.com the browser couldn't hand the
posthog-code://callback?code=... redirect back to the app — users had to
create the .desktop file and run xdg-mime by hand.

app.setAsDefaultProtocolClient is a no-op for AppImages: there is no installed
.desktop file for xdg to point at, and the AppImage mount path (/tmp/.mount_*)
changes every launch. On AppImage builds we now write a desktop entry to the
user applications dir with Exec pointing at the stable $APPIMAGE path and
register it as the default handler for each scheme (mirroring the manual
xdg-mime default step). Also declare the scheme in the maker's bundled
.desktop entry so AppImage integrators (e.g. AppImageLauncher) pick it up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aMsqBjTdturnFTpnTsD1f
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 0e61eb1.

@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/code/src/main/utils/linux-appimage-protocol.test.ts:62-80
**Prefer parameterised tests for `isAppImage`**

The three cases here — `(linux, APPIMAGE set) → true`, `(linux, APPIMAGE missing) → false`, `(darwin, APPIMAGE set) → false` — all exercise the same predicate with different `(platform, envVar, expected)` inputs, which is the canonical use case for `it.each`. As a single table-driven test it would be easier to extend with new platforms and avoids the repeated `setPlatform` / `process.env` setup boilerplate.

### Issue 2 of 2
apps/code/src/main/services/deep-link/service.ts:55-59
**Dead `.catch()``registerAppImageSchemes` never rejects**

`registerAppImageSchemes` swallows every failure path internally: `runXdg` always resolves (warnings are logged, errors are not re-thrown), and the `writeFileSync` / `mkdirSync` catch block returns rather than throwing. The `.catch()` here can therefore never fire, making it a superfluous part. The `void` plus `.catch(log.error)` pattern is idiomatic only when the callee can reject — if you want to surface any future errors here, the callee's error handling would need to change too.

```suggestion
    if (isAppImage()) {
      void registerAppImageSchemes(schemes);
    }
```

Reviews (1): Last reviewed commit: "fix(deep-links): register posthog-code:/..." | Re-trigger Greptile

Comment thread apps/code/src/main/utils/linux-appimage-protocol.test.ts
Comment thread apps/code/src/main/services/deep-link/service.ts
gantoine and others added 2 commits June 18, 2026 07:13
- Parameterise isAppImage tests with it.each over (platform, env, expected)
- Drop dead .catch() on registerAppImageSchemes (it never rejects)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gantoine gantoine marked this pull request as ready for review June 18, 2026 14:33
@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Reviews (2): Last reviewed commit: "fix linxu build image target" | Re-trigger Greptile

Copilot AI 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.

Pull request overview

Adds Linux AppImage-specific deep-link protocol registration so OAuth callbacks (e.g. posthog-code://callback?...) can be handed back to the app even when no system .desktop file is installed.

Changes:

  • Introduces an AppImage runtime helper that writes a user-scoped .desktop entry (Exec → $APPIMAGE), stages an icon, updates desktop DB, and registers x-scheme-handler/* via xdg-mime.
  • Updates DeepLinkService to register all active schemes (dev/prod + legacy) and trigger AppImage registration best-effort on AppImage builds.
  • Updates Forge AppImage maker config to include x-scheme-handler/posthog-code, and adjusts the Linux docker build script target mapping.

Reviewed changes

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

Show a summary per file
File Description
apps/code/src/main/utils/linux-appimage-protocol.ts Adds AppImage detection + .desktop/xdg-mime registration utilities.
apps/code/src/main/utils/linux-appimage-protocol.test.ts Adds unit tests for AppImage scheme registration and desktop entry generation.
apps/code/src/main/services/deep-link/service.ts Collects schemes consistently and triggers AppImage-specific registration.
apps/code/scripts/build-linux-docker.sh Maps friendly maker targets to Forge maker names for Linux container builds.
apps/code/forge.config.ts Declares deep-link MIME handler for AppImage .desktop generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/code/src/main/utils/linux-appimage-protocol.test.ts Outdated
Comment thread apps/code/src/main/utils/linux-appimage-protocol.test.ts
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@gantoine gantoine force-pushed the claude/blissful-brahmagupta-b9pwa3 branch from 16d5e02 to 0e61eb1 Compare June 18, 2026 15:42
@gantoine gantoine requested a review from a team June 18, 2026 18:22
@charlesvien charlesvien merged commit 0e6ea2c into main Jun 18, 2026
23 checks passed
@charlesvien charlesvien deleted the claude/blissful-brahmagupta-b9pwa3 branch June 18, 2026 21: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.

4 participants