buninu 0.4.3 → 0.4.6

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,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.6 - 2026-09-14
4
+
5
+ ### Fixed
6
+
7
+ - Experimental macOS support
8
+ * Fall back to `$0` when `/proc` is unavailable
9
+ * Rename the shell wrapper's `status` variable to `_buninu_status`; `status`
10
+ is read-only in zsh, so the web terminal died the moment it connected on a
11
+ default macOS shell
12
+ * Thanks @hcyuser for the contribution! (#1, #2)
13
+
14
+ ## 0.4.5 - 2026-09-10
15
+
16
+ 0.4.4 is intentionally skipped 不吉利
17
+
18
+ ### Changed
19
+
20
+ - Sync bunmsh to 0.3.5
21
+ - Sync jsgotty to 1.1.11
22
+ * Security fix CSWSH
23
+ - Sync jsmdcui to 0.19.1
24
+ * Security fix CSWSH for CDP server
25
+
26
+ ## 0.4.3 - 2026-09-05
27
+
28
+ - Don't check exit status for bunx
29
+
3
30
  ## 0.4.2 - 2026-09-03
4
31
 
5
32
  ### Changed
package/README.md CHANGED
@@ -33,8 +33,9 @@ Buninu requires [Bun](https://bun.com). On Android, install Bun in Termux:
33
33
  npm install -g bun
34
34
  ```
35
35
 
36
- On Linux and Windows, follow the
36
+ - On Linux, Windows, and macOS, follow the
37
37
  [official Bun installation guide](https://bun.com/docs/installation).
38
+ * macOS support is currently experimental
38
39
 
39
40
  ## Start
40
41
 
@@ -2,6 +2,40 @@
2
2
 
3
3
  All notable user-visible changes to bunmsh are documented here.
4
4
 
5
+ ## [0.3.5] - 2026-09-09
6
+
7
+ Version 0.3.4 was intentionally skipped because the number four is considered
8
+ unlucky in Chinese culture, so this release advances directly from 0.3.3 to
9
+ 0.3.5.
10
+
11
+ ### Fixed
12
+
13
+ - Point the npm `bunmsh` bin at a new package-root `index.js` trampoline,
14
+ which immediately loads the real `src/main.js` entry point. On affected Bun
15
+ versions, validating a bin target below the package root goes through
16
+ `openat2`; Android can reject that syscall with `SIGSYS`, leaving an
17
+ otherwise successful install without its bin link. Keeping the declared bin
18
+ target at the package root avoids that path while preserving `src/main.js`
19
+ as the implementation entry point.
20
+
21
+ - Make the test suite portable between native Android and PRoot. Redirect
22
+ tests now create isolated directories below `os.tmpdir()` instead of
23
+ assuming `/tmp` is writable or empty, terminal assertions compare visible
24
+ text after `Bun.stripANSI()` instead of requiring one exact repaint
25
+ sequence, and true terminal behaviour is exercised through `Bun.Terminal`.
26
+ Negative-DNS curl checks run in parallel and have explicit timeouts because
27
+ PRoot resolution takes about five seconds while native Android returns
28
+ immediately.
29
+
30
+ ### Changed
31
+
32
+ - Split the former `shell.test.js` into `shell1.test.js`, `shell2.test.js`, and
33
+ `shell3.test.js`, and run test files with `bun test --parallel=4`. This keeps
34
+ the suite isolated and stable while reducing the measured run from roughly
35
+ 37 to 17 seconds under PRoot and from roughly 23 to 9 seconds on native
36
+ Android. Test-case-level `--concurrent` is deliberately not used because
37
+ cwd-changing and PTY tests share process-global state.
38
+
5
39
  ## [0.3.3] - 2026-09-03
6
40
 
7
41
  ### Fixed
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bun
2
+ // This top-level entry exists because Bun's bin-link containment check uses openat2
3
+ // when a package bin target has a parent directory. Android blocks that syscall
4
+ // with SIGSYS on affected Bun versions, so a target such as ./src/main.js is
5
+ // installed without its bin link. A target at the package root avoids that
6
+ // containment path while keeping the real entry point in src/main.js.
7
+ import "./src/main.js";
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "bunmsh",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Cross-platform command shell for Bun JavaScript",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./src/main.js",
8
8
  "bin": {
9
- "bunmsh": "./src/main.js"
9
+ "bunmsh": "./index.js"
10
10
  },
11
11
  "scripts": {
12
12
  "start": "bun ./src/main.js",
13
- "test": "bun test",
13
+ "test": "bun test --parallel=4",
14
14
  "genallhelp": "bun ./src/main.js -c 'builtin cat --exclude help/README.md help/*.md' > help/README.md"
15
15
  },
16
16
  "keywords": [
@@ -252,7 +252,7 @@ describe("curl transfers", () => {
252
252
  expect(unsupported.status).toBe(1);
253
253
  expect(unsupported.stderr)
254
254
  .toBe('curl: (1) Protocol "ftp" not supported or disabled in libcurl\n');
255
- });
255
+ }, 10_000);
256
256
  });
257
257
 
258
258
  describe("curl file output", () => {
@@ -31,6 +31,18 @@ async function expectLikeSh(source, env, args) {
31
31
  expect(actual).toEqual(reference);
32
32
  }
33
33
 
34
+ async function expectLikeShInTemp(source) {
35
+ const directory = mkdtempSync(join(tmpdir(), "bunmsh-reference-"));
36
+ try {
37
+ await expectLikeSh(source, {
38
+ ...process.env,
39
+ BUNMSH_TEST_TMPDIR: directory,
40
+ });
41
+ } finally {
42
+ rmSync(directory, { recursive: true, force: true });
43
+ }
44
+ }
45
+
34
46
  async function invokeInternal(source, options = {}) {
35
47
  const state = createState(options);
36
48
  const output = await execute(source, state, { capture: true });
@@ -590,7 +602,7 @@ describe("CLI direct argv forwarding", () => {
590
602
 
591
603
  test("-cc without a command is a usage error", async () => {
592
604
  const output = await invoke([process.execPath, "src/main.js"], "-cc");
593
- expect(output).toEqual({
605
+ expect({ ...output, stderr: Bun.stripANSI(output.stderr) }).toEqual({
594
606
  status: 2,
595
607
  stdout: "",
596
608
  stderr: "bunmsh: -cc requires a command\n",
@@ -614,29 +626,29 @@ describe("concurrent streaming pipelines", () => {
614
626
  });
615
627
 
616
628
  test("matches /bin/sh for streamed stdout overwrite and append redirects", async () => {
617
- await expectLikeSh(
618
- "out=/tmp/bunmsh-redirect-$$; printf first > \"$out\"; " +
629
+ await expectLikeShInTemp(
630
+ "out=$BUNMSH_TEST_TMPDIR/redirect; printf first > \"$out\"; " +
619
631
  "printf second >> \"$out\"; cat \"$out\"; rm \"$out\"",
620
632
  );
621
633
  });
622
634
 
623
635
  test("matches /bin/sh for a streamed stderr redirect", async () => {
624
- await expectLikeSh(
625
- "out=/tmp/bunmsh-stderr-$$; sh -c 'printf error >&2' 2> \"$out\"; " +
636
+ await expectLikeShInTemp(
637
+ "out=$BUNMSH_TEST_TMPDIR/stderr; sh -c 'printf error >&2' 2> \"$out\"; " +
626
638
  "cat \"$out\"; rm \"$out\"",
627
639
  );
628
640
  });
629
641
 
630
642
  test("matches /bin/sh when a redirect overrides the pipeline output", async () => {
631
- await expectLikeSh(
632
- "out=/tmp/bunmsh-override-$$; printf file > \"$out\" | cat; " +
643
+ await expectLikeShInTemp(
644
+ "out=$BUNMSH_TEST_TMPDIR/override; printf file > \"$out\" | cat; " +
633
645
  "printf :; cat \"$out\"; rm \"$out\"",
634
646
  );
635
647
  });
636
648
 
637
649
  test("streams a large redirect without collecting command output", async () => {
638
- await expectLikeSh(
639
- "out=/tmp/bunmsh-large-$$; head -c 1048576 /dev/zero > \"$out\"; " +
650
+ await expectLikeShInTemp(
651
+ "out=$BUNMSH_TEST_TMPDIR/large; head -c 1048576 /dev/zero > \"$out\"; " +
640
652
  "wc -c < \"$out\"; rm \"$out\"",
641
653
  );
642
654
  });
@@ -741,11 +753,13 @@ describe("system curl reference", () => {
741
753
  await expectLikeCurl(["-sSf", `${origin}/missing`]);
742
754
  await expectLikeCurl(["-s", "--fail-with-body", `${origin}/missing`]);
743
755
  await expectLikeCurl(["-s", "http://localhost:1/"]);
744
- await expectLikeCurl(["-s", "http://no-such-host-zzz.invalid/"]);
745
- await expectLikeCurl(["-sS", "http://no-such-host-zzz.invalid/"]);
756
+ await Promise.all([
757
+ expectLikeCurl(["-s", "http://no-such-host-zzz.invalid/"]),
758
+ expectLikeCurl(["-sS", "http://no-such-host-zzz.invalid/"]),
759
+ ]);
746
760
  await expectLikeCurl(["--bogus", `${origin}/text`]);
747
761
  await expectLikeCurl([]);
748
- });
762
+ }, 10_000);
749
763
 
750
764
  test.skipIf(!systemCurl)("matches redirect following and the method it lands on", async () => {
751
765
  await expectLikeCurl(["-s", `${origin}/redirect`]);