buninu-linux 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSES/Apache-2.0.txt +202 -0
  2. package/LICENSES/BSD-3-Clause-Skia.txt +29 -0
  3. package/LICENSES/Bitstream-Vera.txt +44 -0
  4. package/LICENSES/MIT-xterm.js.txt +21 -0
  5. package/LICENSES/OFL-1.1.txt +91 -0
  6. package/NOTICE.md +18 -1
  7. package/README.md +48 -1
  8. package/graphics.md +213 -0
  9. package/initramfs/bin/bunterm +66 -0
  10. package/initramfs/buninu/CHANGELOG.md +40 -0
  11. package/initramfs/buninu/apps/jsgotty/gotty.js +4 -3
  12. package/initramfs/buninu/apps/jsgotty/package.json +1 -1
  13. package/initramfs/buninu/package.json +1 -1
  14. package/initramfs/init.js +6 -0
  15. package/initramfs/lib/bunterm/glyphs.js +446 -0
  16. package/initramfs/lib/bunterm/images.js +225 -0
  17. package/initramfs/lib/bunterm/input.js +140 -0
  18. package/initramfs/lib/bunterm/renderer.js +424 -0
  19. package/initramfs/lib/bunterm/terminal.js +203 -0
  20. package/initramfs/lib/canvas.js +181 -0
  21. package/initramfs/lib/canvaskit/LICENSE +29 -0
  22. package/initramfs/lib/canvaskit/canvaskit.js +264 -0
  23. package/initramfs/lib/canvaskit/canvaskit.wasm +0 -0
  24. package/initramfs/lib/dlopen.js +14 -2
  25. package/initramfs/lib/fbdev.js +581 -0
  26. package/initramfs/lib/xterm/LICENSE +21 -0
  27. package/initramfs/lib/xterm/addon-unicode-graphemes.mjs +44 -0
  28. package/initramfs/lib/xterm/xterm-headless.mjs +46 -0
  29. package/initramfs/usr/share/doc/buninu-linux/bunterm.md +83 -0
  30. package/initramfs/usr/share/doc/buninu-linux/canvas.md +91 -0
  31. package/initramfs/usr/share/doc/buninu-linux/fbdev.md +113 -0
  32. package/initramfs/usr/share/fonts/DejaVuSansMono-Bold.ttf +0 -0
  33. package/initramfs/usr/share/fonts/DejaVuSansMono.ttf +0 -0
  34. package/initramfs/usr/share/fonts/LICENSE-Apache-2.0.txt +202 -0
  35. package/initramfs/usr/share/fonts/LICENSE-DejaVu.txt +44 -0
  36. package/initramfs/usr/share/fonts/LICENSE-OFL-1.1.txt +91 -0
  37. package/initramfs/usr/share/fonts/NotoColorEmoji.ttf +0 -0
  38. package/initramfs/usr/share/fonts/NotoColorEmojiFlags.ttf +0 -0
  39. package/initramfs/usr/share/fonts/NotoSansCJK-Regular.ttc +0 -0
  40. package/initramfs/usr/share/fonts/NotoSansSymbols-Regular-Subsetted.ttf +0 -0
  41. package/initramfs/usr/share/fonts/NotoSansSymbols-Regular-Subsetted2.ttf +0 -0
  42. package/initramfs/usr/share/fonts/Roboto-Regular.ttf +0 -0
  43. package/initramfs/usr/share/fonts/fonts.json +28 -0
  44. package/package.json +2 -2
  45. package/run-qemu.sh +1 -1
package/graphics.md ADDED
@@ -0,0 +1,213 @@
1
+ # The Buninu Linux graphics stack
2
+
3
+ Buninu Linux draws on the screen without X11, Wayland, a GPU or any native
4
+ graphics library: the Linux framebuffer is mapped into Bun, Skia (compiled to
5
+ WebAssembly as CanvasKit) rasterizes into it, and `bunterm` puts an
6
+ xterm-compatible terminal on top. Everything is JavaScript or WebAssembly
7
+ except the kernel's `/dev/fb0`, reached through a few `ioctl`s and one `mmap`
8
+ via Bun FFI.
9
+
10
+ ```
11
+ ┌──────────────────────────────────────────────────────────────────────┐
12
+ │ programs on a PTY: bunmsh, jsmdcui, bun scripts, kitten icat … │
13
+ └───────────────▲───────────────────────────────┬──────────────────────┘
14
+ keyboard │ (raw console bytes) │ output bytes + kitty APC
15
+ ┌───────────────┴───────────────────────────────▼──────────────────────┐
16
+ │ /bin/bunterm → /lib/bunterm/terminal.js │
17
+ │ BunPtyBackend (jsgotty) ─ Bun.spawn({ terminal }) ← Bun's PTY │
18
+ │ KittyGraphicsParser (jsgotty) ─ splits ESC _ G … ESC \ packets │
19
+ │ @xterm/headless Terminal ─ VT parser, screen buffer, attributes │
20
+ │ images.js ─ kitty placements as Skia images anchored to lines │
21
+ │ input.js ─ /dev/ttyN raw mode, console→xterm key sequences │
22
+ │ renderer.js ─ cells → glyphs (fonts) or vectors (glyphs.js) │
23
+ └───────────────────────────────────────────────┬──────────────────────┘
24
+ │ Skia draw calls
25
+ ┌───────────────────────────────────────────────▼──────────────────────┐
26
+ │ /lib/canvas.js ─ CanvasKit 0.41.1 (Skia in wasm, /lib/canvaskit/) │
27
+ │ openCanvas(): MakeRasterDirectSurface in the framebuffer's own │
28
+ │ pixel format (BGRA_8888 / RGBA_8888 / RGB_565) inside the wasm heap │
29
+ │ loadFontSet(): /usr/share/fonts/fonts.json → Typefaces + FontMgr │
30
+ └───────────────────────────────────────────────┬──────────────────────┘
31
+ │ one memcpy per frame
32
+ ┌───────────────────────────────────────────────▼──────────────────────┐
33
+ │ /lib/fbdev.js ─ Framebuffer: FBIOGET_*SCREENINFO, mmap, KDSETMODE │
34
+ │ runGraphics(): graphics mode + restore on exit/signal │
35
+ │ JS drawing (drawLine, fillPolygon …) and blitImageData() fallback │
36
+ └───────────────────────────────────────────────┬──────────────────────┘
37
+ │ ioctl / mmap (bun:ffi, /lib/dlopen.js)
38
+ ┌───────────────────────────────────────────────▼──────────────────────┐
39
+ │ Linux: /dev/fb0 (efifb / simpledrm from the UEFI GOP), /dev/ttyN │
40
+ └──────────────────────────────────────────────────────────────────────┘
41
+ ```
42
+
43
+ ## Layers
44
+
45
+ ### 1. Framebuffer — `/lib/fbdev.js`
46
+
47
+ `Framebuffer` opens `/dev/fb0`, reads the variable and fixed screen info
48
+ (size, stride, bits per pixel, the red/green/blue bit offsets) and `mmap`s
49
+ the device. Drawing goes to a JavaScript back buffer laid out exactly like
50
+ the device; `flush()` copies it row by row into the mapping. Nothing draws
51
+ straight into the mapping: on efifb the memory is write-combining, reads are
52
+ very slow, and drawing there would tear.
53
+
54
+ `runGraphics(draw)` wraps a graphical program: it switches the virtual
55
+ console to `KD_GRAPHICS` (otherwise the kernel's text console keeps
56
+ overwriting the screen), runs `draw`, and restores `KD_TEXT` whether the
57
+ call returns, throws, exits, or is killed by a catchable signal. Given a
58
+ specific `/dev/ttyN`, it `VT_ACTIVATE`s that console first and switches
59
+ back to the previous one at the end; while drawing it takes `VT_PROCESS`
60
+ mode, so Ctrl-Alt-Fn still switches consoles and `onAcquire` lets the
61
+ program repaint when its console returns.
62
+
63
+ Manual: `fbdev --help` / `initramfs/usr/share/doc/buninu-linux/fbdev.md`.
64
+
65
+ ### 2. Skia — `/lib/canvas.js` and `/lib/canvaskit/`
66
+
67
+ CanvasKit is Google's Skia compiled to WebAssembly (the same npm package the
68
+ browser uses). WebAssembly can only write its own linear memory, so Skia
69
+ cannot draw into the `mmap` directly. Instead `openCanvas()` allocates a
70
+ buffer in the wasm heap and creates a `MakeRasterDirectSurface` on it in the
71
+ framebuffer's native pixel layout (`pickColorType()` maps the kernel's
72
+ bitfields to `BGRA_8888` for the usual XRGB8888, or `RGBA_8888` /
73
+ `RGB_565`). The `Framebuffer`'s `pixels` view is pointed at that buffer, so
74
+ `flush()` is the same single `memcpy` as before and the JavaScript drawing
75
+ functions keep working on the same frame. A 24-bit or paletted device falls
76
+ back to CanvasKit's HTML-canvas emulation plus `blitImageData()`, which
77
+ converts per pixel.
78
+
79
+ Skia is CPU-only here (no GPU, no WebGL); the whole 1080p frame is a few
80
+ milliseconds to copy and cells are cached by Skia's glyph cache. The wasm
81
+ heap starts at 128 MiB and grows as fonts are loaded into it, which is why
82
+ QEMU is now started with `-m 1G`.
83
+
84
+ `loadFontSet()` reads `/usr/share/fonts/fonts.json` and builds the typefaces
85
+ and a `FontMgr` for a named set (`terminal`, `ui`). Noto Sans CJK is a
86
+ collection; the manager registers all five faces and the set's preferred
87
+ face (`Noto Sans CJK TC`) is the one handed out, so Taiwanese glyph forms
88
+ are used without relying on `locl`.
89
+
90
+ Manual: `initramfs/usr/share/doc/buninu-linux/canvas.md`.
91
+
92
+ ### 3. Fonts — `/usr/share/fonts/`
93
+
94
+ | File | Role | License |
95
+ |---|---|---|
96
+ | `DejaVuSansMono.ttf`, `-Bold.ttf` | terminal grid font: 0.6 em wide, 1.16 em tall, box drawing, arrows, `☐☒✓`, Braille-free but everything jsmdcui draws | Bitstream Vera |
97
+ | `NotoSansCJK-Regular.ttc` | 32 MiB variable collection: JP/KR/SC/TC/HK faces, ~21 000 unified ideographs, ext. A, part of ext. B, kana, bopomofo, hangul, full-width forms | OFL 1.1 |
98
+ | `NotoColorEmoji.ttf`, `NotoColorEmojiFlags.ttf` | CBDT bitmap colour emoji; Skia's FreeType port renders them in colour | OFL 1.1 |
99
+ | `NotoSansSymbols-Regular-Subsetted.ttf`, `-Subsetted2.ttf` | arrows, math, geometric shapes, dingbats, Braille, musical symbols, cards | OFL 1.1 |
100
+ | `Roboto-Regular.ttf` | variable Latin/Greek/Cyrillic for non-terminal UI (`ui` set) | Apache 2.0 |
101
+
102
+ The Noto and Roboto files are the ones Android ships; DejaVu comes from
103
+ Debian. Each license text sits next to the fonts and in `LICENSES/`.
104
+
105
+ ### 4. Terminal — `/bin/bunterm` and `/lib/bunterm/`
106
+
107
+ `bunterm` reuses three finished components instead of writing a terminal
108
+ from scratch:
109
+
110
+ - **PTY**: jsgotty's `BunPtyBackend`, which is `Bun.spawn(cmd, { terminal:
111
+ { cols, rows, data, exit } })` — Bun's built-in pseudo-terminal, no
112
+ node-pty, no FFI. jsgotty now exports the class for this.
113
+ - **Emulation**: `@xterm/headless`, the xterm.js core (VT parser, screen
114
+ and scrollback buffers, SGR attributes, terminal replies, markers) with
115
+ its DOM renderer removed. `@xterm/addon-unicode-graphemes` makes 🇹🇼,
116
+ ZWJ sequences and combining marks occupy one cell.
117
+ - **Images**: jsgotty's `KittyGraphicsParser`, which splits the kitty
118
+ graphics APC packets out of the byte stream, reassembles chunked
119
+ transfers, inflates `o=z`, and produces placement / delete / query events
120
+ and the replies to send back. (Two small changes to the vendored jsgotty:
121
+ the export, and later chunks of a transfer whose first chunk named `i=`
122
+ now continue that transfer, as the protocol allows — to be carried back
123
+ to the jsgotty repository.)
124
+
125
+ Around those, `/lib/bunterm/` adds:
126
+
127
+ | File | Does |
128
+ |---|---|
129
+ | `renderer.js` | Paints `term.buffer` cell by cell. Cell size comes from DejaVu Sans Mono; every glyph is looked up in the regular font, then the fallbacks (colour emoji first for emoji-presentation code points, monochrome symbols first otherwise) and centred in its one or two cells; oversized fallback glyphs are scaled to fit. Multi-code-point graphemes are shaped by Skia's `Paragraph` and cached. Only rows whose content hash changed since the last frame, the cursor rows, and rows under moved images are repainted. 16/256/24-bit colour, bold (with bright base colours), italic, dim, underline, strikethrough, inverse, invisible. |
130
+ | `glyphs.js` | Box drawing (U+2500–257F incl. double, dashed, rounded, mixed-weight), block elements and shades (U+2580–259F), Powerline (U+E0A0–E0BF) and legacy computing (U+1FB70–1FB97) drawn as Skia paths, so they meet seamlessly at any size. The shape tables are xterm.js's `CustomGlyphs.ts` (MIT); coordinates snap to pixel centres for crisp 1-px lines. |
131
+ | `images.js` | Kitty placements: decodes PNG (`f=100`) with Skia or raw RGB/RGBA (`f=24/32`), with `Bun.Image` as a transcoder for other encodings; anchors each placement to an xterm marker so it scrolls with its line and disappears with it (on the alternate screen, where xterm.js issues no markers, to a fixed row that is dropped when that screen ends); sizes in cells (`c,r`) or from pixel size; crops (`x,y,w,h`), cell offsets (`X,Y`), `p=` placement ids, `a=d` deletion scopes, and the cursor move after a placement. |
132
+ | `input.js` | Raw mode on the console (`TCGETS`/`TCSETS` through the shared libc binding) and translation of the kernel's "linux" key sequences to xterm's, honouring DECCKM. |
133
+ | `terminal.js` | `createSession()` wires PTY → parser → emulator → renderer with a coalesced ~60 Hz frame timer and a serialized output queue, so a kitty packet always sees the cursor position left by the text before it. `runTerminal()` adds `runGraphics()` and the keyboard. |
134
+
135
+ Manual: `bunterm --help` / `initramfs/usr/share/doc/buninu-linux/bunterm.md`.
136
+
137
+ ## Data flow of one frame
138
+
139
+ 1. The program writes to the PTY; Bun delivers the bytes to `BunPtyBackend`'s
140
+ `data` callback.
141
+ 2. `KittyGraphicsParser.consume()` returns plain-text runs and kitty packets
142
+ in order. Plain runs go to `term.write()` (awaited, so the buffer is
143
+ current); each packet is parsed with the cursor position at that point,
144
+ handed to `ImageStore`, and acknowledged back to the PTY if the client
145
+ asked.
146
+ 3. A frame is requested. Sixteen milliseconds later `Renderer.render()`
147
+ hashes each visible row, repaints the changed ones (background rect,
148
+ glyph or vector, underline), draws the cursor block, and re-draws the
149
+ parts of image placements that intersect the repainted rows.
150
+ 4. `screen.flush()` finishes Skia's work and copies the wasm-heap frame into
151
+ the `/dev/fb0` mapping.
152
+
153
+ Keyboard bytes travel the other way: console → `input.js` → PTY. Terminal
154
+ replies (cursor position, device attributes, kitty acks) go from the
155
+ emulator straight to the PTY.
156
+
157
+ ## Sizes
158
+
159
+ | Component | Raw | In the gzip initramfs |
160
+ |---|---|---|
161
+ | CanvasKit wasm + js | 7.3 MB | ~2.7 MB |
162
+ | xterm headless + graphemes addon | 0.2 MB | ~0.05 MB |
163
+ | Fonts | 39.9 MB | ~24 MB |
164
+ | Total added | ~47 MB | ~27 MB |
165
+
166
+ The initramfs grew from 44.7 MB to 71.8 MB compressed; the UKI is 84.5 MB and
167
+ the 127 MB EFI system partition keeps 46 MB free. The initramfs is unpacked
168
+ into RAM, and CanvasKit copies the fonts it uses into its heap, so the guest
169
+ needs about 1 GB.
170
+
171
+ ## Trying it
172
+
173
+ The framebuffer needs a kernel that provides one. Alpine's `linux-lts` has
174
+ `CONFIG_FB`, `CONFIG_FB_EFI` and `CONFIG_DRM_SIMPLEDRM` built in; the default
175
+ `linux-virt` builds them as modules, and the image ships only the network,
176
+ storage, USB and HID modules, so there `/dev/fb0` never appears. Build with
177
+ `./index.js -b --linux-lts` (or `--real`); under QEMU the lts kernel gets a
178
+ 1280×800 `simpledrm` framebuffer from the UEFI GOP even with `-display none`,
179
+ and the monitor's `screendump` shows it. From a virtual console in the guest:
180
+
181
+ ```sh
182
+ bunterm # /bin/sh on this console
183
+ bunterm /dev/tty1 --font-size 20 # from a serial console, use VT 1
184
+ bunterm -e bun /buninu/apps/jsmdcui/src/index.js --demo
185
+ bun /lib/fbdev.js # the plain-framebuffer triangle
186
+ ```
187
+
188
+ To render off-screen on the build host (no framebuffer), give `openCanvas()`
189
+ a plain object with `width`, `height`, `stride`, `bitsPerPixel`, `fields` and
190
+ a `pixels` `Uint8Array`, replace `screen.flush`, and snapshot the surface —
191
+ that is how the renderer and the kitty pipeline were tested during
192
+ development (`BUNINU_LIBC=/lib/aarch64-linux-gnu/libc.so.6` lets `dlopen.js`
193
+ load the host libc).
194
+
195
+ Verified in QEMU (lts kernel, `-vga std`, 1 GB): the attribute/CJK/emoji
196
+ sample, a kitty PNG placement, an interactive bunmsh with keys sent through
197
+ the console, and the jsmdcui editor demo all render as on the host;
198
+ `bunterm /dev/tty2` from the serial REPL switches the display to tty2 and
199
+ back to tty1 on exit, and Ctrl-Alt-F2 / Ctrl-Alt-F1 during a session
200
+ switch away and repaint on return. On the
201
+ host, `jsmdcui --tui` on a Markdown file with a JPEG (bunterm sets
202
+ `JSMDCUI_KITTY_MODE=extended` for the program it runs) places the image
203
+ through its transmit / `a=p` / `a=d` sequence exactly as in the browser.
204
+
205
+ ## Not done yet
206
+
207
+ - Mouse, selection and scrollback viewing in `bunterm`.
208
+ - Kitty `z < 0` (images behind text), animation frames, Unicode
209
+ placeholders, and shared-memory transmission.
210
+ - Text run shaping with ligatures for single-code-point cells (each cell is
211
+ one glyph; Paragraph shaping is only used for grapheme clusters).
212
+ - Non-terminal UI on `canvas.js` (the `ui` font set and Roboto are there for
213
+ it).
@@ -0,0 +1,66 @@
1
+ #!/bin/bun
2
+ // bunterm — a graphical terminal emulator on the Linux framebuffer.
3
+
4
+ import { showDocument } from "../lib/document.js";
5
+ import { runTerminal } from "../lib/bunterm/terminal.js";
6
+
7
+ const usage = () => {
8
+ console.error(`Usage:
9
+ bunterm [/dev/ttyN] [--font-size N] [--fb /dev/fb0] [-e command [argument...]]
10
+ bunterm -h | --help`);
11
+ };
12
+
13
+ const main = async () => {
14
+ const options = { argv: [] };
15
+ const arguments_ = process.argv.slice(2);
16
+ for (let index = 0; index < arguments_.length; index++) {
17
+ const argument = arguments_[index];
18
+ if (argument === "-h" || argument === "--help") {
19
+ await showDocument("bunterm");
20
+ return 0;
21
+ }
22
+ if (argument === "-e") {
23
+ if (index + 1 >= arguments_.length) {
24
+ usage();
25
+ throw new Error("-e needs a command");
26
+ }
27
+ options.command = arguments_[index + 1];
28
+ options.argv = arguments_.slice(index + 2);
29
+ break;
30
+ }
31
+ const valued = (name) => {
32
+ const value = argument.startsWith(`${name}=`) ? argument.slice(name.length + 1) : arguments_[++index];
33
+ if (value === undefined) {
34
+ usage();
35
+ throw new Error(`${name} needs a value`);
36
+ }
37
+ return value;
38
+ };
39
+ if (argument === "--font-size" || argument.startsWith("--font-size=")) {
40
+ options.fontSize = Number(valued("--font-size"));
41
+ if (!Number.isFinite(options.fontSize) || options.fontSize < 6) throw new Error("--font-size must be a number of at least 6");
42
+ } else if (argument === "--line-height" || argument.startsWith("--line-height=")) {
43
+ options.lineHeight = Number(valued("--line-height"));
44
+ if (!Number.isFinite(options.lineHeight) || options.lineHeight <= 0) throw new Error("--line-height must be a positive number");
45
+ } else if (argument === "--fb" || argument.startsWith("--fb=")) {
46
+ options.device = valued("--fb");
47
+ } else if (argument === "--no-blink") {
48
+ options.cursorBlink = false;
49
+ } else if (argument.startsWith("/dev/")) {
50
+ options.console = argument;
51
+ } else {
52
+ usage();
53
+ throw new Error(`unexpected argument: ${argument}`);
54
+ }
55
+ }
56
+ return runTerminal(options);
57
+ };
58
+
59
+ let status = 1;
60
+ try {
61
+ status = await main();
62
+ } catch (error) {
63
+ console.error(`bunterm: ${error?.message ?? error}`);
64
+ }
65
+ // A pending console read would otherwise keep the process alive.
66
+ process.exit(status);
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.15 - 2026-09-22
4
+
5
+ ### Changed
6
+
7
+ - Sync jsgotty to 1.1.12
8
+ * Export `BunPtyBackend` from `gotty.js`, the PTY layer built on
9
+ `Bun.spawn({ terminal })`, so other programs can run a command on a
10
+ pseudo-terminal without their own FFI. Buninu Linux's `bunterm`, a
11
+ graphical terminal on the framebuffer, is its first user, together with
12
+ the already exported `KittyGraphicsParser`
13
+
14
+ ### Fixed
15
+
16
+ - jsgotty: a chunked kitty graphics transfer whose first chunk names an
17
+ image id (`i=`) is now continued by later chunks that carry only `m=`, as
18
+ the protocol allows. Previously those chunks were treated as new anonymous
19
+ transfers, so the image never completed. jsgotty's own `showimg` repeats
20
+ the id in every chunk and was unaffected; `kitten icat`, timg, chafa and
21
+ similar clients were
22
+
23
+ ## 0.4.13 - 2026-09-22
24
+
25
+ ### Changed
26
+
27
+ - Sync bunmsh to 0.3.9
28
+ * `Ctrl-U` removes and saves the text before the cursor; pressing it again
29
+ at the beginning of the line restores it. `Ctrl-K` independently toggles
30
+ the text after the cursor when at the end of the line
31
+ * Unquoted pathname patterns follow directory symbolic links used as
32
+ intermediate path components, as traditional shells do, so patterns such
33
+ as `/sys/class/net/*/device` pass through sysfs class links
34
+ * The fallback `ls`/`lsfancy` lists a glob's files as one listing instead
35
+ of one section per file, honors `--`, and follows a command-line symlink
36
+ to a directory
37
+ - Sync jsmdcui to 0.19.2
38
+ * Pressing `Ctrl-W` twice quickly switches to the next tab like `Alt-T`
39
+ from either an editor or a terminal pane; at the rightmost tab, when every
40
+ tab holds only terminal panes, it opens a new editor tab instead of
41
+ cycling back
42
+
3
43
  ## 0.4.12 - 2026-09-20
4
44
 
5
45
  ### Fixed
@@ -1173,9 +1173,9 @@ class KittyGraphicsParser {
1173
1173
 
1174
1174
  if (control.m === "1") {
1175
1175
  this.transfers.set(key, existing);
1176
- if (!control.i && !control.I) {
1177
- this.implicitTransferKey = key;
1178
- }
1176
+ // Later chunks of a transfer only need m=; they continue the transfer
1177
+ // in progress whether or not its first chunk named an image id.
1178
+ this.implicitTransferKey = key;
1179
1179
  return null;
1180
1180
  }
1181
1181
 
@@ -3314,6 +3314,7 @@ async function bootstrap() {
3314
3314
 
3315
3315
  module.exports.CursorStateTracker = CursorStateTracker;
3316
3316
  module.exports.KittyGraphicsParser = KittyGraphicsParser;
3317
+ module.exports.BunPtyBackend = BunPtyBackend;
3317
3318
  module.exports.webSocketOriginAllowed = webSocketOriginAllowed;
3318
3319
 
3319
3320
  if (require.main === module) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsgotty",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "Share your terminal as a web application: A JavaScript rewrite of GoTTY",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu",
3
- "version": "0.4.13",
3
+ "version": "0.4.15",
4
4
  "description": "Buninu is a portable, self-bootstrapping Unix-like userspace built on Bun that runs across operating systems",
5
5
  "type": "module",
6
6
  "main": "./bin/init.js",
package/initramfs/init.js CHANGED
@@ -341,6 +341,12 @@ const launchBunmsh = () => {
341
341
 
342
342
  const launchBuninu = () => {
343
343
 
344
+ console.log(`
345
+ Type bunterm in bunmsh: Graphical Terminal
346
+ Shows Emojis, CJK chars
347
+ Supports Kitty Graphics Protocol
348
+ `)
349
+
344
350
  const entry = `/buninu/bin/init.js`;
345
351
  console.log(`buninu: Starting ${entry} --local`);
346
352
  const shell = Bun.spawnSync([