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,514 @@
1
+ import { expect, test } from "bun:test";
2
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { createTuiSelector } from "../src/plugins/js-bridge.js";
6
+
7
+ const tui = join(import.meta.dir, "..", "tui");
8
+ const bunBin = Bun.which("bun") || process.argv0;
9
+
10
+ async function runCheck(markdown) {
11
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-check-"));
12
+ const file = join(dir, "app.md");
13
+ await writeFile(file, markdown);
14
+ const result = Bun.spawnSync([bunBin, tui, "--check", file], { stdout: "pipe", stderr: "pipe" });
15
+ await rm(dir, { recursive: true, force: true });
16
+ return result;
17
+ }
18
+
19
+ async function runOutline(markdown, extraArgs = []) {
20
+ const dir = await mkdtemp(join(tmpdir(), "jsmdcui-outline-"));
21
+ const file = join(dir, "app.md");
22
+ await writeFile(file, markdown);
23
+ const result = Bun.spawnSync(
24
+ [bunBin, tui, "--outline", ...extraArgs, file],
25
+ { stdout: "pipe", stderr: "pipe" },
26
+ );
27
+ await rm(dir, { recursive: true, force: true });
28
+ return result;
29
+ }
30
+
31
+ test("--check exits 0 and reports unique IDs", async () => {
32
+ const result = await runCheck("## Input Path\n\n```text#output-path\nvalue\n```\n");
33
+ expect(result.exitCode).toBe(0);
34
+ const raw = result.stdout.toString();
35
+ const output = Bun.stripANSI(raw);
36
+ expect(output).toContain("No ID collisions found");
37
+ expect(output).toContain("PASSED");
38
+ expect(raw).toContain(`${Bun.color("#00d75f", "ansi-16m")}\x1b[1mPASSED\x1b[0m`);
39
+ });
40
+
41
+ test("--check fails closed when browser heading parsing is ambiguous", async () => {
42
+ const result = await runCheck('<div/a< x=">TAIL\n\n# 中文\n');
43
+ expect(result.exitCode).toBe(2);
44
+ expect(result.stderr.toString()).toContain(
45
+ "Markdown headings could not be classified safely",
46
+ );
47
+ expect(result.stdout.toString()).not.toContain("PASSED");
48
+ });
49
+
50
+ test("--check reports heading/fenced-block collisions with line details", async () => {
51
+ const result = await runCheck("## Write Status\n\n```text#write-status\nwaiting\n```\n");
52
+ const output = Bun.stripANSI(result.stdout.toString());
53
+ expect(result.exitCode).toBe(1);
54
+ expect(output).toContain("FAIL — Found 1 colliding ID(s)");
55
+ expect(output).toContain("ID #write-status");
56
+ expect(output).toContain("Declarations: 2");
57
+ expect(output).toContain("Line 1");
58
+ expect(output).toContain("Type: heading");
59
+ expect(output).toContain("Source: ## Write Status");
60
+ expect(output).toContain("Line 3");
61
+ expect(output).toContain("Type: text fenced block");
62
+ expect(output).toContain("Source: ```text#write-status");
63
+ expect(result.stdout.toString()).toContain(`${Bun.color("#ff3030", "ansi-16m")}\x1b[1mFAILED\x1b[0m`);
64
+ expect(output.lastIndexOf("FAILED")).toBeGreaterThan(output.lastIndexOf("Suggested fix"));
65
+ });
66
+
67
+ test("--check keeps fenced IDs that are followed by inline event attributes", async () => {
68
+ const result = await runCheck(
69
+ '## Write Status\n\n```text#write-status @keydown="refresh(); validate(event)"\nwaiting\n```\n',
70
+ );
71
+ const output = Bun.stripANSI(result.stdout.toString());
72
+ expect(result.exitCode).toBe(1);
73
+ expect(output).toContain("ID #write-status");
74
+ expect(output).toContain("Type: text fenced block");
75
+ expect(output).toContain('Source: ```text#write-status @keydown="refresh(); validate(event)"');
76
+ });
77
+
78
+ test("--check reports duplicate fenced-block IDs", async () => {
79
+ const result = await runCheck("```text#myid\na\n```\n\n```textarea#myid\nb\n```\n");
80
+ expect(result.exitCode).toBe(1);
81
+ const output = Bun.stripANSI(result.stdout.toString());
82
+ expect(output).toContain("ID #myid");
83
+ expect(output).toContain("Declarations: 2");
84
+ expect(output).toContain("FAILED");
85
+ });
86
+
87
+ test("--check includes IDs on arbitrary fenced-block tags", async () => {
88
+ const result = await runCheck("```hello#myid\nyou\n```\n\n# myid\n");
89
+ const output = Bun.stripANSI(result.stdout.toString());
90
+ expect(result.exitCode).toBe(1);
91
+ expect(output).toContain("ID #myid");
92
+ expect(output).toContain("Declarations: 2");
93
+ expect(output).toContain("Type: hello fenced block");
94
+ expect(output).toContain("Fenced blocks: 1");
95
+ expect(output).toContain("FAILED");
96
+ });
97
+
98
+ test("--check rejects duplicate Markdown heading IDs before Bun adds suffixes", async () => {
99
+ const result = await runCheck("# myid\n\n# myid\n");
100
+ const output = Bun.stripANSI(result.stdout.toString());
101
+ expect(result.exitCode).toBe(1);
102
+ expect(output).toContain("ID #myid");
103
+ expect(output).toContain("Declarations: 2");
104
+ expect(output).toContain("Line 1");
105
+ expect(output).toContain("Line 3");
106
+ expect(output).toContain("FAILED");
107
+ });
108
+
109
+ test("--check treats a normalized Chinese heading as a selectable ID", async () => {
110
+ const result = await runCheck("# 中文 設定!\n");
111
+ const output = Bun.stripANSI(result.stdout.toString());
112
+ expect(result.exitCode).toBe(0);
113
+ expect(output).toContain("Selectable IDs: 1");
114
+ expect(output).toContain("Headings: 1");
115
+ expect(output).toContain("PASSED");
116
+ });
117
+
118
+ test("--check reports Chinese headings that normalize to the same ID", async () => {
119
+ const result = await runCheck("# 中文,設定\n\n# 中文 設定!\n");
120
+ const output = Bun.stripANSI(result.stdout.toString());
121
+ expect(result.exitCode).toBe(1);
122
+ expect(output).toContain("ID #中文-設定");
123
+ expect(output).toContain("Declarations: 2");
124
+ expect(output).toContain("Line 1");
125
+ expect(output).toContain("Line 3");
126
+ expect(output).toContain("FAILED");
127
+ });
128
+
129
+ test("--check reports a Chinese heading and fenced-block ID collision", async () => {
130
+ const result = await runCheck(
131
+ "# 中文 設定!\n\n```text#中文-設定\nvalue\n```\n",
132
+ );
133
+ const output = Bun.stripANSI(result.stdout.toString());
134
+ expect(result.exitCode).toBe(1);
135
+ expect(output).toContain("ID #中文-設定");
136
+ expect(output).toContain("Type: heading");
137
+ expect(output).toContain("Type: text fenced block");
138
+ expect(output).toContain("FAILED");
139
+ });
140
+
141
+ test("--check includes blockquote and list headings", async () => {
142
+ const result = await runCheck(`> # 中文
143
+
144
+ - # 中文
145
+
146
+ # 中文
147
+ `);
148
+ const output = Bun.stripANSI(result.stdout.toString());
149
+ expect(result.exitCode).toBe(1);
150
+ expect(output).toContain("ID #中文");
151
+ expect(output).toContain("Declarations: 3");
152
+ expect(output).toContain("Line 1");
153
+ expect(output).toContain("Line 3");
154
+ expect(output).toContain("Line 5");
155
+ });
156
+
157
+ test("--check preserves ATX closing hashes while locating source headings", async () => {
158
+ const result = await runCheck("# 中文 ###\n\n# 中文\n");
159
+ const output = Bun.stripANSI(result.stdout.toString());
160
+ expect(result.exitCode).toBe(1);
161
+ expect(output).toContain("ID #中文");
162
+ expect(output).toContain("Declarations: 2");
163
+ expect(output).toContain("Line 1");
164
+ expect(output).toContain("Line 3");
165
+ });
166
+
167
+ test("--check source markers do not turn a closing fence into content", async () => {
168
+ const result = await runCheck("```\ncode\n```\n---\n# 中文\n");
169
+ const output = Bun.stripANSI(result.stdout.toString());
170
+ expect(result.exitCode).toBe(0);
171
+ expect(output).toContain("Selectable IDs: 1");
172
+ expect(output).toContain("Headings: 1");
173
+ expect(output).toContain("PASSED");
174
+ });
175
+
176
+ test("--check ignores raw-heading examples in code and escaped HTML", async () => {
177
+ const result = await runCheck(`\`\`\`html
178
+ <h1 id="example">code sample</h1>
179
+ \`\`\`
180
+
181
+ &lt;h1 id="example"&gt;escaped sample&lt;/h1&gt;
182
+
183
+ \`\`\`text#example
184
+ value
185
+ \`\`\`
186
+ `);
187
+ const output = Bun.stripANSI(result.stdout.toString());
188
+ expect(result.exitCode).toBe(0);
189
+ expect(output).toContain("Selectable IDs: 1");
190
+ expect(output).toContain("PASSED");
191
+ });
192
+
193
+ test("--check derives IDs and source lines from multiline Setext headings", async () => {
194
+ const result = await runCheck(`Foo
195
+ bar
196
+ ---
197
+
198
+ \`\`\`text#foo-bar
199
+ value
200
+ \`\`\`
201
+ `);
202
+ const output = Bun.stripANSI(result.stdout.toString());
203
+ expect(result.exitCode).toBe(1);
204
+ expect(output).toContain("ID #foo-bar");
205
+ expect(output).toContain("Line 1");
206
+ expect(output).toContain("Type: heading");
207
+ expect(output).toContain("FAILED");
208
+ });
209
+
210
+ test("--check does not mistake an inline hash for an ATX heading", async () => {
211
+ const result = await runCheck(`Title # note
212
+ ===
213
+
214
+ \`\`\`text#title-note
215
+ value
216
+ \`\`\`
217
+ `);
218
+ const output = Bun.stripANSI(result.stdout.toString());
219
+ expect(result.exitCode).toBe(1);
220
+ expect(output).toContain("ID #title-note");
221
+ expect(output).toContain("Line 1");
222
+ expect(output).toContain("FAILED");
223
+ });
224
+
225
+ test("--check keeps list context when identifying an indented heading", async () => {
226
+ const result = await runCheck(`- item
227
+
228
+ # child
229
+
230
+ \`\`\`text#child
231
+ value
232
+ \`\`\`
233
+ `);
234
+ const output = Bun.stripANSI(result.stdout.toString());
235
+ expect(result.exitCode).toBe(1);
236
+ expect(output).toContain("ID #child");
237
+ expect(output).toContain("Line 3");
238
+ expect(output).toContain("FAILED");
239
+ });
240
+
241
+ test("--check ignores heading-looking text in raw HTML and comments", async () => {
242
+ const result = await runCheck(`<!--
243
+ # 中文
244
+ -->
245
+
246
+ <script type="text/plain">
247
+ # 中文
248
+ </script>
249
+
250
+ <div>
251
+ # 中文
252
+ </div>
253
+
254
+ # 中文
255
+ `);
256
+ const output = Bun.stripANSI(result.stdout.toString());
257
+ expect(result.exitCode).toBe(0);
258
+ expect(output).toContain("Selectable IDs: 1");
259
+ expect(output).toContain("Headings: 1");
260
+ expect(output).toContain("PASSED");
261
+ });
262
+
263
+ test("--check includes actual raw HTML heading IDs in the selector namespace", async () => {
264
+ const result = await runCheck(`<h1 title="a > b" id="中文">Raw</h1>
265
+
266
+ # 中文
267
+ `);
268
+ const output = Bun.stripANSI(result.stdout.toString());
269
+ expect(result.exitCode).toBe(1);
270
+ expect(output).toContain("ID #中文");
271
+ expect(output).toContain("Declarations: 2");
272
+ expect(output).toContain("Type: raw HTML heading");
273
+ expect(output).toContain("Type: heading");
274
+ expect(output).toContain("Line 1");
275
+ expect(output).toContain("Line 3");
276
+ });
277
+
278
+ test("--check decodes named entities in raw heading IDs", async () => {
279
+ const result = await runCheck(`<h1 id="caf&eacute;">Café</h1>
280
+
281
+ \`\`\`text#café
282
+ value
283
+ \`\`\`
284
+ `);
285
+ const output = Bun.stripANSI(result.stdout.toString());
286
+ expect(result.exitCode).toBe(1);
287
+ expect(output).toContain("ID #café");
288
+ expect(output).toContain("Type: raw HTML heading");
289
+ expect(output).toContain("Type: text fenced block");
290
+ expect(output).toContain("FAILED");
291
+ });
292
+
293
+ test("--check includes fenced IDs inside Markdown containers", async () => {
294
+ const result = await runCheck(`# quote
295
+
296
+ > \`\`\`text#quote
297
+ > value
298
+ > \`\`\`
299
+
300
+ # list
301
+
302
+ - \`\`\`textarea#list
303
+ value
304
+ \`\`\`
305
+ `);
306
+ const output = Bun.stripANSI(result.stdout.toString());
307
+ expect(result.exitCode).toBe(1);
308
+ expect(output).toContain("Found 2 colliding ID(s)");
309
+ expect(output).toContain("ID #quote");
310
+ expect(output).toContain("ID #list");
311
+ expect(output).toContain("FAILED");
312
+ });
313
+
314
+ test("--check ignores fence-looking text inside raw HTML", async () => {
315
+ const result = await runCheck(`# raw-div
316
+
317
+ <div>
318
+ \`\`\`text#raw-div
319
+ value
320
+ \`\`\`
321
+ </div>
322
+
323
+ # comment
324
+
325
+ <!--
326
+ \`\`\`text#comment
327
+ value
328
+ \`\`\`
329
+ -->
330
+ `);
331
+ const output = Bun.stripANSI(result.stdout.toString());
332
+ expect(result.exitCode).toBe(0);
333
+ expect(output).toContain("Selectable IDs: 2");
334
+ expect(output).toContain("PASSED");
335
+ });
336
+
337
+ test("--check reserves malformed raw heading IDs", async () => {
338
+ const result = await runCheck(`<h1 id="中文"/>raw</h1>
339
+
340
+ # 中文
341
+ `);
342
+ const output = Bun.stripANSI(result.stdout.toString());
343
+ expect(result.exitCode).toBe(1);
344
+ expect(output).toContain("ID #中文");
345
+ expect(output).toContain("Type: raw HTML heading");
346
+ expect(output).toContain("Type: heading");
347
+ expect(output).toContain("FAILED");
348
+ });
349
+
350
+ test("--check ignores heading-looking text inside raw attributes", async () => {
351
+ const result = await runCheck(
352
+ '<h2 title="prefix <h1 id=fake> suffix" id="中文">Raw</h2>\n\n'
353
+ + "# 中文\n",
354
+ );
355
+ const output = Bun.stripANSI(result.stdout.toString());
356
+ expect(result.exitCode).toBe(1);
357
+ expect(output).toContain("ID #中文");
358
+ expect(output).not.toContain("ID #fake");
359
+ expect(output).toContain("FAILED");
360
+ });
361
+
362
+ test("--check preserves slash-separated raw heading attributes", async () => {
363
+ const result = await runCheck("<h1/id=中文>Raw</h1>\n\n# 中文\n");
364
+ const output = Bun.stripANSI(result.stdout.toString());
365
+ expect(result.exitCode).toBe(1);
366
+ expect(output).toContain("ID #中文");
367
+ expect(output).toContain("Type: raw HTML heading");
368
+ expect(output).toContain("Type: heading");
369
+ expect(output).toContain("FAILED");
370
+ });
371
+
372
+ test("--check ignores heading-like custom tag names", async () => {
373
+ const result = await runCheck(
374
+ "<h1! id=中文>Fake</h1!>\n\n# 中文\n",
375
+ );
376
+ const output = Bun.stripANSI(result.stdout.toString());
377
+ expect(result.exitCode).toBe(0);
378
+ expect(output).toContain("Selectable IDs: 1");
379
+ expect(output).toContain("PASSED");
380
+ });
381
+
382
+ const identityMatrix = [
383
+ {
384
+ name: "tag without class",
385
+ info: "text#myid",
386
+ selectable: true,
387
+ },
388
+ {
389
+ name: "tag with class",
390
+ info: "text#myid.field",
391
+ selectable: true,
392
+ },
393
+ {
394
+ name: "no tag and no class",
395
+ info: "#myid",
396
+ selectable: false,
397
+ },
398
+ {
399
+ name: "no tag with class",
400
+ info: "#myid.field",
401
+ selectable: false,
402
+ },
403
+ ];
404
+
405
+ for (const scenario of identityMatrix) {
406
+ test(`--check identity matrix: ${scenario.name}`, async () => {
407
+ const result = await runCheck(`\`\`\`${scenario.info}\nvalue\n\`\`\`\n\n# myid\n`);
408
+ const output = Bun.stripANSI(result.stdout.toString());
409
+ expect(result.exitCode).toBe(scenario.selectable ? 1 : 0);
410
+ expect(output).toContain(`Fenced blocks: ${scenario.selectable ? 1 : 0}`);
411
+ if (scenario.selectable) {
412
+ expect(output).toContain("ID #myid");
413
+ expect(output).toContain("Declarations: 2");
414
+ expect(output).toContain("FAILED");
415
+ } else {
416
+ expect(output).toContain("Selectable IDs: 1");
417
+ expect(output).toContain("PASSED");
418
+ }
419
+ });
420
+ }
421
+
422
+ test("--check ignores tag and class differences when fenced-block IDs collide", async () => {
423
+ const result = await runCheck(
424
+ "```text#myid.left.primary\na\n```\n\n```json#myid.right.secondary\nb\n```\n",
425
+ );
426
+ const output = Bun.stripANSI(result.stdout.toString());
427
+ expect(result.exitCode).toBe(1);
428
+ expect(output).toContain("ID #myid");
429
+ expect(output).toContain("Declarations: 2");
430
+ expect(output).toContain("Type: text fenced block");
431
+ expect(output).toContain("Type: json fenced block");
432
+ expect(output).toContain("FAILED");
433
+ });
434
+
435
+ test("TUI $ selector finds one ID across every tag/class query combination", () => {
436
+ const markdown = "```text#myid.field.primary\nvalue\n```\n";
437
+ const buffer = { lines: markdown.trimEnd().split("\n") };
438
+ const $ = createTuiSelector(() => buffer);
439
+ const selectors = [
440
+ "text#myid.field",
441
+ "text#myid",
442
+ "#myid.field",
443
+ "#myid",
444
+ ];
445
+ for (const selector of selectors) expect($(selector).val()).toBe("value");
446
+ });
447
+
448
+ test("--check requires exactly one file", () => {
449
+ const result = Bun.spawnSync([bunBin, tui, "--check"], { stdout: "pipe", stderr: "pipe" });
450
+ expect(result.exitCode).toBe(2);
451
+ expect(result.stderr.toString()).toContain("Usage: jsmdcui --check FILE.md");
452
+ });
453
+
454
+ test("--outline prints heading IDs as a hierarchy and fenced IDs at top level", async () => {
455
+ const result = await runOutline(`# Root
456
+
457
+ ## 中文 子項
458
+
459
+ > \`\`\`text#輸入
460
+ > value
461
+ > \`\`\`
462
+
463
+ ### Deep
464
+
465
+ # Second
466
+
467
+ - \`\`\`custom#myfence
468
+ value
469
+ \`\`\`
470
+ `);
471
+ expect(result.exitCode).toBe(0);
472
+ expect(result.stderr.toString()).toBe("");
473
+ expect(result.stdout.toString()).toBe(
474
+ "- root\n"
475
+ + " - 中文-子項\n"
476
+ + "+ 輸入\n"
477
+ + " - deep\n"
478
+ + "- second\n"
479
+ + "+ myfence\n",
480
+ );
481
+ });
482
+
483
+ test("--outline reuses check declarations and keeps duplicate IDs", async () => {
484
+ const result = await runOutline(`# Same
485
+
486
+ # Same
487
+
488
+ \`\`\`text#same
489
+ value
490
+ \`\`\`
491
+ `);
492
+ expect(result.exitCode).toBe(0);
493
+ expect(result.stdout.toString()).toBe("- same\n- same\n+ same\n");
494
+ });
495
+
496
+ test("--outline fails closed when browser heading parsing is ambiguous", async () => {
497
+ const result = await runOutline('<div/a< x=">TAIL\n\n# 中文\n');
498
+ expect(result.exitCode).toBe(2);
499
+ expect(result.stderr.toString()).toContain(
500
+ "Markdown headings could not be classified safely",
501
+ );
502
+ expect(result.stdout.toString()).toBe("");
503
+ });
504
+
505
+ test("--outline requires exactly one file", () => {
506
+ const result = Bun.spawnSync(
507
+ [bunBin, tui, "--outline"],
508
+ { stdout: "pipe", stderr: "pipe" },
509
+ );
510
+ expect(result.exitCode).toBe(2);
511
+ expect(result.stderr.toString()).toContain(
512
+ "Usage: jsmdcui --outline FILE.md",
513
+ );
514
+ });
@@ -0,0 +1,110 @@
1
+ import { expect, test } from "bun:test";
2
+ import { buildMicroGlobal } from "../src/plugins/js-bridge.js";
3
+
4
+ test("micro prompt APIs delegate and return synchronously", () => {
5
+ const previousMicro = globalThis.micro;
6
+ const previousSelector = globalThis.$;
7
+ const calls = [];
8
+ const app = {
9
+ protectedAlert(message) {
10
+ calls.push(["alert", message]);
11
+ return undefined;
12
+ },
13
+ protectedConfirm(message) {
14
+ calls.push(["confirm", message]);
15
+ return true;
16
+ },
17
+ protectedPrompt(message, defaultValue) {
18
+ calls.push(["prompt", message, defaultValue]);
19
+ return "answer";
20
+ },
21
+ };
22
+
23
+ try {
24
+ const micro = buildMicroGlobal({ _app: app, _ctx: null, on() {} });
25
+ const alertResult = micro.alert("hello");
26
+ const confirmResult = micro.confirm("continue?");
27
+ const promptResult = micro.prompt("name", "Ada");
28
+
29
+ expect(alertResult).toBeUndefined();
30
+ expect(confirmResult).toBe(true);
31
+ expect(promptResult).toBe("answer");
32
+ expect(alertResult?.then).toBeUndefined();
33
+ expect(confirmResult?.then).toBeUndefined();
34
+ expect(promptResult?.then).toBeUndefined();
35
+ expect(calls).toEqual([
36
+ ["alert", "hello"],
37
+ ["confirm", "continue?"],
38
+ ["prompt", "name", "Ada"],
39
+ ]);
40
+ } finally {
41
+ if (previousMicro === undefined) delete globalThis.micro;
42
+ else globalThis.micro = previousMicro;
43
+ if (previousSelector === undefined) delete globalThis.$;
44
+ else globalThis.$ = previousSelector;
45
+ }
46
+ });
47
+
48
+ test("current buffer exposes its actual MDCUI module source", () => {
49
+ const previousMicro = globalThis.micro;
50
+ const previousSelector = globalThis.$;
51
+ const previousMain = global.MDCUI_MAIN;
52
+ const buffer = {
53
+ path: "/tmp/app.md",
54
+ _useBundledMdcuiModules: true,
55
+ };
56
+ const app = { buffer };
57
+
58
+ try {
59
+ global.MDCUI_MAIN = "/build/app.md";
60
+ const micro = buildMicroGlobal({ _app: app, _ctx: null, on() {} });
61
+
62
+ expect(micro.CurPane().Buf.MdcuiModuleSource).toBe("embedded");
63
+ buffer._useBundledMdcuiModules = false;
64
+ expect(micro.CurPane().Buf.MdcuiModuleSource).toBe("external");
65
+ delete global.MDCUI_MAIN;
66
+ buffer._useBundledMdcuiModules = true;
67
+ expect(micro.CurPane().Buf.MdcuiModuleSource).toBe("external");
68
+ } finally {
69
+ if (previousMain === undefined) delete global.MDCUI_MAIN;
70
+ else global.MDCUI_MAIN = previousMain;
71
+ if (previousMicro === undefined) delete globalThis.micro;
72
+ else globalThis.micro = previousMicro;
73
+ if (previousSelector === undefined) delete globalThis.$;
74
+ else globalThis.$ = previousSelector;
75
+ }
76
+ });
77
+
78
+ test("TUI $.tts forwards text and updates process-local pitch and speed", async () => {
79
+ const previousSelector = globalThis.$;
80
+ const previousPitch = Bun.env.TTS_PITCH;
81
+ const previousSpeed = Bun.env.TTS_SPEED;
82
+ const calls = [];
83
+ let stopped = 0;
84
+ const app = {
85
+ async runTts(text, options) {
86
+ calls.push([text, options]);
87
+ return "done";
88
+ },
89
+ stopTts() {
90
+ stopped++;
91
+ return true;
92
+ },
93
+ };
94
+ try {
95
+ buildMicroGlobal({ _app: app, _ctx: null, on() {} });
96
+ expect(await globalThis.$.tts("你好", 1.2, 0.8)).toBe("done");
97
+ expect(Bun.env.TTS_PITCH).toBe("1.2");
98
+ expect(Bun.env.TTS_SPEED).toBe("0.8");
99
+ expect(calls).toEqual([["你好", { trackBuffer: false }]]);
100
+ expect(await globalThis.$.tts.stop()).toBe(true);
101
+ expect(stopped).toBe(1);
102
+ } finally {
103
+ if (previousPitch === undefined) delete Bun.env.TTS_PITCH;
104
+ else Bun.env.TTS_PITCH = previousPitch;
105
+ if (previousSpeed === undefined) delete Bun.env.TTS_SPEED;
106
+ else Bun.env.TTS_SPEED = previousSpeed;
107
+ if (previousSelector === undefined) delete globalThis.$;
108
+ else globalThis.$ = previousSelector;
109
+ }
110
+ });
@@ -0,0 +1,10 @@
1
+ ```text#myid @keydown.prevent="handle(event)"
2
+ hello
3
+ ```
4
+
5
+ ```js front
6
+ export function handle(e)
7
+ {
8
+ alert(JSON.stringify(e,null,1))
9
+ }
10
+ ```