fix(shell): emit legacy short-int terminfo so macOS less stops warning#319
Merged
Conversation
Issue: less-based pagers like git log and man printed "WARNING: terminal is not fully functional" inside Architect shells, while more stayed silent. The bundled xterm-ghostty terminfo was unreadable by the libncurses those tools link against. Solution: macOS ships libncurses 5.4 inside dyld_shared_cache, and it only understands the legacy short-int terminfo format (magic 0x011a). Modern ncurses 6.x ships xterm-256color with pairs#0x10000, which our use= inherits and forces tic to emit the extended-numbers format (magic 0x021e) that 5.4 cannot parse. Pin pairs#0x7fff in the bundled source so the compiled entry stays in signed-16-bit range and tic falls back to the legacy format. Add a regression test that recompiles the embedded asset and asserts the magic bytes. 24-bit truecolor and kitty keyboard capabilities are unaffected. Closes #318
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
less(and other macOS pagers / TUI tools) printedWARNING: terminal is not fully functional / Press RETURN to continuewhenever Architect setTERM=xterm-ghostty.moreand other tools that skip terminfo lookups stayed silent. The bundled terminfo entry was technically present in~/.cache/architect/terminfoand resolvable by the Nix-providedinfocmp, so the issue looked invisible until you traced which library each tool actually links against.Root cause
macOS ships
libncurses 5.4insidedyld_shared_cache, and everything in/usr/binthat touches terminfo (less,man, ...) links against it. That library only understands the legacy short-int terminfo file format (magic bytes0x011a).Architect bundles
xterm-ghostty.terminfowhose source usesuse=xterm-256color. Whenticresolves that against the Nix ncurses 6.6 terminfo DB, it inheritspairs#0x10000(65536), which overflows signed 16-bit.ticthen has to emit the file in the extended-numbers format (magic bytes0x021e). The 5.4 library cannot parse that format, solesscan't findclear/cupand falls back to the warning.Solution
Pin
pairs#0x7fff(32767 — the largest signed-16-bit value) in the bundled terminfo source ahead of theuse=line. The override clamps the inherited capability back into signed-16-bit range, soticemits the legacy short-int format that the system libncurses can read. 24-bit truecolor (Tc/RGB) and kitty keyboard protocol capabilities are unaffected.The compiled cache entry is rewritten by
ensureTerminfoSetupon every Architect launch, so existing users get the fix automatically the next time they open the app.Regression test
src/shell.zigadds a new test that writes the embedded terminfo source to a temp dir, runstic -xagainst it, and asserts the first two bytes of the compiled file are0x1a 0x01. The test skips witherror.SkipZigTestwhenticis not onPATH. Verified: it fails before the fix (gets0x1e, the long-int marker) and passes after.Also added
_ = @import("shell.zig");to the root test block insrc/main.zig, since shell.zig's tests weren't previously reachable from the test entry point. This incidentally enables the existingpathContainsEntrytest, which still passes.Closes #318
Test plan
~/.cache/architect/terminfoto force a fresh compile, build withzig build, launch Architect.git logand confirm the pager opens directly into the log view with no warning prompt above it.less /etc/hostsandman ls— both should open without the warning.infocmp "$TERM"inside the session resolves the entry and showspairs#0x7fffnear the top.