buninu 0.4.8 → 0.4.10

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,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.10 - 2026-09-20
4
+
5
+ ### Fixed
6
+
7
+ - Sync bunmsh to 0.3.7. Its fallback `tr` builtin now decodes NUL, octal and
8
+ common backslash escapes in character sets, so commands such as
9
+ `tr '\0' '\n' < /proc/$$/cmdline` correctly split NUL-delimited process
10
+ arguments. Previously the NUL bytes passed through unchanged; the Buninu
11
+ multicall launcher could then misidentify a command invoked with arguments
12
+ and exit with status 127 before reaching its shell wrapper, for example
13
+ `jmi hlw.js` even though plain `jmi` worked.
14
+
15
+ ## 0.4.9 - 2026-09-16
16
+
17
+ ### Changed
18
+
19
+ - Sync bunmsh to 0.3.6
20
+ * VS Code compatibility: accepts leading &
21
+
3
22
  ## 0.4.8 - 2026-09-16
4
23
 
5
24
  ### Documentation
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
 
@@ -560,7 +562,13 @@ own projects ship.
560
562
 
561
563
  `bunproot` is an optional tool downloaded by the user through `bunx` and is
562
564
  licensed under GPL-2.0-or-later; `js-udocker` is licensed under Apache-2.0.
563
- Neither is distributed with Buninu. The example below is Android-only.
565
+ Neither is distributed with Buninu.
566
+
567
+ - `bunproot --git clone` should be cross-platform
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`
571
+ - The container example below is Android-only.
564
572
 
565
573
  ```sh
566
574
  bunx bunproot
@@ -2,6 +2,27 @@
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
+
17
+ ## [0.3.6] - 2026-09-15
18
+
19
+ ### Added
20
+
21
+ - Accept a leading `&` as a PowerShell-compatible call operator on Windows,
22
+ or on any platform when `BUNMSH_LEADING_AND` is set before bunmsh starts.
23
+ This lets commands sent by VS Code's Play action run inside an already-open
24
+ bunmsh session, such as `& 'C:\Python313\python.exe' script.py`.
25
+
5
26
  ## [0.3.5] - 2026-09-09
6
27
 
7
28
  Version 0.3.4 was intentionally skipped because the number four is considered
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunmsh",
3
- "version": "0.3.5",
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) {
@@ -3337,7 +3363,15 @@ async function runCommandArgv(
3337
3363
  captureStderr,
3338
3364
  options = {},
3339
3365
  ) {
3340
- let commandArgv = argv;
3366
+ let commandArgv = argv;
3367
+
3368
+ if( process.env.BUNMSH_LEADING_AND ||
3369
+ process.platform === "win32" )
3370
+ {
3371
+ if(argv[0] === "&")
3372
+ commandArgv = argv.slice(1) ;
3373
+ }
3374
+
3341
3375
  let commandState = state;
3342
3376
  if (options.pipelineStage && runsInPipelineSubprocess(commandArgv, commandState))
3343
3377
  return runExternal(
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
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",