Bundle mosh terminfo on Linux and macOS (#890)#894
Conversation
The bundled statically-linked mosh-client links a privately-built ncurses whose compiled-in TERMINFO path is the build-time --prefix (a temp dir gone after build). On a clean install setupterm() fails with "Terminfo database could not be found." Issue #890 reports this on Ubuntu 26.04 after upgrading from 1.1.0 (which used the system mosh and therefore the system ncurses' working default path). Mirror the Windows fix (#889) on Linux and macOS: - build-linux.sh / build-macos.sh: copy a curated set of terminfo entries (xterm-256color and friends) out of the freshly built $PREFIX/share/terminfo/ and tar them up alongside the binary as mosh-client-<plat>-<arch>.tar.gz. macOS gets terminfo from the native arch's prefix where tic could actually run. - fetch-mosh-binaries.cjs: switch Linux/Darwin TARGETS to the .tar.gz bundle and generalize bundle normalization (windows + posix paths share extraction safety + terminfo presence assertions). - mosh-extra-resources.cjs: ship the bundled terminfo dir alongside the binary in extraResources for Linux and Darwin too. - terminalBridge.cjs: prefer the bundled terminfo at runtime; fall back to standard distro paths when it's absent (older mosh binary release pre-dating the bundle), and merge any caller-supplied TERMINFO_DIRS in between. Tests cover Linux/Darwin tar.gz extraction (happy + missing terminfo + missing binary), packaging (legacy + bundled), and runtime env (bundle-first, system fallback, caller override). Requires republishing mosh-bin-* with the new bundle layout (workflow_dispatch on build-mosh-binaries.yml). Once published, resolve-mosh-bin-release.cjs auto-discovers it as the latest non-draft tag — no code change needed to bump it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb0bebf1a4
ℹ️ 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".
| { platform: "linux", arch: "x64", file: "mosh-client-linux-x64.tar.gz", localDir: "linux-x64", extract: "tar.gz" }, | ||
| { platform: "linux", arch: "arm64", file: "mosh-client-linux-arm64.tar.gz", localDir: "linux-arm64", extract: "tar.gz" }, | ||
| { platform: "darwin", arch: "universal", file: "mosh-client-darwin-universal.tar.gz", localDir: "darwin-universal", extract: "tar.gz" }, |
There was a problem hiding this comment.
Keep legacy POSIX asset names in fetch target list
Switching Linux/Darwin targets to only *.tar.gz breaks compatibility with already-published mosh binary releases that still expose mosh-client-linux-* / mosh-client-darwin-universal as plain files. In that case follow() fails with HTTP 404 before normalizePosixBundle()/assertBundledTerminfo() can run, so packaging and fetch:mosh:dev fail until a new binary release is published. Add a fallback to legacy filenames (or attempt both names) so existing releases keep working during rollout.
Useful? React with 👍 / 👎.
Codex review on #894 flagged that switching the Linux/Darwin TARGETS to *.tar.gz alone breaks fetching from the existing mosh-bin-1.4.0-1 release (which still ships only flat binaries for those platforms): the download HTTP 404s before bundle normalization can run, so packaging and `npm run fetch:mosh:dev` would fail until a new bundle release was republished. Add a `legacy` descriptor to each Linux/Darwin target and select it when SHA256SUMS lists only the legacy filename. The bundled tarball is still preferred when published. Empty SHA256SUMS (allowUnverified mirror) keeps the primary path so 404s surface naturally instead of silently downgrading. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex review on #894 P3: the new Linux/macOS bundles drop resources/mosh/<platform-arch>/terminfo/ at fetch time, but the existing mosh ignore rules only cover the binaries and Windows DLLs. Without this rule, `npm run fetch:mosh:dev` leaves the compiled terminfo files showing up as untracked and they could be accidentally committed. Add a recursive ignore so every platform's bundle stays out of git, including the Windows side that the #889 fix already populated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Delightful! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Closes #890. Supersedes #893 (the runtime-only patch).
Why a deeper fix
The bundled
mosh-clientwe ship since 1.1.1 is statically linked against an ncurses we built ourselves in CI with--prefix=$WORK/prefix— a temp dir gone after the build. ncurses' compiled-in default terminfo path therefore points at a directory that doesn't exist on the user's machine, andsetupterm("xterm-256color")fails with the exact message in the issue. Mac happened to work because users typically have something in/usr/share/terminfo,~/.terminfo, or an exportedTERMINFO_DIRSthat satisfies an earlier ncurses search step. Linux on a clean .deb does not. #893 papers over this by pointingTERMINFO_DIRSat standard distro paths at spawn time — that fixes #890 today but still relies on the host havingncurses-base. This PR makes the binary fully self-sufficient by shipping the database alongside it (mirroring the Windows fix in #889).Changes
scripts/build-mosh/build-linux.shandbuild-macos.sh: copy a curated set of compiled terminfo entries (xterm-256color,xterm,vt100,screen-256color,tmux-256color, …) out of$PREFIX/share/terminfo/and tar them up next to the binary asmosh-client-<plat>-<arch>.tar.gz. macOS does the install on the native arch only becausetichas to run on the build host.scripts/fetch-mosh-binaries.cjs: Linux + DarwinTARGETSswitch to.tar.gzextracts; bundle-normalize logic split intonormalizeWindowsBundle/normalizePosixBundleand a sharedassertBundledTerminfohelper.scripts/mosh-extra-resources.cjs: include the siblingterminfo/dir inextraResourcesfor Linux + Darwin when present.electron/bridges/terminalBridge.cjs:addBundledMoshTerminfoEnvprefers the bundled dir on POSIX, then merges any caller-suppliedTERMINFO_DIRS, then falls back to standard distro paths so an older mosh release without the bundle still works.Rollout
Requires re-running
build-mosh-binaries.yml(workflow_dispatchwith a newrelease_tag, e.g.mosh-bin-1.4.0-2) to publish the new bundle layout.resolve-mosh-bin-release.cjsauto-discovers the latest non-draftmosh-bin-*tag, so no code change is needed to bump it after the rebuild.Until the new mosh release is published, packaged builds keep working:
fetch-mosh-binarieswill warn about missing terminfo on the old artifacts but still write the binary, andterminalBridgefalls back to the system terminfo paths the runtime-only patch added — so this PR does not regress in the gap between merge and rebuild.Test plan
node --test electron/bridges/terminalBridge.bareMoshClient.test.cjs scripts/mosh-extra-resources.test.cjs scripts/fetch-mosh-binaries.test.cjs(36/36 incl. new Linux/Darwin tar.gz extract, packaging, and runtime-env cases)node --test electron/bridges/terminalBridge.bundledMosh.test.cjs electron/bridges/terminalBridge.moshHandshakeSession.test.cjs electron/bridges/moshHandshake.test.cjs(39/39)bash -n scripts/build-mosh/build-linux.sh scripts/build-mosh/build-macos.shworkflow_dispatchonbuild-mosh-binaries.ymlwithrelease_tag=mosh-bin-1.4.0-2, then a packaged Netcatty .deb on Ubuntu 26.04 (and a stripped container withoutncurses-base) connects via mosh without the terminfo errornormalizeBundle/assertBundledTerminfohelpers run on the same path)🤖 Generated with Claude Code