buninu 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/.bashrc +11 -0
  2. package/ARCHITECTURE.md +452 -0
  3. package/LICENSE +21 -0
  4. package/README.md +121 -0
  5. package/apps/bun/make-bunBin.sh +84 -0
  6. package/apps/jsgotty/LICENSE +23 -0
  7. package/apps/jsgotty/LICENSES/Apache-2.0-zmodem.js.txt +201 -0
  8. package/apps/jsgotty/NOTICE +21 -0
  9. package/apps/jsgotty/README.en.md +290 -0
  10. package/apps/jsgotty/README.md +292 -0
  11. package/apps/jsgotty/client.mjs +700 -0
  12. package/apps/jsgotty/env.sh +2 -0
  13. package/apps/jsgotty/gotty.js +3325 -0
  14. package/apps/jsgotty/node_modules/.package-lock.json +35 -0
  15. package/apps/jsgotty/node_modules/node-addon-api/LICENSE.md +9 -0
  16. package/apps/jsgotty/node_modules/node-addon-api/README.md +319 -0
  17. package/apps/jsgotty/node_modules/node-addon-api/common.gypi +20 -0
  18. package/apps/jsgotty/node_modules/node-addon-api/except.gypi +25 -0
  19. package/apps/jsgotty/node_modules/node-addon-api/index.js +12 -0
  20. package/apps/jsgotty/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
  21. package/apps/jsgotty/node_modules/node-addon-api/napi-inl.h +6607 -0
  22. package/apps/jsgotty/node_modules/node-addon-api/napi.h +3201 -0
  23. package/apps/jsgotty/node_modules/node-addon-api/node_addon_api.gyp +32 -0
  24. package/apps/jsgotty/node_modules/node-addon-api/node_api.gyp +9 -0
  25. package/apps/jsgotty/node_modules/node-addon-api/noexcept.gypi +26 -0
  26. package/apps/jsgotty/node_modules/node-addon-api/nothing.c +0 -0
  27. package/apps/jsgotty/node_modules/node-addon-api/package-support.json +21 -0
  28. package/apps/jsgotty/node_modules/node-addon-api/package.json +480 -0
  29. package/apps/jsgotty/node_modules/node-addon-api/tools/README.md +73 -0
  30. package/apps/jsgotty/node_modules/node-addon-api/tools/check-napi.js +99 -0
  31. package/apps/jsgotty/node_modules/node-addon-api/tools/clang-format.js +71 -0
  32. package/apps/jsgotty/node_modules/node-addon-api/tools/conversion.js +301 -0
  33. package/apps/jsgotty/node_modules/node-addon-api/tools/eslint-format.js +79 -0
  34. package/apps/jsgotty/node_modules/ws/LICENSE +20 -0
  35. package/apps/jsgotty/node_modules/ws/README.md +548 -0
  36. package/apps/jsgotty/node_modules/ws/browser.js +8 -0
  37. package/apps/jsgotty/node_modules/ws/index.js +22 -0
  38. package/apps/jsgotty/node_modules/ws/lib/buffer-util.js +131 -0
  39. package/apps/jsgotty/node_modules/ws/lib/constants.js +19 -0
  40. package/apps/jsgotty/node_modules/ws/lib/event-target.js +292 -0
  41. package/apps/jsgotty/node_modules/ws/lib/extension.js +203 -0
  42. package/apps/jsgotty/node_modules/ws/lib/limiter.js +55 -0
  43. package/apps/jsgotty/node_modules/ws/lib/permessage-deflate.js +528 -0
  44. package/apps/jsgotty/node_modules/ws/lib/receiver.js +760 -0
  45. package/apps/jsgotty/node_modules/ws/lib/sender.js +607 -0
  46. package/apps/jsgotty/node_modules/ws/lib/stream.js +161 -0
  47. package/apps/jsgotty/node_modules/ws/lib/subprotocol.js +62 -0
  48. package/apps/jsgotty/node_modules/ws/lib/validation.js +152 -0
  49. package/apps/jsgotty/node_modules/ws/lib/websocket-server.js +562 -0
  50. package/apps/jsgotty/node_modules/ws/lib/websocket.js +1407 -0
  51. package/apps/jsgotty/node_modules/ws/package.json +70 -0
  52. package/apps/jsgotty/node_modules/ws/wrapper.mjs +21 -0
  53. package/apps/jsgotty/package-lock.json +46 -0
  54. package/apps/jsgotty/package.json +13 -0
  55. package/apps/jsgotty/patches/windowsPtyAgent.js +326 -0
  56. package/apps/jsgotty/patches/windowsTerminal.js +204 -0
  57. package/apps/jsgotty/rz.js +199 -0
  58. package/apps/jsgotty/single-exe/README.md +80 -0
  59. package/apps/jsgotty/single-exe/assetsHelper.js +90 -0
  60. package/apps/jsgotty/single-exe/assetsLoader.mjs +85 -0
  61. package/apps/jsgotty/single-exe/compiled.js +138 -0
  62. package/apps/jsgotty/single-exe/entry.mjs +9 -0
  63. package/apps/jsgotty/single-exe/packAssets.sh +7 -0
  64. package/apps/jsgotty/static/css/index.css +13 -0
  65. package/apps/jsgotty/static/css/kitty.css +61 -0
  66. package/apps/jsgotty/static/css/xterm.css +218 -0
  67. package/apps/jsgotty/static/css/xterm_customize.css +32 -0
  68. package/apps/jsgotty/static/favicon.ico +0 -0
  69. package/apps/jsgotty/static/help.md +125 -0
  70. package/apps/jsgotty/static/icon.svg +66 -0
  71. package/apps/jsgotty/static/icon_192.png +0 -0
  72. package/apps/jsgotty/static/index.html +164 -0
  73. package/apps/jsgotty/static/js/gotty.js +31537 -0
  74. package/apps/jsgotty/static/js/gotty.js.LICENSE.txt +7 -0
  75. package/apps/jsgotty/static/js/gotty.js.map +1 -0
  76. package/apps/jsgotty/static/js/gotty.licenses.txt +650 -0
  77. package/apps/jsgotty/static/js/kitty.js +1045 -0
  78. package/apps/jsgotty/static/js/windows_bridge.js +194 -0
  79. package/apps/jsgotty/static/js/xterm-addon-unicode11.js +2 -0
  80. package/apps/jsgotty/static/js/zmodem.js +1 -0
  81. package/apps/jsgotty/static/manifest.json +15 -0
  82. package/apps/jsgotty/sz.js +273 -0
  83. package/apps/jsgotty/tests/kitty-order.test.js +58 -0
  84. package/apps/jsgotty/viu.mjs +393 -0
  85. package/apps/jsgotty/wgotty +62 -0
  86. package/apps/jsgotty/windows-bridge-node.js +60 -0
  87. package/apps/jsgotty/zmodem-node.js +260 -0
  88. package/apps/jsmdcui/CHANGELOG.md +1048 -0
  89. package/apps/jsmdcui/LICENSE +22 -0
  90. package/apps/jsmdcui/README.md +1269 -0
  91. package/apps/jsmdcui/cdp-maze.js +141 -0
  92. package/apps/jsmdcui/clean.sh +9 -0
  93. package/apps/jsmdcui/demos/basic.jpg +0 -0
  94. package/apps/jsmdcui/demos/chinese.md +32 -0
  95. package/apps/jsmdcui/demos/event.md +170 -0
  96. package/apps/jsmdcui/demos/good.jpg +0 -0
  97. package/apps/jsmdcui/demos/image-processor.md +366 -0
  98. package/apps/jsmdcui/demos/image-processor.zh-TW.md +366 -0
  99. package/apps/jsmdcui/demos/img-change.md +73 -0
  100. package/apps/jsmdcui/demos/imgtool-zh.md +298 -0
  101. package/apps/jsmdcui/demos/imgtool.md +298 -0
  102. package/apps/jsmdcui/demos/maze.md +149 -0
  103. package/apps/jsmdcui/demos/reactive.md +40 -0
  104. package/apps/jsmdcui/demos/reader.md +513 -0
  105. package/apps/jsmdcui/demos/select.md +63 -0
  106. package/apps/jsmdcui/demos/todo-zh.md +190 -0
  107. package/apps/jsmdcui/demos/todo.md +191 -0
  108. package/apps/jsmdcui/edit +9 -0
  109. package/apps/jsmdcui/jsmdcui.sh +5 -0
  110. package/apps/jsmdcui/llm-maze.txt +94 -0
  111. package/apps/jsmdcui/package.json +19 -0
  112. package/apps/jsmdcui/project_structure.txt +35 -0
  113. package/apps/jsmdcui/runmd.mjs +1140 -0
  114. package/apps/jsmdcui/runtime/colorschemes/atom-dark.micro +33 -0
  115. package/apps/jsmdcui/runtime/colorschemes/bubblegum.micro +31 -0
  116. package/apps/jsmdcui/runtime/colorschemes/cmc-16.micro +47 -0
  117. package/apps/jsmdcui/runtime/colorschemes/cmc-tc.micro +43 -0
  118. package/apps/jsmdcui/runtime/colorschemes/darcula.micro +34 -0
  119. package/apps/jsmdcui/runtime/colorschemes/default.micro +1 -0
  120. package/apps/jsmdcui/runtime/colorschemes/dracula-tc.micro +49 -0
  121. package/apps/jsmdcui/runtime/colorschemes/dukedark-tc.micro +38 -0
  122. package/apps/jsmdcui/runtime/colorschemes/dukelight-tc.micro +38 -0
  123. package/apps/jsmdcui/runtime/colorschemes/dukeubuntu-tc.micro +38 -0
  124. package/apps/jsmdcui/runtime/colorschemes/geany.micro +29 -0
  125. package/apps/jsmdcui/runtime/colorschemes/gotham.micro +29 -0
  126. package/apps/jsmdcui/runtime/colorschemes/gruvbox-tc.micro +29 -0
  127. package/apps/jsmdcui/runtime/colorschemes/gruvbox.micro +26 -0
  128. package/apps/jsmdcui/runtime/colorschemes/material-tc.micro +36 -0
  129. package/apps/jsmdcui/runtime/colorschemes/monokai-dark.micro +28 -0
  130. package/apps/jsmdcui/runtime/colorschemes/monokai.micro +34 -0
  131. package/apps/jsmdcui/runtime/colorschemes/one-dark.micro +39 -0
  132. package/apps/jsmdcui/runtime/colorschemes/railscast.micro +37 -0
  133. package/apps/jsmdcui/runtime/colorschemes/simple.micro +33 -0
  134. package/apps/jsmdcui/runtime/colorschemes/solarized-tc.micro +31 -0
  135. package/apps/jsmdcui/runtime/colorschemes/solarized.micro +30 -0
  136. package/apps/jsmdcui/runtime/colorschemes/sunny-day.micro +29 -0
  137. package/apps/jsmdcui/runtime/colorschemes/twilight.micro +40 -0
  138. package/apps/jsmdcui/runtime/colorschemes/zenburn.micro +30 -0
  139. package/apps/jsmdcui/runtime/help/actions.md +161 -0
  140. package/apps/jsmdcui/runtime/help/cdp.md +124 -0
  141. package/apps/jsmdcui/runtime/help/colors.md +421 -0
  142. package/apps/jsmdcui/runtime/help/commands.md +161 -0
  143. package/apps/jsmdcui/runtime/help/copypaste.md +149 -0
  144. package/apps/jsmdcui/runtime/help/defaultkeys.md +148 -0
  145. package/apps/jsmdcui/runtime/help/help.md +1269 -0
  146. package/apps/jsmdcui/runtime/help/keybindings.md +355 -0
  147. package/apps/jsmdcui/runtime/help/linter.md +90 -0
  148. package/apps/jsmdcui/runtime/help/options.md +709 -0
  149. package/apps/jsmdcui/runtime/help/plugins.md +544 -0
  150. package/apps/jsmdcui/runtime/help/tutorial.md +112 -0
  151. package/apps/jsmdcui/runtime/jsplugins/cdp/cdp-server.js +1185 -0
  152. package/apps/jsmdcui/runtime/jsplugins/cdp/cdp.js +201 -0
  153. package/apps/jsmdcui/runtime/jsplugins/chapter/chapter.js +111 -0
  154. package/apps/jsmdcui/runtime/jsplugins/diff/diff.js +46 -0
  155. package/apps/jsmdcui/runtime/jsplugins/example/example.js +117 -0
  156. package/apps/jsmdcui/runtime/jsplugins/linter/linter.js +281 -0
  157. package/apps/jsmdcui/runtime/plugins/autoclose/autoclose.lua +75 -0
  158. package/apps/jsmdcui/runtime/plugins/ftoptions/ftoptions.lua +17 -0
  159. package/apps/jsmdcui/runtime/plugins/literate/README.md +5 -0
  160. package/apps/jsmdcui/runtime/plugins/literate/literate.lua +55 -0
  161. package/apps/jsmdcui/runtime/plugins/status/help/status.md +21 -0
  162. package/apps/jsmdcui/runtime/plugins/status/status.lua +62 -0
  163. package/apps/jsmdcui/runtime/syntax/LICENSE +22 -0
  164. package/apps/jsmdcui/runtime/syntax/PowerShell.yaml +128 -0
  165. package/apps/jsmdcui/runtime/syntax/README.md +63 -0
  166. package/apps/jsmdcui/runtime/syntax/ada.yaml +43 -0
  167. package/apps/jsmdcui/runtime/syntax/apacheconf.yaml +59 -0
  168. package/apps/jsmdcui/runtime/syntax/arduino.yaml +101 -0
  169. package/apps/jsmdcui/runtime/syntax/asciidoc.yaml +51 -0
  170. package/apps/jsmdcui/runtime/syntax/asm.yaml +123 -0
  171. package/apps/jsmdcui/runtime/syntax/ats.yaml +99 -0
  172. package/apps/jsmdcui/runtime/syntax/awk.yaml +44 -0
  173. package/apps/jsmdcui/runtime/syntax/b.yaml +87 -0
  174. package/apps/jsmdcui/runtime/syntax/bat.yaml +57 -0
  175. package/apps/jsmdcui/runtime/syntax/c.yaml +60 -0
  176. package/apps/jsmdcui/runtime/syntax/caddyfile.yaml +23 -0
  177. package/apps/jsmdcui/runtime/syntax/cake.yaml +7 -0
  178. package/apps/jsmdcui/runtime/syntax/clojure.yaml +38 -0
  179. package/apps/jsmdcui/runtime/syntax/cmake.yaml +42 -0
  180. package/apps/jsmdcui/runtime/syntax/coffeescript.yaml +56 -0
  181. package/apps/jsmdcui/runtime/syntax/colortest.yaml +19 -0
  182. package/apps/jsmdcui/runtime/syntax/conky.yaml +17 -0
  183. package/apps/jsmdcui/runtime/syntax/cpp.yaml +91 -0
  184. package/apps/jsmdcui/runtime/syntax/crontab.yaml +36 -0
  185. package/apps/jsmdcui/runtime/syntax/crystal.yaml +72 -0
  186. package/apps/jsmdcui/runtime/syntax/csharp.yaml +52 -0
  187. package/apps/jsmdcui/runtime/syntax/css.yaml +44 -0
  188. package/apps/jsmdcui/runtime/syntax/csx.yaml +8 -0
  189. package/apps/jsmdcui/runtime/syntax/cuda.yaml +68 -0
  190. package/apps/jsmdcui/runtime/syntax/cython.yaml +52 -0
  191. package/apps/jsmdcui/runtime/syntax/d.yaml +121 -0
  192. package/apps/jsmdcui/runtime/syntax/dart.yaml +46 -0
  193. package/apps/jsmdcui/runtime/syntax/default.yaml +10 -0
  194. package/apps/jsmdcui/runtime/syntax/dockerfile.yaml +36 -0
  195. package/apps/jsmdcui/runtime/syntax/dot.yaml +29 -0
  196. package/apps/jsmdcui/runtime/syntax/elixir.yaml +30 -0
  197. package/apps/jsmdcui/runtime/syntax/elm.yaml +38 -0
  198. package/apps/jsmdcui/runtime/syntax/erb.yaml +42 -0
  199. package/apps/jsmdcui/runtime/syntax/erlang.yaml +45 -0
  200. package/apps/jsmdcui/runtime/syntax/fish.yaml +48 -0
  201. package/apps/jsmdcui/runtime/syntax/forth.yaml +34 -0
  202. package/apps/jsmdcui/runtime/syntax/fortran.yaml +64 -0
  203. package/apps/jsmdcui/runtime/syntax/freebsd-kernel.yaml +14 -0
  204. package/apps/jsmdcui/runtime/syntax/fsharp.yaml +48 -0
  205. package/apps/jsmdcui/runtime/syntax/gdscript.yaml +61 -0
  206. package/apps/jsmdcui/runtime/syntax/gemini.yaml +19 -0
  207. package/apps/jsmdcui/runtime/syntax/gentoo-ebuild.yaml +48 -0
  208. package/apps/jsmdcui/runtime/syntax/gentoo-etc-portage.yaml +23 -0
  209. package/apps/jsmdcui/runtime/syntax/git-commit.yaml +35 -0
  210. package/apps/jsmdcui/runtime/syntax/git-config.yaml +14 -0
  211. package/apps/jsmdcui/runtime/syntax/git-rebase-todo.yaml +19 -0
  212. package/apps/jsmdcui/runtime/syntax/gleam.yaml +69 -0
  213. package/apps/jsmdcui/runtime/syntax/glsl.yaml +26 -0
  214. package/apps/jsmdcui/runtime/syntax/gnuplot.yaml +15 -0
  215. package/apps/jsmdcui/runtime/syntax/go.yaml +62 -0
  216. package/apps/jsmdcui/runtime/syntax/godoc.yaml +17 -0
  217. package/apps/jsmdcui/runtime/syntax/golo.yaml +73 -0
  218. package/apps/jsmdcui/runtime/syntax/gomod.yaml +31 -0
  219. package/apps/jsmdcui/runtime/syntax/graphql.yaml +47 -0
  220. package/apps/jsmdcui/runtime/syntax/groff.yaml +30 -0
  221. package/apps/jsmdcui/runtime/syntax/groovy.yaml +111 -0
  222. package/apps/jsmdcui/runtime/syntax/haml.yaml +16 -0
  223. package/apps/jsmdcui/runtime/syntax/hare.yaml +52 -0
  224. package/apps/jsmdcui/runtime/syntax/haskell.yaml +52 -0
  225. package/apps/jsmdcui/runtime/syntax/hc.yaml +52 -0
  226. package/apps/jsmdcui/runtime/syntax/html.yaml +70 -0
  227. package/apps/jsmdcui/runtime/syntax/html4.yaml +25 -0
  228. package/apps/jsmdcui/runtime/syntax/html5.yaml +25 -0
  229. package/apps/jsmdcui/runtime/syntax/ini.yaml +23 -0
  230. package/apps/jsmdcui/runtime/syntax/inputrc.yaml +14 -0
  231. package/apps/jsmdcui/runtime/syntax/java.yaml +37 -0
  232. package/apps/jsmdcui/runtime/syntax/javascript.yaml +124 -0
  233. package/apps/jsmdcui/runtime/syntax/jinja2.yaml +19 -0
  234. package/apps/jsmdcui/runtime/syntax/json.yaml +39 -0
  235. package/apps/jsmdcui/runtime/syntax/jsonnet.yaml +92 -0
  236. package/apps/jsmdcui/runtime/syntax/julia.yaml +57 -0
  237. package/apps/jsmdcui/runtime/syntax/justfile.yaml +40 -0
  238. package/apps/jsmdcui/runtime/syntax/keymap.yaml +27 -0
  239. package/apps/jsmdcui/runtime/syntax/kickstart.yaml +16 -0
  240. package/apps/jsmdcui/runtime/syntax/kotlin.yaml +66 -0
  241. package/apps/jsmdcui/runtime/syntax/kvlang.yaml +67 -0
  242. package/apps/jsmdcui/runtime/syntax/ledger.yaml +14 -0
  243. package/apps/jsmdcui/runtime/syntax/lfe.yaml +17 -0
  244. package/apps/jsmdcui/runtime/syntax/lilypond.yaml +26 -0
  245. package/apps/jsmdcui/runtime/syntax/lisp.yaml +17 -0
  246. package/apps/jsmdcui/runtime/syntax/log.yaml +92 -0
  247. package/apps/jsmdcui/runtime/syntax/lua.yaml +111 -0
  248. package/apps/jsmdcui/runtime/syntax/mail.yaml +25 -0
  249. package/apps/jsmdcui/runtime/syntax/makefile.yaml +38 -0
  250. package/apps/jsmdcui/runtime/syntax/man.yaml +12 -0
  251. package/apps/jsmdcui/runtime/syntax/markdown.yaml +64 -0
  252. package/apps/jsmdcui/runtime/syntax/mc.yaml +23 -0
  253. package/apps/jsmdcui/runtime/syntax/meson.yaml +51 -0
  254. package/apps/jsmdcui/runtime/syntax/micro.yaml +34 -0
  255. package/apps/jsmdcui/runtime/syntax/mpdconf.yaml +13 -0
  256. package/apps/jsmdcui/runtime/syntax/msbuild.yaml +6 -0
  257. package/apps/jsmdcui/runtime/syntax/nanorc.yaml +16 -0
  258. package/apps/jsmdcui/runtime/syntax/nftables.yaml +30 -0
  259. package/apps/jsmdcui/runtime/syntax/nginx.yaml +22 -0
  260. package/apps/jsmdcui/runtime/syntax/nim.yaml +27 -0
  261. package/apps/jsmdcui/runtime/syntax/nix.yaml +32 -0
  262. package/apps/jsmdcui/runtime/syntax/nu.yaml +114 -0
  263. package/apps/jsmdcui/runtime/syntax/objc.yaml +60 -0
  264. package/apps/jsmdcui/runtime/syntax/ocaml.yaml +43 -0
  265. package/apps/jsmdcui/runtime/syntax/octave.yaml +83 -0
  266. package/apps/jsmdcui/runtime/syntax/odin.yaml +64 -0
  267. package/apps/jsmdcui/runtime/syntax/pascal.yaml +45 -0
  268. package/apps/jsmdcui/runtime/syntax/patch.yaml +14 -0
  269. package/apps/jsmdcui/runtime/syntax/peg.yaml +16 -0
  270. package/apps/jsmdcui/runtime/syntax/perl.yaml +58 -0
  271. package/apps/jsmdcui/runtime/syntax/php.yaml +60 -0
  272. package/apps/jsmdcui/runtime/syntax/pkg-config.yaml +12 -0
  273. package/apps/jsmdcui/runtime/syntax/po.yaml +12 -0
  274. package/apps/jsmdcui/runtime/syntax/pony.yaml +37 -0
  275. package/apps/jsmdcui/runtime/syntax/pov.yaml +21 -0
  276. package/apps/jsmdcui/runtime/syntax/privoxy-action.yaml +14 -0
  277. package/apps/jsmdcui/runtime/syntax/privoxy-config.yaml +10 -0
  278. package/apps/jsmdcui/runtime/syntax/privoxy-filter.yaml +12 -0
  279. package/apps/jsmdcui/runtime/syntax/proto.yaml +40 -0
  280. package/apps/jsmdcui/runtime/syntax/prql.yaml +84 -0
  281. package/apps/jsmdcui/runtime/syntax/puppet.yaml +22 -0
  282. package/apps/jsmdcui/runtime/syntax/python2.yaml +60 -0
  283. package/apps/jsmdcui/runtime/syntax/python3.yaml +80 -0
  284. package/apps/jsmdcui/runtime/syntax/r.yaml +32 -0
  285. package/apps/jsmdcui/runtime/syntax/raku.yaml +42 -0
  286. package/apps/jsmdcui/runtime/syntax/reST.yaml +18 -0
  287. package/apps/jsmdcui/runtime/syntax/renpy.yaml +15 -0
  288. package/apps/jsmdcui/runtime/syntax/rpmspec.yaml +43 -0
  289. package/apps/jsmdcui/runtime/syntax/ruby.yaml +73 -0
  290. package/apps/jsmdcui/runtime/syntax/rust.yaml +78 -0
  291. package/apps/jsmdcui/runtime/syntax/sage.yaml +60 -0
  292. package/apps/jsmdcui/runtime/syntax/scad.yaml +53 -0
  293. package/apps/jsmdcui/runtime/syntax/scala.yaml +33 -0
  294. package/apps/jsmdcui/runtime/syntax/sed.yaml +13 -0
  295. package/apps/jsmdcui/runtime/syntax/sh.yaml +69 -0
  296. package/apps/jsmdcui/runtime/syntax/sls.yaml +15 -0
  297. package/apps/jsmdcui/runtime/syntax/smalltalk.yaml +55 -0
  298. package/apps/jsmdcui/runtime/syntax/solidity.yaml +41 -0
  299. package/apps/jsmdcui/runtime/syntax/sql.yaml +35 -0
  300. package/apps/jsmdcui/runtime/syntax/stata.yaml +67 -0
  301. package/apps/jsmdcui/runtime/syntax/svelte.yaml +27 -0
  302. package/apps/jsmdcui/runtime/syntax/swift.yaml +103 -0
  303. package/apps/jsmdcui/runtime/syntax/systemd.yaml +16 -0
  304. package/apps/jsmdcui/runtime/syntax/tcl.yaml +18 -0
  305. package/apps/jsmdcui/runtime/syntax/terraform.yaml +87 -0
  306. package/apps/jsmdcui/runtime/syntax/tex.yaml +32 -0
  307. package/apps/jsmdcui/runtime/syntax/toml.yaml +56 -0
  308. package/apps/jsmdcui/runtime/syntax/twig.yaml +55 -0
  309. package/apps/jsmdcui/runtime/syntax/typescript.yaml +49 -0
  310. package/apps/jsmdcui/runtime/syntax/v.yaml +80 -0
  311. package/apps/jsmdcui/runtime/syntax/vala.yaml +26 -0
  312. package/apps/jsmdcui/runtime/syntax/verilog.yaml +60 -0
  313. package/apps/jsmdcui/runtime/syntax/vhdl.yaml +37 -0
  314. package/apps/jsmdcui/runtime/syntax/vi.yaml +31 -0
  315. package/apps/jsmdcui/runtime/syntax/vue.yaml +64 -0
  316. package/apps/jsmdcui/runtime/syntax/xml.yaml +37 -0
  317. package/apps/jsmdcui/runtime/syntax/xresources.yaml +14 -0
  318. package/apps/jsmdcui/runtime/syntax/yaml.yaml +34 -0
  319. package/apps/jsmdcui/runtime/syntax/yum.yaml +12 -0
  320. package/apps/jsmdcui/runtime/syntax/zig.yaml +52 -0
  321. package/apps/jsmdcui/runtime/syntax/zscript.yaml +72 -0
  322. package/apps/jsmdcui/runtime/syntax/zsh.yaml +52 -0
  323. package/apps/jsmdcui/single-exe/README.md +473 -0
  324. package/apps/jsmdcui/single-exe/assetsHelper.js +191 -0
  325. package/apps/jsmdcui/single-exe/assetsLoader.mjs +85 -0
  326. package/apps/jsmdcui/single-exe/compiled.js +212 -0
  327. package/apps/jsmdcui/single-exe/entry.mjs +10 -0
  328. package/apps/jsmdcui/single-exe/packAssets.sh +7 -0
  329. package/apps/jsmdcui/src/MDCUI_DEFAULT_EDIT +0 -0
  330. package/apps/jsmdcui/src/buffer/backup.js +165 -0
  331. package/apps/jsmdcui/src/buffer/buffer.js +126 -0
  332. package/apps/jsmdcui/src/buffer/fixed3-codec.js +140 -0
  333. package/apps/jsmdcui/src/buffer/loc.js +38 -0
  334. package/apps/jsmdcui/src/buffer/message.js +29 -0
  335. package/apps/jsmdcui/src/build-args.js +40 -0
  336. package/apps/jsmdcui/src/config/clean.js +172 -0
  337. package/apps/jsmdcui/src/config/colorscheme.js +99 -0
  338. package/apps/jsmdcui/src/config/config.js +125 -0
  339. package/apps/jsmdcui/src/config/defaults.js +109 -0
  340. package/apps/jsmdcui/src/cui/fence-events.mjs +144 -0
  341. package/apps/jsmdcui/src/cui/heading-ids.mjs +1568 -0
  342. package/apps/jsmdcui/src/cui/id-collision.mjs +111 -0
  343. package/apps/jsmdcui/src/cui/identity.mjs +26 -0
  344. package/apps/jsmdcui/src/cui/kitty-debug.mjs +25 -0
  345. package/apps/jsmdcui/src/cui/kitty-images.mjs +280 -0
  346. package/apps/jsmdcui/src/cui/kitty-mode.mjs +6 -0
  347. package/apps/jsmdcui/src/cui/rerender-queue.mjs +66 -0
  348. package/apps/jsmdcui/src/cui/rpc.mjs +1525 -0
  349. package/apps/jsmdcui/src/cui/server.mjs +128 -0
  350. package/apps/jsmdcui/src/cui/table-render.mjs +286 -0
  351. package/apps/jsmdcui/src/cui/table-row-edit.mjs +226 -0
  352. package/apps/jsmdcui/src/cui/task-checkbox.mjs +60 -0
  353. package/apps/jsmdcui/src/cui/template-components.mjs +253 -0
  354. package/apps/jsmdcui/src/cui/text-block-resize.mjs +177 -0
  355. package/apps/jsmdcui/src/cui/tui-links.mjs +560 -0
  356. package/apps/jsmdcui/src/display/ansi-style.js +60 -0
  357. package/apps/jsmdcui/src/highlight/highlighter.js +243 -0
  358. package/apps/jsmdcui/src/highlight/parser.js +225 -0
  359. package/apps/jsmdcui/src/index.js +9573 -0
  360. package/apps/jsmdcui/src/lua/engine.js +68 -0
  361. package/apps/jsmdcui/src/platform/archive.js +50 -0
  362. package/apps/jsmdcui/src/platform/clipboard.js +278 -0
  363. package/apps/jsmdcui/src/platform/commands.js +221 -0
  364. package/apps/jsmdcui/src/platform/terminal.js +5 -0
  365. package/apps/jsmdcui/src/plugins/js-bridge.js +3377 -0
  366. package/apps/jsmdcui/src/plugins/manager.js +674 -0
  367. package/apps/jsmdcui/src/runtime/encodings.js +10 -0
  368. package/apps/jsmdcui/src/runtime/registry.js +134 -0
  369. package/apps/jsmdcui/src/screen/cell-buffer.js +81 -0
  370. package/apps/jsmdcui/src/screen/events.js +263 -0
  371. package/apps/jsmdcui/src/screen/screen.js +249 -0
  372. package/apps/jsmdcui/src/screen/vt100.js +571 -0
  373. package/apps/jsmdcui/src/shell/shell.js +70 -0
  374. package/apps/jsmdcui/testapp.md +78 -0
  375. package/apps/jsmdcui/tests/assets-helper.test.js +150 -0
  376. package/apps/jsmdcui/tests/backup.test.js +158 -0
  377. package/apps/jsmdcui/tests/cat-markdown.test.js +139 -0
  378. package/apps/jsmdcui/tests/cmphex3b64.js +95 -0
  379. package/apps/jsmdcui/tests/compiled-runtime.test.js +139 -0
  380. package/apps/jsmdcui/tests/config-settings.test.js +52 -0
  381. package/apps/jsmdcui/tests/demo.test.js +447 -0
  382. package/apps/jsmdcui/tests/docs-sync.test.js +14 -0
  383. package/apps/jsmdcui/tests/fence-events.test.js +1293 -0
  384. package/apps/jsmdcui/tests/heading-ids.test.js +559 -0
  385. package/apps/jsmdcui/tests/heading-list-selector.test.js +2393 -0
  386. package/apps/jsmdcui/tests/id-collision.test.js +514 -0
  387. package/apps/jsmdcui/tests/js-plugin-prompts.test.js +110 -0
  388. package/apps/jsmdcui/tests/key-event.md +10 -0
  389. package/apps/jsmdcui/tests/kitty-demo.md +184 -0
  390. package/apps/jsmdcui/tests/kitty-images.test.js +288 -0
  391. package/apps/jsmdcui/tests/kitty-mode.test.js +14 -0
  392. package/apps/jsmdcui/tests/platform-commands.test.js +18 -0
  393. package/apps/jsmdcui/tests/platform-terminal.test.js +8 -0
  394. package/apps/jsmdcui/tests/pty-demo.js +492 -0
  395. package/apps/jsmdcui/tests/rerender-queue.test.js +130 -0
  396. package/apps/jsmdcui/tests/table-render.test.js +150 -0
  397. package/apps/jsmdcui/tests/table-row-edit.test.js +138 -0
  398. package/apps/jsmdcui/tests/task-checkbox.test.js +33 -0
  399. package/apps/jsmdcui/tests/template-components.test.js +422 -0
  400. package/apps/jsmdcui/tests/text-block-resize.test.js +222 -0
  401. package/apps/jsmdcui/tests/textarea.md +8 -0
  402. package/apps/jsmdcui/tests/tui-links.test.js +298 -0
  403. package/apps/jsmdcui/tests/wui-responsive-images.test.js +60 -0
  404. package/apps/jsmdcui/tests/wui.test.js +108 -0
  405. package/apps/jsmdcui/tests/wv-client.js +96 -0
  406. package/apps/jsmdcui/tui +7 -0
  407. package/apps/jsmdcui/wui +9 -0
  408. package/apps/musl-la/LICENSES/Apache-2.0_LLVM_Exceptions_license.txt +311 -0
  409. package/apps/musl-la/LICENSES/Apache-2.0_license.txt +177 -0
  410. package/apps/musl-la/LICENSES/BSD-3-Clause_license.txt +43 -0
  411. package/apps/musl-la/LICENSES/GPL-3.0.txt +674 -0
  412. package/apps/musl-la/LICENSES/LGPL-3.0.txt +165 -0
  413. package/apps/musl-la/LICENSES/MIT.txt +21 -0
  414. package/apps/musl-la/LICENSES/curl_license.txt +22 -0
  415. package/apps/musl-la/LICENSES/gcc_runtime_exception.txt +73 -0
  416. package/apps/musl-la/LICENSES/zlib_license.txt +22 -0
  417. package/apps/musl-la/LICENSE_musl.txt +193 -0
  418. package/apps/musl-la/NOTICE +56 -0
  419. package/apps/musl-la/ldmusl +0 -0
  420. package/apps/musl-la/libgcc_s.so.1 +0 -0
  421. package/apps/musl-la/libstdc++.so.6 +0 -0
  422. package/apps/musl-la/musl-la.sh +5 -0
  423. package/bin/bun.sh +57 -0
  424. package/bin/glow.sh +5 -0
  425. package/bin/init.js +395 -0
  426. package/bin/jmi.sh +5 -0
  427. package/bin/jsgotty.sh +5 -0
  428. package/bin/libsh-loader.c +135 -0
  429. package/bin/libsh-loader.so +0 -0
  430. package/bin/multicall.sh +90 -0
  431. package/bin/shc.js +5 -0
  432. package/bin/switch_to_android.sh +9 -0
  433. package/bin/switch_to_linux.sh +7 -0
  434. package/icon.png +0 -0
  435. package/package.json +31 -0
@@ -0,0 +1,139 @@
1
+ import { expect, test } from "bun:test";
2
+ import { expandBuildMdAliases } from "../src/build-args.js";
3
+ import {
4
+ isCompiledBinary as isSingleExeCompiled,
5
+ stringifyNonPrimitiveDefineValues,
6
+ } from "../single-exe/compiled.js";
7
+
8
+ test("single-exe recognizes Bun compiled virtual paths", () => {
9
+ expect(isSingleExeCompiled(["bun", "/$bunfs/root/app.js"])).toBe(true);
10
+ expect(isSingleExeCompiled(["bun", "B:/~BUN/root/app.js"])).toBe(true);
11
+ expect(isSingleExeCompiled(["bun", "/project/src/index.js"])).toBe(false);
12
+ });
13
+
14
+ test("--build-md-exe expands before the existing build flow", () => {
15
+ const argv = [
16
+ "bun",
17
+ "src/index.js",
18
+ "--build-md-exe",
19
+ "../中文工具.md",
20
+ "--sourcemap",
21
+ ];
22
+ expect(expandBuildMdAliases(argv)).toBe(true);
23
+ expect(argv).toEqual([
24
+ "bun",
25
+ "src/index.js",
26
+ "--build-exe",
27
+ "--define",
28
+ "global.MDCUI_MAIN=../中文工具.md",
29
+ "--sourcemap",
30
+ ]);
31
+ expect(expandBuildMdAliases(argv)).toBe(false);
32
+ });
33
+
34
+ test("--build-md-exe requires a Markdown path", () => {
35
+ expect(() => expandBuildMdAliases(["bun", "index.js", "--build-md-exe"]))
36
+ .toThrow("Missing Markdown path for --build-md-exe");
37
+ expect(() => expandBuildMdAliases([
38
+ "bun",
39
+ "index.js",
40
+ "--build-md-exe",
41
+ "--sourcemap",
42
+ ])).toThrow("Missing Markdown path for --build-md-exe");
43
+ });
44
+
45
+ test("--build-md-for expands before the existing cross-build flow", () => {
46
+ const argv = [
47
+ "bun",
48
+ "src/index.js",
49
+ "--build-md-for",
50
+ "bun-linux-x64",
51
+ "../中文工具.md",
52
+ "--sourcemap",
53
+ ];
54
+ expect(expandBuildMdAliases(argv)).toBe(true);
55
+ expect(argv).toEqual([
56
+ "bun",
57
+ "src/index.js",
58
+ "--build-for",
59
+ "bun-linux-x64",
60
+ "--define",
61
+ "global.MDCUI_MAIN=../中文工具.md",
62
+ "--sourcemap",
63
+ ]);
64
+ });
65
+
66
+ test("--build-md-for requires a platform and Markdown path", () => {
67
+ expect(() => expandBuildMdAliases(["bun", "index.js", "--build-md-for"]))
68
+ .toThrow("Missing platform for --build-md-for");
69
+ expect(() => expandBuildMdAliases([
70
+ "bun",
71
+ "index.js",
72
+ "--build-md-for",
73
+ "bun-linux-x64",
74
+ ])).toThrow("Missing Markdown path for --build-md-for");
75
+ });
76
+
77
+ test("non-primitive MDCUI_MAIN define values become strings", () => {
78
+ const split = [
79
+ "bun",
80
+ "src/index.js",
81
+ "--build-exe",
82
+ "--define",
83
+ "global.MDCUI_MAIN=../中文=工具.md",
84
+ ];
85
+ expect(
86
+ stringifyNonPrimitiveDefineValues(split, "global.MDCUI_MAIN"),
87
+ ).toBe(split);
88
+ expect(split.at(-1)).toBe(
89
+ 'global.MDCUI_MAIN="../中文=工具.md"',
90
+ );
91
+
92
+ const inline = [
93
+ "--define=global.MDCUI_MAIN=../m.md",
94
+ "--define",
95
+ "OTHER=../other.md",
96
+ "--define",
97
+ "global.MDCUI_MAIN_BASE=m.md",
98
+ ];
99
+ stringifyNonPrimitiveDefineValues(inline, "global.MDCUI_MAIN");
100
+ expect(inline).toEqual([
101
+ '--define=global.MDCUI_MAIN="../m.md"',
102
+ "--define",
103
+ "OTHER=../other.md",
104
+ "--define",
105
+ "global.MDCUI_MAIN_BASE=m.md",
106
+ ]);
107
+
108
+ for (const source of ["", "[]", "{}", "makePath()"]) {
109
+ const argv = ["--define", `global.MDCUI_MAIN=${source}`];
110
+ stringifyNonPrimitiveDefineValues(argv, "global.MDCUI_MAIN");
111
+ expect(argv[1]).toBe(
112
+ `global.MDCUI_MAIN=${JSON.stringify(source)}`,
113
+ );
114
+ }
115
+ });
116
+
117
+ test("primitive MDCUI_MAIN define values keep their type", () => {
118
+ const cases = new Map([
119
+ ['"../m.md"', '"../m.md"'],
120
+ ["'../m.md'", '"../m.md"'],
121
+ ["true", "true"],
122
+ ["false", "false"],
123
+ ["null", "null"],
124
+ ["undefined", "undefined"],
125
+ ["0", "0"],
126
+ ["-1.5", "-1.5"],
127
+ ["NaN", "NaN"],
128
+ ["Infinity", "Infinity"],
129
+ ["0xff", "0xff"],
130
+ ["0b10", "0b10"],
131
+ ["1_000", "1_000"],
132
+ ]);
133
+
134
+ for (const [source, normalized] of cases) {
135
+ const argv = ["--define", `global.MDCUI_MAIN=${source}`];
136
+ stringifyNonPrimitiveDefineValues(argv, "global.MDCUI_MAIN");
137
+ expect(argv[1]).toBe(`global.MDCUI_MAIN=${normalized}`);
138
+ }
139
+ });
@@ -0,0 +1,52 @@
1
+ import { afterEach, expect, test } from "bun:test";
2
+ import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { Config } from "../src/config/config.js";
6
+
7
+ const tempDirs = [];
8
+
9
+ afterEach(async () => {
10
+ await Promise.all(tempDirs.splice(0).map((path) => rm(path, { recursive: true, force: true })));
11
+ });
12
+
13
+ async function loadConfig(settings) {
14
+ const configDir = await mkdtemp(join(tmpdir(), "jsmdcui-config-"));
15
+ tempDirs.push(configDir);
16
+ await writeFile(join(configDir, "settings.json"), JSON.stringify(settings), "utf8");
17
+ return await new Config({ configDir }).init();
18
+ }
19
+
20
+ test("Config.init discards top-level encoding from settings.json in memory", async () => {
21
+ const config = await loadConfig({
22
+ encoding: "big5",
23
+ ruler: false,
24
+ "ft:markdown": { encoding: "big5", tabsize: 2 },
25
+ });
26
+
27
+ expect(config.getGlobalOption("encoding")).toBe("utf-8");
28
+ expect(config.parsedSettings).not.toHaveProperty("encoding");
29
+ expect(config.parsedSettings["ft:markdown"].encoding).toBe("big5");
30
+ });
31
+
32
+ test("Config.saveSettings removes the top-level encoding discarded during init", async () => {
33
+ const config = await loadConfig({
34
+ encoding: "big5",
35
+ ruler: false,
36
+ "ft:markdown": { encoding: "big5", tabsize: 2 },
37
+ });
38
+
39
+ await config.saveSettings();
40
+ const saved = JSON.parse(await readFile(join(config.configDir, "settings.json"), "utf8"));
41
+ expect(saved).toEqual({ ruler: false, "ft:markdown": { encoding: "big5", tabsize: 2 } });
42
+ });
43
+
44
+ test("CLI encoding applies to the current invocation but saveSettings never persists it", async () => {
45
+ const config = await loadConfig({ ruler: false });
46
+ config.applyCliSettings(new Map([["encoding", "big5"]]));
47
+
48
+ expect(config.getGlobalOption("encoding")).toBe("big5");
49
+ await config.saveSettings();
50
+ const saved = JSON.parse(await readFile(join(config.configDir, "settings.json"), "utf8"));
51
+ expect(saved).toEqual({ ruler: false });
52
+ });
@@ -0,0 +1,447 @@
1
+ import { expect, test } from "bun:test";
2
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { readMarkdownInput } from "../runmd.mjs";
6
+
7
+ const tui = join(import.meta.dir, "..", "tui");
8
+ const indexEntry = join(import.meta.dir, "..", "src", "index.js");
9
+ const demosDirectory = join(import.meta.dir, "..", "demos");
10
+ const bunBin = Bun.which("bun") || process.argv0;
11
+
12
+ test("--help describes the non-overwriting demo behavior", () => {
13
+ const result = Bun.spawnSync([bunBin, tui, "--help"], {
14
+ stdout: "pipe",
15
+ stderr: "pipe",
16
+ });
17
+
18
+ expect(result.exitCode).toBe(0);
19
+ const output = result.stdout.toString();
20
+ expect(output).toContain("Execute an existing ./testapp.md");
21
+ expect(output).toContain("Or write the bundled demo if missing");
22
+ expect(output).toContain("--demo-<filename>");
23
+ expect(output).toContain("--demo-reader");
24
+ expect(output).toContain("Text-to-speech reader");
25
+ expect(output).toContain("demos/<filename>.md");
26
+ expect(output.match(/Open it in the TUI and write 5 generated files beside it/g)?.length).toBe(2);
27
+ expect(output).not.toContain("Alias for --demo-image-processor");
28
+ expect(output).toContain("--cdp-maze");
29
+ });
30
+
31
+ test("--demo-list lists root and automatically discovered demos", () => {
32
+ const result = Bun.spawnSync([bunBin, tui, "--demo-list"], {
33
+ stdout: "pipe",
34
+ stderr: "pipe",
35
+ });
36
+
37
+ expect(result.exitCode).toBe(0);
38
+ const output = result.stdout.toString();
39
+ expect(output).toMatch(/--demo\s+testapp\.md/);
40
+ expect(output).toMatch(/--demo-image-processor\s+demos\/image-processor\.md/);
41
+ expect(output).toMatch(/--demo-imgtool\s+demos\/imgtool\.md/);
42
+ expect(output).toMatch(/--demo-imgtool-zh\s+demos\/imgtool-zh\.md/);
43
+ expect(output).toContain("compact table-based modern image processor UI");
44
+ expect(output).toContain("long-form document image processor UI");
45
+ expect(output).toMatch(/--demo-select\s+demos\/select\.md/);
46
+ expect(output).toMatch(/--demo-reader\s+demos\/reader\.md\s+— text-to-speech reader/);
47
+ expect(output).toMatch(/--demo-todo-zh\s+demos\/todo-zh\.md/);
48
+ expect(output).not.toContain("Compatibility aliases:");
49
+ });
50
+
51
+ test("--version lists every MDCUI build define", () => {
52
+ const result = Bun.spawnSync([bunBin, tui, "--version"], {
53
+ stdout: "pipe",
54
+ stderr: "pipe",
55
+ });
56
+
57
+ expect(result.exitCode).toBe(0);
58
+ const output = result.stdout.toString();
59
+ expect(output).toContain("MDCUI_DEFAULT_EDIT:");
60
+ expect(output).toContain("MDCUI_DEFAULT_DEMO:");
61
+ expect(output).toContain("MDCUI_DEFAULT_DEMO_WUI:");
62
+ expect(output).toContain("MDCUI_OVERWRITE_DEMO:");
63
+ expect(output).toContain("global.MDCUI_MAIN:");
64
+ expect(output).toContain("global.MDCUI_MAIN_BASE:");
65
+
66
+ const presenceResult = Bun.spawnSync(
67
+ [
68
+ bunBin,
69
+ "--define",
70
+ "MDCUI_DEFAULT_DEMO_WUI=0",
71
+ indexEntry,
72
+ "--version",
73
+ ],
74
+ {
75
+ stdout: "pipe",
76
+ stderr: "pipe",
77
+ },
78
+ );
79
+ expect(presenceResult.exitCode).toBe(0);
80
+ expect(presenceResult.stdout.toString()).toContain(
81
+ "MDCUI_DEFAULT_DEMO_WUI: enabled",
82
+ );
83
+ });
84
+
85
+ test("--demo names allow Chinese but reject whitespace", () => {
86
+ const unicodeResult = Bun.spawnSync(
87
+ [bunBin, tui, "--demo-不存在的程式", "-cat", "-encoding", "utf8"],
88
+ {
89
+ stdout: "pipe",
90
+ stderr: "pipe",
91
+ },
92
+ );
93
+ expect(unicodeResult.exitCode).toBe(2);
94
+ expect(unicodeResult.stderr.toString()).toContain(
95
+ "Unknown demo --demo-不存在的程式",
96
+ );
97
+ expect(unicodeResult.stderr.toString()).not.toContain("Invalid demo option");
98
+
99
+ const whitespaceResult = Bun.spawnSync(
100
+ [bunBin, tui, "--demo-中文 程式", "-cat", "-encoding", "utf8"],
101
+ {
102
+ stdout: "pipe",
103
+ stderr: "pipe",
104
+ },
105
+ );
106
+ expect(whitespaceResult.exitCode).toBe(2);
107
+ expect(whitespaceResult.stderr.toString()).toContain("Invalid demo option");
108
+ expect(whitespaceResult.stderr.toString()).toContain(
109
+ "whitespace is not allowed",
110
+ );
111
+ });
112
+
113
+ test("Unicode MDCUI_MAIN overwrite starts the embedded WUI server", async () => {
114
+ const directory = await mkdtemp(join(tmpdir(), "jsmdcui-main-unicode-"));
115
+ const sourceDirectory = join(directory, "source");
116
+ const workDirectory = join(directory, "work");
117
+ const demoName = `中文工具-${crypto.randomUUID()}`;
118
+ const markdownName = `${demoName}.md`;
119
+ const sourcePath = join(sourceDirectory, markdownName);
120
+ const workPath = join(workDirectory, markdownName);
121
+ const bundledDemoPath = join(demosDirectory, markdownName);
122
+ const preloadPath = join(directory, "mock-serve.mjs");
123
+ const markdown = `# 中文工具
124
+
125
+ \`\`\`js front
126
+ export async function run() {
127
+ return await rpc.answer();
128
+ }
129
+ \`\`\`
130
+
131
+ \`\`\`js back
132
+ import { helper } from "./helper.js";
133
+ export function answer() {
134
+ return helper();
135
+ }
136
+ \`\`\`
137
+ `;
138
+
139
+ try {
140
+ await mkdir(sourceDirectory);
141
+ await mkdir(workDirectory);
142
+ await writeFile(sourcePath, markdown);
143
+ await writeFile(
144
+ join(sourceDirectory, "helper.js"),
145
+ 'export function helper() { return "ok"; }\n',
146
+ );
147
+ await writeFile(workPath, "# stale file with a different byte length\n");
148
+ await writeFile(
149
+ preloadPath,
150
+ `Bun.serve = () => ({ port: 34567, stop() {} });\n`,
151
+ );
152
+
153
+ const result = Bun.spawnSync(
154
+ [
155
+ bunBin,
156
+ "--preload",
157
+ preloadPath,
158
+ "--define",
159
+ `global.MDCUI_MAIN=${JSON.stringify(sourcePath)}`,
160
+ indexEntry,
161
+ "--wui",
162
+ `--demo-${demoName}`,
163
+ "--overwrite-demo",
164
+ ],
165
+ {
166
+ cwd: workDirectory,
167
+ stdout: "pipe",
168
+ stderr: "pipe",
169
+ },
170
+ );
171
+
172
+ expect(result.exitCode).toBe(0);
173
+ expect(await readFile(workPath, "utf8")).toBe(markdown);
174
+ const stderr = Bun.stripANSI(result.stderr.toString());
175
+ expect(stderr).toContain("[mdcui] Starting embedded WUI server:");
176
+ expect(stderr).toContain(sourcePath);
177
+ expect(stderr).not.toContain("Cannot find module");
178
+ } finally {
179
+ await rm(bundledDemoPath, { force: true });
180
+ await rm(directory, { recursive: true, force: true });
181
+ }
182
+ });
183
+
184
+ test("--export-cdp-maze writes and overwrites the bundled solver", async () => {
185
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-export-cdp-maze-"));
186
+ const outputPath = join(dir, "cdp-maze.js");
187
+ try {
188
+ await writeFile(outputPath, "old solver\n");
189
+ const result = Bun.spawnSync([bunBin, tui, "--export-cdp-maze"], {
190
+ cwd: dir,
191
+ stdout: "pipe",
192
+ stderr: "pipe",
193
+ });
194
+
195
+ expect(result.exitCode).toBe(0);
196
+ expect(result.stdout.toString()).toContain(`Wrote ${outputPath}`);
197
+ const exported = await readFile(outputPath, "utf8");
198
+ expect(exported).toContain("export async function runCdpMaze");
199
+ expect(exported).not.toContain("old solver");
200
+ } finally {
201
+ await rm(dir, { recursive: true, force: true });
202
+ }
203
+ });
204
+
205
+ test("--demo writes bundled testapp.md to cwd before opening it", async () => {
206
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-demo-"));
207
+ try {
208
+ const result = Bun.spawnSync([bunBin, tui, "--demo", "-cat", "-encoding", "utf8"], {
209
+ cwd: dir,
210
+ stdout: "pipe",
211
+ stderr: "pipe",
212
+ });
213
+
214
+ expect(result.exitCode).toBe(0);
215
+ const written = await readFile(join(dir, "testapp.md"), "utf8");
216
+ expect(written).toContain("計算機");
217
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("計算機");
218
+ } finally {
219
+ await rm(dir, { recursive: true, force: true });
220
+ }
221
+ });
222
+
223
+ test("--demo preserves an existing testapp.md", async () => {
224
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-demo-existing-"));
225
+ const existing = "# Keep my demo\n";
226
+ try {
227
+ await writeFile(join(dir, "testapp.md"), existing);
228
+ const result = Bun.spawnSync([bunBin, tui, "--demo", "-cat", "-encoding", "utf8"], {
229
+ cwd: dir,
230
+ stdout: "pipe",
231
+ stderr: "pipe",
232
+ });
233
+
234
+ expect(result.exitCode).toBe(0);
235
+ expect(await readFile(join(dir, "testapp.md"), "utf8")).toBe(existing);
236
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("Keep my demo");
237
+ } finally {
238
+ await rm(dir, { recursive: true, force: true });
239
+ }
240
+ });
241
+
242
+ test("--overwrite-demo replaces an existing demo with the bundled copy", async () => {
243
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-demo-overwrite-"));
244
+ const existing = "# Replace my demo\n";
245
+ try {
246
+ await writeFile(join(dir, "testapp.md"), existing);
247
+ const result = Bun.spawnSync(
248
+ [bunBin, tui, "--overwrite-demo", "--demo", "-cat", "-encoding", "utf8"],
249
+ {
250
+ cwd: dir,
251
+ stdout: "pipe",
252
+ stderr: "pipe",
253
+ },
254
+ );
255
+
256
+ expect(result.exitCode).toBe(0);
257
+ const written = await readFile(join(dir, "testapp.md"), "utf8");
258
+ expect(written).toContain("計算機");
259
+ expect(written).not.toBe(existing);
260
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("計算機");
261
+ } finally {
262
+ await rm(dir, { recursive: true, force: true });
263
+ }
264
+ });
265
+
266
+ test("WUI demo loading can overwrite an existing testapp.md", async () => {
267
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-wui-demo-overwrite-"));
268
+ const demoPath = join(dir, "testapp.md");
269
+ try {
270
+ await writeFile(demoPath, "# Replace my WUI demo\n");
271
+ const source = await readMarkdownInput(demoPath, true);
272
+
273
+ expect(source).toContain("計算機");
274
+ expect(await readFile(demoPath, "utf8")).toBe(source);
275
+ } finally {
276
+ await rm(dir, { recursive: true, force: true });
277
+ }
278
+ });
279
+
280
+ test("--demo-<filename> automatically loads a matching demos file", async () => {
281
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-demo-generic-"));
282
+ try {
283
+ const result = Bun.spawnSync([bunBin, tui, "--demo-todo", "-cat", "-encoding", "utf8"], {
284
+ cwd: dir,
285
+ stdout: "pipe",
286
+ stderr: "pipe",
287
+ });
288
+
289
+ expect(result.exitCode).toBe(0);
290
+ const written = await readFile(join(dir, "todo.md"), "utf8");
291
+ expect(written).toContain("# Todo List");
292
+ expect(written).toContain("javascript:addTodo()");
293
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("Show Completed");
294
+ } finally {
295
+ await rm(dir, { recursive: true, force: true });
296
+ }
297
+ });
298
+
299
+ test("--cdp-maze loads the maze demo", async () => {
300
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-cdp-maze-"));
301
+ try {
302
+ const result = Bun.spawnSync([bunBin, tui, "--cdp-maze", "-cat", "-encoding", "utf8"], {
303
+ cwd: dir,
304
+ stdout: "pipe",
305
+ stderr: "pipe",
306
+ });
307
+
308
+ expect(result.exitCode).toBe(0);
309
+ const written = await readFile(join(dir, "maze.md"), "utf8");
310
+ expect(written).toContain("Put the cursor here");
311
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("Put the cursor here");
312
+ } finally {
313
+ await rm(dir, { recursive: true, force: true });
314
+ }
315
+ });
316
+
317
+ test("--demo-<filename> preserves an existing local copy", async () => {
318
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-demo-generic-existing-"));
319
+ const existing = "# Keep my selector demo\n";
320
+ try {
321
+ await writeFile(join(dir, "select.md"), existing);
322
+ const result = Bun.spawnSync([bunBin, tui, "--demo-select", "-cat", "-encoding", "utf8"], {
323
+ cwd: dir,
324
+ stdout: "pipe",
325
+ stderr: "pipe",
326
+ });
327
+
328
+ expect(result.exitCode).toBe(0);
329
+ expect(await readFile(join(dir, "select.md"), "utf8")).toBe(existing);
330
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("Keep my selector demo");
331
+ } finally {
332
+ await rm(dir, { recursive: true, force: true });
333
+ }
334
+ });
335
+
336
+ test("an unknown --demo-<filename> reports an error without creating a file", async () => {
337
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-demo-unknown-"));
338
+ try {
339
+ const result = Bun.spawnSync([bunBin, tui, "--demo-does-not-exist", "-cat", "-encoding", "utf8"], {
340
+ cwd: dir,
341
+ stdout: "pipe",
342
+ stderr: "pipe",
343
+ });
344
+
345
+ expect(result.exitCode).toBe(2);
346
+ expect(result.stderr.toString()).toContain("Unknown demo --demo-does-not-exist");
347
+ expect(await Bun.file(join(dir, "does-not-exist.md")).exists()).toBe(false);
348
+ } finally {
349
+ await rm(dir, { recursive: true, force: true });
350
+ }
351
+ });
352
+
353
+ test("--demo-image-processor works through generic demo discovery", async () => {
354
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-imgtool-generic-"));
355
+ try {
356
+ const result = Bun.spawnSync([bunBin, tui, "--demo-image-processor", "-cat", "-encoding", "utf8"], {
357
+ cwd: dir,
358
+ stdout: "pipe",
359
+ stderr: "pipe",
360
+ });
361
+
362
+ expect(result.exitCode).toBe(0);
363
+ expect(await readFile(join(dir, "image-processor.md"), "utf8")).toContain("# Bun.Image Processor");
364
+ } finally {
365
+ await rm(dir, { recursive: true, force: true });
366
+ }
367
+ });
368
+
369
+ test("--demo-imgtool uses generic discovery for the table image processor", async () => {
370
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-imgtool-"));
371
+ try {
372
+ const result = Bun.spawnSync([bunBin, tui, "--demo-imgtool", "-cat", "-encoding", "utf8"], {
373
+ cwd: dir,
374
+ stdout: "pipe",
375
+ stderr: "pipe",
376
+ });
377
+
378
+ expect(result.exitCode).toBe(0);
379
+ const written = await readFile(join(dir, "imgtool.md"), "utf8");
380
+ expect(written).toContain("# Bun.Image Processor");
381
+ expect(written).toContain("javascript:readMetadata()");
382
+ expect(written).toContain("optionText('common-options'");
383
+ expect(written).toContain("cell.val(!cell.val())");
384
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("Bun.Image Processor");
385
+ } finally {
386
+ await rm(dir, { recursive: true, force: true });
387
+ }
388
+ });
389
+
390
+ test("--demo-imgtool preserves an existing imgtool.md", async () => {
391
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-imgtool-existing-"));
392
+ const existing = "# Keep my image tool\n";
393
+ try {
394
+ await writeFile(join(dir, "imgtool.md"), existing);
395
+ const result = Bun.spawnSync([bunBin, tui, "--demo-imgtool", "-cat", "-encoding", "utf8"], {
396
+ cwd: dir,
397
+ stdout: "pipe",
398
+ stderr: "pipe",
399
+ });
400
+
401
+ expect(result.exitCode).toBe(0);
402
+ expect(await readFile(join(dir, "imgtool.md"), "utf8")).toBe(existing);
403
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("Keep my image tool");
404
+ } finally {
405
+ await rm(dir, { recursive: true, force: true });
406
+ }
407
+ });
408
+
409
+ test("--demo-imgtool-zh uses generic discovery for the table image processor", async () => {
410
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-imgtool-zh-"));
411
+ try {
412
+ const result = Bun.spawnSync([bunBin, tui, "--demo-imgtool-zh", "-cat", "-encoding", "utf8"], {
413
+ cwd: dir,
414
+ stdout: "pipe",
415
+ stderr: "pipe",
416
+ });
417
+
418
+ expect(result.exitCode).toBe(0);
419
+ const written = await readFile(join(dir, "imgtool-zh.md"), "utf8");
420
+ expect(written).toContain("先把本機圖片路徑貼到下方");
421
+ expect(written).toContain("javascript:readMetadata()");
422
+ expect(written).toContain("optionText('常用選項'");
423
+ expect(written).toContain("cell.val(!cell.val())");
424
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("先把本機圖片路徑貼到下方");
425
+ } finally {
426
+ await rm(dir, { recursive: true, force: true });
427
+ }
428
+ });
429
+
430
+ test("--demo-imgtool-zh preserves an existing imgtool-zh.md", async () => {
431
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-imgtool-zh-existing-"));
432
+ const existing = "# 保留我的圖片工具\n";
433
+ try {
434
+ await writeFile(join(dir, "imgtool-zh.md"), existing);
435
+ const result = Bun.spawnSync([bunBin, tui, "--demo-imgtool-zh", "-cat", "-encoding", "utf8"], {
436
+ cwd: dir,
437
+ stdout: "pipe",
438
+ stderr: "pipe",
439
+ });
440
+
441
+ expect(result.exitCode).toBe(0);
442
+ expect(await readFile(join(dir, "imgtool-zh.md"), "utf8")).toBe(existing);
443
+ expect(Bun.stripANSI(result.stdout.toString())).toContain("保留我的圖片工具");
444
+ } finally {
445
+ await rm(dir, { recursive: true, force: true });
446
+ }
447
+ });
@@ -0,0 +1,14 @@
1
+ import { expect, test } from "bun:test";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+
5
+ const projectRoot = join(import.meta.dir, "..");
6
+
7
+ test("bundled help is byte-for-byte identical to README", async () => {
8
+ const [readme, help] = await Promise.all([
9
+ readFile(join(projectRoot, "README.md")),
10
+ readFile(join(projectRoot, "runtime", "help", "help.md")),
11
+ ]);
12
+
13
+ expect(help.equals(readme)).toBe(true);
14
+ });