buninu-linux 0.7.2 → 0.7.3

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.
@@ -19,3 +19,103 @@ Included third-party component:
19
19
 
20
20
  The bundled file [static/js/zmodem.js] is byte-for-byte identical to the
21
21
  upstream npm release zmodem.js version 0.1.10 dist/zmodem.js.
22
+
23
+ 2. ConPTY - Windows pseudoconsole library and console host
24
+ (conpty/conpty.dll, conpty/OpenConsole.exe), part of Windows Terminal
25
+ Copyright (c) Microsoft Corporation. All rights reserved.
26
+ Licensed under the MIT License
27
+ Upstream: https://github.com/microsoft/terminal
28
+ Local copy of license text:
29
+ LICENSES/MIT-microsoft-terminal-conpty.txt
30
+ Upstream third-party notices for Windows Terminal:
31
+ LICENSES/NOTICE-microsoft-terminal-conpty.md
32
+
33
+ The bundled files in [conpty/] are byte-for-byte identical to the win-x64
34
+ binaries in the official NuGet package
35
+ Microsoft.Windows.Console.ConPTY 1.25.260710002-preview, published with the
36
+ Windows Terminal Preview v1.25.1912.0 release
37
+ (https://github.com/microsoft/terminal/releases/tag/v1.25.1912.0):
38
+
39
+ conpty/conpty.dll (runtimes/win-x64/native/conpty.dll)
40
+ SHA-256 e2fe87e2258c4e46ffc5157f727218cc25f34a174902f72eb8a5b49edd9a6458
41
+ conpty/OpenConsole.exe (build/native/runtimes/x64/OpenConsole.exe)
42
+ SHA-256 2525c351aa136d555e5df9a3c9d6ce9be43f785e37e3c993b8f23b3f0a53c7fa
43
+
44
+ The license and notice files are taken verbatim from the microsoft/terminal
45
+ repository at tag v1.25.1912.0. The notice file lists third-party components
46
+ used across Windows Terminal; it is included in full because the subset built
47
+ into these two binaries is not documented separately.
48
+
49
+ 3. node-pty 1.1.0 - forkpty(3) bindings for Node.js (lib/node-pty)
50
+ Copyright (c) 2012-2015, Christopher Jeffrey
51
+ Copyright (c) 2016, Daniel Imms
52
+ Copyright (c) 2018 - present Microsoft Corporation
53
+ Licensed under the MIT License
54
+ Upstream: https://github.com/microsoft/node-pty
55
+ License text: lib/node-pty/LICENSE
56
+
57
+ node-pty in turn bundles:
58
+
59
+ a. winpty 0.4.4-dev (lib/node-pty/deps/winpty,
60
+ lib/node-pty/prebuilds/win32-*/winpty.dll and winpty-agent.exe)
61
+ Copyright (c) 2011-2016 Ryan Prichard
62
+ Licensed under the MIT License
63
+ Upstream: https://github.com/rprichard/winpty
64
+ License text: lib/node-pty/deps/winpty/LICENSE
65
+
66
+ b. ConPTY 1.23.251008001 from Windows Terminal
67
+ (lib/node-pty/prebuilds/win32-*/conpty/conpty.dll and OpenConsole.exe)
68
+ Copyright (c) Microsoft Corporation. All rights reserved.
69
+ Licensed under the MIT License; see item 2 for the license and
70
+ Windows Terminal notice files.
71
+
72
+ The prebuilt binaries under [lib/node-pty/prebuilds] and the license files
73
+ lib/node-pty/LICENSE and lib/node-pty/deps/winpty/LICENSE are byte-for-byte
74
+ identical to those in the upstream npm release node-pty 1.1.0; they are not
75
+ rebuilt by this project.
76
+
77
+ The files in [patches/] (windowsPtyAgent.js, windowsTerminal.js) are modified
78
+ copies of node-pty source files; they keep node-pty's copyright headers and
79
+ remain under its MIT License.
80
+
81
+ 4. npm dependencies committed under [node_modules/]
82
+
83
+ a. ws 8.21.0 - WebSocket client and server
84
+ Copyright (c) 2011 Einar Otto Stangvik
85
+ Copyright (c) 2013 Arnout Kazemier and contributors
86
+ Copyright (c) 2016 Luigi Pinca and contributors
87
+ Licensed under the MIT License
88
+ License text: node_modules/ws/LICENSE (also LICENSES/MIT-ws.txt,
89
+ which single executables carry because ws is bundled into them)
90
+
91
+ b. node-addon-api 7.1.1 - C++ headers used to build node-pty
92
+ Copyright (c) 2017 Node.js API collaborators
93
+ Licensed under the MIT License
94
+ License text: node_modules/node-addon-api/LICENSE.md
95
+
96
+ 5. Web client assets under [static/]
97
+
98
+ static/js/gotty.js is a webpack bundle. The licenses of every package it
99
+ contains (xterm.js and its fit, web-links, webgl and unicode11 addons,
100
+ Bootstrap, Popper, Preact, crc-32, zmodem.js, css-loader, style-loader)
101
+ are listed in static/js/gotty.licenses.txt, with the retained banners in
102
+ static/js/gotty.js.LICENSE.txt.
103
+
104
+ static/js/xterm-addon-unicode11.js is byte-for-byte identical to
105
+ lib/addon-unicode11.js of the npm release @xterm/addon-unicode11 0.9.0, and
106
+ static/css/xterm.css comes from xterm.js
107
+ (Copyright (c) 2014 The xterm.js authors; Copyright (c) 2012-2013
108
+ Christopher Jeffrey; MIT License, text in static/js/gotty.licenses.txt).
109
+
110
+ static/favicon.ico, static/icon.svg and static/icon_192.png are
111
+ byte-for-byte identical to the icons of GoTTY
112
+ (https://github.com/sorenisanerd/gotty), covered by the MIT License and
113
+ the GoTTY copyright notices in LICENSE.
114
+
115
+ Single executables built with --build-exe / --build-for embed the Bun
116
+ runtime. Bun is MIT-licensed but statically links JavaScriptCore and WebKit
117
+ (LGPL-2) and other libraries under their own licenses; anyone distributing
118
+ such an executable must also follow Bun's license terms, including the LGPL
119
+ relinking provisions described at
120
+ https://github.com/oven-sh/bun/blob/main/LICENSE.md. The executables carry
121
+ LICENSE, NOTICE and LICENSES/ as embedded assets.
@@ -115,6 +115,26 @@ function assetFilePath(key) {
115
115
  return assets ? assets.assetDiskPath(key) : path.join(__dirname, key);
116
116
  }
117
117
 
118
+ function windowsConptyDllPath() {
119
+ const dll = assetFilePath("conpty/conpty.dll");
120
+ if (fs.existsSync(dll)) return dll;
121
+ if (!assets) return null;
122
+ try {
123
+ const dllBytes = assets.readAssetBytesSync("conpty/conpty.dll");
124
+ const hostBytes = assets.readAssetBytesSync("conpty/OpenConsole.exe");
125
+ const version = crypto.createHash("sha256").update(dllBytes).digest("hex").slice(0, 16);
126
+ const dir = path.join(os.tmpdir(), `jsgotty-conpty-${version}`);
127
+ fs.mkdirSync(dir, { recursive: true });
128
+ for (const [name, bytes] of [["conpty.dll", dllBytes], ["OpenConsole.exe", hostBytes]]) {
129
+ const dest = path.join(dir, name);
130
+ if (!fs.existsSync(dest)) fs.writeFileSync(dest, bytes);
131
+ }
132
+ return path.join(dir, "conpty.dll");
133
+ } catch (error) {
134
+ throw new Error(`Could not prepare bundled ConPTY: ${error.message}`);
135
+ }
136
+ }
137
+
118
138
  // URL-relative path -> asset key, or null when it escapes `static/`.
119
139
  // Normalizing against "/" is what makes "../../etc/passwd" unreachable.
120
140
  function staticAssetKey(relativePath) {
@@ -1624,6 +1644,10 @@ function createPtyBackend(options) {
1624
1644
  if (globalThis.Bun?.semver?.satisfies?.(
1625
1645
  globalThis.Bun?.version, ">=1.3.14"
1626
1646
  )) {
1647
+ const conptyDll = windowsConptyDllPath();
1648
+ if (conptyDll) {
1649
+ return new (require("./windows-conpty.js"))(options, conptyDll);
1650
+ }
1627
1651
  return new BunPtyBackend(options);
1628
1652
  }
1629
1653
  return new NodePtyBackend(options);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "jsgotty",
3
- "version": "1.1.11",
3
+ "version": "1.1.14",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "jsgotty",
9
- "version": "1.1.11",
9
+ "version": "1.1.14",
10
10
  "dependencies": {
11
11
  "node-addon-api": "^7.1.1",
12
12
  "ws": "^8.18.3"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsgotty",
3
- "version": "1.1.12",
3
+ "version": "1.1.14",
4
4
  "description": "Share your terminal as a web application: A JavaScript rewrite of GoTTY",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -8,9 +8,13 @@
8
8
  },
9
9
  "type": "commonjs",
10
10
  "assets": [
11
+ "conpty",
11
12
  "static",
12
13
  "README.md",
13
- "README.en.md"
14
+ "README.en.md",
15
+ "LICENSE",
16
+ "NOTICE",
17
+ "LICENSES"
14
18
  ],
15
19
  "dependencies": {
16
20
  "node-addon-api": "^7.1.1",
@@ -0,0 +1,135 @@
1
+ // Windows PTY adapter for the out-of-band Microsoft Console package.
2
+ // Keep the same interface as BunPtyBackend in gotty.js.
3
+ const { dlopen, ptr } = require("bun:ffi");
4
+ const path = require("path");
5
+
6
+ const kernel = dlopen("kernel32.dll", {
7
+ CreatePipe: { args: ["ptr", "ptr", "ptr", "u32"], returns: "i32" },
8
+ InitializeProcThreadAttributeList: { args: ["ptr", "u32", "u32", "ptr"], returns: "i32" },
9
+ UpdateProcThreadAttribute: { args: ["ptr", "u32", "usize", "ptr", "usize", "ptr", "ptr"], returns: "i32" },
10
+ DeleteProcThreadAttributeList: { args: ["ptr"], returns: "void" },
11
+ CreateProcessW: { args: ["ptr", "ptr", "ptr", "ptr", "i32", "u32", "ptr", "ptr", "ptr", "ptr"], returns: "i32" },
12
+ PeekNamedPipe: { args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"], returns: "i32" },
13
+ ReadFile: { args: ["ptr", "ptr", "u32", "ptr", "ptr"], returns: "i32" },
14
+ WriteFile: { args: ["ptr", "ptr", "u32", "ptr", "ptr"], returns: "i32" },
15
+ GetExitCodeProcess: { args: ["ptr", "ptr"], returns: "i32" },
16
+ TerminateProcess: { args: ["ptr", "u32"], returns: "i32" },
17
+ CloseHandle: { args: ["ptr"], returns: "i32" },
18
+ GetLastError: { args: [], returns: "u32" },
19
+ }).symbols;
20
+
21
+ const conptySymbols = {
22
+ ConptyCreatePseudoConsole: { args: ["u32", "ptr", "ptr", "u32", "ptr"], returns: "i32" },
23
+ ConptyResizePseudoConsole: { args: ["ptr", "u32"], returns: "i32" },
24
+ ConptyClosePseudoConsole: { args: ["ptr"], returns: "void" },
25
+ };
26
+ const wide = (value) => Buffer.from(`${value}\0`, "utf16le");
27
+ const handle = (buffer) => Number(buffer.readBigUInt64LE(0));
28
+ const size = (cols, rows) => ((Math.max(1, rows) & 0xffff) << 16) | (Math.max(1, cols) & 0xffff);
29
+ const winError = (operation) => new Error(`${operation} failed: ${kernel.GetLastError()}`);
30
+ // Windows CRT argv escaping: double backslashes before quotes and at the end.
31
+ function quoteArg(value) {
32
+ let result = '"', slashes = 0;
33
+ for (const char of String(value)) {
34
+ if (char === "\\") { slashes++; continue; }
35
+ if (char === '"') result += "\\".repeat(slashes * 2 + 1) + '"';
36
+ else result += "\\".repeat(slashes) + char;
37
+ slashes = 0;
38
+ }
39
+ return result + "\\".repeat(slashes * 2) + '"';
40
+ }
41
+
42
+ class WindowsConptyBackend {
43
+ constructor(options, dllPath) {
44
+ this.options = options;
45
+ this.dataHandlers = [];
46
+ this.exitHandlers = [];
47
+ this.closed = false;
48
+ this.conpty = dlopen(path.resolve(dllPath), conptySymbols).symbols;
49
+ const inputRead = Buffer.alloc(8), inputWrite = Buffer.alloc(8);
50
+ const outputRead = Buffer.alloc(8), outputWrite = Buffer.alloc(8);
51
+ if (!kernel.CreatePipe(inputRead, inputWrite, 0, 0)) throw winError("CreatePipe input");
52
+ if (!kernel.CreatePipe(outputRead, outputWrite, 0, 0)) throw winError("CreatePipe output");
53
+ this.input = handle(inputWrite);
54
+ this.output = handle(outputRead);
55
+ const pseudo = Buffer.alloc(8);
56
+ const hr = this.conpty.ConptyCreatePseudoConsole(
57
+ size(options.width || 80, options.height || 24), handle(inputRead), handle(outputWrite), 0, pseudo);
58
+ kernel.CloseHandle(handle(inputRead));
59
+ kernel.CloseHandle(handle(outputWrite));
60
+ if (hr !== 0) throw new Error(`ConptyCreatePseudoConsole failed: ${hr}`);
61
+ this.pseudo = handle(pseudo);
62
+
63
+ const listSize = Buffer.alloc(8);
64
+ kernel.InitializeProcThreadAttributeList(0, 1, 0, listSize);
65
+ const list = Buffer.alloc(Number(listSize.readBigUInt64LE(0)));
66
+ if (!kernel.InitializeProcThreadAttributeList(list, 1, 0, listSize)) throw winError("InitializeProcThreadAttributeList");
67
+ if (!kernel.UpdateProcThreadAttribute(list, 0, 0x00020016, this.pseudo, 8, 0, 0)) throw winError("UpdateProcThreadAttribute");
68
+ const startup = Buffer.alloc(112);
69
+ startup.writeUInt32LE(112, 0);
70
+ startup.writeUInt32LE(0x100, 60); // STARTF_USESTDHANDLES
71
+ startup.writeBigUInt64LE(BigInt(ptr(list)), 104);
72
+ const processInfo = Buffer.alloc(24);
73
+ const env = { ...process.env, TERM: "xterm-256color", ...(options.headerEnv || {}) };
74
+ const envBlock = wide(Object.entries(env).filter(([key]) => !key.startsWith("="))
75
+ .map(([key, value]) => `${key}=${value}`).join("\0") + "\0");
76
+ const executable = Bun.which(options.command) || options.command;
77
+ const command = wide([executable, ...options.argv].map(quoteArg).join(" "));
78
+ const ok = kernel.CreateProcessW(wide(executable), command, 0, 0, 0,
79
+ 0x00080000 | 0x00000400, envBlock, wide(process.cwd()), startup, processInfo);
80
+ kernel.DeleteProcThreadAttributeList(list);
81
+ if (!ok) throw winError("CreateProcessW");
82
+ this.process = handle(processInfo);
83
+ this.pid = processInfo.readUInt32LE(16);
84
+ kernel.CloseHandle(Number(processInfo.readBigUInt64LE(8)));
85
+ this.pollTimer = setInterval(() => this.poll(), 5);
86
+ }
87
+
88
+ onData(handler) { this.dataHandlers.push(handler); }
89
+ onExit(handler) { this.exitHandlers.push(handler); }
90
+ write(buffer) { this.writeBinary(buffer); }
91
+ writeBinary(buffer) {
92
+ const data = Buffer.from(buffer);
93
+ const written = Buffer.alloc(4);
94
+ for (let offset = 0; offset < data.length;) {
95
+ const chunk = data.subarray(offset);
96
+ if (!kernel.WriteFile(this.input, chunk, chunk.length, written, 0)) throw winError("WriteFile");
97
+ const count = written.readUInt32LE(0);
98
+ if (!count) throw new Error("WriteFile wrote no data");
99
+ offset += count;
100
+ }
101
+ }
102
+ resize(cols, rows) {
103
+ const hr = this.conpty.ConptyResizePseudoConsole(this.pseudo, size(cols, rows));
104
+ if (hr !== 0) throw new Error(`ConptyResizePseudoConsole failed: ${hr}`);
105
+ }
106
+ kill() { if (!this.closed) kernel.TerminateProcess(this.process, 1); }
107
+ close() { this.kill(); }
108
+
109
+ poll() {
110
+ if (this.closed) return;
111
+ const available = Buffer.alloc(4), readCount = Buffer.alloc(4);
112
+ if (kernel.PeekNamedPipe(this.output, 0, 0, 0, available, 0)) {
113
+ for (let bytes = available.readUInt32LE(0); bytes > 0; bytes = available.readUInt32LE(0)) {
114
+ const data = Buffer.alloc(Math.min(bytes, 65536));
115
+ if (!kernel.ReadFile(this.output, data, data.length, readCount, 0)) break;
116
+ const count = readCount.readUInt32LE(0);
117
+ if (!count) break;
118
+ for (const handler of this.dataHandlers) handler(data.subarray(0, count));
119
+ if (!kernel.PeekNamedPipe(this.output, 0, 0, 0, available, 0)) break;
120
+ }
121
+ }
122
+ const exitCode = Buffer.alloc(4);
123
+ if (kernel.GetExitCodeProcess(this.process, exitCode) && exitCode.readUInt32LE(0) !== 259) {
124
+ this.closed = true;
125
+ clearInterval(this.pollTimer);
126
+ this.conpty.ConptyClosePseudoConsole(this.pseudo);
127
+ kernel.CloseHandle(this.input);
128
+ kernel.CloseHandle(this.output);
129
+ kernel.CloseHandle(this.process);
130
+ for (const handler of this.exitHandlers) handler();
131
+ }
132
+ }
133
+ }
134
+
135
+ module.exports = WindowsConptyBackend;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu",
3
- "version": "0.4.17",
3
+ "version": "0.4.18",
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buninu-linux",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "description": "A Linux distribution running Bun as PID 1 with the Buninu userspace.",
5
5
  "type": "module",
6
6
  "main": "./index.js",