Emoji: OpenEmoji built in and on by default, plus the font installer and inline art - #96
Merged
Merged
Conversation
ralyodio
marked this pull request as ready for review
September 24, 2026 07:04
ralyodio
added this pull request to stack #97
September 24, 2026 07:18
…best it can
The OpenEmoji pack (every standard emoji, 3,963 in Emoji 18.0) ships beside
OpenIcon, generated by scripts/generate-emoji.ts into one table for the
TypeScript library and the Go, Python and Rust ports (about 270 KB each):
emoji(), emojify(":tada:"), emojiSearch("lol"), emojiInfo(), setEmojiMode()
and HQTUI_EMOJI=emoji|text. Text is an emoticon where one fits and the name in
brackets elsewhere; the Linux console gets text.
Width: emoji are one two-column cell in every port (TS, Go, Rust, Python, Zig,
C): skin tones join their base, regional indicators pair into flags, tag
sequences join, and U+FE0F, keycaps and a skin tone make a text-default
pictograph two columns (❤️, #️⃣, ☝🏽). Cell width and measured width share one
rule, including when the cluster table is full. Conformance fixtures gain the
emoji cases; unrelated pre-existing drift in screen.json/input.json is left.
TypeScript also gets:
- hqtui fonts install|status|remove and installEmojiFont(): the OpenEmoji
colour font (CBDT on Linux, sbix on macOS) from the set's release, falling
back to the repository, wired through fontconfig (emoji family, other emoji
families aliased, appended to text families so digits stay text), with
Kitty/WezTerm/iTerm2 snippets, backups as <name>.bak-001.<ext> outside
conf.d, and a record that remove undoes. Only on the explicit command.
- emojiImage(): the artwork inline via the Kitty graphics protocol (Kitty,
Ghostty) or iTerm2 images (iTerm2, WezTerm), off unless HQTUI_EMOJI_ART=1,
PNG size from the cell's pixel height x2 (128/256/512, CSI 16 t or
HQTUI_CELL_PX), cached under XDG_CACHE_HOME. Node modules load lazily, so
importing hqtui stays side-effect free.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ay the code does Windows CI caught both: the fallback used the process's emoji mode (text on the runner) instead of the env passed in, and the tests expected path.join's backslashes where the code joins with /. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ralyodio
force-pushed
the
openemoji-pack
branch
from
September 24, 2026 07:30
11a85f6 to
885f731
Compare
ralyodio
added a commit
to profullstack/cli-tools
that referenced
this pull request
Sep 24, 2026
…nt (0.45.2) (#87) `gh pr merge` calls the GraphQL mergePullRequest mutation, and GitHub refuses that mutation outright for a pull request that belongs to a stack, naming the asynchronous merge REST API instead. Nothing is wrong with such a PR: it reads MERGEABLE and CLEAN with every check green, so no repair applies and the sweep just reported FAILED and merged nothing. `Gh.squashMerge` now falls back to PUT /repos/{owner}/{repo}/pulls/{n}/merge-async and polls the uuid it returns until the merge settles. The fallback is narrow on purpose: it fires only on that one refusal message, still pins the head commit, still asks for a squash, and still passes no --admin, so a PR is held to exactly the rules it was held to before. A PR the endpoint hands to a merge queue reports enqueued, which counts as merged because nothing further is ours to do. The refusal is matched on the message rather than on the base branch: GitHub still calls a PR stacked after it has retargeted it onto the default branch, which is how profullstack/hqtui#96 behaved in practice. The shell original in profullstack/scripts got the same fix (v0.3.2) and is being retired in favour of this one. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio
added a commit
that referenced
this pull request
Sep 24, 2026
The version sites that no build step touches, moved together: the library and demo package.json, the CLI's VERSION, the demo's --version string, the site badge, and the workspace ranges in bun.lock. A minor rather than a patch because the public API grew: icon() and emoji() landed in #95 and #96, along with `hqtui fonts install`. The three ^0.6.2 ranges in apps/web, apps/benchmark and examples move too. A caret below 1.0.0 stops at <0.7.0, so left alone they would declare a range the library in this tree no longer satisfies. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Stacked on #95 (OpenIcon), so the two land together. Retarget to
mainonce #95 merges.The pack. OpenEmoji (every standard emoji, 3,963 in Emoji 18.0) is built in and on by default, next to OpenIcon.
scripts/generate-emoji.tswrites one table for TypeScript, Go, Python and Rust, about 270 KB each (skin-tone variants stored as key plus base, shortcodes only where they differ from the name, the ten rarest CLDR keywords).emoji(),emojify(":tada:"),emojiSearch("lol"),emojiInfo(),emojiText(),setEmojiMode(),HQTUI_EMOJI=emoji|text.Emoji/EmojiIn/Emojify/EmojiSearch, Pythonemoji/emojify/emoji_search, Rustemoji/emoji_in/emojify/emoji_search.:),<3), otherwise[name]. The Linux console gets text.Width, in every port. An emoji is now one two-column cell in TS, Go, Rust, Python, Zig and C:
Cell width and measured width share one rule, including when the cluster table is full. The conformance fixtures gain these cases.
screen.json/input.jsonalready drift from the generator onopenicon-packitself; that drift is left alone.hqtui fonts install | status | remove(TypeScript; runs only on that explicit command):~/.local/share/fontson Linux, sbix into~/Library/Fontson macOS.emojifamily, the other emoji families alias to it, and it is appended to monospace/sans/serif so digits stay text. Thenfc-cache.symbol_mapand WezTermfont_with_fallbacklines, and on macOS the iTerm2 setting and the Terminal.app caveat.<name>.bak-001.<ext>in~/.config/hqtui/backups, outside conf.d.removeundoes everything and restores those files.emojiImage()draws the artwork inline (Kitty graphics in Kitty/Ghostty, iTerm2 images in iTerm2/WezTerm).HQTUI_EMOJI_ART=1; tmux and every other terminal get the character.HQTUI_CELL_PX), chosen from 128/256/512, cached underXDG_CACHE_HOME.Docs: an Emoji section on hqtui.com/docs and in the package README, including the xterm.js
openemoji.cssnote.Tests run locally:
-race, Rust (46 + 17 demo), Python (45), Zig (16), and C ctest with conformance all pass.What was actually verified:
fonts installran with real fontconfig in a sandbox home:fc-matchgave OpenEmoji for emoji and U+1F525, while the digit 7 stayed DejaVu Sans Mono.removerestored the original.🤖 Generated with Claude Code