buninu-linux 0.14.57 → 0.16.59

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 (299) hide show
  1. package/LICENSES/linux-firmware/LICENCE.nvidia +131 -0
  2. package/LICENSES/linux-firmware/LICENSE.amdgpu +51 -0
  3. package/LICENSES/linux-firmware/LICENSE.amdisp +31 -0
  4. package/LICENSES/linux-firmware/LICENSE.i915 +39 -0
  5. package/LICENSES/linux-firmware/LICENSE.radeon +51 -0
  6. package/LICENSES/linux-firmware/LICENSE.xe +39 -0
  7. package/LICENSES/linux-firmware/WHENCE +10280 -0
  8. package/NOTICE.md +64 -46
  9. package/README.md +378 -87
  10. package/README.zh.md +2041 -0
  11. package/build-image.sh +10 -1
  12. package/build-uki.sh +3 -1
  13. package/fetch-alpine.sh +14 -0
  14. package/graphics.md +31 -0
  15. package/index.js +28 -11
  16. package/initramfs/bin/buninu-browser +4 -1
  17. package/initramfs/bin/buninu-land +1 -1
  18. package/initramfs/bin/bunterm +3 -3
  19. package/initramfs/bin/chroot +13 -0
  20. package/initramfs/bin/chvt +11 -0
  21. package/initramfs/bin/mount +4 -0
  22. package/initramfs/bin/umount +6 -0
  23. package/initramfs/bin/xdg-open +33 -0
  24. package/initramfs/buninu/CHANGELOG.md +66 -0
  25. package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +4 -0
  26. package/initramfs/buninu/apps/bunmsh/package.json +1 -1
  27. package/initramfs/buninu/apps/bunmsh/src/main.js +1 -1
  28. package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-jsmdcui.txt +22 -0
  29. package/initramfs/buninu/apps/jsgotty/NOTICE +5 -0
  30. package/initramfs/buninu/apps/jsgotty/README.en.md +61 -0
  31. package/initramfs/buninu/apps/jsgotty/README.md +61 -0
  32. package/initramfs/buninu/apps/jsgotty/client-modes.mjs +117 -0
  33. package/initramfs/buninu/apps/jsgotty/client.mjs +100 -10
  34. package/initramfs/buninu/apps/jsgotty/clipboard-powershell.js +18 -0
  35. package/initramfs/buninu/apps/jsgotty/clipboard.js +148 -0
  36. package/initramfs/buninu/apps/jsgotty/gotty.js +13 -0
  37. package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
  38. package/initramfs/buninu/apps/jsgotty/package.json +1 -1
  39. package/initramfs/buninu/apps/jsgotty/static/css/index.css +14 -1
  40. package/initramfs/buninu/apps/jsgotty/static/index.html +1 -0
  41. package/initramfs/buninu/apps/jsgotty/static/js/gotty.js +187 -23
  42. package/initramfs/buninu/apps/jsgotty/static/js/kitty-keyboard.js +193 -0
  43. package/initramfs/buninu/apps/jsgotty/static/js/kitty.js +115 -7
  44. package/initramfs/buninu/apps/jsgotty/terminal-modes.js +332 -0
  45. package/initramfs/buninu/apps/jsgotty/tests/android-alt.test.js +115 -0
  46. package/initramfs/buninu/apps/jsgotty/tests/arrow-modifiers.test.js +80 -0
  47. package/initramfs/buninu/apps/jsgotty/tests/client-exit.test.mjs +45 -0
  48. package/initramfs/buninu/apps/jsgotty/tests/client-modes.test.mjs +105 -0
  49. package/initramfs/buninu/apps/jsgotty/tests/clipboard-browser.test.js +81 -0
  50. package/initramfs/buninu/apps/jsgotty/tests/clipboard.test.js +75 -0
  51. package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard-browser.test.js +53 -0
  52. package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard.test.js +102 -0
  53. package/initramfs/buninu/apps/jsgotty/tests/manual/README.md +20 -0
  54. package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-collector.cjs +55 -0
  55. package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-debug.js +74 -0
  56. package/initramfs/buninu/apps/jsgotty/tests/manual/kitty-keyboard.js +80 -0
  57. package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-collector.cjs +55 -0
  58. package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-debug.js +39 -0
  59. package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.js +33 -0
  60. package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.mjs +22 -0
  61. package/initramfs/buninu/apps/jsgotty/tests/nested-cli-pty.test.mjs +116 -0
  62. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes-browser.test.js +144 -0
  63. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.md +44 -0
  64. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.test.js +166 -0
  65. package/initramfs/buninu/apps/jsgotty/tests/touch-drag-browser.test.js +106 -0
  66. package/initramfs/buninu/apps/jsgotty/tests/wheel-browser.test.js +60 -0
  67. package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +44 -0
  68. package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
  69. package/initramfs/buninu/apps/jsmdcui/src/highlight/go-regexp.js +83 -0
  70. package/initramfs/buninu/apps/jsmdcui/src/highlight/highlighter.js +49 -62
  71. package/initramfs/buninu/apps/jsmdcui/src/highlight/parser.js +8 -5
  72. package/initramfs/buninu/apps/jsmdcui/tests/go-regexp.test.js +98 -0
  73. package/initramfs/buninu/apps/jsmdcui/tests/heading-ids.test.js +21 -16
  74. package/initramfs/buninu/apps/jsmdcui/tests/highlight-regions.test.js +73 -0
  75. package/initramfs/buninu/apps/jsmdcui/tests/id-collision.test.js +32 -9
  76. package/initramfs/buninu/apps/jsmdcui/tests/markdown-behavior.mjs +9 -0
  77. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/NORMAL-HTML.md +46 -0
  78. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/README.md +85 -0
  79. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/REPORT.md +328 -0
  80. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/compare.mjs +75 -0
  81. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/go.mod +5 -0
  82. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html-report.json +619 -0
  83. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html.html +9 -0
  84. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/oracle.go +49 -0
  85. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/report.json +2174 -0
  86. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/PowerShell.txt +39 -0
  87. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ada.txt +25 -0
  88. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/apacheconf.txt +49 -0
  89. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/arduino.txt +38 -0
  90. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asciidoc.txt +33 -0
  91. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asm.txt +77 -0
  92. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ats.txt +48 -0
  93. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/awk.txt +28 -0
  94. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/b.txt +27 -0
  95. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/bat.txt +39 -0
  96. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/c.txt +34 -0
  97. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/caddyfile.txt +14 -0
  98. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cake.txt +7 -0
  99. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/clojure.txt +18 -0
  100. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cmake.txt +20 -0
  101. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/coffeescript.txt +32 -0
  102. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/colortest.txt +19 -0
  103. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/conky.txt +12 -0
  104. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cpp.txt +46 -0
  105. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crontab.txt +16 -0
  106. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crystal.txt +28 -0
  107. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csharp.txt +28 -0
  108. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/css.txt +19 -0
  109. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csx.txt +7 -0
  110. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cuda.txt +37 -0
  111. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cython.txt +22 -0
  112. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/d.txt +52 -0
  113. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dart.txt +27 -0
  114. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/default.txt +8 -0
  115. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dockerfile.txt +10 -0
  116. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dot.txt +15 -0
  117. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elixir.txt +23 -0
  118. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elm.txt +20 -0
  119. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erb.txt +32 -0
  120. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erlang.txt +23 -0
  121. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fish.txt +20 -0
  122. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/forth.txt +17 -0
  123. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fortran.txt +40 -0
  124. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/freebsd-kernel.txt +10 -0
  125. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fsharp.txt +27 -0
  126. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gdscript.txt +26 -0
  127. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gemini.txt +11 -0
  128. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-ebuild.txt +28 -0
  129. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-etc-portage.txt +14 -0
  130. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-commit.txt +19 -0
  131. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-config.txt +11 -0
  132. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-rebase-todo.txt +10 -0
  133. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gleam.txt +44 -0
  134. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/glsl.txt +18 -0
  135. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gnuplot.txt +11 -0
  136. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/go.txt +33 -0
  137. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/godoc.txt +9 -0
  138. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/golo.txt +50 -0
  139. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gomod.txt +16 -0
  140. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/graphql.txt +20 -0
  141. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groff.txt +18 -0
  142. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groovy.txt +42 -0
  143. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haml.txt +16 -0
  144. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hare.txt +31 -0
  145. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haskell.txt +26 -0
  146. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hc.txt +28 -0
  147. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html.txt +26 -0
  148. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html4.txt +20 -0
  149. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html5.txt +20 -0
  150. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ini.txt +16 -0
  151. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/inputrc.txt +14 -0
  152. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/java.txt +18 -0
  153. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/javascript.txt +41 -0
  154. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jinja2.txt +13 -0
  155. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/json.txt +21 -0
  156. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jsonnet.txt +28 -0
  157. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/julia.txt +24 -0
  158. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/justfile.txt +26 -0
  159. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/keymap.txt +15 -0
  160. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kickstart.txt +16 -0
  161. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kotlin.txt +30 -0
  162. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kvlang.txt +37 -0
  163. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ledger.txt +13 -0
  164. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lfe.txt +17 -0
  165. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lilypond.txt +15 -0
  166. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lisp.txt +17 -0
  167. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/log.txt +45 -0
  168. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lua.txt +48 -0
  169. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mail.txt +17 -0
  170. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/makefile.txt +25 -0
  171. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/man.txt +12 -0
  172. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/markdown.txt +21 -0
  173. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mc.txt +11 -0
  174. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/meson.txt +29 -0
  175. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/micro.txt +25 -0
  176. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mpdconf.txt +13 -0
  177. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/msbuild.txt +7 -0
  178. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nanorc.txt +16 -0
  179. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nftables.txt +22 -0
  180. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nginx.txt +17 -0
  181. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nim.txt +23 -0
  182. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nix.txt +15 -0
  183. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nu.txt +92 -0
  184. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/objc.txt +36 -0
  185. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ocaml.txt +25 -0
  186. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/octave.txt +35 -0
  187. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/odin.txt +35 -0
  188. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pascal.txt +22 -0
  189. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/patch.txt +13 -0
  190. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/peg.txt +16 -0
  191. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/perl.txt +27 -0
  192. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/php.txt +44 -0
  193. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pkg-config.txt +12 -0
  194. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/po.txt +12 -0
  195. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pony.txt +29 -0
  196. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pov.txt +17 -0
  197. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-action.txt +14 -0
  198. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-config.txt +10 -0
  199. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-filter.txt +12 -0
  200. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/proto.txt +22 -0
  201. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/prql.txt +42 -0
  202. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/puppet.txt +22 -0
  203. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python2.txt +24 -0
  204. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python3.txt +28 -0
  205. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/r.txt +16 -0
  206. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/raku.txt +19 -0
  207. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/reST.txt +18 -0
  208. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/renpy.txt +11 -0
  209. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rpmspec.txt +31 -0
  210. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ruby.txt +34 -0
  211. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rust.txt +27 -0
  212. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sage.txt +24 -0
  213. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scad.txt +23 -0
  214. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scala.txt +16 -0
  215. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sed.txt +12 -0
  216. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sh.txt +20 -0
  217. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sls.txt +15 -0
  218. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/smalltalk.txt +28 -0
  219. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/solidity.txt +26 -0
  220. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sql.txt +35 -0
  221. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/stata.txt +32 -0
  222. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/svelte.txt +10 -0
  223. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/swift.txt +53 -0
  224. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/systemd.txt +15 -0
  225. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tcl.txt +17 -0
  226. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/terraform.txt +28 -0
  227. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tex.txt +15 -0
  228. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/toml.txt +31 -0
  229. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/twig.txt +29 -0
  230. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/typescript.txt +32 -0
  231. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/v.txt +47 -0
  232. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vala.txt +22 -0
  233. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/verilog.txt +37 -0
  234. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vhdl.txt +37 -0
  235. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vi.txt +17 -0
  236. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vue.txt +29 -0
  237. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xml.txt +14 -0
  238. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xresources.txt +14 -0
  239. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yaml.txt +19 -0
  240. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yum.txt +12 -0
  241. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zig.txt +24 -0
  242. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zscript.txt +31 -0
  243. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zsh.txt +21 -0
  244. package/initramfs/buninu/package.json +1 -1
  245. package/initramfs/init.js +19 -3
  246. package/initramfs/lib/bunterm/clipboard.js +14 -0
  247. package/initramfs/lib/bunterm/commands.js +37 -0
  248. package/initramfs/lib/bunterm/fps.js +38 -0
  249. package/initramfs/lib/bunterm/images.js +14 -6
  250. package/initramfs/lib/bunterm/input.js +58 -15
  251. package/initramfs/lib/bunterm/keyboard.js +62 -0
  252. package/initramfs/lib/bunterm/keycodes.js +104 -0
  253. package/initramfs/lib/bunterm/kitty-keyboard.cjs +195 -0
  254. package/initramfs/lib/bunterm/raw-protocol.js +111 -0
  255. package/initramfs/lib/bunterm/renderer.js +116 -28
  256. package/initramfs/lib/bunterm/selection.js +60 -0
  257. package/initramfs/lib/bunterm/terminal.js +157 -12
  258. package/initramfs/lib/bunterm/vt-menu.js +181 -0
  259. package/initramfs/lib/bunterm/vt.js +27 -1
  260. package/initramfs/lib/canvas.js +99 -0
  261. package/initramfs/lib/chvt.js +31 -0
  262. package/initramfs/lib/fbdev.js +32 -8
  263. package/initramfs/lib/gpu.js +77 -0
  264. package/initramfs/lib/mapped-frame.js +28 -0
  265. package/initramfs/lib/raw-image.js +71 -0
  266. package/initramfs/lib/xdg-open.js +42 -0
  267. package/initramfs/usr/share/doc/buninu-linux/bunterm.md +85 -11
  268. package/initramfs/usr/share/doc/buninu-linux/chvt.md +34 -0
  269. package/initramfs/usr/share/doc/buninu-linux/xdg-open.md +43 -0
  270. package/package.json +1 -1
  271. package/scripts/arch.js +7 -5
  272. package/scripts/arch.sh +5 -5
  273. package/scripts/build.js +16 -3
  274. package/scripts/fetch-gpu.js +105 -0
  275. package/scripts/fetch.js +11 -1
  276. package/scripts/gpu-firmware.json +22 -0
  277. package/scripts/modules.js +4 -1
  278. package/scripts/npm-packages.md +18 -17
  279. package/test/bunterm-fps.test.js +17 -0
  280. package/test/bunterm-image-bytes.test.js +15 -0
  281. package/test/bunterm-keyboard.test.js +116 -0
  282. package/test/bunterm-mapped-lifetime.test.js +147 -0
  283. package/test/bunterm-next-vt.test.js +9 -0
  284. package/test/bunterm-raw-protocol.test.js +39 -0
  285. package/test/bunterm-renderer.test.js +167 -0
  286. package/test/bunterm-selection.test.js +38 -0
  287. package/test/bunterm-vt-menu.test.js +178 -0
  288. package/test/chroot-bind.test.js +40 -2
  289. package/test/chvt.test.js +46 -0
  290. package/test/fbdev-sync.test.js +42 -0
  291. package/test/fetch-npm.test.js +2 -2
  292. package/test/gpu.test.js +155 -0
  293. package/test/image-size.test.js +17 -0
  294. package/test/manual-bunterm-image-paths.js +31 -0
  295. package/test/mount-libc-lifetime.test.js +50 -0
  296. package/test/no-gpu.test.js +43 -0
  297. package/test/readme-cli.test.js +29 -0
  298. package/test/stage-npm.test.js +11 -4
  299. package/test/xdg-open.test.js +55 -0
@@ -0,0 +1,31 @@
1
+ // Use the same VT_ACTIVATE/VT_WAITACTIVE path as bunterm. Never take VT ownership.
2
+ export function parseChvt(args) {
3
+ if (args.length === 1 && ["-h", "--help"].includes(args[0])) return { help: true };
4
+ if (args.length !== 1 || !/^[0-9]+$/.test(args[0]) || Number(args[0]) < 1 || Number(args[0]) > 63)
5
+ throw new Error("usage: chvt N (1–63); see chvt -h or --help");
6
+ return { number: Number(args[0]) };
7
+ }
8
+
9
+ export async function switchVt(number, backend) {
10
+ if (!Number.isInteger(number) || number < 1 || number > 63) throw new Error("VT number must be 1–63");
11
+ const { openConsole, activeConsole, activateConsole } = backend ?? await import("./fbdev.js");
12
+ const failures = [];
13
+ let consoleDevice;
14
+ // /dev/tty in bunterm is a PTY, and /dev/console may be a serial console.
15
+ // Probe VT_GETSTATE before accepting an open fd.
16
+ for (const path of ["/dev/tty0", "/dev/tty", "/dev/console"]) {
17
+ let candidate;
18
+ try {
19
+ candidate = openConsole([path]);
20
+ activeConsole(candidate);
21
+ consoleDevice = candidate;
22
+ break;
23
+ } catch (error) {
24
+ candidate?.close();
25
+ failures.push(`${path}: ${error.message}`);
26
+ }
27
+ }
28
+ if (!consoleDevice) throw new Error(`no accessible Linux VT (${failures.join("; ")})`);
29
+ try { activateConsole(consoleDevice, number); }
30
+ finally { consoleDevice.close(); }
31
+ }
@@ -261,17 +261,41 @@ export const clear = (display, color = { r: 0, g: 0, b: 0, a: 255 }) => {
261
261
  }
262
262
  };
263
263
 
264
+ // msync is a file writeback operation, not a universal fbdev present API.
265
+ // DRM mappings may have no backing fsync operation (vfs_fsync_range then
266
+ // returns EINVAL). Keep working drivers' deferred-I/O sync, but probe unsupported
267
+ // mappings only once. The address is the original mmap base, and flags are fixed.
268
+ export const syncFramebuffer = (display, native = {
269
+ msync: (...args) => libc.symbols.msync(...args), errno, strerror,
270
+ }) => {
271
+ if (display.msyncUnsupported) return;
272
+ for (;;) {
273
+ if (native.msync(display.address, display.memoryLength, MS_SYNC) !== -1) return;
274
+ const code = native.errno();
275
+ if (code === 4) continue; // EINTR
276
+ if (code === 22 || code === 95) { // EINVAL / EOPNOTSUPP on this device mapping
277
+ display.msyncUnsupported = true;
278
+ return;
279
+ }
280
+ throw new Error(`msync(${display.path}): ${native.strerror(code)}`);
281
+ }
282
+ };
283
+
264
284
  export const flush = (display) => {
265
285
  const visibleBytes = display.width * display.bytesPerPixel;
266
- for (let y = 0; y < display.height; y++) {
267
- const row = display.pixels.subarray(y * display.stride, y * display.stride + visibleBytes);
268
- const position = (y + display.yOffset) * display.stride
269
- + display.xOffset * display.bytesPerPixel;
270
- display.memory.set(row, position);
271
- }
272
- if (libc.symbols.msync(display.address, display.memoryLength, MS_SYNC) === -1) {
273
- fail(`msync(${display.path})`);
286
+ if (display.xOffset === 0 && display.stride === visibleBytes) {
287
+ // Contiguous visible rows need one bulk copy, not one JS call per row.
288
+ display.memory.set(display.pixels.subarray(0, display.height * display.stride),
289
+ display.yOffset * display.stride);
290
+ } else {
291
+ for (let y = 0; y < display.height; y++) {
292
+ const row = display.pixels.subarray(y * display.stride, y * display.stride + visibleBytes);
293
+ const position = (y + display.yOffset) * display.stride
294
+ + display.xOffset * display.bytesPerPixel;
295
+ display.memory.set(row, position);
296
+ }
274
297
  }
298
+ syncFramebuffer(display);
275
299
  };
276
300
 
277
301
  // Copies an RGBA ImageData (HTML canvas layout, 4 bytes per pixel, rows of
@@ -0,0 +1,77 @@
1
+ // Explicit one-shot GPU coldplug. Importing this module never loads a driver.
2
+ import * as fs from "node:fs";
3
+ import { join, basename } from "node:path";
4
+
5
+ const drivers = new Set(["i915", "xe", "amdgpu", "radeon", "nouveau", "virtio_gpu", "vmwgfx"]);
6
+ export const isGpuPath = (_module, path) => path.startsWith("kernel/drivers/gpu/");
7
+ export const isGpuDriver = (module, path) => isGpuPath(module, path) && drivers.has(module.replaceAll("-", "_"));
8
+
9
+ export const framebufferUsers = ({ root = "/", io = fs } = {}) => {
10
+ const users = [];
11
+ for (const pid of io.readdirSync(join(root, "proc")).filter(name => /^\d+$/.test(name))) {
12
+ try {
13
+ const dir = join(root, "proc", pid, "fd");
14
+ let busy = false;
15
+ for (const fd of io.readdirSync(dir)) {
16
+ try { if (/^\/dev\/fb\d+(?: \(deleted\))?$/.test(io.readlinkSync(join(dir, fd)))) busy = true; }
17
+ catch (error) { if (error.code !== "ENOENT") throw error; }
18
+ }
19
+ // An mmap can outlive its fd.
20
+ if (/\/dev\/fb\d+(?:\s|$)/m.test(io.readFileSync(join(root, "proc", pid, "maps"), "utf8"))) busy = true;
21
+ if (busy) users.push(pid);
22
+ } catch (error) {
23
+ if (error.code !== "ENOENT" && error.code !== "ESRCH") throw error;
24
+ }
25
+ }
26
+ return users;
27
+ };
28
+
29
+ export const configureGpu = ({ autoload, tryModprobe, root = "/", io = fs, env = process.env, log = console.log } = {}) => {
30
+ const result = { devices: [], renderNodes: [], framebuffers: [], errors: [], blocked: false };
31
+ const say = text => { try { log(`[gpu] ${text}`); } catch {} };
32
+ try {
33
+ const gid = env.BUNINU_RENDER_GID === undefined ? 0 : Number(env.BUNINU_RENDER_GID);
34
+ if (!Number.isInteger(gid) || gid < 0 || gid >= 0xffffffff || env.BUNINU_RENDER_GID === "")
35
+ throw Error("BUNINU_RENDER_GID must be a numeric group ID");
36
+ const users = framebufferUsers({ root, io });
37
+ if (users.length) {
38
+ result.blocked = true;
39
+ say(`not loaded: framebuffer in use by PID ${users.join(", ")}; exit bunterm/fbdev and run cfg.gpu before reopening it`);
40
+ return result;
41
+ }
42
+ // A virtio GPU may not appear on the virtio bus until its PCI transport loads.
43
+ try { tryModprobe("virtio_pci"); } catch (error) { result.errors.push(`virtio_pci: ${error?.message ?? error}`); }
44
+ result.devices = autoload({ buses: ["pci", "virtio"], acceptModule: isGpuDriver });
45
+ for (const device of result.devices) {
46
+ if (device.error) result.errors.push(`${device.bus}/${device.device}: ${device.error}`);
47
+ say(`${device.bus}/${device.device} ${device.modules.join(" ")}: ${device.error ?? (device.loaded.length ? "loaded " + device.loaded.join(" ") : "already loaded/probed")}`);
48
+ }
49
+ const list = path => { try { return io.readdirSync(join(root, path)); } catch (error) { if (error.code === "ENOENT") return []; throw error; } };
50
+ for (const name of list("dev/dri").filter(name => /^renderD\d+$/.test(name)).sort()) {
51
+ const path = join(root, "dev/dri", name);
52
+ try {
53
+ if (!io.statSync(path).isCharacterDevice()) continue;
54
+ io.chownSync(path, 0, gid);
55
+ io.chmodSync(path, 0o660);
56
+ let driver = "unknown";
57
+ try {
58
+ const device = join(root, "sys/class/drm", name, "device");
59
+ driver = basename(io.readlinkSync(join(device, "driver")));
60
+ // virtio DRM nodes can point at the parent PCI transport device.
61
+ if (driver === "virtio-pci") for (const child of io.readdirSync(device).filter(n => /^virtio\d+$/.test(n))) {
62
+ const candidate = basename(io.readlinkSync(join(device, child, "driver")));
63
+ if (candidate === "virtio_gpu" || candidate === "virtio-gpu") { driver = candidate; break; }
64
+ }
65
+ } catch {}
66
+ result.renderNodes.push({ path: `/dev/dri/${name}`, driver, gid });
67
+ say(`/dev/dri/${name}: driver=${driver}, root:${gid} mode=0660`);
68
+ } catch (error) { result.errors.push(`${name}: ${error?.message ?? error}`); }
69
+ }
70
+ result.framebuffers = list("dev").filter(name => /^fb\d+$/.test(name)).sort().map(name => `/dev/${name}`);
71
+ say(`framebuffer: ${result.framebuffers.join(", ") || "none"}; reopen framebuffer clients after GPU handoff`);
72
+ if (!result.renderNodes.length) say("no accessible render node yet; check kernel firmware/driver messages and GPU support, then retry cfg.gpu after probing finishes");
73
+ say("clients still need their own Mesa/Vulkan driver; non-root clients need the render node's numeric group");
74
+ } catch (error) { result.errors.push(String(error?.message ?? error)); }
75
+ for (const error of result.errors) say(`failed: ${error}; init continues`);
76
+ return result;
77
+ };
@@ -0,0 +1,28 @@
1
+ // Only buffers created by our mmap reader may be detached. Ordinary buffers,
2
+ // pooled Buffer slabs and callers' pixel arrays retain their normal lifetime.
3
+ const mappings = new WeakMap();
4
+
5
+ export function ownMapping(bytes) {
6
+ const buffer = bytes.buffer;
7
+ if (mappings.has(buffer)) throw Error('mapping already owned');
8
+ mappings.set(buffer, {refs: 0});
9
+ return retainMapping(bytes);
10
+ }
11
+
12
+ export function retainMapping(bytes) {
13
+ const buffer = bytes?.buffer;
14
+ const state = buffer && mappings.get(buffer);
15
+ if (!state) return null;
16
+ state.refs++;
17
+ let released = false;
18
+ return () => {
19
+ if (released) return;
20
+ released = true;
21
+ if (--state.refs) return;
22
+ mappings.delete(buffer);
23
+ // Transfer to zero bytes runs Bun's mmap deallocator immediately, rather
24
+ // than batching many full frames into a later GC pause. Older runtimes or
25
+ // non-detachable buffers safely fall back to ordinary GC reclamation.
26
+ try { buffer.transfer?.(0); } catch {}
27
+ };
28
+ }
@@ -0,0 +1,71 @@
1
+ import {retainMapping} from "./mapped-frame.js";
2
+ // Retain immutable raw pixels until an operation actually needs a Skia Image.
3
+ // The native image store owns these handles; encoded images remain ordinary Skia images.
4
+ const rawImages = new WeakMap();
5
+ const littleEndian = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
6
+ export const rawImageData = image => rawImages.get(image);
7
+ export const skiaImage = image => rawImages.get(image)?.materialize() ?? image;
8
+
9
+ export function createRawImage(CanvasKit, pixels, width, height, colorType) {
10
+ let decoded = null, closed = false;
11
+ const release = retainMapping(pixels);
12
+ const data = {
13
+ pixels, width, height, colorType,
14
+ opaque: undefined,
15
+ materialize() {
16
+ if (closed) throw Error('raw image is closed');
17
+ if (!decoded) {
18
+ decoded = CanvasKit.MakeImage({width, height, colorType,
19
+ alphaType: CanvasKit.AlphaType.Unpremul, colorSpace: CanvasKit.ColorSpace.SRGB}, pixels, width * 4);
20
+ if (!decoded) throw Error('raw image rejected');
21
+ }
22
+ return decoded;
23
+ },
24
+ };
25
+ const image = {
26
+ width: () => width,
27
+ height: () => height,
28
+ delete() {
29
+ if (closed) return;
30
+ closed = true;
31
+ try { decoded?.delete(); }
32
+ finally {
33
+ decoded = null;
34
+ data.pixels = pixels = null;
35
+ rawImages.delete(image);
36
+ release?.();
37
+ }
38
+ },
39
+ };
40
+ rawImages.set(image, data);
41
+ return image;
42
+ }
43
+
44
+ // Check actual bytes once; raw protocol support does not imply opacity.
45
+ export function rawImageOpaque(data) {
46
+ if (data.opaque === undefined) {
47
+ const pixels = data.pixels;
48
+ data.opaque = true;
49
+ if (littleEndian && pixels.byteOffset % 4 === 0 && pixels.byteLength % 4 === 0) {
50
+ const words = new Uint32Array(pixels.buffer, pixels.byteOffset, pixels.byteLength / 4);
51
+ let i = 0;
52
+ // All eight alpha bytes must be 255 for their AND to stay 255. Group
53
+ // the common opaque case without skipping any pixel or reading a tail.
54
+ for (; i + 7 < words.length; i += 8) {
55
+ if (((words[i] & words[i + 1] & words[i + 2] & words[i + 3]
56
+ & words[i + 4] & words[i + 5] & words[i + 6] & words[i + 7]) >>> 24) !== 255) {
57
+ data.opaque = false;
58
+ break;
59
+ }
60
+ }
61
+ for (; data.opaque && i < words.length; i++) {
62
+ if ((words[i] >>> 24) !== 255) { data.opaque = false; break; }
63
+ }
64
+ } else {
65
+ for (let i = 3; i < pixels.length; i += 4) {
66
+ if (pixels[i] !== 255) { data.opaque = false; break; }
67
+ }
68
+ }
69
+ }
70
+ return data.opaque;
71
+ }
@@ -0,0 +1,42 @@
1
+ import { realpathSync, statSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+
5
+ export function browserTarget(target, cwd = process.cwd()) {
6
+ if (/^about:/i.test(target)) return target;
7
+ if (/^https?:\/\//i.test(target)) {
8
+ // Reject malformed URLs before starting a new terminal.
9
+ try { return new URL(target).href; }
10
+ catch { throw openError("Invalid HTTP/HTTPS URL", 1); }
11
+ }
12
+ const fileUrl = /^file:/i.test(target);
13
+ if (!fileUrl && /^[a-z][a-z0-9+.-]*:/i.test(target)) {
14
+ throw openError("Unsupported URL scheme; use http://, https://, about: or a local file", 4);
15
+ }
16
+ const path = realpathSync(fileUrl ? fileURLToPath(target) : resolve(cwd, target));
17
+ if (!statSync(path).isFile()) throw openError("Expected a regular file", 4);
18
+ // Encode spaces, #, %, and non-ASCII characters as URL path components.
19
+ return pathToFileURL(path).href;
20
+ }
21
+
22
+ export function parseOpenArgs(args) {
23
+ if (args.length === 1 && ["-h", "--help", "--manual"].includes(args[0])) return { help: true };
24
+ if (args.length === 1 && args[0] === "--version") return { version: true };
25
+ if (args.length !== 1 || !args[0]) throw openError("Usage: xdg-open URL | FILE (see --help)", 1);
26
+ if (args[0].startsWith("-")) throw openError("Use ./ before a filename beginning with '-'", 1);
27
+ return { target: args[0] };
28
+ }
29
+
30
+ export function openError(message, exitCode) {
31
+ return Object.assign(new Error(message), { exitCode });
32
+ }
33
+
34
+ export function openExitCode(error) {
35
+ return error.exitCode ?? (["ENOENT", "ENOTDIR"].includes(error.code) ? 2 : 4);
36
+ }
37
+
38
+ export function releaseVersion(text) {
39
+ const value = /^VERSION_ID=(.*)$/m.exec(text)?.[1]?.trim();
40
+ if (!value) throw new Error("VERSION_ID missing from os-release");
41
+ return value.replace(/^["']|["']$/g, "");
42
+ }
@@ -8,7 +8,7 @@ box drawing and kitty graphics protocol images — no X11, Wayland or GPU.
8
8
  ```sh
9
9
  bunterm 2 # start a detached bunterm on /dev/tty2
10
10
  bunterm /dev/tty2 # the full virtual-console spelling also works
11
- bunterm # take over the console you are on (on tty1 that hides the bun-repl)
11
+ bunterm # open a new VT after the last session; first is tty2
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
@@ -16,14 +16,19 @@ bunterm --no-clipboard # ignore OSC 52 copy and paste
16
16
  bunterm -h
17
17
  ```
18
18
 
19
+ Use `chvt 1` inside bunterm to return to tty1 without stopping it, and
20
+ `chvt 2` from a shell to return to a bunterm started on tty2. See `chvt --help`
21
+ for use from the init REPL.
22
+
19
23
  The program's `TERM` is `xterm-256color`, `COLORTERM=truecolor`,
20
24
  `TERM_PROGRAM=bunterm` and `JSMDCUI_KITTY_MODE=extended` (so `jsmdcui` shows
21
25
  Markdown images without `--kitty`). When it exits, the console returns to
22
26
  text mode and `bunterm` exits with its status.
23
27
 
24
28
  Every live session has a canonical `/bin/bunterm /dev/ttyN ...` command line.
25
- When no console is named, the currently active VT is used in the foreground.
26
- Naming a different VT starts bunterm as a detached session and returns
29
+ When no console is named, a new VT after the last known session is selected,
30
+ starting at tty2 and keeping tty1 for hardware setup.
31
+ Using a VT other than the active one starts bunterm as a detached session and returns
27
32
  immediately to the calling shell. Only one bunterm may control a given VT;
28
33
  ownership is
29
34
  identified from the process task name and its open console descriptor under
@@ -33,14 +38,14 @@ identified from the process task name and its open console descriptor under
33
38
 
34
39
  | Option | Meaning |
35
40
  | --- | --- |
36
- | `N`, `/dev/ttyN` | The virtual console to use for graphics and the keyboard; for example, `2` means `/dev/tty2`. Naming a VT other than the active one starts a detached bunterm there, switches the display to it, and immediately returns control to the calling shell. Without this argument, bunterm uses the active VT in the foreground. |
41
+ | `N`, `/dev/ttyN` | The virtual console to use for graphics and the keyboard; for example, `2` means `/dev/tty2`. Naming a VT other than the active one starts a detached bunterm there, switches the display to it, and immediately returns control to the calling shell. Without this argument, bunterm selects the next VT after the last known session (tty2 initially). |
37
42
  | `-e command [argument...]` | The program to run; everything after `-e` belongs to it. Default `/bin/sh`. |
38
43
  | `-s N`, `--font-size N` | Font size in pixels (default 13). The cell is 0.6 × N wide and 1.16 × N tall with DejaVu Sans Mono, so 1024×768 at 16 px gives 106 × 41 cells. |
39
44
  | `--line-height F` | Multiplies the cell height (default 1). |
40
45
  | `--fb /dev/fbN` | The framebuffer device (default `/dev/fb0`). |
41
46
  | `--no-blink` | A steady cursor. |
42
47
  | `--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. |
48
+ | `--no-clipboard` | Disable both OSC 52 and menu copy/paste; `xclip` is never run. |
44
49
 
45
50
  ## What is drawn
46
51
 
@@ -66,7 +71,7 @@ identified from the process task name and its open console descriptor under
66
71
 
67
72
  ## Keyboard
68
73
 
69
- The console stays in the kernel's translated keyboard mode, so
74
+ Without Kitty keyboard negotiation, the console stays in the kernel's translated keyboard mode, so
70
75
  `Ctrl-Alt-F2` and friends still switch consoles; coming back repaints the
71
76
  screen. While its VT is inactive, bunterm continues consuming PTY output and
72
77
  updating its scrollback and kitty images, but neither writes the framebuffer
@@ -76,6 +81,28 @@ forth through the normal Linux VT switch. A few console-specific
76
81
  sequences are rewritten to xterm's (`F1`–`F5`, `Home`, `End`), and arrow keys
77
82
  follow the program's application cursor mode.
78
83
 
84
+ ### Kitty keyboard
85
+
86
+ The Kitty keyboard protocol uses the same encoder as jsgotty 1.2.0:
87
+ flags **1** (disambiguation), **2** (press/repeat/release), and **8** (all keys).
88
+ Applications enable it with `CSI > flags u`, query with `CSI ? u`, and restore
89
+ with `CSI < u`; normal and alternate buffers have separate stacks. Flags 4
90
+ (alternate keys) and 16 (associated text) are not advertised.
91
+
92
+ Only while an application enables Kitty, the active console uses Linux
93
+ `K_MEDIUMRAW` to distinguish Ctrl, Alt, Shift, Super, keypad and key releases.
94
+ Bunterm restores the original mode on pop/reset or exit. Ctrl+Alt+F1–F12 and
95
+ Alt+Left/Right remain reserved for VT switching. The kernel keymap supplies
96
+ printable characters, including Shift/Caps Lock/AltGr. Kernel dead-key/Compose
97
+ sequences are not implemented in this Kitty path; the ordinary translated
98
+ console path retains its existing behavior. No global evdev keyboard grab is
99
+ needed. A mode transition discards pending console typeahead so raw keycodes
100
+ cannot leak into the child as text.
101
+
102
+ 中文:Kitty 模式與 jsgotty 支援相同的 flags 1、2、8,可區分 Super、
103
+ Ctrl/Alt/Shift 組合及按下/重複/放開。程式退出模式後恢復原有 console
104
+ 輸入;Ctrl+Alt+Fn、Alt+左右保留為切換 VT。Kitty 模式尚不處理 dead key/Compose。
105
+
79
106
  ## Mouse
80
107
 
81
108
  Every pointing device under `/dev/input/event*` is opened and an arrow is
@@ -94,6 +121,13 @@ arrow keys on the alternate screen, which has no scrollback and is what a
94
121
  pager expects. Typing returns to the live screen, and the text cursor is
95
122
  hidden while it is scrolled out of view.
96
123
 
124
+ When mouse reporting is off, left-drag selects terminal text. Wide characters
125
+ and graphemes are selected whole; wrapped lines copy without extra newlines.
126
+ Use **Copy** in the top-left menu to send the selection to xclip. Selection is
127
+ cleared when new PTY text arrives or the font size changes, so it cannot refer
128
+ to replaced cells. Applications requesting mouse reporting receive the drag
129
+ instead; selection never overrides their mouse mode.
130
+
97
131
  `--no-mouse` turns all of this off: the terminal then never looks at
98
132
  `/dev/input` and never loads the mouse module.
99
133
 
@@ -114,7 +148,12 @@ bunterm keeps no clipboard of its own: `ESC ] 52 ; c ; <base64>` is passed to
114
148
  with the output of `xclip -selection clipboard -o`, so every bunterm session
115
149
  shares the same clipboard as `xclip`. A query xclip cannot answer is replied
116
150
  to with empty contents. `--no-clipboard` turns this off, so a program can
117
- neither set nor read the clipboard through the terminal.
151
+ neither set nor read the clipboard through the terminal; menu copy/paste is
152
+ also disabled. The menu's **Paste** reads xclip and sends one paste to the PTY,
153
+ wrapped in `CSI 200~` / `CSI 201~` when the application enabled bracketed paste
154
+ (`DECSET 2004`). Programs that have not requested it receive plain text.
155
+ Newlines are normalized to CR; embedded ESC bytes are stripped in bracketed
156
+ mode so clipboard text cannot close the paste early.
118
157
 
119
158
  ## Limits
120
159
 
@@ -123,10 +162,8 @@ neither set nor read the clipboard through the terminal.
123
162
  `--linux-lts` or `--real` (efifb/simpledrm from UEFI).
124
163
  - The aarch64 image has no framebuffer yet: `run-qemu.sh` gives QEMU's
125
164
  `virt` machine no display device, so there is no `/dev/fb0` to draw on.
126
- - No selection, and no keyboard way to scroll back: the wheel is it. The
127
- buffer keeps 1000 lines. A program that does not enable mouse reporting
128
- sees no clicks — the arrow still moves, so the pointer is visibly alive.
129
- `--no-mouse` removes the pointer entirely.
165
+ - Scrollback uses the wheel; the buffer keeps 1000 lines.
166
+ `--no-mouse` removes the pointer and local selection.
130
167
  - A program that prints a terminal reply while the tty echoes (that is, one
131
168
  not in raw mode) will see the reply echoed, as on any terminal.
132
169
  - Kitty images are drawn above text; `z` ordering below text and animation
@@ -143,3 +180,40 @@ neither set nor read the clipboard through the terminal.
143
180
  - `/lib/fbdev.js` — the framebuffer itself (`fbdev.md`)
144
181
  - `/buninu/apps/jsgotty/gotty.js` — the PTY backend and kitty packet parser
145
182
  that are reused
183
+
184
+ ## Local menu and commands
185
+
186
+ Left-click the top-left **2×2 physical pixels** to open a text menu of live
187
+ bunterm VTs and the initial tty (normally tty1). Click an entry to switch, or use
188
+ Up/Down and Enter. The active VT is marked `(current)`.
189
+ The wheel scrolls the selection; Escape, right-click, or a click
190
+ outside the entries closes the menu. Menu input is consumed locally, including
191
+ when a terminal application has enabled mouse reporting. Requires mouse support.
192
+ The menu switches existing sessions; it does not create a new bunterm.
193
+
194
+ - **Font − / +** changes the current session's font size and resizes the PTY.
195
+ - **Copy / Paste** uses the same xclip clipboard as OSC 52.
196
+ - Click the light **command input field**, or press Tab, to type a local command.
197
+ Enter executes it, Tab returns to menu navigation, Esc closes the menu.
198
+ Backspace/Delete, Left/Right, Home/End and Ctrl+U edit the field.
199
+
200
+ Commands: `font 16`, `font +`, `font -`, `copy`, `paste`, `vt 2`, `help`.
201
+ Font commands accept integer sizes 6–96; changes last for this session.
202
+ The command registry is `/lib/bunterm/commands.js`; new commands can be added
203
+ there without changing the input widget. These are bunterm commands, not shell
204
+ commands. Clipboard failures and command errors appear in the menu footer.
205
+
206
+ 中文:左鍵點擊螢幕最左上角 2×2 像素,會列出正在運行的 bunterm 和初始 tty。
207
+ 目前顯示的 VT 會標示 `(current)`。
208
+ 可以點選或用上下鍵、Enter 切換;Esc、右鍵或點擊選項外關閉。不會把選單操作
209
+ 送進底下的 shell/應用程式,也不會關閉原本的 bunterm。
210
+ 選單還有字體大小減/加、複製/貼上,以及自由輸入的命令框(點選或按 Tab)。
211
+ 可輸入 `font 16`、`copy`、`paste`、`vt 2`、`help`;Enter 執行。
212
+ 複製前用左鍵拖曳選字,僅在程式未開啟滑鼠回報時生效。貼上沿用 xclip,
213
+ 程式啟用 bracketed paste 時會加上貼上邊界。
214
+
215
+ On GPU-provided fbdev devices, a shared framebuffer mapping may not support
216
+ `msync`. bunterm probes it once: `EINVAL`/`EOPNOTSUPP` disables further msync
217
+ calls for that mapping while pixel writes continue normally. Drivers that
218
+ support msync retain it; other errors still propagate. This is not a vsync or
219
+ GPU-acceleration mechanism.
@@ -0,0 +1,34 @@
1
+ # chvt — switch Linux virtual terminals
2
+
3
+ ```sh
4
+ chvt 1 # switch to /dev/tty1 (normally the init REPL)
5
+ chvt 2 # switch to /dev/tty2
6
+ chvt -h # also --help
7
+ ```
8
+
9
+ Accepts one VT number, 1–63. Requires access to a real Linux virtual console
10
+ and permission to switch it (normally root). A PTY alone, including a remote
11
+ terminal or Android terminal, is not a Linux VT.
12
+
13
+ With bunterm, for example:
14
+
15
+ ```sh
16
+ bunterm 2 # start bunterm on tty2
17
+ chvt 1 # from its shell, return to tty1 without stopping bunterm
18
+ ```
19
+
20
+ Run `chvt 2` from a shell to return, or use Alt+F2 / Ctrl+Alt+F2 as appropriate.
21
+ At the init JavaScript REPL, run a command with
22
+ `Bun.spawnSync(["/bin/chvt", "2"], {stdio: ["inherit", "inherit", "inherit"]})`.
23
+ The command switches the existing VT; it does not start a shell or bunterm on an
24
+ empty VT. bunterm retains ownership of its VT, pauses drawing when switched away,
25
+ and redraws when switched back. chvt does not change keyboard or graphics modes.
26
+
27
+ Like the traditional command, chvt waits for the target VT to become active,
28
+ then exits. If its current owner refuses to release the VT, the wait can persist. No daemon is created.
29
+
30
+ 中文:`chvt 1` 切至 tty1,`chvt 2` 切回 tty2 的 bunterm;不會結束 bunterm,
31
+ 也不會替空白 VT 啟動 shell。切出/切回使用 bunterm 原有的釋放與重繪機制。
32
+
33
+ Uses Linux VT_ACTIVATE and VT_WAITACTIVE:
34
+ https://man7.org/linux/man-pages/man2/ioctl_vt.2.html
@@ -0,0 +1,43 @@
1
+ # xdg-open — open in a new browser terminal / 開啟瀏覽器
2
+
3
+ ```sh
4
+ xdg-open https://buninu.org
5
+ xdg-open about:audio
6
+ xdg-open ./page.html
7
+ xdg-open "./file with spaces.md"
8
+ xdg-open file:///buninu/page.html
9
+ ```
10
+
11
+ Runs `bunterm -e buninu-browser URL` on a new virtual console. HTTP, HTTPS,
12
+ and `about:` URLs go to the browser. Local files must exist: symbolic links
13
+ are resolved and the real path is encoded as a `file://` URL, including spaces,
14
+ Chinese characters, `#`, and `%`. Markdown also opens in the browser.
15
+
16
+ 透過 bunterm 在新 tty 啟動瀏覽器。本地檔案先確認存在、解析實際路徑,再轉成
17
+ `file://` 網址;Markdown 同樣使用瀏覽器。檔名若以 `-` 開頭,請加上 `./`。
18
+
19
+ Directories and other schemes (including `data:`, `mailto:` and `ftp:`) are
20
+ not supported. This is Buninu's lightweight implementation, not xdg-utils;
21
+ it does not consult MIME associations or desktop application registrations.
22
+ 目前不支援目錄與其他協定,也不查詢 MIME 預設程式關聯。
23
+
24
+ ## Options / 選項
25
+
26
+ | Option | Meaning |
27
+ | --- | --- |
28
+ | `-h`, `--help`, `--manual` | Show this Markdown manual / 顯示本手冊 |
29
+ | `--version` | Show the Buninu Linux version from the image's os-release / 顯示映像檔的發行版版本 |
30
+
31
+ ## Exit codes / 退出碼
32
+
33
+ | Code | Meaning |
34
+ | --- | --- |
35
+ | 0 | New terminal launch succeeded / 新終端啟動成功 |
36
+ | 1 | Invalid arguments or URL / 參數或網址格式錯誤 |
37
+ | 2 | Local file does not exist / 本地檔案不存在 |
38
+ | 3 | Required tool not found / 缺少必要工具 |
39
+ | 4 | Opening failed or target unsupported / 開啟失敗或目標不支援 |
40
+
41
+ bunterm detaches when opening a new VT. Exit code 0 confirms the launcher
42
+ succeeded, not that the browser subsequently loaded the page.
43
+ 新 tty 以背景工作階段啟動,因此成功退出不代表後續網頁一定載入成功。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu-linux",
3
- "version": "0.14.57",
3
+ "version": "0.16.59",
4
4
  "description": "A Linux distribution running Bun as PID 1 with the Buninu userspace.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/scripts/arch.js CHANGED
@@ -16,8 +16,8 @@ export const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
16
16
 
17
17
  const pins = {
18
18
  x86_64: {
19
- linuxVirtSha256: "414aa2572ef88164b1af9905fa6dfbe863bf50f6130d895d57282dea3e15f7b9",
20
- linuxLtsSha256: "7614556471859956a436b95813daf409b444aa849ec899178b404e828c5a9d98",
19
+ linuxVirtSha256: "73ad4774ca26c196103a00e2fb8d28ed02de4c08c11fad96e903da03dcb085f4",
20
+ linuxLtsSha256: "ae0a669a08c90ef971996f81f1bcb6f7ca8211ad62624ad8c5b57412c3f1def8",
21
21
  muslSha256: "573712e2f49c15bfc20a2699f204acdfc74c772722b15e7353d768057fae0e71",
22
22
  stubSha256: "8e64a5a3afee5f930e6e6716be726dc6d405530ac7f8fa5be6251dae68671ec9",
23
23
  libstdcppSha256: "14c987b556f5385a5db18376e788c75f37d85321b8dc1920d926ea7daac1d6f6",
@@ -32,8 +32,8 @@ const pins = {
32
32
  serialMajor: 4,
33
33
  },
34
34
  aarch64: {
35
- linuxVirtSha256: "b3820fee22e0366a15f7c139e5bc00348e333f3e7f77802271df7ded795aee4f",
36
- linuxLtsSha256: "67b8f61c5cfb6ac9b5a65cb1610b67d467e6c4ffc17e7d29dbea4bd8c447ff32",
35
+ linuxVirtSha256: "89b68fc32d61a1483ab0d9db78b5a06144ac115fe2ee8102cb4ad7987f46d524",
36
+ linuxLtsSha256: "f6387970517083d5f08abacbf81baf1d70e1baa8fe4c2783469f45bb0751075c",
37
37
  muslSha256: "5e9674b7f41152fe2119093b5cb4c13eaaadb19c2d5422b2d7267913e663ee6e",
38
38
  stubSha256: "a1823d2d7082db555d528f82c1809f276c818aeb5b40f198f4565f104e055c38",
39
39
  libstdcppSha256: "2302e766d4e4926038ec166ecb85837ee884576115236ddb565e3a5fca4a11d7",
@@ -58,6 +58,7 @@ export const config = ({
58
58
  arch = process.env.BUNINU_ARCH || "x86_64",
59
59
  flavor = process.env.LINUX_FLAVOR || "virt",
60
60
  real = process.env.REAL_MACHINE === "1",
61
+ noGpu = process.env.BUNINU_NO_GPU === "1",
61
62
  mirror = process.env.ALPINE_MIRROR || "https://dl-cdn.alpinelinux.org/alpine",
62
63
  } = {}) => {
63
64
  arch = normalizeArch(arch);
@@ -67,7 +68,7 @@ export const config = ({
67
68
  // The Alpine repository keeps only the newest build of a package, so a pin
68
69
  // stops downloading when Alpine bumps it; the hashes then fail loudly.
69
70
  const alpineBase = `${mirror}/v3.24/main/${arch}`;
70
- const kernelVersion = "6.18.57";
71
+ const kernelVersion = "6.18.59";
71
72
  const kernelRelease = `${kernelVersion}-0-${flavor}`;
72
73
  const bunVersion = "1.4.2";
73
74
  const downloadsDir = join(rootDir, "downloads", arch);
@@ -77,6 +78,7 @@ export const config = ({
77
78
  arch,
78
79
  flavor,
79
80
  real,
81
+ noGpu,
80
82
  rootDir,
81
83
  alpineBase,
82
84
  kernelVersion,
package/scripts/arch.sh CHANGED
@@ -44,7 +44,7 @@ fi
44
44
  alpine_mirror=${ALPINE_MIRROR:-https://dl-cdn.alpinelinux.org/alpine}
45
45
  alpine_base="$alpine_mirror/v3.24/main/$arch"
46
46
 
47
- kernel_version=6.18.57
47
+ kernel_version=6.18.59
48
48
  kernel_release="$kernel_version-0-$linux_flavor"
49
49
  linux_package="linux-$linux_flavor-$kernel_version-r0.apk"
50
50
  musl_package=musl-1.2.6-r2.apk
@@ -63,8 +63,8 @@ musl_libc="libc.musl-$arch.so.1"
63
63
 
64
64
  case $arch in
65
65
  x86_64)
66
- linux_virt_sha256=414aa2572ef88164b1af9905fa6dfbe863bf50f6130d895d57282dea3e15f7b9
67
- linux_lts_sha256=7614556471859956a436b95813daf409b444aa849ec899178b404e828c5a9d98
66
+ linux_virt_sha256=73ad4774ca26c196103a00e2fb8d28ed02de4c08c11fad96e903da03dcb085f4
67
+ linux_lts_sha256=ae0a669a08c90ef971996f81f1bcb6f7ca8211ad62624ad8c5b57412c3f1def8
68
68
  musl_sha256=573712e2f49c15bfc20a2699f204acdfc74c772722b15e7353d768057fae0e71
69
69
  stub_sha256=8e64a5a3afee5f930e6e6716be726dc6d405530ac7f8fa5be6251dae68671ec9
70
70
  libstdcpp_sha256=14c987b556f5385a5db18376e788c75f37d85321b8dc1920d926ea7daac1d6f6
@@ -82,8 +82,8 @@ case $arch in
82
82
  serial_major=4
83
83
  ;;
84
84
  aarch64)
85
- linux_virt_sha256=b3820fee22e0366a15f7c139e5bc00348e333f3e7f77802271df7ded795aee4f
86
- linux_lts_sha256=67b8f61c5cfb6ac9b5a65cb1610b67d467e6c4ffc17e7d29dbea4bd8c447ff32
85
+ linux_virt_sha256=89b68fc32d61a1483ab0d9db78b5a06144ac115fe2ee8102cb4ad7987f46d524
86
+ linux_lts_sha256=f6387970517083d5f08abacbf81baf1d70e1baa8fe4c2783469f45bb0751075c
87
87
  musl_sha256=5e9674b7f41152fe2119093b5cb4c13eaaadb19c2d5422b2d7267913e663ee6e
88
88
  stub_sha256=a1823d2d7082db555d528f82c1809f276c818aeb5b40f198f4565f104e055c38
89
89
  libstdcpp_sha256=2302e766d4e4926038ec166ecb85837ee884576115236ddb565e3a5fca4a11d7