buninu 0.3.0 → 0.4.0

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 (142) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +334 -37
  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/cmdlist +6 -1
  119. package/apps/jsgotty/gotty.js +65 -76
  120. package/apps/jsgotty/package.json +6 -1
  121. package/apps/jsgotty/single-exe/README.md +358 -54
  122. package/apps/jsgotty/single-exe/assetsHelper.js +293 -12
  123. package/apps/jsgotty/single-exe/assetsLoader.mjs +1 -1
  124. package/apps/jsgotty/single-exe/assetsPacker.js +218 -0
  125. package/apps/jsgotty/single-exe/compiled.js +379 -19
  126. package/apps/jsgotty/single-exe/entry.mjs +16 -2
  127. package/apps/jsgotty/zmodem-node.js +14 -12
  128. package/apps/jsmdcui/CHANGELOG.md +56 -0
  129. package/apps/jsmdcui/package.json +12 -2
  130. package/apps/jsmdcui/single-exe/README.md +298 -375
  131. package/apps/jsmdcui/single-exe/assetsHelper.js +198 -18
  132. package/apps/jsmdcui/single-exe/assetsLoader.mjs +1 -1
  133. package/apps/jsmdcui/single-exe/assetsPacker.js +218 -0
  134. package/apps/jsmdcui/single-exe/compiled.js +291 -5
  135. package/apps/jsmdcui/single-exe/entry.mjs +7 -0
  136. package/apps/jsmdcui/src/index.js +11 -8
  137. package/apps/jsmdcui/tests/jmigt.js +16 -0
  138. package/bin/bunmsh.bat +3 -0
  139. package/bin/bunmsh.sh +5 -0
  140. package/bin/init.js +48 -5
  141. package/bin/install.js +541 -0
  142. package/package.json +4 -2
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ echo shell-before
4
+ Bun.version
5
+ Bun.e, Math.cos(1)
6
+
7
+ Bun.sha.var = { message: "shared", count: 1 }
8
+ Bun.sha.var.count += 1
9
+ Bun.sha.var
10
+ echo "from command substitution: $(Bun.sha.var.message)"
11
+
12
+ echo shell-after
package/apps/cmdlist CHANGED
@@ -39,5 +39,10 @@ rz
39
39
  ### sz — Download a file over ZMODEM (bun apps/jsgotty/sz.js)
40
40
  sz
41
41
 
42
- ### xdg-open — Open a file or URL with the platform's default handler (native bridge on Android, open/start/xdg-open elsewhere)
42
+ ### xdg-open — Open a file or URL with the platform's default handler (native bridge on Android, open/start/xdg-open elsewhere) '
43
43
  xdg-open
44
+
45
+
46
+ ### bunmsh – Bun Modern Shell
47
+
48
+ bunmsh
@@ -97,25 +97,30 @@ const DEFAULTS = {
97
97
  const compiledHelperPromise = import("./single-exe/compiled.js").catch(() => null);
98
98
  const assetsHelperPromise = import("./single-exe/assetsHelper.js").catch(() => null);
99
99
 
100
- let RESOURCE_ROOT = __dirname;
101
- let STATIC_ROOT = path.resolve(RESOURCE_ROOT, "./static");
102
- let DEFAULT_INDEX = path.join(STATIC_ROOT, "index.html");
103
- let DEFAULT_MANIFEST = path.join(STATIC_ROOT, "manifest.json");
104
- let DEFAULT_HELP = path.join(STATIC_ROOT, "help.md");
105
- let DEFAULT_README = path.resolve(RESOURCE_ROOT, "./README.md");
106
- let DEFAULT_README_EN = path.resolve(RESOURCE_ROOT, "./README.en.md");
107
- let helperAssetPath = null;
108
- let helperReadInternalAssetText = null;
109
- let helperReadInternalAssetBytes = null;
110
-
111
- function configureResourceRoot(compiledHelper) {
112
- RESOURCE_ROOT = compiledHelper?.REPO_ROOT
113
- STATIC_ROOT = path.resolve(RESOURCE_ROOT, "./static");
114
- DEFAULT_INDEX = path.join(STATIC_ROOT, "index.html");
115
- DEFAULT_MANIFEST = path.join(STATIC_ROOT, "manifest.json");
116
- DEFAULT_HELP = path.join(STATIC_ROOT, "help.md");
117
- DEFAULT_README = path.resolve(RESOURCE_ROOT, "./README.md");
118
- DEFAULT_README_EN = path.resolve(RESOURCE_ROOT, "./README.en.md");
100
+ // Assets are addressed by the package-relative keys package.json declares
101
+ // ("static/index.html", "README.md"). assetsHelper turns a key into bytes,
102
+ // wherever they live: the embedded store, the compiled binary's virtual
103
+ // filesystem, or a file on disk. Nothing here builds an absolute path.
104
+ let assets = null;
105
+
106
+ // Node runs this file without the ESM-only helper. Then there is nothing
107
+ // embedded either, so a key is just a path under the source checkout.
108
+ function assetText(key) {
109
+ return assets
110
+ ? assets.readAssetTextSync(key)
111
+ : fs.readFileSync(path.join(__dirname, key), "utf8");
112
+ }
113
+
114
+ function assetFilePath(key) {
115
+ return assets ? assets.assetDiskPath(key) : path.join(__dirname, key);
116
+ }
117
+
118
+ // URL-relative path -> asset key, or null when it escapes `static/`.
119
+ // Normalizing against "/" is what makes "../../etc/passwd" unreachable.
120
+ function staticAssetKey(relativePath) {
121
+ const rel = path.posix.normalize(`/${String(relativePath ?? "")}`).slice(1);
122
+ if (!rel || rel === ".." || rel.startsWith("../")) return null;
123
+ return `static/${rel}`;
119
124
  }
120
125
 
121
126
  let cliBootstrapPromise = null;
@@ -247,8 +252,8 @@ Experimental:
247
252
  --build-for <target> Build a Bun single-file executable for target`);
248
253
  }
249
254
 
250
- function printMarkdownFile(filePath) {
251
- const text = readTextFile(filePath);
255
+ function printMarkdownFile(key) {
256
+ const text = assetText(key);
252
257
  const markdownAnsi =
253
258
  typeof Bun !== "undefined" &&
254
259
  Bun &&
@@ -259,10 +264,6 @@ function printMarkdownFile(filePath) {
259
264
  console.log(markdownAnsi ? markdownAnsi(text, { hyperlinks: true }) : text);
260
265
  }
261
266
 
262
- function printWebHelp() {
263
- printMarkdownFile(DEFAULT_HELP);
264
- }
265
-
266
267
  function fatal(message, code = 1) {
267
268
  console.error(message);
268
269
  process.exit(code);
@@ -510,15 +511,15 @@ function parseArgs(argv) {
510
511
  process.exit(0);
511
512
  break;
512
513
  case "--help-web":
513
- printWebHelp();
514
+ printMarkdownFile("static/help.md");
514
515
  process.exit(0);
515
516
  break;
516
517
  case "--readme":
517
- printMarkdownFile(DEFAULT_README);
518
+ printMarkdownFile("README.md");
518
519
  process.exit(0);
519
520
  break;
520
521
  case "--readme-en":
521
- printMarkdownFile(DEFAULT_README_EN);
522
+ printMarkdownFile("README.en.md");
522
523
  process.exit(0);
523
524
  break;
524
525
  case "--address":
@@ -664,36 +665,6 @@ function previewBuffer(buffer, limit = 96) {
664
665
  });
665
666
  }
666
667
 
667
- function readTextFile(filePath) {
668
- const bundledText = helperReadInternalAssetText?.(internalAssetPathFor(filePath));
669
- if (bundledText == null) {
670
- return fs.readFileSync(filePath, "utf8");
671
- }
672
- return bundledText;
673
- }
674
-
675
- function internalAssetPathFor(filePath) {
676
- if (!helperAssetPath) {
677
- return filePath;
678
- }
679
-
680
- const normalizedPath = path.normalize(filePath);
681
- const staticRelativePath = path.relative(STATIC_ROOT, normalizedPath);
682
- if (staticRelativePath && !staticRelativePath.startsWith("..") && !path.isAbsolute(staticRelativePath)) {
683
- return helperAssetPath("static", staticRelativePath);
684
- }
685
-
686
- if (normalizedPath === DEFAULT_README) {
687
- return helperAssetPath("README.md");
688
- }
689
-
690
- if (normalizedPath === DEFAULT_README_EN) {
691
- return helperAssetPath("README.en.md");
692
- }
693
-
694
- return filePath;
695
- }
696
-
697
668
  function contentType(filePath) {
698
669
  const ext = path.extname(filePath).toLowerCase();
699
670
  switch (ext) {
@@ -1357,10 +1328,26 @@ class NodePtyBackend {
1357
1328
  constructor(options) {
1358
1329
  let nodePty;
1359
1330
  try {
1331
+ // Split so the bundler cannot resolve it. This branch is unreachable
1332
+ // in a compiled binary (Bun >= 1.3.14 always takes BunPtyBackend), so
1333
+ // a static require would only bake ~54 KB of dead JS into the exe —
1334
+ // and node-pty's own `.node` loading is dynamic anyway, so it would
1335
+ // still need the files on disk.
1360
1336
  let preventSingleExe="./lib/"
1361
1337
  nodePty = require(preventSingleExe+"node-pty");
1362
1338
  } catch (error) {
1363
- throw new Error("node-pty is required on Windows but is not installed");
1339
+ const detail = error && error.message ? `: ${error.message}` : "";
1340
+ throw new Error(
1341
+ globalThis.Bun
1342
+ ? "This build falls back to node-pty because Bun " + globalThis.Bun.version
1343
+ + " is older than 1.3.14, which is where the built-in ConPTY backend landed. "
1344
+ + "A compiled binary cannot load node-pty — it is deliberately left out of the "
1345
+ + "bundle — so rebuild with Bun 1.3.14 or newer, or run from a source checkout "
1346
+ + "with node-pty installed" + detail
1347
+ : "node-pty is required to run under Node on Windows, and it could not be loaded "
1348
+ + "from ./lib/node-pty. Run with Bun 1.3.14 or newer to use the built-in ConPTY "
1349
+ + "backend instead" + detail,
1350
+ );
1364
1351
  }
1365
1352
 
1366
1353
  const system32 = path.join(process.env.windir, 'System32');
@@ -2659,8 +2646,10 @@ function createServerRuntime(command, argv, options) {
2659
2646
  );
2660
2647
  const wsPath = `${basePath}ws`;
2661
2648
  const originMatcher = options.wsOrigin ? new RegExp(options.wsOrigin) : null;
2662
- const indexTemplate = readTextFile(options.index ? expandHome(options.index) : DEFAULT_INDEX);
2663
- const manifestTemplate = readTextFile(DEFAULT_MANIFEST);
2649
+ const indexTemplate = options.index
2650
+ ? fs.readFileSync(expandHome(options.index), "utf8")
2651
+ : assetText("static/index.html");
2652
+ const manifestTemplate = assetText("static/manifest.json");
2664
2653
  const activeSessions = new Set();
2665
2654
  const reconnectRegistry = new Map();
2666
2655
  let acceptedOnce = false;
@@ -2784,7 +2773,7 @@ function createServerRuntime(command, argv, options) {
2784
2773
  }
2785
2774
 
2786
2775
  if (relativePath === "help.md" || relativePath === "help") {
2787
- const markdown = readTextFile(DEFAULT_HELP);
2776
+ const markdown = assetText("static/help.md");
2788
2777
  const markdownToHtml = global.Bun?.markdown?.html;
2789
2778
  const renderHtml = relativePath === "help" && typeof markdownToHtml === "function";
2790
2779
  const body = renderHtml
@@ -2865,18 +2854,18 @@ function createServerRuntime(command, argv, options) {
2865
2854
  return;
2866
2855
  }
2867
2856
 
2868
- const assetPath = path.normalize(path.join(STATIC_ROOT, relativePath));
2869
- if (!assetPath.startsWith(STATIC_ROOT)) {
2857
+ const assetKey = staticAssetKey(relativePath);
2858
+ if (!assetKey) {
2870
2859
  res.writeHead(403);
2871
2860
  res.end("Forbidden");
2872
2861
  return;
2873
2862
  }
2874
2863
 
2875
- const bundledAsset = helperReadInternalAssetBytes?.(internalAssetPathFor(assetPath));
2864
+ const bundledAsset = assets?.readInternalAssetBytes(assetKey);
2876
2865
  if (bundledAsset != null) {
2877
2866
  const body = bundledAsset instanceof Uint8Array ? bundledAsset : new Uint8Array(bundledAsset);
2878
2867
  res.writeHead(200, {
2879
- "Content-Type": contentType(assetPath),
2868
+ "Content-Type": contentType(assetKey),
2880
2869
  "Content-Length": body.length,
2881
2870
  "Server": "GoTTY"
2882
2871
  });
@@ -2884,7 +2873,8 @@ function createServerRuntime(command, argv, options) {
2884
2873
  return;
2885
2874
  }
2886
2875
 
2887
- fs.stat(assetPath, (error, stats) => {
2876
+ const externalPath = assetFilePath(assetKey);
2877
+ fs.stat(externalPath, (error, stats) => {
2888
2878
  if (error || !stats.isFile()) {
2889
2879
  res.writeHead(404, { "Server": "GoTTY" });
2890
2880
  res.end("Not Found");
@@ -2892,11 +2882,11 @@ function createServerRuntime(command, argv, options) {
2892
2882
  }
2893
2883
 
2894
2884
  res.writeHead(200, {
2895
- "Content-Type": contentType(assetPath),
2885
+ "Content-Type": contentType(assetKey),
2896
2886
  "Content-Length": stats.size,
2897
2887
  "Server": "GoTTY"
2898
2888
  });
2899
- fs.createReadStream(assetPath).pipe(res);
2889
+ fs.createReadStream(externalPath).pipe(res);
2900
2890
  });
2901
2891
  };
2902
2892
 
@@ -3290,15 +3280,9 @@ function main() {
3290
3280
  async function bootstrap() {
3291
3281
  try {
3292
3282
  const compiledHelper = await compiledHelperPromise;
3293
- configureResourceRoot(compiledHelper);
3294
3283
  await compiledHelper?.buildEarlyExit?.(process.argv,'jsgt');
3295
3284
 
3296
- const assetsHelper = await assetsHelperPromise;
3297
- if (assetsHelper) {
3298
- helperAssetPath = assetsHelper.assetPath;
3299
- helperReadInternalAssetText = assetsHelper.readInternalAssetText;
3300
- helperReadInternalAssetBytes = assetsHelper.readInternalAssetBytes;
3301
- }
3285
+ assets = await assetsHelperPromise;
3302
3286
  await globalThis.assetsLoaderPromise;
3303
3287
  } catch (error) {
3304
3288
  console.error(String(error && error.stack ? error.stack : error));
@@ -3323,3 +3307,8 @@ if (require.main === module) {
3323
3307
  process.exitCode = 1;
3324
3308
  });
3325
3309
  }
3310
+
3311
+ // The guard above is inlined to false once this file is bundled, because
3312
+ // the bundle entry point is single-exe/entry.mjs rather than this file.
3313
+ // Export the starter so that entry point can call it.
3314
+ module.exports.bootstrap = bootstrap;
@@ -1,11 +1,16 @@
1
1
  {
2
2
  "name": "jsgotty",
3
- "version": "1.1.5",
3
+ "version": "1.1.9",
4
4
  "description": "Share your terminal as a web application: A JavaScript rewrite of GoTTY",
5
5
  "bin": {
6
6
  "jsgotty": "./gotty.js"
7
7
  },
8
8
  "type": "commonjs",
9
+ "assets": [
10
+ "static",
11
+ "README.md",
12
+ "README.en.md"
13
+ ],
9
14
  "dependencies": {
10
15
  "node-addon-api": "^7.1.1",
11
16
  "ws": "^8.18.3"