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
package/build-image.sh CHANGED
@@ -25,7 +25,16 @@ done
25
25
  temporary_esp="$(mktemp --tmpdir=. .esp.XXXXXX.img)"
26
26
  trap 'rm -f "$temporary_esp"' EXIT
27
27
 
28
- disk_sectors=$((128 * 1024 * 1024 / 512))
28
+ # Match scripts/build.js: payload + 1/16 + 4 MiB, rounded to 64 MiB.
29
+ payload_bytes=$(stat -c %s "vda/EFI/BOOT/$efi_boot_name")
30
+ if ((payload_bytes > 4294967295)); then
31
+ echo "error: EFI payload exceeds the FAT32 single-file limit" >&2
32
+ exit 1
33
+ fi
34
+ unit=$((64 * 1024 * 1024))
35
+ disk_bytes=$(((payload_bytes + (payload_bytes + 15) / 16 + 4 * 1024 * 1024 + unit - 1) / unit * unit))
36
+ ((disk_bytes >= 128 * 1024 * 1024)) || disk_bytes=$((128 * 1024 * 1024))
37
+ disk_sectors=$((disk_bytes / 512))
29
38
  esp_start=2048
30
39
  esp_end=$((disk_sectors - 34))
31
40
  esp_sectors=$((esp_end - esp_start + 1))
package/build-uki.sh CHANGED
@@ -5,7 +5,9 @@ cd "$(dirname "$0")"
5
5
 
6
6
  . ./scripts/arch.sh
7
7
 
8
- if [ ! -s "$kernel_image" ] || [ ! -s "$kernel_dir/$efi_stub" ] || [ ! -s "$modules_root/modules.dep" ] || \
8
+ gpu_js=$(command -v bun || command -v node)
9
+
10
+ if [ ! -s "$kernel_image" ] || [ ! -s "$kernel_dir/$efi_stub" ] || [ ! -s "$modules_root/modules.dep" ] || ! "$gpu_js" scripts/fetch-gpu.js --check || \
9
11
  { [ "${REAL_MACHINE:-}" = 1 ] && \
10
12
  { [ ! -s "$modules_root/kernel/drivers/hid/usbhid/usbhid.ko" ] || \
11
13
  [ ! -s "$modules_root/kernel/drivers/acpi/battery.ko" ]; }; }; then
package/fetch-alpine.sh CHANGED
@@ -33,6 +33,9 @@ depfile="$(mktemp)"
33
33
  selected="$(mktemp)"
34
34
  trap 'rm -f "$depfile" "$selected" "$selected.names"' EXIT
35
35
  extract "$linux_package" "lib/modules/$kernel_release/modules.dep" > "$depfile"
36
+ # Recreate the generated module tree so removed selections cannot linger.
37
+ rm -rf "$modules_root"
38
+ mkdir -p "$modules_root"
36
39
  extract "$linux_package" "lib/modules/$kernel_release/modules.builtin" > "$modules_root/modules.builtin"
37
40
 
38
41
  select_module() {
@@ -65,6 +68,13 @@ select_optional_module() {
65
68
  # it in, linux-lts has it as a module that nothing in modules.dep pulls in.
66
69
  for module in failover net_failover virtio_net af_packet; do select_module "$module"; done
67
70
  select_optional_module virtio_pci
71
+ # GPU modules are packaged only; init and cfg.all leave them unloaded.
72
+ if [ "${BUNINU_NO_GPU:-}" != 1 ]; then
73
+ for module in virtio-gpu vmwgfx; do select_optional_module "$module"; done
74
+ if [ "$arch" = x86_64 ]; then
75
+ for module in i915 xe amdgpu radeon nouveau; do select_optional_module "$module"; done
76
+ fi
77
+ fi
68
78
  # Storage: what /bin/mount loads on demand. ext4 brings jbd2, mbcache and
69
79
  # crc16; FAT, exFAT and NTFS ask the kernel for the NLS tables at mount
70
80
  # time, which has no /sbin/modprobe to answer, so mount preloads them.
@@ -145,4 +155,8 @@ extract "$linux_package" "lib/modules/$kernel_release/modules.alias" \
145
155
 
146
156
  chmod 0755 "$native_dir/lib/$musl_loader"
147
157
 
158
+ # Share the verified firmware extraction and cache marker with the JS build.
159
+ js=$(command -v bun || command -v node)
160
+ "$js" scripts/fetch-gpu.js
161
+
148
162
  echo "Fetched Alpine $arch linux-$linux_flavor kernel, $(wc -l < "$selected") modules, musl, and the $efi_stub UKI stub."
package/graphics.md CHANGED
@@ -158,6 +158,28 @@ screen and xterm.js's `CoreMouseService` → PTY. Terminal
158
158
  replies (cursor position, device attributes, kitty acks) go from the
159
159
  emulator straight to the PTY.
160
160
 
161
+ ## Raw image fast path
162
+
163
+ Native bunterm can negotiate BGRA (`f=1111970369`, a private Buninu format) or
164
+ standard RGBA (`f=32`) with Casty. `images.js` retains the received raw bytes;
165
+ `raw-image.js` creates a Skia image only when a fallback operation needs one.
166
+ For an opaque, integer-aligned 1:1 placement matching the framebuffer channel
167
+ order, `canvas.js` copies these bytes into the existing raster back buffer.
168
+ This avoids `MakeImage` followed by `readPixels`, but still performs the raster
169
+ copy and the final framebuffer flush. Opacity is checked from the actual alpha
170
+ bytes once per image, not assumed from its format or filename.
171
+
172
+ Rows completely covered by such an image skip text hashing and painting.
173
+ Partially covered rows keep normal rendering, and uncovering a row forces its
174
+ current text to repaint. Pointer and menu overlays are still drawn afterwards.
175
+ Scaling, transparency, other channel orders and 16-bit framebuffers retain
176
+ CanvasKit rendering. Encoded PNG/JPEG handling is unchanged.
177
+
178
+ 原始像素只有在通道排列一致、1:1 整數座標且經檢查確定不透明時,才直接複製到
179
+ 繪圖緩衝區,省去先建立 Skia Image 再讀回像素的步驟。完全被圖片覆蓋的文字列
180
+ 略過雜湊與重畫;圖片移開後會重畫當下的文字。縮放、透明、格式不符時仍使用
181
+ CanvasKit,最後寫入 framebuffer 的複製也仍然存在。
182
+
161
183
  ## Sizes
162
184
 
163
185
  | Component | Raw | In the gzip initramfs |
@@ -222,6 +244,15 @@ at once and draws on VT 2; and keys sent with the monitor's `sendkey` reach
222
244
  it: `showimg /buninu/icon.png` places the kitty image, and the prompt's
223
245
  colour emoji and the pointer render, all checked with `screendump`.
224
246
 
247
+ ## Optional client GPU acceleration
248
+
249
+ Client GPU rendering can be enabled separately with the PID 1 REPL's `cfg.gpu`,
250
+ before opening framebuffer clients. It loads matched GPU drivers and exposes
251
+ render nodes, while this CanvasKit/bunterm stack remains software-rendered.
252
+ Boot and `cfg.all` do not load those GPU drivers. See the README's
253
+ [optional client GPU acceleration](README.md#optional-client-gpu-acceleration-cfggpu)
254
+ for firmware, device permissions and framebuffer handoff constraints.
255
+
225
256
  ## Not done yet
226
257
 
227
258
  - Selection and scrollback viewing in `bunterm` (the pointer itself works,
package/index.js CHANGED
@@ -79,7 +79,7 @@ function usage() {
79
79
 
80
80
  Usage:
81
81
  ${pkg.name} [-f] [-b] [-r] [--arch ARCH] [--docker] [--export] [--linux-lts]
82
- [--real] [-- qemu arguments]
82
+ [--real] [--no-gpu] [-- qemu arguments]
83
83
  ${pkg.name} --check [FILE...]
84
84
 
85
85
  Stages (always run in this order, whichever you pick):
@@ -107,6 +107,8 @@ Stages (always run in this order, whichever you pick):
107
107
  primary console, and include USB xHCI/HID keyboard modules
108
108
  (x86_64 only)
109
109
 
110
+ --no-gpu omit the added GPU modules/firmware; retain the original framebuffer path
111
+
110
112
  --check [FILE...]
111
113
  print content checksums of the build outputs that ignore
112
114
  mtimes, timestamps and GUIDs, and exit (check_build.js; the
@@ -116,6 +118,8 @@ Stages (always run in this order, whichever you pick):
116
118
  -h, --help show this
117
119
  -V, --version show name, version, runtime and platform
118
120
  --readme render README.md in the terminal and exit
121
+ --readme-zh, --docs
122
+ render README.zh.md in the terminal and exit
119
123
 
120
124
  Short flags combine: -fbr is the whole pipeline, -br is what an edit to
121
125
  initramfs/init.js needs, -r just boots what is already there. Anything after
@@ -134,11 +138,12 @@ reported before anything starts.
134
138
  `;
135
139
  }
136
140
 
137
- function parse(argv) {
141
+ async function parse(argv) {
138
142
  const selected = new Set();
139
143
  const passthrough = [];
140
144
  let linuxLts = false;
141
145
  let real = false;
146
+ let noGpu = false;
142
147
  let exportImage = false;
143
148
  let docker = false;
144
149
  // BUNINU_ARCH is what scripts/arch.sh reads; --arch overrides it.
@@ -165,12 +170,17 @@ function parse(argv) {
165
170
  printVersion();
166
171
  process.exit(0);
167
172
  } else if (argument === "--readme") {
168
- printReadme();
173
+ await printReadme();
174
+ process.exit(0);
175
+ } else if (argument === "--readme-zh" || argument === "--docs") {
176
+ await printReadme("README.zh.md");
169
177
  process.exit(0);
170
178
  } else if (argument === "--check") {
171
179
  runCheck(argv.slice(index + 1));
172
180
  } else if (argument === "--linux-lts") {
173
181
  linuxLts = true;
182
+ } else if (argument === "--no-gpu") {
183
+ noGpu = true;
174
184
  } else if (argument === "--real") {
175
185
  real = true;
176
186
  } else if (argument === "--export") {
@@ -197,8 +207,8 @@ function parse(argv) {
197
207
  if (passthrough.length > 0 && !selected.has(stages[2])) {
198
208
  fail("arguments after -- only make sense with -r/--run");
199
209
  }
200
- if ((linuxLts || real) && !selected.has(stages[0]) && !selected.has(stages[1])) {
201
- fail("--linux-lts/--real only make sense with -f/--fetch or -b/--build");
210
+ if ((linuxLts || real || noGpu) && !selected.has(stages[0]) && !selected.has(stages[1])) {
211
+ fail("--linux-lts/--real/--no-gpu only make sense with -f/--fetch or -b/--build");
202
212
  }
203
213
  if (exportImage && !selected.has(stages[1])) {
204
214
  fail("--export requires -b/--build (use -fb --export for a clean build)");
@@ -206,7 +216,7 @@ function parse(argv) {
206
216
  if (real && arch === "aarch64") {
207
217
  fail("--real builds an x86_64 PC image; it cannot be combined with --arch aarch64");
208
218
  }
209
- return { selected, passthrough, linuxLts, real, exportImage, docker, arch };
219
+ return { selected, passthrough, linuxLts, real, noGpu, exportImage, docker, arch };
210
220
  }
211
221
 
212
222
  // Same shape as Buninu's --version. The runtime line tells you whether this
@@ -222,8 +232,8 @@ function printVersion() {
222
232
 
223
233
  // Same as Buninu's --readme: Bun renders the Markdown to ANSI with clickable
224
234
  // links. Under node there is no renderer, so the file is printed as-is.
225
- function printReadme() {
226
- const path = resolve(rootDir, "README.md");
235
+ function printReadme(filename = "README.md") {
236
+ const path = resolve(rootDir, filename);
227
237
  let markdown;
228
238
  try {
229
239
  markdown = readFileSync(path, "utf8");
@@ -234,7 +244,12 @@ function printReadme() {
234
244
  typeof Bun !== "undefined" && typeof Bun.markdown?.ansi === "function"
235
245
  ? Bun.markdown.ansi(markdown, { hyperlinks: true })
236
246
  : markdown;
237
- process.stdout.write(rendered.endsWith("\n") ? rendered : rendered + "\n");
247
+ // Wait for the whole document to flush before parse() exits. Large README
248
+ // output can otherwise be truncated when stdout is a pipe.
249
+ return new Promise((resolve, reject) => {
250
+ process.stdout.write(rendered.endsWith("\n") ? rendered : rendered + "\n",
251
+ (error) => error ? reject(error) : resolve());
252
+ });
238
253
  }
239
254
 
240
255
  // --check hands everything after it to check_build.js, under the same
@@ -316,7 +331,7 @@ function dockerImage() {
316
331
  // into the bind-mounted checkout stays owned by that user; fakeroot provides
317
332
  // the root ownership the initramfs records.
318
333
  function dockerRun(script, env) {
319
- const passEnv = ["BUNINU_ARCH", "LINUX_FLAVOR", "REAL_MACHINE", "ALPINE_MIRROR", "BUNINU_JS_UKI", "BUNINU_JS_CPIO"]
334
+ const passEnv = ["BUNINU_ARCH", "LINUX_FLAVOR", "REAL_MACHINE", "BUNINU_NO_GPU", "ALPINE_MIRROR", "BUNINU_JS_UKI", "BUNINU_JS_CPIO"]
320
335
  .filter((name) => env[name] !== undefined)
321
336
  .flatMap((name) => ["--env", `${name}=${env[name]}`]);
322
337
  const user = typeof process.getuid === "function"
@@ -344,7 +359,7 @@ function runScript(stage, script, args = [], env = process.env) {
344
359
  }
345
360
  }
346
361
 
347
- const { selected, passthrough, linuxLts, real, exportImage, docker, arch } = parse(process.argv.slice(2));
362
+ const { selected, passthrough, linuxLts, real, noGpu, exportImage, docker, arch } = await parse(process.argv.slice(2));
348
363
  const ordered = stages.filter((stage) => selected.has(stage));
349
364
  const useDocker = docker || process.platform === "darwin";
350
365
  const buildArch = arch ?? "x86_64";
@@ -357,6 +372,7 @@ const stageEnv = {
357
372
  ...(arch && { BUNINU_ARCH: arch }),
358
373
  ...((linuxLts || real) && { LINUX_FLAVOR: "lts" }),
359
374
  ...(real && { REAL_MACHINE: "1" }),
375
+ ...(noGpu && { BUNINU_NO_GPU: "1" }),
360
376
  };
361
377
 
362
378
  // The arch.js config for the JS stages, from the same settings as stageEnv.
@@ -364,6 +380,7 @@ const jsConfig = async (env) => (await import("./scripts/arch.js")).config({
364
380
  arch: env.BUNINU_ARCH,
365
381
  flavor: env.LINUX_FLAVOR,
366
382
  real: env.REAL_MACHINE === "1",
383
+ noGpu: env.BUNINU_NO_GPU === "1",
367
384
  mirror: env.ALPINE_MIRROR,
368
385
  });
369
386
 
@@ -14,9 +14,12 @@ const { chooseFrontend } = await import(pathToFileURL(entry).href);
14
14
  const args = process.argv.slice(2);
15
15
  const choice = chooseFrontend(args);
16
16
  const casty = choice.frontend === "casty";
17
+ const forwarded = casty ? choice.args : args;
18
+ // Preserve Casty's separator when Bun consumes the first one after the script.
19
+ const runtimeArgs = forwarded[0] === "--" ? ["--", ...forwarded] : forwarded;
17
20
  const child = Bun.spawn({
18
21
  cmd: [process.execPath, casty ? join(modules, "@drxiaozhi/casty/index.js") : entry,
19
- ...(casty ? choice.args : args)],
22
+ ...runtimeArgs],
20
23
  env: casty ? { ...process.env, CASTY_BROWSER: join(browser, "buninu-browser.js") } : process.env,
21
24
  stdio: ["inherit", "inherit", "inherit"],
22
25
  });
@@ -14,7 +14,7 @@ const { chooseFrontend } = await import(pathToFileURL(entry).href);
14
14
  const args = process.argv.slice(2);
15
15
  const choice = chooseFrontend(args);
16
16
  const casty = choice.frontend === "casty";
17
- const forwarded = casty ? choice.args : args;
17
+ const forwarded = casty ? ["--no-shortcuts", ...choice.args] : args;
18
18
  // Bun consumes a leading separator after the script path; preserve Casty's
19
19
  // own separator when --casty is followed directly by -- engine flags.
20
20
  const runtimeArgs = forwarded[0] === "--" ? ["--", ...forwarded] : forwarded;
@@ -4,7 +4,7 @@
4
4
  import { showDocument } from "../lib/document.js";
5
5
  import { runTerminal } from "../lib/bunterm/terminal.js";
6
6
  import { activeConsole, openConsole } from "../lib/fbdev.js";
7
- import { virtualConsoleNumber } from "../lib/bunterm/vt.js";
7
+ import { virtualConsoleNumber, nextVirtualTerminal } from "../lib/bunterm/vt.js";
8
8
  import { closeSync, openSync, readFileSync } from "node:fs";
9
9
 
10
10
  const CANONICAL_BUNTERM = "/bin/bunterm";
@@ -79,7 +79,7 @@ const main = async () => {
79
79
  } finally {
80
80
  probe.close();
81
81
  }
82
- if (!options.console) options.console = `/dev/tty${activeConsoleNumber}`;
82
+ if (!options.console) options.console = `/dev/tty${nextVirtualTerminal()}`;
83
83
 
84
84
  // Every live bunterm converges on one unambiguous /proc/<pid>/cmdline:
85
85
  // /bin/bunterm /bin/bunterm /dev/ttyN [options...]
@@ -94,7 +94,7 @@ const main = async () => {
94
94
  Object.entries(process.env).filter((entry) => typeof entry[1] === "string"),
95
95
  );
96
96
  const targetConsoleNumber = virtualConsoleNumber(options.console);
97
- if (consoleArgumentIndex !== -1 && targetConsoleNumber !== activeConsoleNumber) {
97
+ if (targetConsoleNumber !== activeConsoleNumber) {
98
98
  const consoleFd = openSync(options.console, "r+");
99
99
  try {
100
100
  const child = Bun.spawn(
@@ -53,6 +53,19 @@ try { bindings = resolveBindings(options.binds); }
53
53
  catch (error) { fail(`invalid bind: ${error.message}`); }
54
54
 
55
55
 
56
+ // dlopen.js resolves each symbol lazily. Bind everything needed after mounts
57
+ // or chroot before the host libc path can disappear from this process's root.
58
+ // Even --keep-mounts needs umount2 when setup fails and must be rolled back.
59
+ try {
60
+ void libc.symbols.chroot;
61
+ if (options.mount || bindings.length) {
62
+ void libc.symbols.mount;
63
+ void libc.symbols.umount2;
64
+ }
65
+ errno();
66
+ void libc.symbols.strerror;
67
+ } catch (error) { fail(error.message); }
68
+
56
69
  const report = (message) => { if (options.verbose) console.error(`chroot: ${message}`); };
57
70
 
58
71
  // ---------------------------------------------------------------- mounts --
@@ -0,0 +1,11 @@
1
+ #!/bin/bun
2
+ import { parseChvt, switchVt } from "../lib/chvt.js";
3
+ import { showDocument } from "../lib/document.js";
4
+ try {
5
+ const options = parseChvt(process.argv.slice(2));
6
+ if (options.help) await showDocument("chvt");
7
+ else await switchVt(options.number);
8
+ } catch (error) {
9
+ console.error(`chvt: ${error.message}`);
10
+ process.exitCode = 1;
11
+ }
@@ -325,6 +325,10 @@ const doMount = (source, target, type, flags, data, { verbose, fake }) => {
325
325
  console.log(`mount(${source}, ${target}, ${type ?? "(none)"}, [${words.join(",")}], "${data}")`);
326
326
  }
327
327
  if (fake) return;
328
+ // A bind over /lib can hide libc before the read-only remount pass fails.
329
+ void libc.symbols.mount;
330
+ errno();
331
+ void libc.symbols.strerror;
328
332
  const dataBytes = data ? cString(data) : null;
329
333
  const typeBytes = type ? cString(type) : null;
330
334
  const result = libc.symbols.mount(
@@ -58,6 +58,12 @@ const unmount = (target) => {
58
58
  return false;
59
59
  };
60
60
 
61
+ // A previous target may contain libc; later failures still need strerror.
62
+ if (targets.length) {
63
+ try { void libc.symbols.umount2; errno(); void libc.symbols.strerror; }
64
+ catch (error) { console.error(`umount: ${error.message}`); process.exit(1); }
65
+ }
66
+
61
67
  let status = 0;
62
68
  for (const target of targets) {
63
69
  const path = target.length > 1 ? target.replace(/\/+$/, "") : target;
@@ -0,0 +1,33 @@
1
+ #!/bin/bun
2
+ import { browserTarget, parseOpenArgs, openError, openExitCode, releaseVersion } from "../lib/xdg-open.js";
3
+ import { showDocument } from "../lib/document.js";
4
+
5
+ try {
6
+ const options = parseOpenArgs(process.argv.slice(2));
7
+ if (options.help) {
8
+ await showDocument("xdg-open");
9
+ } else if (options.version) {
10
+ // Both image builders already generate this from buninu-linux's version.
11
+ const release = new URL("../usr/lib/os-release", import.meta.url);
12
+ let version;
13
+ if (await Bun.file(release).exists()) version = releaseVersion(await Bun.file(release).text());
14
+ else version = (await Bun.file(new URL("../../package.json", import.meta.url)).json()).version;
15
+ console.log(`xdg-open (Buninu Linux) ${version}`);
16
+ } else {
17
+ const url = browserTarget(options.target);
18
+ for (const tool of ["bunterm", "buninu-browser"])
19
+ if (!Bun.which(tool)) throw openError(`Required tool not found: ${tool}`, 3);
20
+ let child;
21
+ try {
22
+ child = Bun.spawn(["bunterm", "-e", "buninu-browser", url], {
23
+ stdio: ["inherit", "inherit", "inherit"],
24
+ });
25
+ } catch (error) {
26
+ throw openError(error.message, error.code === "ENOENT" ? 3 : 4);
27
+ }
28
+ process.exitCode = await child.exited === 0 ? 0 : 4;
29
+ }
30
+ } catch (error) {
31
+ console.error(`xdg-open: ${error.message}`);
32
+ process.exitCode = openExitCode(error);
33
+ }
@@ -1,5 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0 - 2026-10-26
4
+
5
+ - Sync jsgotty to 1.4.0:
6
+ * Add horizontal and diagonal scrolling through terminal mouse reporting,
7
+ including Shift-wheel horizontal scrolling and preserved wheel modifiers.
8
+ * Double-tap and hold the second tap to drag with the left mouse button when
9
+ application mouse reporting is enabled. Release the button on touch
10
+ cancellation, backgrounding or disconnect; ordinary swipes still scroll.
11
+ * Add Right click to the existing image long-press menu, sending the click
12
+ at the position where the menu was opened without removing the image.
13
+ * Prevent Android WebView from automatically zooming the terminal's hidden
14
+ input after native long-press paste, including at reduced viewport zoom.
15
+ Keep native paste, IME input and pinch zoom on the visible terminal.
16
+ - Sync jsmdcui to 0.19.4:
17
+ * Restore Dockerfile highlighting and improve compatibility with Micro's
18
+ syntax definitions by translating Go regexp flags and POSIX character
19
+ classes while preserving scoped flags.
20
+ * Fix nested HTML/XML highlighting regions so quoted attributes return to
21
+ their enclosing tags and unfinished attributes retain state across lines.
22
+ * Use iterative region scanning to support long minified lines without
23
+ recursive stack exhaustion or truncating highlighting.
24
+ * Guard against zero-width region cycles, cyclic syntax/state trees and
25
+ excessively nested regexp conversion. Disable failing rules individually
26
+ instead of losing an entire syntax definition; retain support for long
27
+ lines. These guards do not impose timeouts on individual JavaScript regexps.
28
+
29
+ ## 0.6.0 - 2026-10-25
30
+
31
+ - Sync jsgotty to 1.3.0:
32
+ * Add OSC 52 clipboard reads and writes for browser terminals using the
33
+ server host's clipboard. Try xclip first on every platform, then available
34
+ platform tools, with an in-memory fallback when all tools fail. Only the
35
+ session writer performs clipboard operations; CLI clients pass OSC 52
36
+ through to their terminal emulator.
37
+ * Restore mouse reporting, mouse encoding, Kitty keyboard state and other
38
+ terminal modes when reconnecting to an existing session, including from
39
+ a fresh terminal and through nested CLI clients. Preserve keyboard mode
40
+ stacks without unnecessarily switching screens.
41
+ * Probe and restore the CLI client's original terminal modes on exit;
42
+ handle unsupported mode replies and independently enabled mouse modes
43
+ without leaving stale mouse reporting behind.
44
+ * Fix read-only CLI viewer exit shortcuts (Ctrl-C, Ctrl-D and Ctrl-Q) when
45
+ the enclosing terminal uses Kitty keyboard encoding.
46
+ * Fix Android WebView double-tap handling at non-default viewport zoom so
47
+ terminal clicks reach applications instead of triggering browser zoom,
48
+ while retaining two-finger pinch zoom.
49
+
50
+ ## 0.5.0 - 2026-10-21
51
+
52
+ - Sync jsgotty to 1.2.0:
53
+ * Add opt-in Kitty keyboard support for disambiguated shortcuts, including
54
+ Super, and press/repeat/release events. Support flags 1, 2 and 8, mode
55
+ queries, and independent mode stacks for normal and alternate screens;
56
+ legacy keyboard encoding remains the default.
57
+ * Recover Super state on Android WebViews that deliver Meta key events but
58
+ omit the modifier state. Handle Android Alt shortcuts without accent
59
+ dead-key conversion, including recognizable keyup-only events.
60
+ * Preserve Alt on arrow, Insert, PageUp and PageDown shortcuts, and encode
61
+ Ctrl+/ as the conventional US control character.
62
+ * Add a manual keyboard tester with readable, colored shortcut names and
63
+ raw sequences; restore keyboard and raw modes when it exits.
64
+ * Allow local Kitty graphics consumers to request binary image data,
65
+ avoiding a base64 conversion; browser clients retain base64 by default.
66
+ - Sync bunmsh to 0.4.1: use the existing linker-aware shell launcher for the
67
+ awk fallback's subprocess commands instead of bypassing linker handling.
68
+
3
69
  ## 0.4.21 - 2026-10-15
4
70
 
5
71
  - Sync jsgotty to 1.1.16: Turn on pixel report
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable user-visible changes to bunmsh are documented here.
4
4
 
5
+ ## [0.4.1] - 2026-10-13
6
+
7
+ - Fixed awk bypassing linker protection
8
+
5
9
  ## [0.4.0] - 2026-10-13
6
10
 
7
11
  ### Added and fixed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunmsh",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Cross-platform command shell for Bun JavaScript",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -302,7 +302,7 @@ async function interactive(state) {
302
302
  const timer = setTimeout(() => {
303
303
  if (pendingCursorQuery?.resolve === resolve) pendingCursorQuery = null;
304
304
  resolve(null);
305
- }, 60);
305
+ }, 400);
306
306
  pendingCursorQuery = {
307
307
  resolve(position) {
308
308
  clearTimeout(timer);
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016-2020: Zachary Yedidia, et al.
4
+ Copyright (c) 2026 Dr. John (醫者小智)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -119,3 +119,8 @@ such an executable must also follow Bun's license terms, including the LGPL
119
119
  relinking provisions described at
120
120
  https://github.com/oven-sh/bun/blob/main/LICENSE.md. The executables carry
121
121
  LICENSE, NOTICE and LICENSES/ as embedded assets.
122
+
123
+ Clipboard backend helpers reference jsmdcui (MIT).
124
+ clipboard-powershell.js retains its powershellClipboard function verbatim from
125
+ jsmdcui/src/platform/clipboard.js, Copyright (c) 2026 Dr. John (醫者小智).
126
+ Full source license: LICENSES/MIT-jsmdcui.txt.
@@ -3,6 +3,11 @@
3
3
  [中文 README](README.md)
4
4
 
5
5
  ## News
6
+
7
+ ### 2026/10/21
8
+
9
+ - Added [Kitty keyboard](#kitty-keyboard) support for distinct modifier combinations, including Super, and press/repeat/release events.
10
+
6
11
  ### 2026/08/16
7
12
  - Fixed the disconnected-screen `Reconnect` button not being clickable in WebGL mode.
8
13
  - The `Reconnect` UI now stays above the WebGL canvas and receives mouse and touch events correctly; Kitty image handling no longer intercepts right-click / long-press for entering a reconnect token or PID.
@@ -238,6 +243,41 @@ The `jsgotty` server has two connection modes:
238
243
  - On disconnect, the overlay provides a `Reconnect` button for immediate manual retry.
239
244
  - Right-click / long-press on that button lets you enter a custom reconnect token or PID.
240
245
 
246
+ ## Kitty keyboard
247
+
248
+ The web terminal supports the shortcut-related parts of the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/), separately from Kitty graphics. Legacy keyboard encoding remains the default. A terminal application can opt in:
249
+
250
+ ```sh
251
+ printf '\033[>11u' # 1: disambiguation + 2: repeat/release + 8: all keys
252
+ printf '\033[<u' # restore the previous mode when the application exits
253
+ ```
254
+
255
+ The receiving application must decode these sequences and restore the mode in its exit/finally handler; do not leave an ordinary shell in this mode. Negotiation supports `CSI ? u`, `CSI = flags ; mode u`, push and pop. Normal and alternate screens have independent stacks, limited to 32 entries. Reconnection, full reset and soft reset clear the state. Use flag `1` for unambiguous shortcuts, or `11` for modifier keys and press/repeat/release reporting.
256
+
257
+ DOM Meta maps to Kitty **Super (bit 8)**, not the separate Meta bit (32). Super+X is `CSI 120;9u`; Ctrl+Shift+Super+X is `CSI 120;14u`. Release events add `:3` when enabled.
258
+
259
+ Supported flags are **1, 2 and 8**; alternate keys (4) and associated text (16) are not implemented or reflected in the negotiated flags. IME composition/text commits and paste retain their existing paths; physical keys and releases cannot be inferred from committed text. Letters, digits, punctuation, navigation, Tab/Enter, function keys, keypad keys and standard Kitty media keys retain distinct modifiers. OS/browser-reserved shortcuts may never reach the page. Keys without standard Kitty codes, such as brightness and microphone mute, are not assigned private encodings.
260
+
261
+ This implements **jsgotty → PTY** encoding. Controlling Hyprland/Omarchy still requires Casty or another receiver to enable/decode Kitty keyboard and forward Super and release events. It does not complete the remote desktop input chain or change the mouse protocol.
262
+
263
+ Reload the jsgotty page after updating. Run the manual tester inside its terminal:
264
+
265
+ ```sh
266
+ bun tests/manual/kitty-keyboard.js
267
+ ```
268
+
269
+ It prints negotiated flags, raw sequences, modifiers and event types, exits after 60 seconds or unmodified Escape/q/Ctrl-C, and restores the previous keyboard/raw modes. An optional real bundled-xterm test uses an already installed browser:
270
+
271
+ ```sh
272
+ CHROMIUM_HEADLESS=/path/to/chromium-headless-shell node --test tests/kitty-keyboard-browser.test.js
273
+ ```
274
+
275
+ ## Android Keyboards
276
+
277
+ For Android WebViews that deliver Meta down/up but lose `metaKey`, jsgotty tracks both Meta keys inside its own input handler. Blur or page hiding clears held state and sends releases for reported keys when event reporting is enabled.
278
+
279
+ In the Android terminal, Alt with letters, digits, punctuation, or space sends terminal Alt sequences based on physical key positions (US layout, including Shift), bypassing accent dead-key handling. Alt-E/I/N/U therefore no longer compose characters such as é, ê, ñ, and ü; input methods and paste remain available. When WebView omits `code`, recognized legacy `keyCode` values provide a fallback. Dead keys delivered only as `keyup` send the shortcut on release, without duplicating a previously handled `keydown`. Active composition, Ctrl, Meta, AltGr, and unidentified keys retain their existing handling. This applies only inside the jsgotty terminal and does not modify Android system keyboard settings.
280
+
241
281
  ## Tested platforms
242
282
  - Windows x64: Windows 11
243
283
  - Linux x64: CachyOS
@@ -292,3 +332,24 @@ bun sz.js file.txt
292
332
  - Bun is the primary runtime.
293
333
  - On Linux / macOS, PTY support will not work unless the program is launched with Bun.
294
334
  - GoTTY config file loading is not implemented yet.
335
+
336
+ ## OSC 52 clipboard
337
+
338
+ The browser frontend supports OSC 52 writes and `?` queries against the **server host's clipboard**, not the browser device's clipboard. Only the session writer can request access; viewers do not duplicate operations. Query replies are sent directly back to the originating PTY as OSC 52 sequences.
339
+
340
+ Each operation tries `xclip` first, including on Windows and Android. Missing or failing commands fall through to applicable `termux-clipboard-*`, `wl-copy`/`wl-paste`, `xsel`, macOS `pbcopy`/`pbpaste`, then Windows PowerShell. The PowerShell function is copied verbatim from jsmdcui. If all tools fail, the server uses its in-memory cache. A successful empty read remains empty, rather than returning stale cached text. There is no polling; external commands run in a worker.
341
+
342
+ Supported selections: `c` (clipboard), `p` (primary), `q` (secondary); `s` maps to clipboard, and `0`–`7` are in-memory buffers. An empty selector uses `s0`. Tools without primary/secondary support do not substitute the clipboard. Requests are limited to 1 MiB.
343
+
344
+ ```sh
345
+ # Write to the server clipboard
346
+ printf '\033]52;c;%s\007' "$(printf 'Hello' | base64 | tr -d '\n')"
347
+ ```
348
+
349
+ Applications can send `ESC ] 52 ; c ; ? ST` to read and receive a base64-encoded OSC 52 reply on stdin.
350
+
351
+ `jsgotty --client` **does not intercept OSC 52**: it forwards reads and writes unchanged for the outer terminal emulator to handle.
352
+
353
+ ### Touch dragging and right click
354
+
355
+ When the application enables mouse reporting, double-tap and hold the second tap to drag with the left button; lifting your finger releases it. Single-finger swipes still scroll. The existing image long-press menu now includes `Right click` below `Remove image`; it sends a right click at the position where the menu was opened. Pinch zoom and the existing remove-image gesture remain unchanged. To disable double-tap dragging, set `window.touchDoubleTapDrag = false` in the page JavaScript.