node-pty 1.2.0-beta.15 → 1.2.0-beta.16
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/lib/unixTerminal.js +4 -0
- package/lib/windowsPtyAgent.js +9 -0
- package/lib/windowsTerminal.js +5 -0
- package/package.json +15 -4
- package/prebuilds/darwin-arm64/pty.node +0 -0
- package/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/prebuilds/darwin-x64/pty.node +0 -0
- package/prebuilds/darwin-x64/spawn-helper +0 -0
- package/prebuilds/linux-arm64/pty.node +0 -0
- package/prebuilds/linux-x64/pty.node +0 -0
- package/prebuilds/win32-arm64/conpty.node +0 -0
- package/prebuilds/win32-arm64/conpty.pdb +0 -0
- package/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
- package/prebuilds/win32-x64/conpty.node +0 -0
- package/prebuilds/win32-x64/conpty.pdb +0 -0
- package/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
- package/src/win/conpty.cc +69 -3
- package/typings/node-pty.d.ts +17 -0
package/lib/unixTerminal.js
CHANGED
|
@@ -261,6 +261,10 @@ var UnixTerminal = /** @class */ (function (_super) {
|
|
|
261
261
|
};
|
|
262
262
|
UnixTerminal.prototype.clear = function () {
|
|
263
263
|
};
|
|
264
|
+
UnixTerminal.prototype.setParentWindow = function (handle) {
|
|
265
|
+
// Windows only
|
|
266
|
+
return false;
|
|
267
|
+
};
|
|
264
268
|
UnixTerminal.prototype._sanitizeEnv = function (env) {
|
|
265
269
|
// Make sure we didn't start our server from inside tmux.
|
|
266
270
|
delete env['TMUX'];
|
package/lib/windowsPtyAgent.js
CHANGED
|
@@ -181,6 +181,15 @@ var WindowsPtyAgent = /** @class */ (function () {
|
|
|
181
181
|
WindowsPtyAgent.prototype.clear = function () {
|
|
182
182
|
this._ptyNative.clear(this._pty, this._useConptyDll);
|
|
183
183
|
};
|
|
184
|
+
/**
|
|
185
|
+
* Tells ConPTY which top-level window hosts the terminal (ConptyReparentPseudoConsole). The
|
|
186
|
+
* window becomes the owner of the console window returned by GetConsoleWindow(), so dialogs
|
|
187
|
+
* that console apps parent to it (e.g. WAM sign-in) stack above the host window. Returns
|
|
188
|
+
* whether the request was sent to ConPTY, which applies it asynchronously.
|
|
189
|
+
*/
|
|
190
|
+
WindowsPtyAgent.prototype.setParentWindow = function (handle) {
|
|
191
|
+
return this._ptyNative.reparent(this._pty, handle, this._useConptyDll);
|
|
192
|
+
};
|
|
184
193
|
WindowsPtyAgent.prototype.kill = function () {
|
|
185
194
|
var _this = this;
|
|
186
195
|
// Prevent deferred connection from completing after kill
|
package/lib/windowsTerminal.js
CHANGED
|
@@ -148,6 +148,11 @@ var WindowsTerminal = /** @class */ (function (_super) {
|
|
|
148
148
|
_this._agent.clear();
|
|
149
149
|
});
|
|
150
150
|
};
|
|
151
|
+
WindowsTerminal.prototype.setParentWindow = function (handle) {
|
|
152
|
+
// Not deferred: the pseudoconsole exists as soon as the agent is created, and the owner
|
|
153
|
+
// should be requested before the shell starts asking for it.
|
|
154
|
+
return this._agent.setParentWindow(handle);
|
|
155
|
+
};
|
|
151
156
|
WindowsTerminal.prototype.destroy = function () {
|
|
152
157
|
var _this = this;
|
|
153
158
|
this._deferNoArgs(function () {
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Microsoft Corporation"
|
|
6
6
|
},
|
|
7
|
-
"version": "1.2.0-beta.
|
|
7
|
+
"version": "1.2.0-beta.16",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"main": "./lib/index.js",
|
|
10
10
|
"types": "./typings/node-pty.d.ts",
|
|
@@ -27,6 +27,18 @@
|
|
|
27
27
|
"bugs": {
|
|
28
28
|
"url": "https://github.com/microsoft/node-pty/issues"
|
|
29
29
|
},
|
|
30
|
+
"devEngines": {
|
|
31
|
+
"runtime": {
|
|
32
|
+
"name": "node",
|
|
33
|
+
"version": ">=24",
|
|
34
|
+
"onFail": "error"
|
|
35
|
+
},
|
|
36
|
+
"packageManager": {
|
|
37
|
+
"name": "npm",
|
|
38
|
+
"version": ">=11.6.3",
|
|
39
|
+
"onFail": "error"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
30
42
|
"keywords": [
|
|
31
43
|
"pty",
|
|
32
44
|
"tty",
|
|
@@ -51,15 +63,14 @@
|
|
|
51
63
|
"node-addon-api": "^7.1.0"
|
|
52
64
|
},
|
|
53
65
|
"devDependencies": {
|
|
54
|
-
"@types/mocha": "^
|
|
66
|
+
"@types/mocha": "^10.0.10",
|
|
55
67
|
"@types/node": "12",
|
|
56
68
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
57
69
|
"@typescript-eslint/parser": "^8.0.0",
|
|
58
70
|
"cross-env": "^5.1.4",
|
|
59
71
|
"eslint": "^10.4.0",
|
|
60
72
|
"globals": "^14.0.0",
|
|
61
|
-
"mocha": "
|
|
62
|
-
"node-gyp": "^11.4.2",
|
|
73
|
+
"mocha": "12.0.2",
|
|
63
74
|
"ps-list": "^6.0.0",
|
|
64
75
|
"typescript": "^5.0.0"
|
|
65
76
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/win/conpty.cc
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#include <assert.h>
|
|
16
16
|
#include <Shlwapi.h> // PathCombine, PathIsRelative
|
|
17
17
|
#include <atomic>
|
|
18
|
+
#include <cstring>
|
|
18
19
|
#include <mutex>
|
|
19
20
|
#include <sstream>
|
|
20
21
|
#include <iostream>
|
|
@@ -40,6 +41,9 @@ typedef void (__stdcall *PFNRELEASEPSEUDOCONSOLE)(HPCON hpc);
|
|
|
40
41
|
|
|
41
42
|
#endif
|
|
42
43
|
|
|
44
|
+
// Only exported by the bundled conpty.dll; kernel32 has no equivalent.
|
|
45
|
+
typedef HRESULT (__stdcall *PFNREPARENTPSEUDOCONSOLE)(HPCON hpc, HWND newParent);
|
|
46
|
+
|
|
43
47
|
struct pty_baton {
|
|
44
48
|
int id;
|
|
45
49
|
HANDLE hIn;
|
|
@@ -495,7 +499,7 @@ static Napi::Value PtyResize(const Napi::CallbackInfo& info) {
|
|
|
495
499
|
std::lock_guard<std::mutex> lock(g_ptyHandlesMutex);
|
|
496
500
|
const pty_baton* handle = get_pty_baton(lock, id);
|
|
497
501
|
|
|
498
|
-
if (handle != nullptr) {
|
|
502
|
+
if (handle != nullptr && handle->hpc != nullptr) {
|
|
499
503
|
HANDLE hLibrary = LoadConptyDll(info, useConptyDll);
|
|
500
504
|
bool fLoadedDll = hLibrary != nullptr;
|
|
501
505
|
if (fLoadedDll)
|
|
@@ -537,7 +541,7 @@ static Napi::Value PtyClear(const Napi::CallbackInfo& info) {
|
|
|
537
541
|
std::lock_guard<std::mutex> lock(g_ptyHandlesMutex);
|
|
538
542
|
const pty_baton* handle = get_pty_baton(lock, id);
|
|
539
543
|
|
|
540
|
-
if (handle != nullptr) {
|
|
544
|
+
if (handle != nullptr && handle->hpc != nullptr) {
|
|
541
545
|
HANDLE hLibrary = LoadConptyDll(info, useConptyDll);
|
|
542
546
|
bool fLoadedDll = hLibrary != nullptr;
|
|
543
547
|
if (fLoadedDll)
|
|
@@ -553,6 +557,65 @@ static Napi::Value PtyClear(const Napi::CallbackInfo& info) {
|
|
|
553
557
|
return env.Undefined();
|
|
554
558
|
}
|
|
555
559
|
|
|
560
|
+
// The handle is the bytes of an HWND in native byte order, which is how Electron's
|
|
561
|
+
// BrowserWindow.getNativeWindowHandle() returns it.
|
|
562
|
+
static bool TryGetWindowHandle(const Napi::Value& value, HWND* hwnd) {
|
|
563
|
+
if (!value.IsBuffer()) {
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
566
|
+
const auto buffer = value.As<Napi::Buffer<uint8_t>>();
|
|
567
|
+
if (buffer.Length() != sizeof(HWND)) {
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
std::memcpy(hwnd, buffer.Data(), sizeof(*hwnd));
|
|
571
|
+
return true;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
static Napi::Value PtyReparent(const Napi::CallbackInfo& info) {
|
|
575
|
+
Napi::Env env(info.Env());
|
|
576
|
+
Napi::HandleScope scope(env);
|
|
577
|
+
|
|
578
|
+
if (info.Length() != 3 ||
|
|
579
|
+
!info[0].IsNumber() ||
|
|
580
|
+
!info[2].IsBoolean()) {
|
|
581
|
+
throw Napi::Error::New(env, "Usage: pty.reparent(id, hwnd, useConptyDll)");
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
int id = info[0].As<Napi::Number>().Int32Value();
|
|
585
|
+
HWND newParent;
|
|
586
|
+
if (!TryGetWindowHandle(info[1], &newParent)) {
|
|
587
|
+
throw Napi::Error::New(env, "pty.reparent: hwnd must be a Buffer the size of an HWND");
|
|
588
|
+
}
|
|
589
|
+
const bool useConptyDll = info[2].As<Napi::Boolean>().Value();
|
|
590
|
+
|
|
591
|
+
// ConptyReparentPseudoConsole only exists in the bundled conpty.dll.
|
|
592
|
+
if (!useConptyDll) {
|
|
593
|
+
return Napi::Boolean::New(env, false);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
std::lock_guard<std::mutex> lock(g_ptyHandlesMutex);
|
|
597
|
+
const pty_baton* handle = get_pty_baton(lock, id);
|
|
598
|
+
|
|
599
|
+
bool sent = false;
|
|
600
|
+
if (handle != nullptr && handle->hpc != nullptr) {
|
|
601
|
+
HANDLE hLibrary = LoadConptyDll(info, useConptyDll);
|
|
602
|
+
bool fLoadedDll = hLibrary != nullptr;
|
|
603
|
+
if (fLoadedDll)
|
|
604
|
+
{
|
|
605
|
+
PFNREPARENTPSEUDOCONSOLE const pfnReparentPseudoConsole = (PFNREPARENTPSEUDOCONSOLE)GetProcAddress(
|
|
606
|
+
(HMODULE)hLibrary, "ConptyReparentPseudoConsole");
|
|
607
|
+
if (pfnReparentPseudoConsole)
|
|
608
|
+
{
|
|
609
|
+
// Asks ConPTY to make newParent the owner of the console window returned by
|
|
610
|
+
// GetConsoleWindow(); ConPTY applies it asynchronously.
|
|
611
|
+
sent = SUCCEEDED(pfnReparentPseudoConsole(handle->hpc, newParent));
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
return Napi::Boolean::New(env, sent);
|
|
617
|
+
}
|
|
618
|
+
|
|
556
619
|
static Napi::Value PtyKill(const Napi::CallbackInfo& info) {
|
|
557
620
|
Napi::Env env(info.Env());
|
|
558
621
|
Napi::HandleScope scope(env);
|
|
@@ -577,9 +640,11 @@ static Napi::Value PtyKill(const Napi::CallbackInfo& info) {
|
|
|
577
640
|
PFNCLOSEPSEUDOCONSOLE const pfnClosePseudoConsole = (PFNCLOSEPSEUDOCONSOLE)GetProcAddress(
|
|
578
641
|
(HMODULE)hLibrary,
|
|
579
642
|
useConptyDll ? "ConptyClosePseudoConsole" : "ClosePseudoConsole");
|
|
580
|
-
if (pfnClosePseudoConsole)
|
|
643
|
+
if (pfnClosePseudoConsole && handle->hpc != nullptr)
|
|
581
644
|
{
|
|
582
645
|
pfnClosePseudoConsole(handle->hpc);
|
|
646
|
+
// Closing frees the pseudoconsole, but the baton lives until the exit thread erases it.
|
|
647
|
+
handle->hpc = nullptr;
|
|
583
648
|
}
|
|
584
649
|
}
|
|
585
650
|
// Defensive: if PtyConnect was never called (or failed before closing the
|
|
@@ -609,6 +674,7 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
|
|
|
609
674
|
exports.Set("connect", Napi::Function::New(env, PtyConnect));
|
|
610
675
|
exports.Set("resize", Napi::Function::New(env, PtyResize));
|
|
611
676
|
exports.Set("clear", Napi::Function::New(env, PtyClear));
|
|
677
|
+
exports.Set("reparent", Napi::Function::New(env, PtyReparent));
|
|
612
678
|
exports.Set("kill", Napi::Function::New(env, PtyKill));
|
|
613
679
|
return exports;
|
|
614
680
|
};
|
package/typings/node-pty.d.ts
CHANGED
|
@@ -173,6 +173,23 @@ declare module 'node-pty' {
|
|
|
173
173
|
*/
|
|
174
174
|
clear(): void;
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Sets the handle (HWND) of the top-level window that hosts this terminal. ConPTY makes it the
|
|
178
|
+
* owner of the console window returned by `GetConsoleWindow()`, so windows that console
|
|
179
|
+
* applications parent to it (for example `GetAncestor(GetConsoleWindow(), GA_ROOTOWNER)`, which
|
|
180
|
+
* MSAL/WAM sign-in uses) open on top of the host window instead of behind it. Calling it right
|
|
181
|
+
* after spawning sends the request before the process is launched. Call it again whenever the
|
|
182
|
+
* terminal moves to a different window. Optional so existing implementations of `IPty` keep
|
|
183
|
+
* compiling.
|
|
184
|
+
* @param handle The window handle (HWND) as its bytes in native byte order, the way Electron's
|
|
185
|
+
* `BrowserWindow.getNativeWindowHandle()` returns it. Throws unless it's a Buffer the size of
|
|
186
|
+
* an HWND (8 bytes in a 64-bit process).
|
|
187
|
+
* @returns Whether the request was sent to ConPTY, which applies it asynchronously. This is
|
|
188
|
+
* always false unless on Windows with `useConptyDll`, and false once the pseudoconsole is
|
|
189
|
+
* closed.
|
|
190
|
+
*/
|
|
191
|
+
setParentWindow?(handle: Buffer): boolean;
|
|
192
|
+
|
|
176
193
|
/**
|
|
177
194
|
* Writes data to the pty.
|
|
178
195
|
* @param data The data to write.
|