Skip to content

fix(desktop): improve AppImage icons and remote environment#2538

Open
mwolson wants to merge 25 commits into
pingdotgg:mainfrom
mwolson:fix/linux-secret-store-backend
Open

fix(desktop): improve AppImage icons and remote environment#2538
mwolson wants to merge 25 commits into
pingdotgg:mainfrom
mwolson:fix/linux-secret-store-backend

Conversation

@mwolson
Copy link
Copy Markdown
Contributor

@mwolson mwolson commented May 6, 2026

Summary

  • Generates standard hicolor Linux icon sizes for AppImage builds so AppImageLauncher and desktop shells can resolve the installed app icon.
  • Fixes Linux AppImage/Niri remote environment pairing by configuring Electron's Linux startup options before ready, including --password-store, Wayland/X11 app class, and desktop scheme privileges.
  • Hydrates Linux desktop session environment values, including DBUS_SESSION_BUS_ADDRESS, so GNOME Keyring/libsecret is reachable when launching outside GNOME.
  • Hardens SSH remote environment auth by accepting JSON date strings from remote auth APIs and preserving/rolling back saved environment metadata consistently when bearer-token persistence fails.
  • Fixes saved SSH environment removal so deleting an environment cannot resurrect it on restart. Desktop now removes the saved environment record and embedded encrypted token in one atomic persistence operation before the UI clears local state or starts SSH cleanup.

Closes #2331.
Fixes #2539.

Diagnosis

The icon issue came from Linux AppImage builds staging only a single large icon.png. This PR stages a directory of standard icon sizes (16, 22, 24, 32, 48, 64, 128, 256, and 512) and points electron-builder at that directory. CI installs ImageMagick for Linux release builds so those sizes can be generated reliably.

The credential-store failure came from Electron selecting a non-encrypting Linux safeStorage backend when running under desktop environments it does not recognize, such as Niri. The app was also relying on shell/session environment values that may not be present when launched from an AppImage or desktop entry.

This PR moves the Linux Electron setup into the synchronous process bootstrap path so it happens before Electron emits ready, which is required for --password-store and privileged protocol registration to take effect. It also imports enough login/session environment to reach the user's DBus session bus and falls back to /run/user/$UID/bus when appropriate.

While testing the remote flow, two separate persistence issues showed up:

  • Auth responses returned JSON ISO date strings over the SSH HTTP bridge, while the contract expected already-materialized DateTime.Utc values.
  • Removing a saved SSH environment used two separate persistence writes: one fire-and-forget registry rewrite and one secret removal. Those writes could race, letting secret removal read the old record and write it back, so the environment reappeared after restart.

Scope

This is intentionally focused on Linux desktop/AppImage remote environment reliability. It does not change remote server behavior, and SSH process cleanup after removal remains fire-and-forget so the Settings UI does not hang if disconnect stalls.

Test plan

  • bun fmt
  • bun lint
  • bun typecheck
  • bun run test
  • bun run --filter @t3tools/desktop test -- DesktopEarlyElectronStartup DesktopEnvironment ElectronProtocol DesktopShellEnvironment linuxSecretStorage
  • bun run --filter @t3tools/desktop test -- DesktopSavedEnvironments
  • bun run --filter @t3tools/web test -- localApi service.addSavedEnvironment catalog
  • bun run dist:desktop:linux
  • Extracted AppImages and confirmed hicolor icon entries for 16, 22, 24, 32, 48, 64, 128, 256, and 512.
  • Built a local AppImage and launched it under Niri with T3CODE_HOME isolated.
  • Confirmed packaged logs report passwordStore: gnome-libsecret, backend: gnome_libsecret, and encryptionAvailable: true.
  • Installed with Shelly, added remote-game, and ran a trivial task on it.
  • Deleted remote-game, reinstalled/restarted, and confirmed the saved environment did not come back.

Note

Medium Risk
Touches Linux Electron startup, encrypted credential persistence, and shared auth schema decoding; saved-environment removal ordering changed but covered by tests.

Overview
Improves Linux AppImage packaging and remote saved-environment reliability on non-GNOME desktops (e.g. Niri).

Linux desktop bootstrap now applies Electron options before ready: persisted linuxPasswordStore, --password-store heuristics for unrecognized sessions, WM class, synchronous t3 scheme privileges, and optional DBUS_SESSION_BUS_ADDRESS from /run/user/$UID/bus. Login-shell hydration also pulls more XDG/desktop vars. Secret save failures return Keyring/KWallet guidance via selectedStorageBackend.

Saved environments: new removeSavedEnvironment IPC/persistence removes registry + encrypted token in one write; the web layer deletes persisted state first and runs SSH disconnect in the background. Bearer-token persistence uses clearer rollback (preserves primary errors) and replaces stale SSH records via atomic remove.

Remote auth over SSH HTTP decodes expiresAt from ISO strings (DateTimeUtcFromString in contracts).

Release/build: Linux CI installs ImageMagick; desktop Linux artifacts stage hicolor-sized icons (icons/ dir) instead of a single PNG.

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

Note

Improve Linux AppImage icons and remote environment credential management

  • Linux AppImage builds now generate multi-size icons (16–512px) via ImageMagick into a resources/icons directory; electron-builder is updated to point at this directory instead of a single icon.png
  • Adds a removeSavedEnvironment method end-to-end: IPC channel, preload bridge, DesktopSavedEnvironments service, LocalApi persistence, and web-side catalog/store update
  • Introduces linuxSecretStorage.ts with helpers to normalize password-store preferences, resolve the Electron --password-store switch, and generate platform-appropriate remediation messages when secret storage is unavailable
  • Pre-ready Linux Electron startup now resolves DBUS session bus address, WM class, and password-store switch from a settings file before app.ready, and logs the safe storage backend after ready
  • DesktopShellEnvironment hydrates additional XDG/Wayland/DBus environment variables from the login shell and auto-discovers DBUS_SESSION_BUS_ADDRESS via the XDG runtime dir socket
  • expiresAt fields in auth contract schemas (AuthBootstrapResult, AuthBearerBootstrapResult, AuthWebSocketTokenResult, AuthSessionState) are changed from DateTimeUtc to DateTimeUtcFromString for correct JSON decoding
  • Risk: removing a saved environment no longer explicitly removes the bearer token; SSH cleanup is non-blocking and failures are only logged

Macroscope summarized 2273d3e.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

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

Run ID: 25c2c134-e105-40a1-a107-735b64a8e3f5

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels May 6, 2026
@mwolson mwolson changed the title fix(desktop): improve Niri AppImage integration fix(desktop): improve Niri AppImage and remote environment May 6, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 6, 2026

Approvability

Verdict: Needs human review

This PR introduces significant new Linux platform behavior including password store detection, DBus session bus address resolution, new IPC methods, and schema changes affecting DateTime serialization. An unresolved comment also questions whether Electron scheme privilege registration timing was affected by the layer restructuring.

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

@mwolson mwolson force-pushed the fix/linux-secret-store-backend branch from dba46b4 to bfc4a7c Compare May 6, 2026 02:10
@mwolson
Copy link
Copy Markdown
Contributor Author

mwolson commented May 6, 2026

Before (missing icon)

Missing icon (works in shelly, doesn't work when appimage is launched directly, or with AppImageLauncher):

image

Before (secret manager)

Error when trying to add environment:

image

@mwolson
Copy link
Copy Markdown
Contributor Author

mwolson commented May 6, 2026

After (icons fix)

Launched appimage directly after chmod +x on it:

image

After (secrets-manager fix)

Screenshot from 2026-05-06 14-07-50-blur

Comment thread apps/web/src/environments/runtime/service.ts
@juliusmarminge
Copy link
Copy Markdown
Member

can you resolve conflcits here?

mwolson added 2 commits May 8, 2026 15:02
…ore-backend

# Conflicts:
#	apps/desktop/src/desktopSettings.test.ts
#	apps/desktop/src/desktopSettings.ts
#	apps/desktop/src/main.ts
@juliusmarminge
Copy link
Copy Markdown
Member

icon looks like this for me on ubuntu?
IMG_5075

@mwolson mwolson changed the title fix(desktop): improve Niri AppImage and remote environment fix(desktop): improve AppImage icons and remote environment May 9, 2026
@mwolson mwolson changed the title fix(desktop): improve AppImage icons and remote environment fix(desktop): harden Linux remote environments May 9, 2026
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels May 9, 2026
@mwolson mwolson changed the title fix(desktop): harden Linux remote environments fix(desktop): improve AppImage icons and remote environment May 9, 2026
Comment thread apps/desktop/src/app/DesktopEarlyElectronStartup.ts
Comment thread apps/desktop/src/app/DesktopEarlyElectronStartup.ts Outdated
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge left a comment

Choose a reason for hiding this comment

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

tested on ubuntu and it works.

desktop app could use some cleanup to follow effect best practices more. i just cleaned it up a bunch so don't wanna move away directly

Comment thread apps/desktop/src/app/DesktopEnvironment.ts Outdated
Comment thread apps/desktop/src/electron/ElectronProtocol.ts Outdated
@mwolson mwolson requested a review from juliusmarminge May 9, 2026 20:57
@mwolson
Copy link
Copy Markdown
Contributor Author

mwolson commented May 9, 2026

@juliusmarminge fixed the issues you mentioned and re-smoked it on my end. If you don't want the AGENTS.md changes around Effect (or want different content there) let me know.

@juliusmarminge
Copy link
Copy Markdown
Member

I can look at it in a bit, but there's nothing that says that just cause it should run before electron it must run synchronously at module scope? The layer graph before was setup so that the protocol was the first thing that executed before the main effect program? Was there an issue with that? We create the electron app inside the effect program ye?

Comment thread apps/desktop/src/shell/DesktopShellEnvironment.ts
@mwolson
Copy link
Copy Markdown
Contributor Author

mwolson commented May 9, 2026

I can look at it in a bit, but there's nothing that says that just cause it should run before electron it must run synchronously at module scope? The layer graph before was setup so that the protocol was the first thing that executed before the main effect program? Was there an issue with that? We create the electron app inside the effect program ye?

Good points; I moved this back into the Effect startup graph as an explicit first layer with Layer.flatMap, and isolated the synchronous process/fs reads in a small pre-ready platform adapter. That keeps the Electron pre-ready ordering intact without doing the setup at module scope. (Also updated AGENTS.md guidance to match.)

Comment thread apps/desktop/src/app/DesktopEarlyElectronStartup.ts Outdated
Comment thread apps/web/src/environments/runtime/service.ts
Comment thread apps/web/src/environments/runtime/service.ts
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

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

Reviewed by Cursor Bugbot for commit 8863f9e. Configure here.

Comment thread apps/desktop/src/app/DesktopApp.ts
@mwolson
Copy link
Copy Markdown
Contributor Author

mwolson commented May 12, 2026

@juliusmarminge I've addressed the earlier feedback, merged latest main, and went through several rounds of bugbot feedback, so it's ready for another look as time allows.

@mwolson
Copy link
Copy Markdown
Contributor Author

mwolson commented Jun 1, 2026

@juliusmarminge I've merged main again to update the branch; if you'd rather have me split out the appimage work (which from our conversation ~1 month ago seemed to be tested on Ubuntu and went well), let me know, either way.

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

Labels

size:XL 500-999 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.

[Bug]: Niri AppImage cannot save remote environment credentials [Bug]: AppImage installed by AppImageLauncher lacks usable Linux desktop icon

2 participants