buninu 0.2.5 → 0.3.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 (122) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +100 -2
  3. package/apps/bunmsh/CHANGELOG.md +262 -0
  4. package/apps/bunmsh/LICENSE +21 -0
  5. package/apps/bunmsh/LICENSE-MKSH +295 -0
  6. package/apps/bunmsh/PORTING.md +192 -0
  7. package/apps/bunmsh/README.md +801 -0
  8. package/apps/bunmsh/bunmsh +7 -0
  9. package/apps/bunmsh/bunshell.md +61 -0
  10. package/apps/bunmsh/help/README.md +1945 -0
  11. package/apps/bunmsh/help/alias.md +22 -0
  12. package/apps/bunmsh/help/basename.md +38 -0
  13. package/apps/bunmsh/help/builtin.md +25 -0
  14. package/apps/bunmsh/help/bun.md +27 -0
  15. package/apps/bunmsh/help/bunmsh.md +47 -0
  16. package/apps/bunmsh/help/cat.md +31 -0
  17. package/apps/bunmsh/help/catfancy.md +35 -0
  18. package/apps/bunmsh/help/cd.md +22 -0
  19. package/apps/bunmsh/help/chmod.md +27 -0
  20. package/apps/bunmsh/help/clear.md +21 -0
  21. package/apps/bunmsh/help/colon.md +22 -0
  22. package/apps/bunmsh/help/command.md +27 -0
  23. package/apps/bunmsh/help/cp.md +28 -0
  24. package/apps/bunmsh/help/cut.md +25 -0
  25. package/apps/bunmsh/help/date.md +25 -0
  26. package/apps/bunmsh/help/dirname.md +25 -0
  27. package/apps/bunmsh/help/echo.md +25 -0
  28. package/apps/bunmsh/help/env.md +27 -0
  29. package/apps/bunmsh/help/eval.md +22 -0
  30. package/apps/bunmsh/help/exec.md +22 -0
  31. package/apps/bunmsh/help/exit.md +21 -0
  32. package/apps/bunmsh/help/export.md +22 -0
  33. package/apps/bunmsh/help/false.md +22 -0
  34. package/apps/bunmsh/help/find.md +33 -0
  35. package/apps/bunmsh/help/getopts.md +28 -0
  36. package/apps/bunmsh/help/grep.md +34 -0
  37. package/apps/bunmsh/help/head.md +27 -0
  38. package/apps/bunmsh/help/kill.md +27 -0
  39. package/apps/bunmsh/help/ln.md +28 -0
  40. package/apps/bunmsh/help/ls.md +37 -0
  41. package/apps/bunmsh/help/lsbun.md +29 -0
  42. package/apps/bunmsh/help/lsfancy.md +37 -0
  43. package/apps/bunmsh/help/md5sum.md +21 -0
  44. package/apps/bunmsh/help/mkdir.md +27 -0
  45. package/apps/bunmsh/help/mktemp.md +26 -0
  46. package/apps/bunmsh/help/mv.md +26 -0
  47. package/apps/bunmsh/help/print.md +30 -0
  48. package/apps/bunmsh/help/printf.md +25 -0
  49. package/apps/bunmsh/help/pwd.md +21 -0
  50. package/apps/bunmsh/help/read.md +27 -0
  51. package/apps/bunmsh/help/readonly.md +27 -0
  52. package/apps/bunmsh/help/realpath.md +21 -0
  53. package/apps/bunmsh/help/rm.md +33 -0
  54. package/apps/bunmsh/help/rmdir.md +27 -0
  55. package/apps/bunmsh/help/sed.md +29 -0
  56. package/apps/bunmsh/help/seq.md +29 -0
  57. package/apps/bunmsh/help/serve.md +50 -0
  58. package/apps/bunmsh/help/set.md +26 -0
  59. package/apps/bunmsh/help/sha256sum.md +21 -0
  60. package/apps/bunmsh/help/shift.md +23 -0
  61. package/apps/bunmsh/help/sleep.md +25 -0
  62. package/apps/bunmsh/help/sort.md +29 -0
  63. package/apps/bunmsh/help/source.md +23 -0
  64. package/apps/bunmsh/help/tab.md +30 -0
  65. package/apps/bunmsh/help/tac.md +29 -0
  66. package/apps/bunmsh/help/tail.md +27 -0
  67. package/apps/bunmsh/help/tee.md +25 -0
  68. package/apps/bunmsh/help/test.md +30 -0
  69. package/apps/bunmsh/help/time.md +29 -0
  70. package/apps/bunmsh/help/touch.md +26 -0
  71. package/apps/bunmsh/help/tr.md +26 -0
  72. package/apps/bunmsh/help/true.md +22 -0
  73. package/apps/bunmsh/help/type.md +21 -0
  74. package/apps/bunmsh/help/umask.md +22 -0
  75. package/apps/bunmsh/help/unalias.md +28 -0
  76. package/apps/bunmsh/help/uname.md +31 -0
  77. package/apps/bunmsh/help/unset.md +28 -0
  78. package/apps/bunmsh/help/wc.md +27 -0
  79. package/apps/bunmsh/help/whence.md +26 -0
  80. package/apps/bunmsh/help/which.md +41 -0
  81. package/apps/bunmsh/help/yes.md +23 -0
  82. package/apps/bunmsh/package.json +26 -0
  83. package/apps/bunmsh/serve.js +468 -0
  84. package/apps/bunmsh/single-exe/README.md +402 -0
  85. package/apps/bunmsh/single-exe/assetsHelper.js +371 -0
  86. package/apps/bunmsh/single-exe/assetsLoader.mjs +85 -0
  87. package/apps/bunmsh/single-exe/assetsPacker.js +218 -0
  88. package/apps/bunmsh/single-exe/compiled.js +527 -0
  89. package/apps/bunmsh/single-exe/entry.mjs +17 -0
  90. package/apps/bunmsh/src/cat-fancy.js +117 -0
  91. package/apps/bunmsh/src/cat-operands.js +31 -0
  92. package/apps/bunmsh/src/completion.js +247 -0
  93. package/apps/bunmsh/src/environment.js +61 -0
  94. package/apps/bunmsh/src/fancy-ls.js +186 -0
  95. package/apps/bunmsh/src/find.js +119 -0
  96. package/apps/bunmsh/src/history.js +198 -0
  97. package/apps/bunmsh/src/main.js +776 -0
  98. package/apps/bunmsh/src/mouse.js +103 -0
  99. package/apps/bunmsh/src/shell.js +3557 -0
  100. package/apps/bunmsh/test/catfancy.test.js +102 -0
  101. package/apps/bunmsh/test/reference-source.sh +1 -0
  102. package/apps/bunmsh/test/reference.test.js +677 -0
  103. package/apps/bunmsh/test/serve/README.md +3 -0
  104. package/apps/bunmsh/test/serve/bad.json +1 -0
  105. package/apps/bunmsh/test/serve/data.json +1 -0
  106. package/apps/bunmsh/test/serve/data.json5 +1 -0
  107. package/apps/bunmsh/test/serve/data.jsonc +2 -0
  108. package/apps/bunmsh/test/serve/data.jsonl +2 -0
  109. package/apps/bunmsh/test/serve/data.ndjson +1 -0
  110. package/apps/bunmsh/test/serve/data.toml +3 -0
  111. package/apps/bunmsh/test/serve/data.ts +15 -0
  112. package/apps/bunmsh/test/serve/data.xml +1 -0
  113. package/apps/bunmsh/test/serve/data.yaml +3 -0
  114. package/apps/bunmsh/test/serve/data.yml +1 -0
  115. package/apps/bunmsh/test/serve.test.js +241 -0
  116. package/apps/bunmsh/test/shell.test.js +1778 -0
  117. package/apps/bunmsh/test/t.sh +12 -0
  118. package/apps/native-bridge/native-bridge.js +45 -0
  119. package/apps/xdg-open/xdg-open.js +74 -2
  120. package/bin/init.js +11 -3
  121. package/demo-server.js +64 -0
  122. package/package.json +4 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 - 2026-08-21
4
+
5
+ ### Added
6
+
7
+ - Add `openWebView`, `evalWebView`, `showWebView` and `currWebView` to
8
+ `apps/native-bridge` (short spellings `openwv`, `evalwv`, `showwv`,
9
+ `currwv`, both accepted over the wire and listed in the host's `_discover`,
10
+ the same arrangement `getcb`/`setcb` already had), plus the
11
+ `WEBVIEW_CURRENT`/`WEBVIEW_CONSOLE`/`WEBVIEW_APP` constants. The host app
12
+ has exactly two WebViews, alive from startup and never created or closed at
13
+ runtime: `0` is the console showing the jsgotty terminal, `1` is the app
14
+ WebView, which starts blank and behind. An id of `-1` means whichever is in
15
+ front. `openWebView` loads without bringing its target forward, so loading
16
+ the app WebView while the user keeps looking at the terminal is one call;
17
+ `showWebView` is the only thing that changes what is on screen, and
18
+ `showWebView(-1)` switches to the *next* WebView rather than being a no-op.
19
+ `evalWebView` resolves to the value the expression produced rather than a
20
+ string containing it, with `undefined`, functions and thrown exceptions all
21
+ arriving as `null` because WebView itself does not distinguish them.
22
+ - `xdg-open` gained `MINAPK_WEBVIEW`, which names the WebView to open a URL
23
+ in (and brings it to the front) instead of handing the URL to the
24
+ platform's default handler. Read here rather than by the host app on
25
+ purpose: it is an environment variable of this process tree, so the host
26
+ could not see a value exported in the shell a moment ago, which is the
27
+ whole point of having it. Only URLs are redirected -- a filesystem path
28
+ still goes to the host, whose `content://` provider can actually serve it,
29
+ unlike a `file://` URL in a WebView. A value that is not a plain integer is
30
+ reported and ignored rather than guessed at, and a WebView the host does
31
+ not have falls back to the default handler after saying so.
32
+ - Add `demo-server.js`: serves one fixed page on an OS-assigned port and
33
+ opens it in the app WebView through `MINAPK_WEBVIEW=1 xdg-open`, as the
34
+ smallest end-to-end exercise of the above.
35
+ - Add `buninu.backToConsole` (default `true`), read by the minapk host app,
36
+ not by Buninu itself: it decides whether the Android back key, pressed on
37
+ the app WebView with no page of its own to go back to, switches to the
38
+ console WebView or takes the leave-the-app path. The host treats a missing,
39
+ unreadable or non-boolean value as `true`, so it cannot fail in a way that
40
+ leaves the back key broken. minapk's `--no-back-to-console` sets it for a
41
+ single build.
42
+
3
43
  ## 0.2.5 - 2026-08-19
4
44
 
5
45
  - Fixed fish shell startup breaking buninu
package/README.md CHANGED
@@ -52,6 +52,8 @@ On Linux and Windows, follow the
52
52
 
53
53
  ## Start
54
54
 
55
+ ### Start a remote shell in a Browser
56
+
55
57
  Run the npm package:
56
58
 
57
59
  ```sh
@@ -82,6 +84,25 @@ remaining argument forwarded to it, and exits with its exit code. Use this to
82
84
  reach an app's own options directly, for example `npx buninu --jsgotty --help`
83
85
  to see jsgotty's actual flag reference instead of Buninu's.
84
86
 
87
+ ### Start a local shell in a Terminal (experimental)
88
+
89
+ Drops you straight into [bunmsh](apps/bunmsh/README.md) (Bun Modern Shell), a
90
+ dependency-free, mksh-inspired command shell that runs on Bun, without going
91
+ through the browser/jsgotty flow.
92
+
93
+ ```sh
94
+ npx buninu --local
95
+ ```
96
+
97
+ Or run it from a source checkout:
98
+
99
+ ```sh
100
+ bun ./bin/init.js --local
101
+ ```
102
+
103
+ Buninu's own tools (`rz`, `sz`, `showimg`, `tts`, `xdg-open`, `native-bridge`,
104
+ etc.) stay available inside this shell too, same as in the browser session.
105
+
85
106
  ## Security
86
107
 
87
108
  `scripts.start` binds jsgotty to `127.0.0.1` by default, so the terminal
@@ -125,7 +146,7 @@ jsmdcui Edit and run interactive Markdown applications
125
146
  musl-la Launch AArch64 ELF programs with the bundled musl loader
126
147
  buninu-help Render README.md with glow, then show icon.png with jsgotty --viu
127
148
  bunx Globally install a package with bun, then exec its matching binary
128
- native-bridge Call the Android host app (toast, clipboard, speak) over PKG_BRIDGE_SOCK
149
+ native-bridge Call the Android host app (toast, clipboard, speak, WebViews) over PKG_BRIDGE_SOCK
129
150
  xclip X11-style clipboard tool; -selection clipboard/-clip bridges to the system clipboard
130
151
  tts Speak text and wait for it to finish (-a to not wait)
131
152
  showimg Shorthand for jsgotty --viu
@@ -150,10 +171,45 @@ APK with, over an abstract-namespace unix socket. A bare `native-bridge`
150
171
  lists what the host implements. Every call
151
172
  times out after 5 seconds instead of hanging; outside such an APK, every call
152
173
  fails with a clear error instead of doing nothing silently. `import { toast,
153
- clipboardRead, clipboardWrite, speak, ttsStatus, call, available } from
174
+ clipboardRead, clipboardWrite, speak, ttsStatus, openWebView, evalWebView,
175
+ showWebView, currWebView, call, available } from
154
176
  "apps/native-bridge/native-bridge.js"` gives the same functions as a library,
155
177
  for use from a `js back` block.
156
178
 
179
+ `openWebView(id, url)`, `evalWebView(id, js)`, `showWebView(id)` and
180
+ `currWebView()` (short: `openwv`, `evalwv`, `showwv`, `currwv`) drive the host
181
+ app's WebViews. There are exactly two, both
182
+ alive from startup and neither ever created nor closed at runtime: id `0` is
183
+ the console -- the jsgotty terminal this shell is rendered in -- and id `1` is
184
+ the app WebView, which starts out blank and behind. Anywhere an id is taken,
185
+ `-1` means whichever WebView is in front right now.
186
+
187
+ `openWebView` loads a URL *without* bringing that WebView to the front, so
188
+ loading the app WebView while the user keeps looking at the terminal is one
189
+ call. `showWebView` is the only thing that changes what is on screen; the
190
+ host's on-screen key bar (Ctrl/Alt/Shift and friends), its volume-key menu and
191
+ its back key all act on whichever WebView is in front, so they follow the
192
+ switch. Back on the app WebView with no page of its own to go back to
193
+ switches to the console rather than leaving the app, unless
194
+ `buninu.backToConsole` says otherwise (see "Back key" below).
195
+ `showWebView(-1)` switches to the next WebView instead of being a no-op --
196
+ with two of them, a toggle. `evalWebView` resolves to the value the
197
+ expression produced, not a string containing it; `undefined`, a function, and
198
+ a thrown exception all arrive as `null`, since WebView itself does not
199
+ distinguish them.
200
+
201
+ All four also answer to a short `openwv`/`evalwv`/`showwv`/`currwv` spelling,
202
+ the same way `clipboardRead`/`clipboardWrite` answer to `getcb`/`setcb`: the
203
+ host accepts either and lists both in its `_discover` response, so either name
204
+ works from the CLI, from `rpcraw`, and as an `import`.
205
+
206
+ ```sh
207
+ native-bridge openwv 1 https://example.com # load it, screen unchanged
208
+ native-bridge showwv 1 # now bring it to the front
209
+ native-bridge evalwv 1 document.title
210
+ native-bridge currwv
211
+ ```
212
+
157
213
  `xclip [-o] [-selection primary|clipboard] [-clip]` is a small X11-`xclip`-
158
214
  compatible clipboard tool. `-selection primary` (the default) never touches
159
215
  the system clipboard, matching real X11 semantics. `-selection
@@ -178,6 +234,25 @@ as its default handler: the host app through native-bridge on Android (or
178
234
  `termux-open` under plain Termux), `open` on macOS, `start` on Windows, and
179
235
  the real system `xdg-open` on Linux.
180
236
 
237
+ Inside minapk's APK, `MINAPK_WEBVIEW` redirects that: set it to a WebView id
238
+ and a URL is loaded into that WebView and brought to the front (`openWebView`
239
+ then `showWebView`) instead of being handed to the system's default handler.
240
+
241
+ ```sh
242
+ MINAPK_WEBVIEW=1 xdg-open https://example.com # in the app WebView, on screen
243
+ export MINAPK_WEBVIEW=1 # ...or for the whole session
244
+ ```
245
+
246
+ `0` is the console, so it navigates the terminal page away -- the back key
247
+ returns to it and jsgotty reconnects, but it is not usually what you want.
248
+ `-1` is whichever WebView is in front. Only URLs are redirected: a file path
249
+ always goes to the host's own handler, since WebView cannot read a `file://`
250
+ URL under Buninu's home (`setAllowFileAccess` is false from API 30 on) while
251
+ the host serves that same file through its content:// provider. A value that
252
+ is not a plain integer is reported on stderr and ignored rather than guessed
253
+ at, an unset or empty value keeps the default behavior, and a WebView the host
254
+ does not have falls back to the default handler after saying so.
255
+
181
256
  ## Export
182
257
 
183
258
  Export the current Buninu installation as a gzip-compressed tar archive:
@@ -349,6 +424,29 @@ from the directory containing `package.json`.
349
424
 
350
425
  Use `--shell <path-or-name>` for a one-time override.
351
426
 
427
+ ## Back key (Android, optional)
428
+
429
+ Set `buninu.backToConsole` in `package.json` to decide what the Android host
430
+ app's back key does while the app WebView (id `1`, see `native-bridge` above)
431
+ is in front and has no page of its own left to go back to. It defaults to
432
+ `true`: back switches to the console WebView, leaving the app WebView loaded
433
+ and running behind it. Set it to `false` and back leaves the app instead.
434
+
435
+ ```json
436
+ {
437
+ "buninu": {
438
+ "backToConsole": false
439
+ }
440
+ }
441
+ ```
442
+
443
+ This one is read by the host app, not by Buninu itself, so it does nothing
444
+ outside an APK built with
445
+ [minapk](https://www.npmjs.com/package/@drxiaozhi/minapk) -- where it can also
446
+ be set for a single build with `--no-back-to-console`. The host treats a
447
+ missing, unreadable, or non-boolean value as `true`, so nothing here can fail
448
+ in a way that leaves the back key broken.
449
+
352
450
  ## Process-list helpers
353
451
 
354
452
  The bundled `.bashrc` provides `pspa` (`ps -eo pid,args`) and `pspac`, which
@@ -0,0 +1,262 @@
1
+ # Changelog
2
+
3
+ All notable user-visible changes to bunmsh are documented here.
4
+
5
+ ## [0.2.0] - 2026-08-29
6
+
7
+ ### Added
8
+
9
+ - Add `SERVE_AUTO_OPEN`, `SERVE_MINAPK_WEBVIEW`, and `SERVE_RANDOM_URL` plus
10
+ overriding `serve` CLI flags for opening the server (cross-platform, with
11
+ `xdg-open` on PATH preferred), targeting the npm `buninu` package's app
12
+ WebView, and protecting it behind a high-entropy random URL prefix.
13
+ - Add repeatable `--exclude PATTERN` and `--exclude=PATTERN` filtering backed
14
+ by `Bun.Glob` to the `cat` and `catfancy` fallback builtins for concatenating
15
+ expanded file sets.
16
+ - Add JS/TS syntax coloring to `catfancy`: `.js`/`.mjs`/`.cjs`/`.jsx` and
17
+ `.ts`/`.mts`/`.cts`/`.tsx` files are wrapped in a fenced ` ```javascript `/
18
+ ` ```typescript ` block and rendered through the same `Bun.markdown.ansi`
19
+ path Markdown gets, reusing its code-block highlighter rather than adding
20
+ one. The fence is widened past the longest run of backticks already in the
21
+ source, so a file containing its own triple-backtick text can't prematurely
22
+ close it.
23
+ - Add bracketed-paste support to the interactive prompt. A paste containing a
24
+ newline no longer gets read back a physical line at a time (which broke any
25
+ `\`-continued command in it, since each line ran on its own the instant its
26
+ line-ending arrived); it now resolves as a single already-typed line, going
27
+ through the same continuation/execute path Enter does, so a whole
28
+ multi-command, `\`-continued tutorial block can be pasted and run as-is. A
29
+ paste's own line-ending convention — `\n`, `\r\n`, or a bare `\r` (some
30
+ terminals use it for pasted content, even though bunmsh's parser otherwise
31
+ treats a standalone `\r` as whitespace) — is normalized before anything
32
+ downstream sees it. A single-line paste is unaffected. Independent of
33
+ `--mouse`/`BUNMSH_MOUSE`.
34
+
35
+ ### Fixed
36
+
37
+ - Recognize a line ending in a bare trailing backslash as an interactive
38
+ continuation request. Previously, typing `echo hi \` and pressing Enter ran
39
+ it immediately as `echo`, `hi`, `\` instead of showing the PS2 prompt and
40
+ waiting for the next line, because the interactive line-by-line `pending`
41
+ buffer only had the lone `\` at that point — the following `\n` that the
42
+ existing backslash-newline splice looks for hadn't been typed yet.
43
+
44
+ ## [0.1.11] - 2026-08-28
45
+
46
+ ### Added
47
+
48
+ - Add a `tac` PATH-fallback builtin for reversing newline-delimited records
49
+ from files or stdin while preserving their bytes and separators.
50
+ - Add asset-backed `-h` and `--help` output for documented regular and fallback
51
+ builtins. Help lives as Markdown under `help/`, starts at level-two headings,
52
+ and renders through `Bun.markdown.ansi` with terminal hyperlinks enabled.
53
+ - Add the `catfancy` PATH-fallback builtin. Previewable data formats are
54
+ parsed and emitted as colorized pretty JSON; Markdown is rendered with
55
+ `Bun.markdown.ansi` and hyperlinks enabled, while unrecognized formats pass
56
+ through unchanged.
57
+
58
+ ### Fixed
59
+
60
+ - Normalize CRLF source to LF at every shell-language input boundary, covering
61
+ script files, stdin, `-c`, interactive continuation, command substitutions,
62
+ compound syntax, quoted text, and here-documents. A standalone carriage
63
+ return remains untouched.
64
+ - Treat backslash followed by either LF or CRLF as a line continuation before
65
+ token recognition. This supports indented multi-line command invocations
66
+ without introducing empty arguments, including `enter_rootfs.sh`-style
67
+ multi-line `exec` commands.
68
+ - Stream top-level compound-command output directly to the terminal. An
69
+ interactive program launched by `exec` inside `if`, loops, or other compound
70
+ syntax previously inherited stdin but had stdout and stderr buffered until
71
+ it exited, making an entered rootfs appear to hang with a blank screen.
72
+
73
+ ## [0.1.10] - 2026-08-27
74
+
75
+ ### Added
76
+
77
+ - Add `<<`/`<<-` here-documents. An unquoted, unescaped delimiter expands
78
+ parameters, command substitution, and arithmetic in the body like a
79
+ double-quoted string; a quoted or backslash-escaped delimiter (`<<'EOF'`,
80
+ `<<\EOF`) leaves it literal. `<<-` strips leading tabs from the body and the
81
+ terminator. Here-documents work on plain command lines, in pipelines, across
82
+ multiple heredocs on one command, and inside `if`/`while`/`for`/`case`
83
+ bodies. Like dash and bash, a script that ends before the terminator line
84
+ appears uses whatever was read as the body instead of raising a syntax
85
+ error.
86
+ - Add `<<<` here-strings, matching mksh's `DOHERESTR | DOSCALAR` word
87
+ expansion: parameter, command, and arithmetic substitution run, but there is
88
+ no field splitting, pathname expansion, or tilde expansion, and a trailing
89
+ newline is appended before the word becomes stdin.
90
+ - Fix an unrelated pre-existing crash surfaced while adding here-documents: any
91
+ tokenizer syntax error (for example an unterminated quote) raised while
92
+ probing whether a script uses compound (`if`/`while`/`for`/`case`) syntax
93
+ used to escape as an unhandled exception instead of the usual
94
+ `bunmsh: syntax error: ...` message.
95
+ - Show mksh's `PS2` continuation prompt (default `"> "`) in interactive mode
96
+ while a here-document, an open quote/substitution, or an unfinished
97
+ `if`/`while`/`for`/`case` body is still being typed, instead of running each
98
+ line on its own as soon as Enter is pressed. Ctrl-C during a continuation
99
+ discards it and returns to the primary prompt; Ctrl-D runs whatever was
100
+ typed so far — the same leniency the non-interactive here-document fallback
101
+ above already has — and then keeps the shell running (Node's `readline`
102
+ closes itself on an empty-line Ctrl-D, so this transparently rebuilds it),
103
+ the same as mksh, instead of exiting the whole session.
104
+ - `lsfancy -l` now shows a symlink's target (`link -> target`), including a
105
+ broken one, matching real `ls` — this was missing from both `lsfancy` and
106
+ the Bun Shell `ls` fallback it is compared against. Reading it works the
107
+ same way on Windows as on POSIX platforms.
108
+ - Give a symlink whose target does not resolve (missing, or a cycle) a
109
+ distinct 🚫 icon instead of the normal 🔗, in both the plain and `-l`
110
+ listing forms.
111
+ - With mouse tracking enabled, clicking inside the line currently being typed
112
+ now moves the cursor there (accounting for the active prompt's own width
113
+ and wrapping, including multi-line/multi-tab prompts and the `PS2`
114
+ continuation prompt), the same as clicking inside a text field, instead of
115
+ only reacting to clicks on tabs. Clicking past the end of the typed text
116
+ moves the cursor to the end of the line rather than doing nothing.
117
+ - Add `-S` (sort by size, largest first), `-1` (force one entry per line,
118
+ even in a terminal), and `-F` (append a classify suffix — `/` directory,
119
+ `@` symlink, `*` executable, `=` socket, `|` FIFO) to `lsfancy`, all
120
+ combinable with the existing flags (`-lSF`, etc.).
121
+ - Save history automatically — every 60s, once more on exit, and once more
122
+ on SIGTERM/SIGHUP — by appending only this session's own new commands to a
123
+ JSON Lines history file, never rewriting it, so several bunmsh sessions
124
+ saving around the same time can no longer overwrite each other's history.
125
+ `tab s`/`tab save` trigger the same append immediately; the new `tab s d`/
126
+ `tab save dedupe` is a separate, explicit whole-file rewrite that drops
127
+ duplicate commands and reports if another session's write raced it. A
128
+ history file saved in the previous single-JSON-array format is still read
129
+ correctly and is silently upgraded to JSON Lines the next time anything
130
+ is saved.
131
+ - Catch SIGTERM and SIGHUP in interactive mode instead of leaving them at
132
+ the default disposition (which killed bunmsh immediately, before it could
133
+ save anything). Receiving either while waiting at the prompt now flushes
134
+ history and exits with the conventional 128+signal status; while a
135
+ foreground command owns the terminal, it flushes history immediately and
136
+ exits once that command finishes on its own, since there is no
137
+ job-control layer yet to also stop the command itself.
138
+
139
+ ### Changed
140
+
141
+ - `tab s`/`tab save` (with no `d`/`dedupe`) no longer removes duplicate
142
+ commands as a side effect of saving — it now only appends, matching how
143
+ most shells' history files work. Use the new `tab s d`/`tab save dedupe`
144
+ to remove duplicates explicitly.
145
+ - The `ls` fallback builtin (used when no PATH `ls` is found, e.g. on
146
+ Windows, or under `--builtin-only`) is now `lsfancy` instead of Bun Shell's
147
+ own `ls`, since it now covers more real `ls` behavior (working `-h`/`-t`/
148
+ `-r`, a symlink's target, alphabetical default order) than Bun Shell's
149
+ version does. Bun Shell's `ls` is still reachable, renamed to `lsbun`.
150
+ `lsfancy` itself is unchanged and still callable under its own name.
151
+
152
+ ### Fixed
153
+
154
+ - Fix an unrelated pre-existing hang found while working on the above: a
155
+ pipeline whose downstream stage closes early (`yes | head -n 3`) could
156
+ leave the killed upstream stage's own output-forwarding stuck forever —
157
+ Bun never releases the reader lock it holds on that pipeline link's read
158
+ side once the stage reading it has exited, so a write already in flight
159
+ into it backpressures permanently and cannot be canceled from outside.
160
+ That write is now abandoned instead of waited on once the downstream stage
161
+ is known to be done, and the shell forces its own exit once a script or
162
+ `-c` command finishes rather than leaving that abandoned operation to keep
163
+ the process running forever.
164
+ - Fix `lsfancy -l` showing every file's modification time in UTC instead of
165
+ local time (it built the column from `Date.prototype.toISOString()`, which
166
+ is always UTC) — a pre-existing bug, not something the symlink-target work
167
+ above introduced.
168
+
169
+ ## [0.1.9] - 2026-08-27
170
+
171
+ ### Added
172
+
173
+ - Render Markdown previews in `serve` with heading anchors, passing
174
+ `{ headings: true }` to `Bun.markdown.html`, so long documents get linkable
175
+ section ids.
176
+ - Document `serve` in its own README section, pulled out of the fallback
177
+ builtin table: port selection and its fallback, the `q`/`quit`/`exit` and `o`
178
+ controls, exit codes, directory listings and previews, and the
179
+ non-interactive forms such as `bmsh -cc builtin serve <directory>` that start
180
+ it from another shell or a script.
181
+ - Document packing a folder into a single executable without a source
182
+ checkout — `npx bunmsh --build-exe --asset /absolute/path/mysite`, then
183
+ `bmsh -cc builtin serve 'B:/~BUN/mysite'` — including the absolute-path
184
+ requirement, the PowerShell and `cmd.exe` spellings, and the trade-off
185
+ against the `package.json` `assets` route, which is what makes the same file
186
+ readable through `readAssetText` from a checkout and from the binary.
187
+ - Document that `serve` always answers a directory with its listing rather than
188
+ the directory's `index.html`, and point site hosting at `npx serve` or Bun
189
+ 1.4's `{ dir }` routes, which do send it.
190
+ - Document that HTTP Range is not honoured for files inside a compiled binary:
191
+ Bun answers those with the whole body and a `200`.
192
+
193
+ ## [0.1.8] - 2026-08-27
194
+
195
+ ### Added
196
+
197
+ - Add the `serve [directory]` fallback builtin and standalone `serve.js` as a
198
+ minimal replacement for `python3 -m http.server`. It provides live directory
199
+ listings, reflects filesystem changes, and serves whole `Bun.file` responses
200
+ with Bun's native HTTP Range support.
201
+ - Add `🔍` preview links to `serve` directory pages. Markdown is rendered by
202
+ `Bun.markdown.html`; JSON, JSON5, JSONC, JSONL/NDJSON, YAML, and TOML are
203
+ parsed by their corresponding runtime parser and pretty-printed as HTML.
204
+ XML is also previewed when the running Bun provides `Bun.XML.parse`.
205
+ - Add basic syntax colouring to structured-data previews, following the
206
+ statement, string, escape, number, and constant groups from jsmdcui's
207
+ `runtime/syntax/json.yaml` after parser output is pretty-printed as JSON.
208
+ - Add interactive `serve` controls: `q`, `quit`, and `exit` stop the server,
209
+ while `o` opens its URL through `xdg-open`.
210
+ - Accept both `/$bunfs/...` and `B:/~BUN/...` serve paths on every platform,
211
+ translating either spelling through the compiled module's
212
+ `import.meta.dirname` to the bunfs mount accepted by the current runtime.
213
+
214
+ ### Fixed
215
+
216
+ - Keep `serve` running after malformed preview data or any other uncaught
217
+ request-handler exception; parser failures return 422 and the outer request
218
+ boundary converts unexpected failures to an isolated HTTP 500 response.
219
+ - Prevent Termux foreground/resume terminal resize events from repainting the
220
+ shell's cwd prompt over a running server or other foreground command.
221
+ - Keep the interactive shell alive when Ctrl-C interrupts the prompt or a
222
+ foreground `serve`. Like mksh, SIGINT now abandons the current operation and
223
+ returns to a fresh prompt; Ctrl-D on an empty input remains the way to send
224
+ EOF and leave the shell.
225
+
226
+ ## [0.1.5] - 2026-08-26
227
+
228
+ ### Added
229
+
230
+ - Mark shell-inserted line endings with `↩️`, making the exact boundary of a
231
+ command's output visible when the command does not emit a trailing newline.
232
+ - Document this marker under **Special Interactions → Terminal behavior**.
233
+
234
+ ### Fixed
235
+
236
+ - Preserve the final line of any interactive command whose output has no
237
+ trailing newline, including streamed external commands such as
238
+ `printf hello`. bunmsh now queries the terminal cursor before repainting the
239
+ prompt and only inserts a marked newline when the cursor remains mid-line.
240
+
241
+ ## [0.1.4] - 2026-08-26
242
+
243
+ ### Added
244
+
245
+ - Added `Alt-P` as a second shortcut for `builtin lsfancy ..`, matching
246
+ `Alt-U` and listing the Parent (upper) folder without changing cwd or
247
+ discarding the current edit buffer.
248
+
249
+ ### Fixed
250
+
251
+ - Preserve short `Alt-L`, `Alt-U`, `Alt-P`, and tab-double-click `lsfancy`
252
+ output when readline redraws the prompt. A two-line prompt previously moved
253
+ upward and erased a one-line listing, which was especially visible for the
254
+ parent of the Termux home directory.
255
+ - Derive `HOME` on Windows from `USERPROFILE`, or from `HOMEDRIVE` plus
256
+ `HOMEPATH`, when the environment does not define it. Bare `cd`, `~`, `$HOME`,
257
+ prompt home shortening, and child environments now share a usable home path.
258
+ - Normalise Windows HOME paths to forward slashes and compare HOME/cwd without
259
+ case sensitivity when deciding whether a prompt path should use `~`.
260
+ - Treat Android's `/data/data/PACKAGE` and `/data/user/0/PACKAGE` app-sandbox
261
+ paths as equivalent for prompt home shortening, so Termux HOME and its
262
+ descendants display as `~` even when HOME and cwd use different aliases.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dr. John (醫者小智)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.