diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a40d47..8ddb53c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,19 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`). overridden per-user (`:set notermguicolors`, or your own init). Base-affecting (`Dockerfile.base` apt package + COPY), rebuilds `base-`. +- **Terminal support beyond kitty: `ncurses-term` + a compiled `xterm-ghostty` + alias.** The base previously shipped only `ncurses-base` (xterm-256color, + tmux), so SSHing in from a modern emulator degraded to a dumb fallback. The + base now installs `ncurses-term` (terminfo for WezTerm, Alacritty, foot, st, + and the base `ghostty` entry, among many others) and compiles an + `xterm-ghostty` alias with `tic -x` (`use=ghostty`) — Ghostty connects as + `TERM=xterm-ghostty` and no distro packages that name. Combined with + `kitty-terminfo` (xterm-kitty) and xterm-256color (iTerm2's default, already + in ncurses-base), the common modern terminals now resolve their TERM. The + approach mirrors the maintainer's ansible `common` role. Base-affecting + (`Dockerfile.base` apt + COPY + `tic` RUN, plus a new + `rootfs/usr/local/share/terminfo-src/ghostty.terminfo`), rebuilds `base-`. + - **Repository hygiene: `LICENSE`, `THIRD_PARTY.md`, and `.dockerignore`.** The repo declared MIT only in prose; it now ships an actual `LICENSE` file (MIT, © Joakim Persson) plus `THIRD_PARTY.md` recording that the published images diff --git a/Dockerfile.base b/Dockerfile.base index 1c5ceb9..6d3c554 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -76,6 +76,13 @@ ENV DEBIAN_FRONTEND=noninteractive # true-colour from kitty over ssh; installing it makes # TERM=xterm-kitty understood. Pairs with the system-wide # Neovim termguicolors default (etc/xdg/nvim/sysinit.vim). +# ncurses-term — broad terminfo bundle (wezterm, alacritty, foot, st, the +# base `ghostty` entry, and many more) so SSHing in from a +# modern emulator resolves its TERM instead of degrading to a +# dumb fallback. xterm-kitty is NOT in it (hence kitty-terminfo +# above); TERM=xterm-ghostty is compiled from an alias further +# down (ncurses ships `ghostty`, not `xterm-ghostty`). iTerm2 +# defaults to xterm-256color (ncurses-base), so needs nothing. RUN apt-get update && \ apt-get upgrade -y --no-install-recommends && \ apt-get install -y --no-install-recommends \ @@ -114,6 +121,7 @@ RUN apt-get update && \ socat \ nano \ kitty-terminfo \ + ncurses-term \ && ln -s /usr/bin/fdfind /usr/local/bin/fd \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -577,6 +585,16 @@ COPY rootfs/home/developer/.gitignore_global /etc/skel-devbox/.gitignore_global # of a muddy 256-colour fallback. Pairs with kitty-terminfo (installed above). COPY rootfs/etc/xdg/nvim/sysinit.vim /etc/xdg/nvim/sysinit.vim +# ── Terminal support: xterm-ghostty terminfo alias ────────────────── +# ncurses-term (installed above) covers wezterm/alacritty/foot/st and the base +# `ghostty` entry, but Ghostty connects with TERM=xterm-ghostty, for which no +# distro packages an entry. Ship a thin alias (use=ghostty) and compile it into +# the system terminfo db with `tic -x`, so it inherits the maintained ghostty +# capability set. The `infocmp` check fails the build if the entry didn't land. +COPY rootfs/usr/local/share/terminfo-src/ghostty.terminfo /usr/local/share/terminfo-src/ghostty.terminfo +RUN tic -x -o /usr/share/terminfo /usr/local/share/terminfo-src/ghostty.terminfo && \ + infocmp -x xterm-ghostty >/dev/null + # ── Entrypoint ──────────────────────────────────────────────────────── COPY rootfs/usr/local/lib/pi-devbox/ /usr/local/lib/pi-devbox/ # Image-baked skills + the global-AGENTS append snippet. Under /usr/local so a diff --git a/rootfs/usr/local/share/terminfo-src/ghostty.terminfo b/rootfs/usr/local/share/terminfo-src/ghostty.terminfo new file mode 100644 index 0000000..2f55f43 --- /dev/null +++ b/rootfs/usr/local/share/terminfo-src/ghostty.terminfo @@ -0,0 +1,14 @@ +# xterm-ghostty — alias of the maintained ncurses `ghostty` terminfo entry. +# +# Ghostty sets TERM=xterm-ghostty by default, but the ncurses terminfo +# database (Debian: ncurses-term) ships the entry under the name `ghostty` +# only — there is no `xterm-ghostty` alias, and no distro packages one. This +# thin alias makes xterm-ghostty resolve to the same upstream-maintained +# capability set, so SSH sessions from a Ghostty terminal work without +# vendoring Ghostty's full (Zig-generated) terminfo here. +# +# `use=ghostty` is resolved by `tic` at compile time against the base +# `ghostty` entry from ncurses-term (installed in Dockerfile.base before the +# compile step). Compiled with `tic -x`. +xterm-ghostty|Ghostty terminal emulator (xterm-ghostty alias), + use=ghostty, diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh index 28b7d88..29ebe32 100755 --- a/scripts/smoke-test.sh +++ b/scripts/smoke-test.sh @@ -8,6 +8,8 @@ # - new v1.0.0 base additions (pandoc, graphviz, imagemagick, yq, tealdeer) # - typst PDF engine for pandoc (Unreleased) — `pandoc --pdf-engine=typst` # - non-modal editors nano + micro (alongside nvim) +# - terminfo for modern emulators: xterm-kitty, xterm-ghostty, wezterm, +# alacritty, foot (kitty-terminfo + ncurses-term + compiled ghostty alias) # - tmux 0-indexing baked in /etc/tmux.conf (required for pi-studio variants) # - pi-toolkit cloned at /opt/pi-toolkit # - pi-extensions cloned at /opt/pi-extensions @@ -77,6 +79,8 @@ run "nvim" "nvim --version" run "nano" "nano --version" run "micro" "micro --version" run "kitty-terminfo" "infocmp -x xterm-kitty >/dev/null 2>&1" +run "terminfo: modern emulators (ncurses-term)" 'for t in wezterm alacritty foot ghostty st-256color; do infocmp -x "$t" >/dev/null 2>&1 || exit 1; done' +run "terminfo: xterm-ghostty alias (tic)" "infocmp -x xterm-ghostty >/dev/null 2>&1" run "nvim true-colour default (sysinit.vim)" "nvim --headless -c 'lua os.exit(vim.o.termguicolors and 0 or 1)'" run "mempalace-mcp" "mempalace-mcp --help" # v1.0.0 base additions — verify presence and basic functionality.