buninu-linux 0.7.0 → 0.7.1

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.
package/README.md CHANGED
@@ -36,6 +36,7 @@
36
36
  * `start` starts the Buninu userspace shell
37
37
  * `cfg.disk` + shell `mount` mounts local disks
38
38
  * `cfg.net` loads common wired NIC and Android USB-tethering drivers
39
+ * `cfg.sound` loads every packaged ALSA sound module
39
40
  * Android phone USB tethering over RNDIS has been tested successfully, allowing Buninu Linux to access the Internet through an Android phone
40
41
  * IP addresses and routes are configured manually because the image does not yet include a DHCP client.
41
42
  * The bundled `jmi` editor, jsmdcui App runtime, and local JavaScript execution also work.
@@ -45,6 +46,7 @@
45
46
  + Also has mouse click, wheel, and cursor drawing
46
47
  + Simplified browser works: @sanohiro/casty in chroot debian
47
48
  + (Use at your own risk: We haven't fully examined its code)
49
+ + Playing YouTube with sound(experimental)
48
50
  + See [Commands inside `/bin`](#commands-inside-bin) for browser usage instructions
49
51
 
50
52
  ---
@@ -142,7 +144,7 @@ display and USB keyboard with a welcome ending like this:
142
144
  Welcome to Buninu Linux!
143
145
  Bun 1.4.2 is now PID 1
144
146
  Type start() to run buninu --local
145
- Configuration getters: cfg.all, cfg.disk, cfg.net, cfg.power
147
+ Configuration getters: cfg.all, cfg.disk, cfg.net, cfg.power, cfg.sound
146
148
 
147
149
  bun-repl>
148
150
  ```
@@ -157,6 +159,7 @@ Load only the subsystem needed, then enter the Buninu shell:
157
159
  cfg.net // wired NIC and Android USB-tethering drivers
158
160
  cfg.disk // SATA/NVMe/USB storage drivers and detected block devices
159
161
  cfg.power // battery, AC, button and thermal drivers
162
+ cfg.sound // all packaged ALSA sound modules and detected sound devices
160
163
  start()
161
164
  ```
162
165
 
@@ -208,6 +211,8 @@ bun ./index.js -fbr
208
211
  The first boot line from `run-qemu.sh` names the guest, machine, accelerator
209
212
  and firmware it picked. A bare `-r` boots whichever architecture `vda.img`
210
213
  was last built for; `-br --arch arm64` is the aarch64 edit-and-boot loop.
214
+ To run `bunterm` in a QEMU window on the aarch64 guest, see
215
+ [What differs on aarch64](#what-differs-on-aarch64).
211
216
 
212
217
  #### amd64 Linux
213
218
 
@@ -231,9 +236,32 @@ qemu-efi-aarch64` to run.
231
236
  Alpine's aarch64 packages and `bun-linux-aarch64-musl`.
232
237
  * The serial console is `ttyAMA0` (QEMU `virt`'s PL011) instead of `ttyS0`.
233
238
  * `--real` is x86_64 only: its module set is PC hardware.
234
- * The current aarch64 QEMU configuration supplies no framebuffer or PS/2
235
- devices, so `bunterm` has nothing to draw on yet; the serial REPL and the
236
- Buninu shell work as on x86_64.
239
+ * QEMU's `virt` machine has no display or PS/2 devices, so by default
240
+ `bunterm` has nothing to draw on; the serial REPL and the Buninu shell work
241
+ as on x86_64. To run `bunterm`, build with `--linux-lts` and give QEMU a
242
+ `ramfb` display and virtio input devices. On a Mac, `-display cocoa` opens
243
+ the window:
244
+
245
+ ```sh
246
+ bun ./index.js -fbr --arch arm64 --linux-lts -- \
247
+ -device ramfb -device virtio-keyboard-pci -device virtio-mouse-pci -display cocoa
248
+ ```
249
+
250
+ Once that image is built, boot it again without rebuilding (and without
251
+ Docker). `--linux-lts` belongs to the build, so leave it off `-r`:
252
+
253
+ ```sh
254
+ bun ./index.js -r --arch arm64 -- \
255
+ -device ramfb -device virtio-keyboard-pci -device virtio-mouse-pci -display cocoa
256
+ ```
257
+
258
+ `start()` in the serial REPL, then `bunterm 2` opens bunterm on VT 2 in the
259
+ QEMU window and returns to the serial shell; type into the window. The
260
+ serial console is not a VT, so a bare `bunterm` there takes the active VT 1
261
+ and holds the serial shell until it exits; naming another VT starts it
262
+ detached (see [Multiple virtual consoles with bunterm](#multiple-virtual-consoles-with-bunterm)). The
263
+ firmware sets up ramfb at 800×600, and `init.js` loads `simpledrm` so it
264
+ becomes `/dev/fb0` (see [graphics.md](graphics.md#trying-it)).
237
265
  * `--export` writes `buninu-linux-<version>-aarch64.img`.
238
266
  * Before the kernel starts, Homebrew's aarch64 EDK2 prints a few
239
267
  `Error: Image at … start failed` lines (its own drivers for hardware `virt`
@@ -283,6 +311,7 @@ Load only the hardware subsystem you need:
283
311
  cfg.net
284
312
  cfg.disk
285
313
  cfg.power
314
+ cfg.sound
286
315
  ```
287
316
 
288
317
  `cfg.net` loads the packaged wired-network and Android USB-tethering drivers and prints detected
@@ -298,7 +327,10 @@ ip route add default via 192.168.1.1
298
327
  The real image initializes `/etc/resolv.conf` with `1.1.1.1` and `8.8.8.8`;
299
328
  replace them if your network requires different DNS servers. `cfg.disk` loads
300
329
  common SATA/PATA/SCSI, NVMe/VMD and USB-storage drivers so detected disks and
301
- partitions appear in `/dev`. To inspect a filesystem without mounting it:
330
+ partitions appear in `/dev`. `cfg.sound` unconditionally loads every sound
331
+ module packaged in the image, then lists the resulting `/dev/snd` devices; it
332
+ does not probe the hardware before loading modules. To inspect a filesystem
333
+ without mounting it:
302
334
 
303
335
  ```sh
304
336
  mount -fv /dev/sda1 /mnt
@@ -475,7 +507,32 @@ below a shown image, and images scroll with the text. When the program you
475
507
  started exits, the console returns to text mode. `bunterm --help` has the
476
508
  options; [graphics.md](graphics.md) describes how it is built. The image
477
509
  needs a kernel with a framebuffer: build with `--linux-lts` or `--real`
478
- (the default `linux-virt` builds one only as modules the image omits).
510
+ (the default `linux-virt` builds one only as modules the image omits). The
511
+ aarch64 guest also needs a QEMU display; see
512
+ [What differs on aarch64](#what-differs-on-aarch64).
513
+
514
+ ### Clipboard
515
+
516
+ `bunterm` supports copy and paste through OSC 52, so programs such as
517
+ `casty` and `jsmdcui` can use the clipboard. bunterm keeps nothing itself; it
518
+ passes every copy and paste to Buninu's `xclip -selection clipboard`. For
519
+ now that clipboard is a file, `$HOME/.xclip.clipboard`, read and written in
520
+ the ramdisk, so all bunterm sessions share it and it is gone after a reboot.
521
+ `bunterm --no-clipboard` turns OSC 52 off.
522
+
523
+ For Chinese input, run the pinyin input method
524
+ [jspinyin](https://www.npmjs.com/package/@drxiaozhi/jspinyin) in a bunterm
525
+ that is not inside a chroot, so it uses Buninu's `xclip`:
526
+
527
+ ```sh
528
+ bun x @drxiaozhi/jspinyin
529
+ ```
530
+
531
+ - jspinyin → casty: press `Ctrl-C` in jspinyin to copy its result box, then
532
+ `Ctrl-V` in casty pastes it through OSC 52.
533
+ - casty → jsmdcui / jspinyin: `Alt-C` in casty copies the selection through
534
+ OSC 52, and `Ctrl-V` pastes it in jsmdcui or jspinyin, since jsmdcui reads
535
+ from `xclip` first by default.
479
536
 
480
537
  ## Commands inside /bin
481
538
 
@@ -561,7 +618,10 @@ git clone https://github.com/jjtseng93/casty
561
618
  cd casty/bin
562
619
  # When clicking around, don’t release the mouse button immediately after pressing it, to make sure the mouse-down event is triggered
563
620
  bun casty.js buninu.org
564
-
621
+ # Playing YouTube with sound(experimental)
622
+ # make sure you have run `cfg.sound` in bun-repl
623
+ # follow the dumped instructions
624
+ bun x bunproot --setup.pulse
565
625
 
566
626
 
567
627
  # Download and enter an x64 Alpine minirootfs
@@ -753,7 +813,7 @@ its own.
753
813
  ```text
754
814
  index.js entry point: -f / -b / -r / --arch / --docker / --export / --linux-lts / --real
755
815
  Dockerfile the Debian 13 build toolchain for --docker (and macOS)
756
- fetch-alpine.sh [fetch] kernel, EFI stub, musl, network/input modules
816
+ fetch-alpine.sh [fetch] kernel, EFI stub, musl, network/input/display modules
757
817
  fetch-bun.sh [fetch] Bun, libstdc++, libgcc
758
818
  build-uki.sh [build] UKI; calls scripts/pack-initramfs.sh
759
819
  build-image.sh [build] GPT disk image; shared with the hello-world EFI
@@ -1089,7 +1149,7 @@ until `cfg.net` loads the packaged drivers and the user assigns an address and
1089
1149
  route.
1090
1150
 
1091
1151
  On a `--real` image the REPL also offers the getter-based `cfg` namespace:
1092
- `cfg.net`, `cfg.disk`, `cfg.power` and `cfg.all` run as soon as the property is read, without
1152
+ `cfg.net`, `cfg.disk`, `cfg.power`, `cfg.sound` and `cfg.all` run as soon as the property is read, without
1093
1153
  parentheses. `cfg.net` loads every packaged network module (including PHY and bus support),
1094
1154
  then reads the `modalias` of every PCI and USB network device, matches it
1095
1155
  against the `pci:`/`usb:` lines
@@ -1101,7 +1161,10 @@ declared dependencies. `--real` ships Intel `e1000`/`e1000e`/`igb`/`igc`,
1101
1161
  Realtek `r8169`, Atheros `alx`, Broadcom `tg3`, common USB dongles, and
1102
1162
  `rndis_host`/`cdc_ether`/`cdc_ncm`/`cdc_eem`/`cdc_subset`/`zaurus` for Android
1103
1163
  USB tethering. `cfg.net` unconditionally attempts all of these packaged
1104
- network modules. `cfg.power` loads the ACPI
1164
+ network modules. `cfg.sound` likewise unconditionally attempts every packaged
1165
+ module below `kernel/sound/`, then lists `/dev/snd`; it does no hardware probe.
1166
+ The packaged sound set covers QEMU ES1371/HDA and common PC HDA/HDMI and USB
1167
+ audio where the selected kernel flavor provides them. `cfg.power` loads the ACPI
1105
1168
  `battery`, `ac`, `button` and `thermal` modules through `/lib/modprobe.js`
1106
1169
  and lists `/sys/class/power_supply` (a desktop without a battery simply
1107
1170
  reports nothing registered). Nothing loads them at boot. PID 1 also installs
@@ -1136,6 +1199,7 @@ for the userspace session.
1136
1199
  - [Pane and tab controls](#pane-and-tab-controls)
1137
1200
  * [Using Bun Modern Shell](#using-bun-modern-shell)
1138
1201
  * [Showing images](#showing-images)
1202
+ * [Clipboard](#clipboard)
1139
1203
  - [Commands inside /bin](#commands-inside-bin)
1140
1204
  - [Environment and dependencies](#environment-and-dependencies)
1141
1205
  * [Build environment](#build-environment)
package/fetch-alpine.sh CHANGED
@@ -81,6 +81,22 @@ if [ "$arch" = x86_64 ]; then
81
81
  else
82
82
  select_module virtio_input
83
83
  fi
84
+ # The framebuffer for bunterm. Both lts kernels set CONFIG_SYSFB_SIMPLEFB, so
85
+ # the UEFI GOP (QEMU's ramfb on aarch64 virt) becomes a simple-framebuffer
86
+ # device that only simpledrm drives: x86_64 lts builds it in, aarch64 lts has
87
+ # it as a module. init.js loads it at boot, which is what makes /dev/fb0.
88
+ if [ "$linux_flavor" = lts ]; then
89
+ select_optional_module simpledrm
90
+ fi
91
+
92
+ # Sound: a compact set covering QEMU's emulated AC97/HDA devices and the
93
+ # usual PC HDA/HDMI and USB-audio paths. Dependencies pull in the ALSA core,
94
+ # PCM, timer, codec and USB support needed by each available leaf driver.
95
+ # Some kernel flavors build fewer of these, so keep every leaf optional.
96
+ for module in snd-ens1371 snd-hda-intel snd-hda-codec-generic \
97
+ snd-hda-codec-hdmi snd-usb-audio; do
98
+ select_optional_module "$module"
99
+ done
84
100
 
85
101
  if [ "${REAL_MACHINE:-}" = 1 ]; then
86
102
  # USB keyboard for the console; common storage paths (SATA/AHCI HDD and
package/graphics.md CHANGED
@@ -174,13 +174,22 @@ needs about 1 GB.
174
174
 
175
175
  ## Trying it
176
176
 
177
- The framebuffer needs a kernel that provides one. Alpine's `linux-lts` has
178
- `CONFIG_FB`, `CONFIG_FB_EFI` and `CONFIG_DRM_SIMPLEDRM` built in; the default
179
- `linux-virt` builds them as modules, and the image ships only the network,
180
- storage, USB and HID modules, so there `/dev/fb0` never appears. Build with
181
- `./index.js -b --linux-lts` (or `--real`); under QEMU the lts kernel gets a
182
- 1280×800 `simpledrm` framebuffer from the UEFI GOP even with `-display none`,
183
- and the monitor's `screendump` shows it. From a virtual console in the guest:
177
+ The framebuffer needs a kernel that provides one. Both `linux-lts` kernels
178
+ set `CONFIG_SYSFB_SIMPLEFB`, so the UEFI GOP becomes a `simple-framebuffer`
179
+ device, which only `simpledrm` drives (`efifb` never sees it). The x86_64
180
+ `linux-lts` builds `simpledrm` in. The aarch64 one has it as a module:
181
+ `fetch-alpine.sh` ships it and its DRM dependencies for lts builds, and
182
+ `init.js` loads it at boot. The default `linux-virt` builds the framebuffer
183
+ drivers as modules, and the image ships only the network, storage, USB and
184
+ HID modules, so there `/dev/fb0` never appears. Build with
185
+ `./index.js -b --linux-lts` (or `--real` on x86_64). Under QEMU, the x86_64
186
+ lts kernel gets a 1280×800 `simpledrm` framebuffer from the UEFI GOP even
187
+ with `-display none`, and the monitor's `screendump` shows it. QEMU's aarch64
188
+ `virt` machine has no display until you add `-device ramfb`; EDK2 then
189
+ provides an 800×600 GOP, and `virtio-keyboard-pci` gives the VTs a keyboard
190
+ (see the README's
191
+ [What differs on aarch64](README.md#what-differs-on-aarch64)). From a virtual
192
+ console in the guest:
184
193
 
185
194
  ```sh
186
195
  bunterm # /bin/sh on this console
@@ -206,6 +215,13 @@ host, `jsmdcui --tui` on a Markdown file with a JPEG (bunterm sets
206
215
  `JSMDCUI_KITTY_MODE=extended` for the program it runs) places the image
207
216
  through its transmit / `a=p` / `a=d` sequence exactly as in the browser.
208
217
 
218
+ Verified on aarch64 (lts kernel, Hypervisor.framework, `-device ramfb
219
+ -device virtio-keyboard-pci -device virtio-mouse-pci`, `-display none`):
220
+ `/proc/fb` lists `simpledrmdrmfb`; `bunterm 2` from the serial shell returns
221
+ at once and draws on VT 2; and keys sent with the monitor's `sendkey` reach
222
+ it: `showimg /buninu/icon.png` places the kitty image, and the prompt's
223
+ colour emoji and the pointer render, all checked with `screendump`.
224
+
209
225
  ## Not done yet
210
226
 
211
227
  - Selection and scrollback viewing in `bunterm` (the pointer itself works,
@@ -11,7 +11,7 @@ const CANONICAL_BUNTERM = "/bin/bunterm";
11
11
 
12
12
  const usage = () => {
13
13
  console.error(`Usage:
14
- bunterm [N | /dev/ttyN] [-s N | --font-size N] [--fb /dev/fb0] [--no-mouse] [-e command [argument...]]
14
+ bunterm [N | /dev/ttyN] [-s N | --font-size N] [--fb /dev/fb0] [--no-mouse] [--no-clipboard] [-e command [argument...]]
15
15
  bunterm -h | --help`);
16
16
  };
17
17
 
@@ -58,6 +58,8 @@ const main = async () => {
58
58
  options.mouse = true;
59
59
  } else if (argument === "--no-mouse") {
60
60
  options.mouse = false;
61
+ } else if (argument === "--no-clipboard") {
62
+ options.clipboard = false;
61
63
  } else if (/^[1-9][0-9]*$/.test(argument) || argument.startsWith("/dev/")) {
62
64
  const number = /^[1-9][0-9]*$/.test(argument) ? Number(argument) : virtualConsoleNumber(argument);
63
65
  if (number === null) throw new Error(`expected N or /dev/ttyN, got ${argument}`);
package/initramfs/init.js CHANGED
@@ -179,6 +179,16 @@ try {
179
179
  console.error(`init.js: input modules: ${error?.message ?? error}`);
180
180
  }
181
181
 
182
+ // The framebuffer for bunterm: the firmware's GOP is a simple-framebuffer
183
+ // device, and simpledrm turns it into /dev/fb0. x86_64 linux-lts builds it
184
+ // in and linux-virt images do not ship it; tryModprobe skips both.
185
+ try {
186
+ const { tryModprobe } = await import("/lib/modprobe.js");
187
+ if (tryModprobe("simpledrm")?.length) console.log("init.js: loaded simpledrm");
188
+ } catch (error) {
189
+ console.error(`init.js: simpledrm: ${error?.message ?? error}`);
190
+ }
191
+
182
192
  const { default: repl } = await import("node:repl");
183
193
  const { mkdirSync, writeFileSync } = await import("node:fs");
184
194
 
@@ -549,11 +559,26 @@ const configureDisks = () => {
549
559
  return devices;
550
560
  };
551
561
 
562
+ // Load the complete sound stack packaged in the image. Like cfg.net this is
563
+ // deliberately unconditional: it does not probe modaliases first, so codec
564
+ // and helper modules without their own discoverable device are loaded too.
565
+ const configureSound = () => {
566
+ const { modprobeAll } = require("/lib/modprobe.js");
567
+ const { readdirSync } = require("node:fs");
568
+ const report = modprobeAll({ accept: (_module, path) => path.startsWith("kernel/sound/") });
569
+ console.log(`sound: loaded all packaged sound modules (${report.inserted.length} newly loaded, ${report.errors.length} failed)`);
570
+ for (const { module, error } of report.errors) console.log(`sound: ${module}: ${error}`);
571
+ const devices = (() => { try { return readdirSync("/dev/snd"); } catch { return []; } })();
572
+ console.log(`sound: ${devices.length ? devices.map((name) => `/dev/snd/${name}`).join(" ") : "no sound devices registered"}`);
573
+ return devices;
574
+ };
575
+
552
576
  globalThis.cfg = Object.freeze(Object.defineProperties({}, {
553
577
  all: { enumerable: true, get: configureModules },
554
578
  disk: { enumerable: true, get: configureDisks },
555
579
  net: { enumerable: true, get: configureEthernet },
556
580
  power: { enumerable: true, get: configureBattery },
581
+ sound: { enumerable: true, get: configureSound },
557
582
  }));
558
583
 
559
584
  // Compatibility aliases for images and notes that used the original API.
@@ -562,6 +587,7 @@ globalThis.cfgNet = configureEthernet;
562
587
  globalThis.cfgDisk = configureDisks;
563
588
  globalThis.cfgMod = configureModules;
564
589
  globalThis.cfgBat = configureBattery;
590
+ globalThis.cfgSound = configureSound;
565
591
 
566
592
  const showWelcome = () => {
567
593
  console.log(`
@@ -0,0 +1,51 @@
1
+ // /lib/bunterm/clipboard.js — OSC 52 clipboard for bunterm, backed by xclip.
2
+ //
3
+ // program ── ESC ] 52 ; c ; <base64> BEL ──▶ xclip -selection clipboard
4
+ // program ── ESC ] 52 ; c ; ? BEL ─────────▶ xclip -selection clipboard -o
5
+ // ◀── ESC ] 52 ; c ; <base64> BEL ──
6
+ //
7
+ // bunterm keeps nothing itself: every copy and paste goes through xclip, so
8
+ // all bunterm sessions (and anything else using xclip) share one clipboard.
9
+ // Buninu's xclip prints status lines on stderr, which must not reach the
10
+ // console under the framebuffer, so stderr is discarded.
11
+
12
+ const runXclip = async (args, input) => {
13
+ const command = ["xclip", "-selection", "clipboard", ...args];
14
+ const proc = Bun.spawn(command, {
15
+ stdin: input === undefined ? "ignore" : input,
16
+ stdout: input === undefined ? "pipe" : "ignore",
17
+ stderr: "ignore",
18
+ });
19
+ const [output, exitCode] = await Promise.all([
20
+ input === undefined ? new Response(proc.stdout).arrayBuffer() : null,
21
+ proc.exited,
22
+ ]);
23
+ if (exitCode !== 0) throw new Error(`${command.join(" ")} exited with ${exitCode}`);
24
+ return output;
25
+ };
26
+
27
+ // Registers the OSC 52 handler on an xterm.js terminal. `reply` sends bytes
28
+ // back to the program, as the terminal's other replies do. A read the xclip
29
+ // call cannot answer is still answered, with empty contents, so the program
30
+ // does not wait out its own timeout.
31
+ export const attachClipboard = ({ term, reply, onError = () => {} }) =>
32
+ term.parser.registerOscHandler(52, (data) => {
33
+ const separator = data.indexOf(";");
34
+ if (separator < 0) return true;
35
+ const target = data.slice(0, separator);
36
+ const payload = data.slice(separator + 1);
37
+
38
+ if (payload === "?") {
39
+ // The reply is sent after xclip returns, when the program may have exited
40
+ // and the PTY closed; writing then throws, and an unhandled rejection
41
+ // would end bunterm before it restores the console.
42
+ runXclip(["-o"])
43
+ .catch((error) => { onError(error); return new ArrayBuffer(0); })
44
+ .then((bytes) => reply(`\u001b]52;${target};${Buffer.from(bytes).toString("base64")}\u0007`))
45
+ .catch(onError);
46
+ return true;
47
+ }
48
+
49
+ runXclip([], Buffer.from(payload, "base64")).catch(onError);
50
+ return true;
51
+ });
@@ -21,6 +21,7 @@ import { Renderer, defaultTheme } from "./renderer.js";
21
21
  import { ImageStore } from "./images.js";
22
22
  import { openKeyboard, translateKeys } from "./input.js";
23
23
  import { claimVirtualConsole } from "./vt.js";
24
+ import { attachClipboard } from "./clipboard.js";
24
25
 
25
26
  const require = createRequire(import.meta.url);
26
27
 
@@ -52,6 +53,7 @@ export const createSession = ({
52
53
  scrollback = 1000,
53
54
  cursorBlink = true,
54
55
  mouse = true,
56
+ clipboard = true,
55
57
  env = {},
56
58
  onError = (error) => console.error(`bunterm: ${error?.stack ?? error}`),
57
59
  }) => {
@@ -158,6 +160,9 @@ export const createSession = ({
158
160
  });
159
161
  backend.onData(pump);
160
162
  term.onData((data) => backend.write(Buffer.from(data, "utf8")));
163
+ // OSC 52 copy and paste go straight to xclip; replies return to the program.
164
+ // Without it (--no-clipboard) xterm.js ignores OSC 52 and nothing reaches xclip.
165
+ if (clipboard) attachClipboard({ term, reply: (text) => backend.write(Buffer.from(text, "utf8")), onError });
161
166
 
162
167
  // Keyboard bytes from the console, rewritten for the program's key mode.
163
168
  const input = (bytes) => {
@@ -12,6 +12,7 @@ bunterm /dev/tty1 # the full virtual-console spelling also works
12
12
  bunterm -s 20 # short for --font-size 20
13
13
  bunterm -e bun /buninu/apps/jsmdcui/src/index.js --demo
14
14
  bunterm --no-mouse # keyboard only
15
+ bunterm --no-clipboard # ignore OSC 52 copy and paste
15
16
  bunterm -h
16
17
  ```
17
18
 
@@ -39,6 +40,7 @@ identified from the process task name and its open console descriptor under
39
40
  | `--fb /dev/fbN` | The framebuffer device (default `/dev/fb0`). |
40
41
  | `--no-blink` | A steady cursor. |
41
42
  | `--no-mouse` | Do not attach a pointing device; nothing then reads `/dev/input`. |
43
+ | `--no-clipboard` | Ignore OSC 52: programs can neither copy to nor read from the clipboard, and `xclip` is never run. |
42
44
 
43
45
  ## What is drawn
44
46
 
@@ -101,6 +103,16 @@ mouse also needs the `usbhid` stack, which a `--real` image carries and
101
103
  ones (a tablet or touchscreen) alike; a device that cannot be opened is
102
104
  reported and the session continues without it.
103
105
 
106
+ ## Clipboard
107
+
108
+ Programs copy and paste through OSC 52, as `casty` and `jsmdcui` do.
109
+ bunterm keeps no clipboard of its own: `ESC ] 52 ; c ; <base64>` is passed to
110
+ `xclip -selection clipboard`, and a query (`ESC ] 52 ; c ; ?`) is answered
111
+ with the output of `xclip -selection clipboard -o`, so every bunterm session
112
+ shares the same clipboard as `xclip`. A query xclip cannot answer is replied
113
+ to with empty contents. `--no-clipboard` turns this off, so a program can
114
+ neither set nor read the clipboard through the terminal.
115
+
104
116
  ## Limits
105
117
 
106
118
  - Needs a framebuffer: `linux-lts` has one built in, while the default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu-linux",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "A Linux distribution running Bun as PID 1 with the Buninu userspace.",
5
5
  "type": "module",
6
6
  "main": "./index.js",