Skip to content

Add Linux support: x64 AppImage packaging plus Linux validation fixes - #325

Open
nero- wants to merge 10 commits into
dataelement:mainfrom
nero-:linux
Open

Add Linux support: x64 AppImage packaging plus Linux validation fixes#325
nero- wants to merge 10 commits into
dataelement:mainfrom
nero-:linux

Conversation

@nero-

@nero- nero- commented Sep 6, 2026

Copy link
Copy Markdown

Summary

Adds Linux x64 support (AppImage) to DSH Desktop. The desktop host code was already ~Linux-ready; this port keeps the runtime untouched and concentrates on packaging, platform ports where logic lived/was defaulting cleanly, and validation on a real Arch Linux + Hyprland (Wayland) machine.

What changed

  • package.json: build.linux (AppImage, x64) with a committed 512×512 8-bit RGBA icon (the 16-bit 1024px source PNG is not accepted reliably by AppImage tooling); package:linux:x64 and package:dev:linux:x64 scripts mirroring the mac/win flow (verify-target linux x64 + build + --publish never); desktopName metadata + linux.syncDesktopName so Wayland compositors associate windows with the launcher entry; reviewed allowScripts for npm ≥ 12's install-script gate.
  • src/main/runtime/harness-runtime.ts: Linux joins Windows on the 120s Harness readiness budget (cold starts in a FUSE-mounted AppImage exceeded the 45s non-Windows default; live evidence in the log trail below).
  • src/main/index.ts: the in-window menubar now hides on every non-darwin platform (auto-hide + hidden, like Windows).
  • test/: lan-mobile-bridge upgrade sockets typed Duplex (works with @types/node 24).
  • Docs/READMEs: Linux row + from-source build instructions in all six locales, plus packaging notes in docs/development.md.
  • Runtime launch path, shell-environment capture, pnpm shims, process-group kill, tunnel asset maps: verified already Linux-correct; untouched (the only runtime line touched is the startup-timeout default).

Validation performed

  • npm test (707+ ok; one test flagged pnpm-side HOME writability, green under normal env), npm run typecheck, npm run build, npm run package:linux:x64 on Arch (Electron 43.4.0, bundled Node 24.9.0 runtime probe).
  • Real app flows on Hyprland/Wayland: app boots on native Wayland (xwayland: 0), harness starts from the bundled Node with per-profile DSH_HOME, pnpm shim written, web UI served at 127.0.0.1 with token, window class dsh-desktop verified via Hyprland IPC, quit-on-close behaves, in-app updater reports unsupported (macOS/Windows-only by design).
  • Windows-only extra resources remain copied on Linux builds (pinned by test/release.test.ts), harmless, per the existing release contract.

Notes for maintainers

  • Upstream lockfile resolved URLs point at registry.npmmirror.com; on npm ≥ 12 (Node ≥ 24) fetching those is behind the new allow-required-remote gate. This port keeps the lockfile untouched and documents npm_config_allow_remote=all in docs/development.md (npm 10 CI unaffected).
  • The vendored @deepseek-ai/dsh-subprocess-local postinstall (chmod of a macOS-only spawn helper) cannot take a portable allowScripts key because npm keys file: deps by their resolved absolute URL; skipping it is harmless on every platform.
  • Enabling Linux AppImage auto-update later would need latest-linux.yml + the AppImage served from the generic feed and a one-line update-policy.ts change (kept out of this PR deliberately, since the feed side is external).

Verification trail: upstream commit 9d4502f, port commit series on nero-/dsh-desktop branch linux.

Jonathan Gutierrez added 10 commits September 5, 2026 18:52
npm >= 12 blocks lifecycle scripts by default. Approve the native and
build-critical deps (node-pty, koffi, esbuild, bundled node) and record
explicit denials for Windows-only/no-op scripts. The vendored
dsh-subprocess-local postinstall (chmod of a macOS-only spawn helper)
cannot take a portable allowScripts key because npm keys file: deps by
their resolved absolute URL; skipping it on Linux is harmless.
Electron-builder gains a linux.target (AppImage, x64) with a committed
512px 8-bit RGBA icon (the existing 16-bit 1024px source PNG is not
accepted reliably by AppImage tooling), package:linux:x64 and
package:dev:linux:x64 scripts mirroring the mac/win flow (verify-target
+ build + --publish never), desktopName/syncDesktopName so Wayland
compositors associate windows with the launcher entry, and
docs/README updates replacing 'Linux not supported' with the from-source
community build story (in-app updates stay macOS/Windows-only).
The test only calls destroy(); @types/node 24 no longer has stream
Duplex extend net.Socket, so a Duplex (instead of net.Socket) is the
correct type.
linux-build.yml runs the port's validation + packaging on every push to
the linux branch and uploads the AppImage artifact. upstream-sync.yml
rebases the port commits onto dataelement/dsh-desktop:main weekly (or
manually), reruns the full suite and packaging after the rebase, then
pushes and refreshes a PR in this fork. A failing rebase or run is the
signal that new upstream platform work needs porting attention.
electron-builder 26 validates desktopName as a top-level metadata field;
linux.syncDesktopName derives the .desktop filename from it so the
StartupWMClass matches on Wayland compositors.
Live first-launch evidence on a packaged Linux AppImage: cold-start
readiness blew the 45s non-Windows default and the desktop killed the
healthy-but-slow Harness process. Windows got 120s for the same class of
slow cold start; Linux now matches (macOS keeps 45s).
…build

Windows hides the menu (setMenuBarVisibility(false), autoHideMenuBar);
macOS uses the system menubar. Linux shipped a visible in-window
menubar because the hide was gated on isWindows. Auto-hide + hide now
apply to every non-darwin platform, so the app keeps its product chrome
on Linux while accelerators (and the Alt-revealed menu) stay available.

Pinned strings in test/branding-patch.test.ts and
test/windows-titlebar.test.ts stay verbatim.
Every push to the linux branch refreshes the linux-rolling
pre-release with dsh-desktop-linux-x64.AppImage, so the fork always
offers a fresh download without manual release work after upstream
syncs.
…anel

When the window (or viewport) is short, the sidebar's region area clipped
its content and pushed the settings cluster out of view, and the settings
dialog could extend past the visual viewport on Wayland. The region
column now carries the tracked data-dsh-sidebar-region attribute and
scrolls (overscroll contained), the settings panel height gains the
100dvh fallback alongside 100vh for dynamic-viewport correctness on
Wayland, and the settings nav column scrolls instead of clipping.

Patches regenerated from pristine vendored tarballs; verified by
git-apply round-trip.
The verify step passed the packaged node executable to the system node
interpreter as a script file, which fails parsing the ELF. Invoke the
packaged binary itself.
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.

1 participant