buninu 0.4.9 → 0.4.11

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.11 - 2026-09-20
4
+
5
+ - Emergency fix: multicall.sh on Buninu Linux
6
+ * /proc/$$/cmdline: /bin/bun /bin/sh ...
7
+
8
+ ## 0.4.10 - 2026-09-20
9
+
10
+ ### Fixed
11
+
12
+ - Sync bunmsh to 0.3.7. Its fallback `tr` builtin now decodes NUL, octal and
13
+ common backslash escapes in character sets, so commands such as
14
+ `tr '\0' '\n' < /proc/$$/cmdline` correctly split NUL-delimited process
15
+ arguments. Previously the NUL bytes passed through unchanged; the Buninu
16
+ multicall launcher could then misidentify a command invoked with arguments
17
+ and exit with status 127 before reaching its shell wrapper, for example
18
+ `jmi hlw.js` even though plain `jmi` worked.
19
+
3
20
  ## 0.4.9 - 2026-09-16
4
21
 
5
22
  ### Changed
package/README.md CHANGED
@@ -336,6 +336,8 @@ for how it works):
336
336
  - **Editing and viewing**
337
337
  * `jmi` — Edit files in the js micro editor
338
338
  * `glow` — View file contents with syntax highlighting
339
+ * `bun pm diff ./dir1 ./dir2` — diff 2 folders
340
+ + Can also diff against npm registry packages
339
341
 
340
342
  ---
341
343
 
@@ -564,6 +566,8 @@ Neither is distributed with Buninu.
564
566
 
565
567
  - `bunproot --git clone` should be cross-platform
566
568
  * Tested on Android, Linux, and Windows
569
+ * If git clone fails, try `bun pm cache rm`
570
+ * This `bunproot --git` also supports many other subcommands. Show them by `--git --help`
567
571
  - The container example below is Android-only.
568
572
 
569
573
  ```sh
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable user-visible changes to bunmsh are documented here.
4
4
 
5
+ ## [0.3.7] - 2026-09-20
6
+
7
+ ### Fixed
8
+
9
+ - Teach the fallback `tr` builtin to decode NUL, octal, and the common
10
+ backslash escapes in its character sets. Commands such as
11
+ `tr '\0' '\n' < /proc/$$/cmdline` now translate NUL-delimited input instead
12
+ of passing the NUL bytes through unchanged; `tr -d '\000'` works as well.
13
+ Range expansion such as `tr a-z A-Z` remains supported, and regression
14
+ tests cover both translating and deleting NUL bytes from general binary
15
+ input.
16
+
5
17
  ## [0.3.6] - 2026-09-15
6
18
 
7
19
  ### Added
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunmsh",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Cross-platform command shell for Bun JavaScript",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1898,11 +1898,37 @@ async function runWcFallback(argv, state, input) {
1898
1898
  }
1899
1899
 
1900
1900
  function expandTrSet(value) {
1901
- return value.replace(/(.)-(.)/g, (_, a, b) => {
1902
- let output = "";
1903
- for (let code = a.charCodeAt(0); code <= b.charCodeAt(0); code++) output += String.fromCharCode(code);
1904
- return output;
1905
- });
1901
+ const escapes = { a: "\x07", b: "\b", f: "\f", n: "\n", r: "\r", t: "\t", v: "\v", "\\": "\\" };
1902
+ const characters = [];
1903
+ for (let i = 0; i < value.length; i++) {
1904
+ if (value[i] !== "\\") {
1905
+ characters.push(value[i]);
1906
+ continue;
1907
+ }
1908
+ const octal = value.slice(i + 1).match(/^[0-7]{1,3}/)?.[0];
1909
+ if (octal) {
1910
+ characters.push(String.fromCharCode(Number.parseInt(octal, 8)));
1911
+ i += octal.length;
1912
+ continue;
1913
+ }
1914
+ const escaped = value[++i];
1915
+ characters.push(escapes[escaped] ?? escaped ?? "\\");
1916
+ }
1917
+
1918
+ let output = "";
1919
+ for (let i = 0; i < characters.length; i++) {
1920
+ if (i + 2 < characters.length && characters[i + 1] === "-") {
1921
+ const first = characters[i].charCodeAt(0);
1922
+ const last = characters[i + 2].charCodeAt(0);
1923
+ if (first <= last) {
1924
+ for (let code = first; code <= last; code++) output += String.fromCharCode(code);
1925
+ i += 2;
1926
+ continue;
1927
+ }
1928
+ }
1929
+ output += characters[i];
1930
+ }
1931
+ return output;
1906
1932
  }
1907
1933
 
1908
1934
  async function runTrFallback(argv, _state, input) {
@@ -381,6 +381,29 @@ describe("execution", () => {
381
381
  expect(await run("builtin sleep 1ms")).toMatchObject({ status: 0, stdout: "", stderr: "" });
382
382
  });
383
383
 
384
+ test("tr translates and deletes NUL bytes", async () => {
385
+ const directory = mkdtempSync(join(tmpdir(), "bunmsh-tr-"));
386
+ const cmdline = join(directory, "cmdline");
387
+ try {
388
+ await Bun.write(cmdline, new Uint8Array([
389
+ ...new TextEncoder().encode("/buninu/bin/jmi"), 0,
390
+ ...new TextEncoder().encode("hlw.js"), 0,
391
+ ]));
392
+ expect(await run(`builtin tr '\\0' '\\n' < '${cmdline}'`)).toMatchObject({
393
+ status: 0,
394
+ stdout: "/buninu/bin/jmi\nhlw.js\n",
395
+ stderr: "",
396
+ });
397
+ expect(await run(`builtin tr -d '\\000' < '${cmdline}'`)).toMatchObject({
398
+ status: 0,
399
+ stdout: "/buninu/bin/jmihlw.js",
400
+ stderr: "",
401
+ });
402
+ } finally {
403
+ rmSync(directory, { recursive: true, force: true });
404
+ }
405
+ });
406
+
384
407
  test("renders asset-backed Markdown help for every documented builtin", async () => {
385
408
  const excluded = new Set([".", "..", "//", "-", "~"]);
386
409
  const titles = { "[": "test", __builtin: "builtin", chdir: "cd" };
@@ -1062,4 +1085,3 @@ fi
1062
1085
  } finally { rmSync(home, { recursive: true, force: true }); }
1063
1086
  });
1064
1087
  });
1065
-
package/bin/bunmsh.sh CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  sd=$(dirname "$(realpath "$0")")
4
4
 
5
- exec bun "$sd"/../apps/bunmsh/bunmsh "$@"
5
+ exec bun "$sd"/../apps/bunmsh/index.js "$@"
package/bin/multicall.sh CHANGED
@@ -2,7 +2,18 @@
2
2
 
3
3
  if [ -f /proc/$$/cmdline ] ; then
4
4
  args=$(tr '\0' '\n' < /proc/$$/cmdline)
5
- caller=$(echo "$args" | head -n 1)
5
+ caller=$(printf '%s\n' "$args" | head -n 1)
6
+
7
+ # Buninu Linux implements /bin/sh in Bun. Its interpreter chain makes the
8
+ # first three cmdline entries /bin/bun, /bin/sh, and the invoked launcher;
9
+ # Android's native loader instead keeps the launcher in the first entry.
10
+ # Match only the exact Buninu chain so the existing Android and conventional
11
+ # Linux paths retain their current behaviour.
12
+ second=$(printf '%s\n' "$args" | head -n 2 | tail -n 1)
13
+ if [ "$caller" = /bin/bun ] && [ "$second" = /bin/sh ] ; then
14
+ caller=$(printf '%s\n' "$args" | head -n 3 | tail -n 1)
15
+ fi
16
+
6
17
  callerb=$(basename "$caller")
7
18
  else
8
19
  callerb=$(basename "$0")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "Buninu is a portable, self-bootstrapping Unix-like userspace built on Bun that runs across operating systems",
5
5
  "type": "module",
6
6
  "main": "./bin/init.js",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "scripts": {
55
55
  "start": "bun ./apps/jsgotty/gotty.js --reconnect -r -w --webgl -a 127.0.0.1",
56
- "local": "bun ./apps/bunmsh/bunmsh -c 'exec bunmsh'",
56
+ "local": "bun ./apps/bunmsh/index.js -c 'exec bunmsh'",
57
57
  "check": "node --check ./bin/init.js"
58
58
  }
59
59
  }