@termwright/pty 0.3.0 → 0.3.2

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/README.md CHANGED
@@ -71,10 +71,13 @@ Win32-input `DECSET` sequences before bytes reach the driver. It preserves the
71
71
  private host-cursor request, DA1, and every original child sequence, including
72
72
  an explicit disable followed by enable. The normalizer is split-safe and
73
73
  releases an incomplete candidate verbatim before authoritative EOF.
74
- The input side still honors the host's always-on Win32 Input Mode. Application
75
- replies, including every ordinary DSR cursor-position report, are therefore
76
- transported as synthesized Win32 `KEY_EVENT` records. OpenConsole's own cursor
77
- recovery instead uses private `OSC 8488` requests and responses carrying a
74
+ The input side wraps each emulator-generated application reply in the private
75
+ `twh-app-reply-v1` OSC envelope. OpenConsole buffers the envelope through BEL,
76
+ validates its byte count and lowercase-hex payload, and commits the decoded
77
+ reply with one `InputBuffer::WriteString`. This works whether VT input is on or
78
+ off: raw CPR cannot be consumed as F3, and separate Win32 `KEY_EVENT` records
79
+ cannot expose a mode report's printable tail after a lone `ESC`. OpenConsole's own cursor recovery instead
80
+ uses private `OSC 8488` requests and responses carrying a
78
81
  random 128-bit request token. Only a response for the matching live token can
79
82
  complete the host query, and that host-control response is written raw and
80
83
  consumed without reaching the application. Startup DA1 remains a separately
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare function encodeWin32InputModeTerminalResponse(data: Uint8Array): Buffer;
1
+ declare function encodeConPtyApplicationTerminalResponse(data: Uint8Array): Buffer;
2
2
  declare function encodeConPtyApplicationInput(data: Uint8Array, kind: 'key' | 'mouse' | 'paste' | 'raw'): Buffer;
3
3
 
4
4
  /**
@@ -18,8 +18,9 @@ declare function encodeConPtyApplicationInput(data: Uint8Array, kind: 'key' | 'm
18
18
  interface WindowsConPtyRuntimeInfo {
19
19
  readonly provider: 'termwright-patched-openconsole';
20
20
  readonly upstreamCommit: 'dd494ac79a82a04e1e7252a91c8939a3c3039908';
21
- readonly patchSha256: '839ff6fb8c2d3490ee8ccd1f20310baa315475fa187b4967e5e940fa98610d1c';
21
+ readonly patchSha256: 'eae93025548fe697fa08242587e28abaeb06cc5ca7646fff0d9bef280c77770c';
22
22
  readonly hostCursorRpc: 'twh-cpr-v1';
23
+ readonly applicationReplyRpc: 'twh-app-reply-v1';
23
24
  readonly mode: 'ordered-vt-passthrough';
24
25
  readonly policy: 'strict';
25
26
  readonly selectedHostArchitecture: '' | 'x64' | 'arm64';
@@ -100,7 +101,7 @@ interface PtyHandle {
100
101
  readonly endReason: number | undefined;
101
102
  write(data: Uint8Array): void;
102
103
  writeApplicationInput?(data: Uint8Array, kind: 'key' | 'mouse' | 'paste' | 'raw'): void;
103
- writeTerminalResponse?(data: Uint8Array): 'host-control' | 'application-direct' | 'application-win32-input';
104
+ writeTerminalResponse?(data: Uint8Array): 'host-control' | 'application-envelope' | 'application-direct';
104
105
  /** Closes the parent-owned terminal input while preserving output drain. */
105
106
  closeInput?(): void;
106
107
  resize(columns: number, rows: number): boolean;
@@ -114,4 +115,4 @@ interface PtyHandle {
114
115
  }
115
116
  declare function spawnPty(options: PtySpawnOptions): PtyHandle;
116
117
 
117
- export { type PtyExit, type PtyHandle, type PtySignal, type PtySpawnOptions, type WindowsConPtyRuntimeInfo, candidatePaths, conPtyRuntimeInfo, encodeConPtyApplicationInput, encodeWin32InputModeTerminalResponse, loadPtyBinding, ptyAvailable, ptyUnavailableReason, spawnPty, writeWindowsConsoleMarker };
118
+ export { type PtyExit, type PtyHandle, type PtySignal, type PtySpawnOptions, type WindowsConPtyRuntimeInfo, candidatePaths, conPtyRuntimeInfo, encodeConPtyApplicationInput, encodeConPtyApplicationTerminalResponse, loadPtyBinding, ptyAvailable, ptyUnavailableReason, spawnPty, writeWindowsConsoleMarker };
package/dist/index.js CHANGED
@@ -32,29 +32,37 @@ var RIS = bytes(ESC, 99);
32
32
  var HOST_CURSOR_REQUEST_PREFIX = Buffer.from("\x1B]8488;twh-cpr-v1:q:", "ascii");
33
33
  var HOST_CURSOR_REQUEST_TOKEN_BYTES = 32;
34
34
  var HOST_CURSOR_REPLY_NAMESPACE = Buffer.from("\x1B]8488;twh-cpr-v1:r:", "ascii");
35
- function encodeWin32InputModeTerminalResponse(data) {
36
- let encoded = "";
35
+ var APPLICATION_REPLY_PREFIX = Buffer.from("\x1B]8488;twh-app-reply-v1:", "ascii");
36
+ var OSC_TERMINATOR = Buffer.from("\x07", "ascii");
37
+ var MAX_APPLICATION_REPLY_BYTES = 4096;
38
+ function encodeConPtyApplicationTerminalResponse(data) {
39
+ if (data.byteLength === 0 || data.byteLength > MAX_APPLICATION_REPLY_BYTES) {
40
+ throw new RangeError(
41
+ `terminal response must contain between 1 and ${MAX_APPLICATION_REPLY_BYTES} bytes`
42
+ );
43
+ }
37
44
  for (const byte of data) {
38
45
  if (byte > 127) {
39
46
  throw new TypeError(
40
47
  `terminal response contains non-ASCII byte 0x${byte.toString(16).padStart(2, "0")}`
41
48
  );
42
49
  }
43
- encoded += `\x1B[0;0;${byte};1;0;1_`;
44
50
  }
45
- return Buffer.from(encoded, "ascii");
46
- }
47
- function encodeConPtyApplicationInput(data, kind) {
48
- return kind === "key" && data.byteLength === 1 && data[0] === 27 ? Buffer.from("\x1B[27;1;27;1;0;1_", "ascii") : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
51
+ const bytes2 = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
52
+ return Buffer.concat([
53
+ APPLICATION_REPLY_PREFIX,
54
+ Buffer.from(`${bytes2.byteLength}:${bytes2.toString("hex")}`, "ascii"),
55
+ OSC_TERMINATOR
56
+ ]);
49
57
  }
50
58
  var ConPtyTerminalResponseTransport = class {
51
59
  encode(route, data) {
52
- if (route === "application-win32-input") {
53
- return encodeWin32InputModeTerminalResponse(data);
54
- }
55
- return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
60
+ return route === "application-envelope" ? encodeConPtyApplicationTerminalResponse(data) : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
56
61
  }
57
62
  };
63
+ function encodeConPtyApplicationInput(data, kind) {
64
+ return kind === "key" && data.byteLength === 1 && data[0] === 27 ? Buffer.from("\x1B[27;1;27;1;0;1_", "ascii") : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
65
+ }
58
66
  function isHostResponse(response) {
59
67
  const text = response.toString("ascii");
60
68
  return /^\x1b\[\?[\d;]*c$/u.test(text);
@@ -71,7 +79,7 @@ var ConPtyTerminalResponseRouter = class {
71
79
  if (bytes2.subarray(0, HOST_CURSOR_REPLY_NAMESPACE.length).equals(HOST_CURSOR_REPLY_NAMESPACE)) {
72
80
  return "host-control";
73
81
  }
74
- if (query === void 0) return "application-win32-input";
82
+ if (query === void 0) return "application-envelope";
75
83
  if (!isHostResponse(bytes2)) {
76
84
  throw new Error(`terminal answered ${query} ConPTY host query with an unexpected response`);
77
85
  }
@@ -198,7 +206,7 @@ var ConPtyControlPlaneNormalizer = class {
198
206
 
199
207
  // src/windows.ts
200
208
  function assertRuntimeInfoShape(value) {
201
- if (value.provider !== "termwright-patched-openconsole" || value.upstreamCommit !== "dd494ac79a82a04e1e7252a91c8939a3c3039908" || value.patchSha256 !== "839ff6fb8c2d3490ee8ccd1f20310baa315475fa187b4967e5e940fa98610d1c" || value.hostCursorRpc !== "twh-cpr-v1" || Object.hasOwn(value, "package") || Object.hasOwn(value, "version") || value.mode !== "ordered-vt-passthrough" || value.policy !== "strict" || value.selectedHostArchitecture !== "" && value.selectedHostArchitecture !== "x64" && value.selectedHostArchitecture !== "arm64" || typeof value.failureCode !== "string" || typeof value.failureWin32 !== "number" || typeof value.assetsValidated !== "boolean" || typeof value.coreExports !== "boolean" || value.orderedMarkerSemantics !== "marker-authoritative-after-behavioral-certification") {
209
+ if (value.provider !== "termwright-patched-openconsole" || value.upstreamCommit !== "dd494ac79a82a04e1e7252a91c8939a3c3039908" || value.patchSha256 !== "eae93025548fe697fa08242587e28abaeb06cc5ca7646fff0d9bef280c77770c" || value.hostCursorRpc !== "twh-cpr-v1" || value.applicationReplyRpc !== "twh-app-reply-v1" || Object.hasOwn(value, "package") || Object.hasOwn(value, "version") || value.mode !== "ordered-vt-passthrough" || value.policy !== "strict" || value.selectedHostArchitecture !== "" && value.selectedHostArchitecture !== "x64" && value.selectedHostArchitecture !== "arm64" || typeof value.failureCode !== "string" || typeof value.failureWin32 !== "number" || typeof value.assetsValidated !== "boolean" || typeof value.coreExports !== "boolean" || value.orderedMarkerSemantics !== "marker-authoritative-after-behavioral-certification") {
202
210
  throw new Error(`invalid vendored ConPTY capability report: ${JSON.stringify(value)}`);
203
211
  }
204
212
  return value;
@@ -770,7 +778,7 @@ export {
770
778
  candidatePaths,
771
779
  conPtyRuntimeInfo,
772
780
  encodeConPtyApplicationInput,
773
- encodeWin32InputModeTerminalResponse,
781
+ encodeConPtyApplicationTerminalResponse,
774
782
  loadPtyBinding,
775
783
  ptyAvailable,
776
784
  ptyUnavailableReason,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/windows.ts","../src/write-drain-epoch.ts","../src/windows-output-normalizer.ts"],"sourcesContent":["/**\n * Termwright-owned native PTY session.\n *\n * The POSIX implementation owns the `forkpty()` master and reads it until the\n * kernel reports EOF (EIO after the queued tail on Linux). No JavaScript\n * stream, private node-pty field, quiet window, or retry decides that output\n * has ended.\n */\nimport { createRequire } from 'node:module';\nimport { getSystemErrorName } from 'node:util';\nimport {\n spawnWindowsPty,\n writeWindowsConsoleMarker as writeNativeWindowsConsoleMarker,\n windowsConPtyRuntimeInfo,\n windowsPtyAvailable,\n windowsPtyUnavailableReason,\n type WindowsConPtyRuntimeInfo,\n} from './windows.js';\nimport { NativeWriteDrainEpoch } from './write-drain-epoch.js';\n\nexport {\n encodeConPtyApplicationInput,\n encodeWin32InputModeTerminalResponse,\n} from './windows-output-normalizer.js';\n\ntype NativeEvent =\n | { readonly type: 'data'; readonly data: Buffer }\n | {\n readonly type: 'exit';\n readonly exitCode: number;\n readonly signal: number;\n }\n | { readonly type: 'eof'; readonly code: number }\n | { readonly type: 'drain'; readonly generation: bigint }\n | { readonly type: 'error'; readonly message: string; readonly code: number };\n\ninterface NativeSession {\n readonly pid: number;\n write(data: Buffer): void;\n resize(columns: number, rows: number): boolean;\n /** Zero on delivery/already-gone; otherwise the positive POSIX errno. */\n signal(signal: number): number;\n treeState(): number;\n dispose(): void;\n}\n\ninterface NativeBinding {\n new (\n options: {\n readonly command: readonly string[];\n readonly cwd?: string;\n readonly env: readonly string[];\n readonly columns: number;\n readonly rows: number;\n },\n onEvent: (event: NativeEvent) => void,\n ): NativeSession;\n}\n\nlet cachedBinding: { readonly PosixPtySession: NativeBinding } | undefined;\n\nexport function candidatePaths(\n platform: NodeJS.Platform = process.platform,\n architecture: string = process.arch,\n): readonly string[] {\n return [\n '../build/Release/termwright_pty.node',\n `@termwright/pty-${platform}-${architecture}/termwright_pty.node`,\n ];\n}\n\nexport function loadPtyBinding(): { readonly PosixPtySession: NativeBinding } {\n if (cachedBinding !== undefined) return cachedBinding;\n if (process.platform === 'win32') {\n throw new Error('the POSIX @termwright/pty binding cannot load on Windows');\n }\n if (process.platform !== 'darwin' && process.platform !== 'linux') {\n throw new Error(`@termwright/pty does not support ${process.platform}-${process.arch}`);\n }\n const require = createRequire(import.meta.url);\n const attempts: string[] = [];\n for (const candidate of candidatePaths()) {\n try {\n cachedBinding = require(candidate) as {\n readonly PosixPtySession: NativeBinding;\n };\n return cachedBinding;\n } catch (error) {\n attempts.push(\n `${candidate}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n );\n }\n }\n throw new Error(\n `no Termwright PTY addon could be loaded for ${process.platform}-${process.arch}. Tried:\\n ${attempts.join('\\n ')}`,\n );\n}\n\nlet unavailableReason: string | undefined;\n\nexport function ptyAvailable(): boolean {\n if (process.platform === 'win32') return windowsPtyAvailable();\n try {\n loadPtyBinding();\n unavailableReason = undefined;\n return true;\n } catch (error) {\n unavailableReason = error instanceof Error ? error.message : String(error);\n return false;\n }\n}\n\nexport function ptyUnavailableReason(): string | undefined {\n return process.platform === 'win32' ? windowsPtyUnavailableReason() : unavailableReason;\n}\n\nexport interface PtySpawnOptions {\n readonly command: readonly string[];\n readonly cwd?: string;\n readonly env: Readonly<Record<string, string>>;\n readonly columns: number;\n readonly rows: number;\n}\n\nexport interface PtyExit {\n readonly code: number | null;\n readonly signal: string | null;\n}\n\nexport type PtySignal = 'INT' | 'TERM' | 'KILL' | 'HUP';\nexport type { WindowsConPtyRuntimeInfo };\n\n/** Runtime provenance and strict initialization status for the Windows backend. */\nexport function conPtyRuntimeInfo(): WindowsConPtyRuntimeInfo {\n if (process.platform !== 'win32') {\n throw new Error('ConPTY runtime information is only available on Windows');\n }\n return windowsConPtyRuntimeInfo();\n}\n\n/**\n * Writes a marker through WriteConsoleW while temporarily enforcing the two\n * output-mode bits required for VT control sequences. Windows probes use this\n * instead of duplicating mode mutation and restoration logic.\n */\nexport function writeWindowsConsoleMarker(fd: number, marker: string): void {\n if (process.platform !== 'win32') {\n throw new Error('Windows console markers are only available on Windows');\n }\n writeNativeWindowsConsoleMarker(fd, marker);\n}\n\nexport interface PtyHandle {\n readonly pid: number;\n readonly outputEnded: Promise<void>;\n readonly sawRealEof: boolean;\n readonly endReason: number | undefined;\n write(data: Uint8Array): void;\n writeApplicationInput?(data: Uint8Array, kind: 'key' | 'mouse' | 'paste' | 'raw'): void;\n writeTerminalResponse?(\n data: Uint8Array,\n ): 'host-control' | 'application-direct' | 'application-win32-input';\n /** Closes the parent-owned terminal input while preserving output drain. */\n closeInput?(): void;\n resize(columns: number, rows: number): boolean;\n signal(signal: PtySignal): boolean;\n treeState(): 'alive' | 'gone' | 'unsupported';\n onData(listener: (data: Uint8Array) => void): () => void;\n onExit(listener: (status: PtyExit) => void): () => void;\n onError(listener: (error: Error) => void): () => void;\n onDrain(listener: () => void): () => void;\n dispose(): void;\n}\n\nconst signalNumbers: Readonly<Record<PtySignal, number>> = Object.freeze({\n HUP: 1,\n INT: 2,\n KILL: 9,\n TERM: 15,\n});\n\nconst signalNames: Readonly<Record<number, string>> = Object.freeze({\n 1: 'SIGHUP',\n 2: 'SIGINT',\n 3: 'SIGQUIT',\n 6: 'SIGABRT',\n 9: 'SIGKILL',\n 13: 'SIGPIPE',\n 15: 'SIGTERM',\n});\n\nfunction validateOptions(options: PtySpawnOptions): void {\n if (\n options.command.length === 0 ||\n options.command.some((part) => typeof part !== 'string' || part.includes('\\0'))\n ) {\n throw new TypeError('command must be a non-empty array of NUL-free strings');\n }\n if (\n options.cwd !== undefined &&\n (typeof options.cwd !== 'string' || options.cwd.includes('\\0'))\n ) {\n throw new TypeError('cwd must be a NUL-free string');\n }\n for (const [key, value] of Object.entries(options.env)) {\n if (\n key.length === 0 ||\n key.includes('=') ||\n key.includes('\\0') ||\n typeof value !== 'string' ||\n value.includes('\\0')\n ) {\n throw new TypeError('environment keys and values must be valid execve strings');\n }\n }\n for (const [field, value] of [\n ['columns', options.columns],\n ['rows', options.rows],\n ] as const) {\n if (!Number.isInteger(value) || value < 1 || value > 32_767) {\n throw new RangeError(`${field} must be an integer from 1 through 32767`);\n }\n }\n}\n\nexport function spawnPty(options: PtySpawnOptions): PtyHandle {\n validateOptions(options);\n if (process.platform === 'win32') {\n const session = spawnWindowsPty(options);\n return {\n get pid(): number {\n return session.pid;\n },\n get sawRealEof(): boolean {\n return session.sawRealEof;\n },\n get endReason(): number | undefined {\n return session.endReason;\n },\n outputEnded: session.outputEnded,\n write(data): void {\n session.write(data);\n },\n writeApplicationInput(data, kind): void {\n session.writeApplicationInput(data, kind);\n },\n writeTerminalResponse(data) {\n return session.writeTerminalResponse(data);\n },\n closeInput(): void {\n session.closeInput();\n },\n resize(columns, rows): boolean {\n return session.resize(columns, rows);\n },\n signal(signal): boolean {\n if (signal !== 'KILL') return false;\n session.terminateTree();\n return true;\n },\n treeState(): 'alive' | 'gone' | 'unsupported' {\n const members = session.activeProcesses();\n return members < 0 ? 'unsupported' : members === 0 ? 'gone' : 'alive';\n },\n onData(listener): () => void {\n return session.onData(listener);\n },\n onExit(listener): () => void {\n return session.onExit(listener);\n },\n onError(listener): () => void {\n return session.onError(listener);\n },\n onDrain(listener): () => void {\n return session.onDrain(listener);\n },\n dispose(): void {\n session.dispose();\n },\n };\n }\n const dataListeners = new Set<(data: Uint8Array) => void>();\n const exitListeners = new Set<(status: PtyExit) => void>();\n const errorListeners = new Set<(error: Error) => void>();\n const drainListeners = new Set<() => void>();\n let exitStatus: PtyExit | undefined;\n let fatalError: Error | undefined;\n let resolveEnded: (() => void) | undefined;\n const outputEnded = new Promise<void>((resolve) => {\n resolveEnded = resolve;\n });\n let ended = false;\n let endReason: number | undefined;\n let disposed = false;\n const writeEpoch = new NativeWriteDrainEpoch();\n\n const session = new (loadPtyBinding().PosixPtySession)(\n {\n command: [...options.command],\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n env: Object.entries(options.env).map(([key, value]) => `${key}=${value}`),\n columns: options.columns,\n rows: options.rows,\n },\n (event) => {\n switch (event.type) {\n case 'data':\n for (const listener of [...dataListeners]) listener(event.data);\n return;\n case 'exit': {\n exitStatus =\n event.signal === 0\n ? { code: event.exitCode, signal: null }\n : {\n code: null,\n signal: signalNames[event.signal] ?? `SIG${event.signal}`,\n };\n for (const listener of [...exitListeners]) listener(exitStatus);\n return;\n }\n case 'eof':\n endReason = event.code;\n ended = event.code === 0;\n resolveEnded?.();\n return;\n case 'drain':\n if (!writeEpoch.isCurrent(event.generation)) return;\n for (const listener of [...drainListeners]) listener();\n return;\n case 'error': {\n const code = getSystemErrorName(-event.code);\n const guidance =\n code === 'EMFILE'\n ? \" Raise this process's open-file limit (for example with `ulimit -n`) and retry.\"\n : code === 'ENFILE'\n ? ' The host-wide open-file table is exhausted; raise the system limit or reduce concurrent processes.'\n : '';\n fatalError ??= Object.assign(new Error(`${event.message}${guidance}`), {\n code,\n errno: event.code,\n });\n for (const listener of [...errorListeners]) listener(fatalError);\n return;\n }\n }\n },\n );\n\n return {\n get pid(): number {\n return session.pid;\n },\n get sawRealEof(): boolean {\n return ended;\n },\n get endReason(): number | undefined {\n return endReason;\n },\n outputEnded,\n write(data): void {\n if (disposed) throw new Error('PTY input is closed');\n const bytes = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n writeEpoch.admit(bytes, (admitted) => session.write(admitted));\n },\n resize(columns, rows): boolean {\n if (\n !Number.isInteger(columns) ||\n !Number.isInteger(rows) ||\n columns < 1 ||\n rows < 1 ||\n columns > 32_767 ||\n rows > 32_767\n )\n return false;\n return !disposed && session.resize(columns, rows);\n },\n signal(signal): boolean {\n if (disposed) return false;\n const code = session.signal(signalNumbers[signal]);\n if (code === 0) return true;\n throw Object.assign(new Error(`kill(PTY process group) failed with errno ${code}`), {\n code: getSystemErrorName(-code),\n errno: code,\n });\n },\n treeState(): 'alive' | 'gone' | 'unsupported' {\n const state = disposed ? -1 : session.treeState();\n return state > 0 ? 'alive' : state === 0 ? 'gone' : 'unsupported';\n },\n onData(listener): () => void {\n dataListeners.add(listener);\n return () => dataListeners.delete(listener);\n },\n onExit(listener): () => void {\n exitListeners.add(listener);\n const observed = exitStatus;\n if (observed !== undefined)\n queueMicrotask(() => {\n if (exitListeners.has(listener)) listener(observed);\n });\n return () => exitListeners.delete(listener);\n },\n onError(listener): () => void {\n errorListeners.add(listener);\n const observed = fatalError;\n if (observed !== undefined)\n queueMicrotask(() => {\n if (errorListeners.has(listener)) listener(observed);\n });\n return () => errorListeners.delete(listener);\n },\n onDrain(listener): () => void {\n drainListeners.add(listener);\n return () => drainListeners.delete(listener);\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n session.dispose();\n resolveEnded?.();\n dataListeners.clear();\n exitListeners.clear();\n errorListeners.clear();\n drainListeners.clear();\n },\n };\n}\n","/**\n * Termwright's Windows PTY backend.\n *\n * One native session owns the pseudoconsole, both host pipe ends, the root\n * process and thread, and the job object holding the tree. Two facts follow\n * from that ownership and are the reason this package exists:\n *\n * - a session ends when the output pipe actually ends, never when a timer says\n * nothing has arrived lately;\n * - the process tree is a job object from before the root can run, so proving\n * it empty is a query rather than a race against process enumeration.\n */\n\nimport { createRequire } from 'node:module';\nimport { NativeWriteDrainEpoch } from './write-drain-epoch.js';\nimport {\n ConPtyControlPlaneNormalizer,\n ConPtyTerminalResponseRouter,\n ConPtyTerminalResponseTransport,\n encodeConPtyApplicationInput,\n type ConPtyTerminalResponseRoute,\n} from './windows-output-normalizer.js';\n\n/** Ordered messages the native session emits. Data always precedes the end. */\ntype NativeEvent =\n | { readonly type: 'data'; readonly data: Buffer }\n | { readonly type: 'exit'; readonly exitCode: number }\n | { readonly type: 'eof'; readonly code: number }\n | { readonly type: 'drain'; readonly generation: bigint }\n | { readonly type: 'notice'; readonly message: string }\n | { readonly type: 'error'; readonly message: string; readonly code: number };\n\ninterface NativeSession {\n readonly pid: number;\n write(data: Buffer): void;\n closeInput(): void;\n resize(columns: number, rows: number): boolean;\n terminateTree(): void;\n activeProcesses(): number;\n dispose(): void;\n}\n\ninterface NativeBindingConstructor {\n new (\n options: {\n readonly commandLine: string;\n readonly cwd?: string;\n readonly env?: readonly string[];\n readonly columns: number;\n readonly rows: number;\n },\n onEvent: (event: NativeEvent) => void,\n ): NativeSession;\n}\n\ninterface LoadedWindowsBinding {\n readonly ConPtySession: NativeBindingConstructor;\n conPtyRuntimeInfo(): WindowsConPtyRuntimeInfo;\n writeWindowsConsoleMarker(fd: number, marker: string): void;\n}\n\n/** Provenance and behavioral contract of the loaded Windows pseudoconsole. */\nexport interface WindowsConPtyRuntimeInfo {\n readonly provider: 'termwright-patched-openconsole';\n readonly upstreamCommit: 'dd494ac79a82a04e1e7252a91c8939a3c3039908';\n readonly patchSha256: '839ff6fb8c2d3490ee8ccd1f20310baa315475fa187b4967e5e940fa98610d1c';\n readonly hostCursorRpc: 'twh-cpr-v1';\n readonly mode: 'ordered-vt-passthrough';\n readonly policy: 'strict';\n readonly selectedHostArchitecture: '' | 'x64' | 'arm64';\n readonly failureCode: string;\n readonly failureWin32: number;\n readonly assetsValidated: boolean;\n readonly coreExports: boolean;\n readonly orderedMarkerSemantics: 'marker-authoritative-after-behavioral-certification';\n}\n\nfunction assertRuntimeInfoShape(value: WindowsConPtyRuntimeInfo): WindowsConPtyRuntimeInfo {\n if (\n value.provider !== 'termwright-patched-openconsole' ||\n value.upstreamCommit !== 'dd494ac79a82a04e1e7252a91c8939a3c3039908' ||\n value.patchSha256 !== '839ff6fb8c2d3490ee8ccd1f20310baa315475fa187b4967e5e940fa98610d1c' ||\n value.hostCursorRpc !== 'twh-cpr-v1' ||\n Object.hasOwn(value, 'package') ||\n Object.hasOwn(value, 'version') ||\n value.mode !== 'ordered-vt-passthrough' ||\n value.policy !== 'strict' ||\n (value.selectedHostArchitecture !== '' &&\n value.selectedHostArchitecture !== 'x64' &&\n value.selectedHostArchitecture !== 'arm64') ||\n typeof value.failureCode !== 'string' ||\n typeof value.failureWin32 !== 'number' ||\n typeof value.assetsValidated !== 'boolean' ||\n typeof value.coreExports !== 'boolean' ||\n value.orderedMarkerSemantics !== 'marker-authoritative-after-behavioral-certification'\n ) {\n throw new Error(`invalid vendored ConPTY capability report: ${JSON.stringify(value)}`);\n }\n return value;\n}\n\nfunction assertCertifiedRuntimeInfo(value: WindowsConPtyRuntimeInfo): WindowsConPtyRuntimeInfo {\n assertRuntimeInfoShape(value);\n if (\n (value.selectedHostArchitecture !== 'x64' && value.selectedHostArchitecture !== 'arm64') ||\n value.failureCode !== '' ||\n value.failureWin32 !== 0 ||\n value.assetsValidated !== true ||\n value.coreExports !== true\n ) {\n throw new Error(`uncertified vendored ConPTY runtime: ${JSON.stringify(value)}`);\n }\n return value;\n}\n\nlet cachedBinding: LoadedWindowsBinding | undefined;\nlet cachedDiagnosticBinding: LoadedWindowsBinding | undefined;\n\n/**\n * Where the addon is looked for, in order.\n *\n * The locally compiled binary comes first so that a working tree tests what it\n * just built rather than a published prebuild that happens to be installed\n * beside it — the alternative is a change to this addon that CI certifies\n * against the previous release.\n */\nexport function windowsCandidatePaths(architecture: string): readonly string[] {\n return [\n '../build/Release/termwright_pty.node',\n `@termwright/pty-win32-${architecture}/termwright_pty.node`,\n ];\n}\n\n/** Loads the compiled addon, or explains why this platform has none. */\nexport function loadWindowsBinding(): LoadedWindowsBinding {\n if (cachedBinding !== undefined) return cachedBinding;\n if (process.platform !== 'win32') {\n throw new Error('@termwright/pty Windows binding cannot load on a non-Windows host');\n }\n const require = createRequire(import.meta.url);\n const attempts: string[] = [];\n for (const candidate of windowsCandidatePaths(process.arch)) {\n try {\n const resolved = require.resolve(candidate);\n const loaded = require(resolved) as LoadedWindowsBinding;\n assertCertifiedRuntimeInfo(loaded.conPtyRuntimeInfo());\n cachedBinding = loaded;\n return cachedBinding;\n } catch (error) {\n // Kept per candidate. \"No addon\" is the same sentence whether the\n // prebuild for this architecture was never published, the install\n // skipped it, or it is present and failed to load — and those are three\n // different things to do next.\n attempts.push(\n `${candidate}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n );\n }\n }\n throw new Error(\n `no termwright ConPTY addon could be loaded for win32-${process.arch}. Tried:\\n ${attempts.join('\\n ')}`,\n );\n}\n\n/**\n * Returns a capability report even when strict runtime initialization failed.\n * A healthy candidate is preferred over an earlier diagnostic-only candidate.\n */\nexport function windowsConPtyRuntimeInfo(): WindowsConPtyRuntimeInfo {\n if (cachedBinding !== undefined) {\n return assertRuntimeInfoShape(cachedBinding.conPtyRuntimeInfo());\n }\n if (process.platform !== 'win32') {\n throw new Error('@termwright/pty Windows binding cannot load on a non-Windows host');\n }\n const require = createRequire(import.meta.url);\n const attempts: string[] = [];\n for (const candidate of windowsCandidatePaths(process.arch)) {\n try {\n const resolved = require.resolve(candidate);\n const loaded = require(resolved) as LoadedWindowsBinding;\n const runtime = assertRuntimeInfoShape(loaded.conPtyRuntimeInfo());\n if (\n runtime.failureCode === '' &&\n runtime.failureWin32 === 0 &&\n runtime.assetsValidated &&\n runtime.coreExports\n ) {\n cachedBinding = loaded;\n return runtime;\n }\n cachedDiagnosticBinding ??= loaded;\n } catch (error) {\n attempts.push(\n `${candidate}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n );\n }\n }\n if (cachedDiagnosticBinding !== undefined) {\n return assertRuntimeInfoShape(cachedDiagnosticBinding.conPtyRuntimeInfo());\n }\n throw new Error(\n `no termwright ConPTY addon could be loaded for win32-${process.arch}. Tried:\\n ${attempts.join('\\n ')}`,\n );\n}\n\nlet unavailableReason: string | undefined;\n\n/** True when the addon is present and usable in this process. */\nexport function windowsPtyAvailable(): boolean {\n try {\n loadWindowsBinding();\n unavailableReason = undefined;\n return true;\n } catch (error) {\n // Kept, because \"not available\" is the least useful half of the answer.\n // A missing file, an ABI mismatch and a load-time failure inside the addon\n // all arrive here, and they are three different pieces of work.\n unavailableReason = error instanceof Error ? error.message : String(error);\n return false;\n }\n}\n\n/** Why the addon could not be loaded, as the loader reported it. */\nexport function windowsPtyUnavailableReason(): string | undefined {\n return unavailableReason;\n}\n\n/**\n * Writes an in-band marker to a real Windows console without inheriting a\n * framework's possibly-disabled VT output mode.\n *\n * The native primitive restores the exact original console mode before it\n * returns or throws. A successful return means WriteConsoleW accepted every\n * UTF-16 code unit synchronously.\n */\nexport function writeWindowsConsoleMarker(fd: number, marker: string): void {\n if (!Number.isInteger(fd) || fd < 0) {\n throw new RangeError('Windows console marker fd must be a non-negative integer');\n }\n if (typeof marker !== 'string' || marker.length === 0) {\n throw new TypeError('Windows console marker must be a non-empty string');\n }\n loadWindowsBinding().writeWindowsConsoleMarker(fd, marker);\n}\n\n/**\n * Quotes one argument the way CommandLineToArgvW parses it.\n *\n * Windows has no argv: the child re-parses a single string, so the caller's\n * exact arguments only survive if they are quoted to that specific grammar.\n * Backslashes are literal except immediately before a quote, where they are\n * doubled — including the run that precedes the closing quote.\n */\nexport function quoteWindowsArgument(argument: string): string {\n if (argument.length > 0 && !/[\\s\"]/u.test(argument)) return argument;\n let quoted = '\"';\n let backslashes = 0;\n for (const character of argument) {\n if (character === '\\\\') {\n backslashes += 1;\n continue;\n }\n if (character === '\"') {\n quoted += '\\\\'.repeat(backslashes * 2 + 1);\n quoted += '\"';\n backslashes = 0;\n continue;\n }\n quoted += '\\\\'.repeat(backslashes);\n quoted += character;\n backslashes = 0;\n }\n quoted += '\\\\'.repeat(backslashes * 2);\n return `${quoted}\"`;\n}\n\n/** Joins a command into the single string CreateProcessW takes. */\nexport function buildCommandLine(command: readonly string[]): string {\n if (command.length === 0) throw new TypeError('a ConPTY command needs at least an executable');\n return command.map(quoteWindowsArgument).join(' ');\n}\n\n/** Renders an environment map as the block CreateProcessW expects. */\nexport function buildEnvironment(env: Readonly<Record<string, string>>): readonly string[] {\n return Object.entries(env)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}=${value}`);\n}\n\nexport interface WindowsPtySpawnOptions {\n readonly command: readonly string[];\n readonly cwd?: string;\n readonly env: Readonly<Record<string, string>>;\n readonly columns: number;\n readonly rows: number;\n}\n\nexport interface WindowsPtyExit {\n readonly code: number | null;\n readonly signal: string | null;\n}\n\n/**\n * A live ConPTY session.\n *\n * `exited` and `outputEnded` are deliberately separate. A root process can\n * finish while its descendants still hold the pseudoconsole, so the last byte\n * of a session routinely arrives after the process that started it is gone.\n */\nexport interface WindowsPtyHandle {\n readonly pid: number;\n readonly runtimeInfo: WindowsConPtyRuntimeInfo;\n readonly outputEnded: Promise<void>;\n /**\n * True only when the output pipe actually ended.\n *\n * `outputEnded` also settles on disposal so a teardown cannot hang, which\n * means resolving it is not by itself evidence of EOF. This is the flag that\n * separates the two, and nothing but the reader sets it.\n *\n * The end itself is reached by the tree emptying: the job reports zero\n * active processes, which means no byte can follow, and the console is\n * closed only then. The reader still ends on the pipe rather than on a\n * timer — what changed is that the moment is chosen by evidence.\n */\n readonly sawRealEof: boolean;\n /**\n * The Win32 code the terminating read reported, or 0 for a clean end.\n *\n * A stream that ended for the wrong reason looks exactly like one that ended\n * properly, and telling them apart is the claim this backend exists to make.\n */\n readonly endReason: number | undefined;\n /**\n * The session's own account of its lifecycle, oldest first.\n *\n * Root exit, what the job said, and when the console was closed. These\n * moments are only observable while they happen: the console takes its\n * evidence with it when it goes, so anything reconstructed afterwards is\n * inference. Kept bounded, because a session is not a log file.\n */\n readonly notices: readonly string[];\n write(data: Uint8Array): void;\n /**\n * Stops further terminal input and closes only that pipe side. The process,\n * pseudoconsole and authoritative output stream stay alive.\n */\n closeInput(): void;\n writeApplicationInput(data: Uint8Array, kind: 'key' | 'mouse' | 'paste' | 'raw'): void;\n writeTerminalResponse(data: Uint8Array): ConPtyTerminalResponseRoute;\n resize(columns: number, rows: number): boolean;\n terminateTree(): void;\n activeProcesses(): number;\n onData(listener: (data: Uint8Array) => void): () => void;\n onExit(listener: (status: WindowsPtyExit) => void): () => void;\n onError(listener: (error: Error) => void): () => void;\n onDrain(listener: () => void): () => void;\n /**\n * Lifecycle notices as they are recorded.\n *\n * A notice describing an instant arrives after the event it follows, so\n * reading `notices` inside an exit listener sees the state before it. This\n * is how a caller waits for the account rather than racing it.\n */\n onNotice(listener: (message: string) => void): () => void;\n dispose(): void;\n}\n\nexport function spawnWindowsPty(options: WindowsPtySpawnOptions): WindowsPtyHandle {\n const binding = loadWindowsBinding();\n const dataListeners = new Set<(data: Uint8Array) => void>();\n const exitListeners = new Set<(status: WindowsPtyExit) => void>();\n const errorListeners = new Set<(error: Error) => void>();\n const drainListeners = new Set<() => void>();\n const noticeListeners = new Set<(message: string) => void>();\n\n let resolveEnded: (() => void) | undefined;\n const outputEnded = new Promise<void>((resolve) => {\n resolveEnded = resolve;\n });\n let ended = false;\n let endReason: number | undefined;\n let disposed = false;\n let inputClosed = false;\n const writeEpoch = new NativeWriteDrainEpoch();\n const terminalResponseRouter = new ConPtyTerminalResponseRouter();\n const terminalResponseTransport = new ConPtyTerminalResponseTransport();\n const outputNormalizer = new ConPtyControlPlaneNormalizer((query) =>\n terminalResponseRouter.noteHostQuery(query),\n );\n const notices: string[] = [];\n const NOTICE_LIMIT = 64;\n\n const write = (data: Uint8Array): void => {\n if (disposed || inputClosed) throw new Error('ConPTY input is closed');\n const bytes = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n writeEpoch.admit(bytes, (admitted) => session.write(admitted));\n };\n\n const session = new binding.ConPtySession(\n {\n commandLine: buildCommandLine(options.command),\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n env: buildEnvironment(options.env),\n columns: options.columns,\n rows: options.rows,\n },\n (event) => {\n switch (event.type) {\n case 'data':\n {\n const data = outputNormalizer.push(event.data);\n if (data.length > 0) {\n for (const listener of [...dataListeners]) listener(data);\n }\n }\n return;\n case 'exit': {\n // A Windows exit code is not a signal. Reporting it as one would\n // invent POSIX semantics the platform does not have.\n const status: WindowsPtyExit = { code: event.exitCode, signal: null };\n for (const listener of [...exitListeners]) listener(status);\n return;\n }\n case 'eof':\n {\n // A possible prefix withheld across a ReadFile boundary is child\n // output unless the rest of the host structure actually arrives.\n // Release it on the same ordered channel, before authoritative EOF.\n const tail = outputNormalizer.finish();\n if (tail.length > 0) {\n for (const listener of [...dataListeners]) listener(tail);\n }\n }\n endReason = event.code;\n // Delivered on the same ordered channel as the data before it, so\n // every chunk has already reached its listeners by now.\n ended = true;\n resolveEnded?.();\n return;\n case 'drain':\n if (!writeEpoch.isCurrent(event.generation)) return;\n for (const listener of [...drainListeners]) listener();\n return;\n case 'notice':\n // Oldest dropped first: a session that somehow produces more of\n // these than the bound must not grow without limit, and the last\n // ones are the ones that describe how it ended.\n if (notices.length >= NOTICE_LIMIT) notices.shift();\n notices.push(event.message);\n for (const listener of [...noticeListeners]) listener(event.message);\n return;\n case 'error': {\n const failure = Object.assign(new Error(event.message), {\n win32: event.code,\n });\n for (const listener of [...errorListeners]) listener(failure);\n return;\n }\n }\n },\n );\n\n return {\n get pid(): number {\n return session.pid;\n },\n get runtimeInfo(): WindowsConPtyRuntimeInfo {\n return windowsConPtyRuntimeInfo();\n },\n get sawRealEof(): boolean {\n return ended;\n },\n get endReason(): number | undefined {\n return endReason;\n },\n get notices(): readonly string[] {\n return [...notices];\n },\n outputEnded,\n write(data: Uint8Array): void {\n write(data);\n },\n closeInput(): void {\n if (disposed || inputClosed) return;\n inputClosed = true;\n session.closeInput();\n },\n writeApplicationInput(data, kind): void {\n write(encodeConPtyApplicationInput(data, kind));\n },\n writeTerminalResponse(data: Uint8Array): ConPtyTerminalResponseRoute {\n const route = terminalResponseRouter.route(data);\n write(terminalResponseTransport.encode(route, data));\n return route;\n },\n resize(columns: number, rows: number): boolean {\n return disposed ? false : session.resize(columns, rows);\n },\n terminateTree(): void {\n if (!disposed) session.terminateTree();\n },\n activeProcesses(): number {\n return disposed ? -1 : session.activeProcesses();\n },\n onData(listener): () => void {\n dataListeners.add(listener);\n return () => dataListeners.delete(listener);\n },\n onExit(listener): () => void {\n exitListeners.add(listener);\n return () => exitListeners.delete(listener);\n },\n onError(listener): () => void {\n errorListeners.add(listener);\n return () => errorListeners.delete(listener);\n },\n onDrain(listener): () => void {\n drainListeners.add(listener);\n return () => drainListeners.delete(listener);\n },\n onNotice(listener): () => void {\n noticeListeners.add(listener);\n return () => noticeListeners.delete(listener);\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n session.dispose();\n // Disposal is not evidence of EOF. It unblocks anyone waiting only so a\n // teardown cannot hang; whether the stream truly ended is recorded by\n // `ended`, which nothing but the reader sets.\n resolveEnded?.();\n dataListeners.clear();\n exitListeners.clear();\n errorListeners.clear();\n drainListeners.clear();\n noticeListeners.clear();\n },\n };\n}\n","/** Keeps native drain edges tied to the writes they actually completed. */\nexport class NativeWriteDrainEpoch {\n #generation = 0n;\n\n admit<T extends Uint8Array>(data: T, write: (data: T) => void): void {\n // Advance only after native admission succeeds. Rejected and zero-length\n // writes therefore leave the JavaScript and native generations aligned.\n write(data);\n if (data.byteLength > 0) this.#generation += 1n;\n }\n\n isCurrent(generation: bigint): boolean {\n return generation === this.#generation;\n }\n}\n","/**\n * Removes control-plane modes injected by the vendored ConPTY host.\n *\n * The passthrough ConPTY deliberately enables focus and Win32 input modes for\n * its own input transport. Those bytes describe the host, not the child, and\n * must not reach the terminal emulator as application-owned mode evidence.\n * The transform is byte based: VT control sequences are ASCII and can be\n * divided at any byte by the anonymous output pipe.\n */\n\nimport { parseConPtyHostCursorResponse } from '@termwright/protocol';\n\nconst ESC = 0x1b;\n\nconst bytes = (...values: number[]): Buffer => Buffer.from(values);\n\nconst DA1 = bytes(ESC, 0x5b, 0x63);\nconst WINDOW_DEICONIFY = bytes(ESC, 0x5b, 0x31, 0x74);\nconst WINDOW_ICONIFY = bytes(ESC, 0x5b, 0x32, 0x74);\nconst FOCUS_ON = bytes(ESC, 0x5b, 0x3f, 0x31, 0x30, 0x30, 0x34, 0x68);\nconst FOCUS_OFF = bytes(ESC, 0x5b, 0x3f, 0x31, 0x30, 0x30, 0x34, 0x6c);\nconst WIN32_ON = bytes(ESC, 0x5b, 0x3f, 0x39, 0x30, 0x30, 0x31, 0x68);\nconst WIN32_OFF = bytes(ESC, 0x5b, 0x3f, 0x39, 0x30, 0x30, 0x31, 0x6c);\nconst RIS = bytes(ESC, 0x63);\nconst HOST_CURSOR_REQUEST_PREFIX = Buffer.from('\\x1b]8488;twh-cpr-v1:q:', 'ascii');\nconst HOST_CURSOR_REQUEST_TOKEN_BYTES = 32;\nconst HOST_CURSOR_REPLY_NAMESPACE = Buffer.from('\\x1b]8488;twh-cpr-v1:r:', 'ascii');\n\ninterface Rewrite {\n readonly input: Buffer;\n readonly output: Buffer;\n readonly hostQueries?: readonly ConPtyHostQuery[];\n}\n\nexport type ConPtyHostQuery = 'primary-device-attributes';\nexport type ConPtyTerminalResponseRoute = 'host-control' | 'application-win32-input';\n\nexport function encodeWin32InputModeTerminalResponse(data: Uint8Array): Buffer {\n let encoded = '';\n for (const byte of data) {\n if (byte > 0x7f) {\n throw new TypeError(\n `terminal response contains non-ASCII byte 0x${byte.toString(16).padStart(2, '0')}`,\n );\n }\n encoded += `\\u001b[0;0;${byte};1;0;1_`;\n }\n return Buffer.from(encoded, 'ascii');\n}\n\nexport function encodeConPtyApplicationInput(\n data: Uint8Array,\n kind: 'key' | 'mouse' | 'paste' | 'raw',\n): Buffer {\n // Preserve the complete physical Escape event. Reusing the byte-oriented\n // terminal-response encoder would deliver UnicodeChar=ESC but erase the\n // VK/scan identity observed by ReadConsoleInput applications.\n return kind === 'key' && data.byteLength === 1 && data[0] === 0x1b\n ? Buffer.from('\\x1b[27;1;27;1;0;1_', 'ascii')\n : Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n}\n\nexport class ConPtyTerminalResponseTransport {\n encode(route: ConPtyTerminalResponseRoute, data: Uint8Array): Buffer {\n if (route === 'application-win32-input') {\n return encodeWin32InputModeTerminalResponse(data);\n }\n return Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n }\n}\n\nfunction isHostResponse(response: Buffer): boolean {\n const text = response.toString('ascii');\n return /^\\x1b\\[\\?[\\d;]*c$/u.test(text);\n}\n\n/**\n * Preserves the ownership of startup queries emitted by ConPTY itself.\n *\n * Host-control replies must be written as raw VT so OpenConsole consumes\n * them. Application replies must use Win32 Input Mode so they reach the\n * child as terminal protocol bytes. The queue is populated by the same\n * split-safe startup rewrite that exposes each query to the emulator.\n */\nexport class ConPtyTerminalResponseRouter {\n readonly #hostQueries: ConPtyHostQuery[] = [];\n\n noteHostQuery(query: ConPtyHostQuery): void {\n this.#hostQueries.push(query);\n }\n\n route(response: Uint8Array): ConPtyTerminalResponseRoute {\n const bytes = Buffer.from(response.buffer, response.byteOffset, response.byteLength);\n const query = this.#hostQueries[0];\n // Cursor synchronization is a private request-addressed OSC RPC in the\n // pinned host. Standard CPR is therefore always application-owned and can\n // never be stolen by a host capture state.\n if (parseConPtyHostCursorResponse(bytes) !== null) return 'host-control';\n // The versioned reply prefix is reserved to the pinned host. A stale or\n // malformed reply must still travel raw to OpenConsole, which consumes it\n // fail-closed; encoding it as W32IM would expose host control bytes to the\n // application input queue. Other OSC 8488 payloads remain application-owned.\n if (bytes.subarray(0, HOST_CURSOR_REPLY_NAMESPACE.length).equals(HOST_CURSOR_REPLY_NAMESPACE)) {\n return 'host-control';\n }\n if (query === undefined) return 'application-win32-input';\n if (!isHostResponse(bytes)) {\n throw new Error(`terminal answered ${query} ConPTY host query with an unexpected response`);\n }\n this.#hostQueries.shift();\n return 'host-control';\n }\n}\n\nconst STARTUP_REWRITES: readonly Rewrite[] = [\n {\n // VtIo's ordinary startup handshake.\n input: Buffer.concat([DA1, FOCUS_ON, WIN32_ON]),\n output: DA1,\n hostQueries: ['primary-device-attributes'],\n },\n];\n\ntype StartupPassThrough =\n | { readonly kind: 'complete'; readonly length: number }\n | {\n readonly kind: 'partial';\n }\n | null;\n\nfunction startupPassThrough(input: Buffer, offset: number): StartupPassThrough {\n for (const fixed of [WINDOW_DEICONIFY, WINDOW_ICONIFY]) {\n if (!hasPrefixAt(input, offset, fixed)) continue;\n return input.length - offset < fixed.length\n ? { kind: 'partial' }\n : { kind: 'complete', length: fixed.length };\n }\n if (!hasPrefixAt(input, offset, HOST_CURSOR_REQUEST_PREFIX)) return null;\n const remaining = input.length - offset;\n if (remaining < HOST_CURSOR_REQUEST_PREFIX.length) return { kind: 'partial' };\n const tokenStart = offset + HOST_CURSOR_REQUEST_PREFIX.length;\n const availableToken = Math.min(HOST_CURSOR_REQUEST_TOKEN_BYTES, input.length - tokenStart);\n for (let index = 0; index < availableToken; index += 1) {\n const byte = input[tokenStart + index]!;\n const hexadecimal = (byte >= 0x30 && byte <= 0x39) || (byte >= 0x61 && byte <= 0x66);\n if (!hexadecimal) return null;\n }\n const total = HOST_CURSOR_REQUEST_PREFIX.length + HOST_CURSOR_REQUEST_TOKEN_BYTES + 1;\n if (remaining < total) return { kind: 'partial' };\n if (input[offset + total - 1] !== 0x07) return null;\n return { kind: 'complete', length: total };\n}\n\nconst HOST_REWRITES: readonly Rewrite[] = [\n // AdaptDispatch reinjects these immediately after the child reset that\n // caused them. Keeping the reset preserves the child's original bytes.\n { input: Buffer.concat([FOCUS_OFF, FOCUS_ON]), output: FOCUS_OFF },\n { input: Buffer.concat([WIN32_OFF, WIN32_ON]), output: WIN32_OFF },\n { input: Buffer.concat([RIS, FOCUS_ON, WIN32_ON]), output: RIS },\n];\n\nfunction hasPrefixAt(input: Buffer, offset: number, pattern: Buffer): boolean {\n const available = Math.min(input.length - offset, pattern.length);\n for (let index = 0; index < available; index += 1) {\n if (input[offset + index] !== pattern[index]) return false;\n }\n return true;\n}\n\n/**\n * A deterministic streaming transducer for one ConPTY output stream.\n *\n * `push()` may retain only a suffix which could still become a host rewrite.\n * `finish()` releases that suffix verbatim, so a truncated or merely similar\n * child sequence is never lost at authoritative EOF.\n */\nexport class ConPtyControlPlaneNormalizer {\n #pending = Buffer.alloc(0);\n #atStreamStart = true;\n #finished = false;\n\n constructor(readonly onHostQuery: (query: ConPtyHostQuery) => void = () => undefined) {}\n\n push(chunk: Uint8Array): Buffer {\n if (this.#finished) {\n throw new Error('ConPTY output arrived after authoritative EOF');\n }\n if (chunk.byteLength === 0) return Buffer.alloc(0);\n\n const incoming = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);\n const input = this.#pending.length === 0 ? incoming : Buffer.concat([this.#pending, incoming]);\n this.#pending = Buffer.alloc(0);\n\n const output: Buffer[] = [];\n let literalStart = 0;\n let offset = 0;\n\n while (offset < input.length) {\n if (this.#atStreamStart) {\n const passThrough = startupPassThrough(input, offset);\n if (passThrough?.kind === 'partial') {\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n this.#pending = Buffer.from(input.subarray(offset));\n return output.length === 0 ? Buffer.alloc(0) : Buffer.concat(output);\n }\n if (passThrough?.kind === 'complete') {\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n output.push(input.subarray(offset, offset + passThrough.length));\n offset += passThrough.length;\n literalStart = offset;\n continue;\n }\n }\n const rewrites = this.#atStreamStart\n ? [...STARTUP_REWRITES, ...HOST_REWRITES]\n : HOST_REWRITES;\n let rewritten = false;\n let awaitingSuffix = false;\n\n for (const rewrite of rewrites) {\n if (!hasPrefixAt(input, offset, rewrite.input)) continue;\n const remaining = input.length - offset;\n if (remaining < rewrite.input.length) {\n awaitingSuffix = true;\n break;\n }\n\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n output.push(rewrite.output);\n for (const query of rewrite.hostQueries ?? []) this.onHostQuery(query);\n offset += rewrite.input.length;\n literalStart = offset;\n this.#atStreamStart = false;\n rewritten = true;\n break;\n }\n\n if (rewritten) continue;\n if (awaitingSuffix) {\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n this.#pending = Buffer.from(input.subarray(offset));\n return output.length === 0 ? Buffer.alloc(0) : Buffer.concat(output);\n }\n\n // This byte cannot begin any host-owned structure. It is child output.\n this.#atStreamStart = false;\n offset += 1;\n }\n\n if (literalStart < input.length) output.push(input.subarray(literalStart));\n return output.length === 0 ? Buffer.alloc(0) : Buffer.concat(output);\n }\n\n finish(): Buffer {\n if (this.#finished) return Buffer.alloc(0);\n this.#finished = true;\n const tail = this.#pending;\n this.#pending = Buffer.alloc(0);\n return tail;\n }\n}\n"],"mappings":"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","names":["createRequire","bytes","require","bytes","cachedBinding","require","createRequire","unavailableReason","writeWindowsConsoleMarker","session","bytes"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/windows.ts","../src/write-drain-epoch.ts","../src/windows-output-normalizer.ts"],"sourcesContent":["/**\n * Termwright-owned native PTY session.\n *\n * The POSIX implementation owns the `forkpty()` master and reads it until the\n * kernel reports EOF (EIO after the queued tail on Linux). No JavaScript\n * stream, private node-pty field, quiet window, or retry decides that output\n * has ended.\n */\nimport { createRequire } from 'node:module';\nimport { getSystemErrorName } from 'node:util';\nimport {\n spawnWindowsPty,\n writeWindowsConsoleMarker as writeNativeWindowsConsoleMarker,\n windowsConPtyRuntimeInfo,\n windowsPtyAvailable,\n windowsPtyUnavailableReason,\n type WindowsConPtyRuntimeInfo,\n} from './windows.js';\nimport { NativeWriteDrainEpoch } from './write-drain-epoch.js';\n\nexport {\n encodeConPtyApplicationInput,\n encodeConPtyApplicationTerminalResponse,\n} from './windows-output-normalizer.js';\n\ntype NativeEvent =\n | { readonly type: 'data'; readonly data: Buffer }\n | {\n readonly type: 'exit';\n readonly exitCode: number;\n readonly signal: number;\n }\n | { readonly type: 'eof'; readonly code: number }\n | { readonly type: 'drain'; readonly generation: bigint }\n | { readonly type: 'error'; readonly message: string; readonly code: number };\n\ninterface NativeSession {\n readonly pid: number;\n write(data: Buffer): void;\n resize(columns: number, rows: number): boolean;\n /** Zero on delivery/already-gone; otherwise the positive POSIX errno. */\n signal(signal: number): number;\n treeState(): number;\n dispose(): void;\n}\n\ninterface NativeBinding {\n new (\n options: {\n readonly command: readonly string[];\n readonly cwd?: string;\n readonly env: readonly string[];\n readonly columns: number;\n readonly rows: number;\n },\n onEvent: (event: NativeEvent) => void,\n ): NativeSession;\n}\n\nlet cachedBinding: { readonly PosixPtySession: NativeBinding } | undefined;\n\nexport function candidatePaths(\n platform: NodeJS.Platform = process.platform,\n architecture: string = process.arch,\n): readonly string[] {\n return [\n '../build/Release/termwright_pty.node',\n `@termwright/pty-${platform}-${architecture}/termwright_pty.node`,\n ];\n}\n\nexport function loadPtyBinding(): { readonly PosixPtySession: NativeBinding } {\n if (cachedBinding !== undefined) return cachedBinding;\n if (process.platform === 'win32') {\n throw new Error('the POSIX @termwright/pty binding cannot load on Windows');\n }\n if (process.platform !== 'darwin' && process.platform !== 'linux') {\n throw new Error(`@termwright/pty does not support ${process.platform}-${process.arch}`);\n }\n const require = createRequire(import.meta.url);\n const attempts: string[] = [];\n for (const candidate of candidatePaths()) {\n try {\n cachedBinding = require(candidate) as {\n readonly PosixPtySession: NativeBinding;\n };\n return cachedBinding;\n } catch (error) {\n attempts.push(\n `${candidate}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n );\n }\n }\n throw new Error(\n `no Termwright PTY addon could be loaded for ${process.platform}-${process.arch}. Tried:\\n ${attempts.join('\\n ')}`,\n );\n}\n\nlet unavailableReason: string | undefined;\n\nexport function ptyAvailable(): boolean {\n if (process.platform === 'win32') return windowsPtyAvailable();\n try {\n loadPtyBinding();\n unavailableReason = undefined;\n return true;\n } catch (error) {\n unavailableReason = error instanceof Error ? error.message : String(error);\n return false;\n }\n}\n\nexport function ptyUnavailableReason(): string | undefined {\n return process.platform === 'win32' ? windowsPtyUnavailableReason() : unavailableReason;\n}\n\nexport interface PtySpawnOptions {\n readonly command: readonly string[];\n readonly cwd?: string;\n readonly env: Readonly<Record<string, string>>;\n readonly columns: number;\n readonly rows: number;\n}\n\nexport interface PtyExit {\n readonly code: number | null;\n readonly signal: string | null;\n}\n\nexport type PtySignal = 'INT' | 'TERM' | 'KILL' | 'HUP';\nexport type { WindowsConPtyRuntimeInfo };\n\n/** Runtime provenance and strict initialization status for the Windows backend. */\nexport function conPtyRuntimeInfo(): WindowsConPtyRuntimeInfo {\n if (process.platform !== 'win32') {\n throw new Error('ConPTY runtime information is only available on Windows');\n }\n return windowsConPtyRuntimeInfo();\n}\n\n/**\n * Writes a marker through WriteConsoleW while temporarily enforcing the two\n * output-mode bits required for VT control sequences. Windows probes use this\n * instead of duplicating mode mutation and restoration logic.\n */\nexport function writeWindowsConsoleMarker(fd: number, marker: string): void {\n if (process.platform !== 'win32') {\n throw new Error('Windows console markers are only available on Windows');\n }\n writeNativeWindowsConsoleMarker(fd, marker);\n}\n\nexport interface PtyHandle {\n readonly pid: number;\n readonly outputEnded: Promise<void>;\n readonly sawRealEof: boolean;\n readonly endReason: number | undefined;\n write(data: Uint8Array): void;\n writeApplicationInput?(data: Uint8Array, kind: 'key' | 'mouse' | 'paste' | 'raw'): void;\n writeTerminalResponse?(\n data: Uint8Array,\n ): 'host-control' | 'application-envelope' | 'application-direct';\n /** Closes the parent-owned terminal input while preserving output drain. */\n closeInput?(): void;\n resize(columns: number, rows: number): boolean;\n signal(signal: PtySignal): boolean;\n treeState(): 'alive' | 'gone' | 'unsupported';\n onData(listener: (data: Uint8Array) => void): () => void;\n onExit(listener: (status: PtyExit) => void): () => void;\n onError(listener: (error: Error) => void): () => void;\n onDrain(listener: () => void): () => void;\n dispose(): void;\n}\n\nconst signalNumbers: Readonly<Record<PtySignal, number>> = Object.freeze({\n HUP: 1,\n INT: 2,\n KILL: 9,\n TERM: 15,\n});\n\nconst signalNames: Readonly<Record<number, string>> = Object.freeze({\n 1: 'SIGHUP',\n 2: 'SIGINT',\n 3: 'SIGQUIT',\n 6: 'SIGABRT',\n 9: 'SIGKILL',\n 13: 'SIGPIPE',\n 15: 'SIGTERM',\n});\n\nfunction validateOptions(options: PtySpawnOptions): void {\n if (\n options.command.length === 0 ||\n options.command.some((part) => typeof part !== 'string' || part.includes('\\0'))\n ) {\n throw new TypeError('command must be a non-empty array of NUL-free strings');\n }\n if (\n options.cwd !== undefined &&\n (typeof options.cwd !== 'string' || options.cwd.includes('\\0'))\n ) {\n throw new TypeError('cwd must be a NUL-free string');\n }\n for (const [key, value] of Object.entries(options.env)) {\n if (\n key.length === 0 ||\n key.includes('=') ||\n key.includes('\\0') ||\n typeof value !== 'string' ||\n value.includes('\\0')\n ) {\n throw new TypeError('environment keys and values must be valid execve strings');\n }\n }\n for (const [field, value] of [\n ['columns', options.columns],\n ['rows', options.rows],\n ] as const) {\n if (!Number.isInteger(value) || value < 1 || value > 32_767) {\n throw new RangeError(`${field} must be an integer from 1 through 32767`);\n }\n }\n}\n\nexport function spawnPty(options: PtySpawnOptions): PtyHandle {\n validateOptions(options);\n if (process.platform === 'win32') {\n const session = spawnWindowsPty(options);\n return {\n get pid(): number {\n return session.pid;\n },\n get sawRealEof(): boolean {\n return session.sawRealEof;\n },\n get endReason(): number | undefined {\n return session.endReason;\n },\n outputEnded: session.outputEnded,\n write(data): void {\n session.write(data);\n },\n writeApplicationInput(data, kind): void {\n session.writeApplicationInput(data, kind);\n },\n writeTerminalResponse(data) {\n return session.writeTerminalResponse(data);\n },\n closeInput(): void {\n session.closeInput();\n },\n resize(columns, rows): boolean {\n return session.resize(columns, rows);\n },\n signal(signal): boolean {\n if (signal !== 'KILL') return false;\n session.terminateTree();\n return true;\n },\n treeState(): 'alive' | 'gone' | 'unsupported' {\n const members = session.activeProcesses();\n return members < 0 ? 'unsupported' : members === 0 ? 'gone' : 'alive';\n },\n onData(listener): () => void {\n return session.onData(listener);\n },\n onExit(listener): () => void {\n return session.onExit(listener);\n },\n onError(listener): () => void {\n return session.onError(listener);\n },\n onDrain(listener): () => void {\n return session.onDrain(listener);\n },\n dispose(): void {\n session.dispose();\n },\n };\n }\n const dataListeners = new Set<(data: Uint8Array) => void>();\n const exitListeners = new Set<(status: PtyExit) => void>();\n const errorListeners = new Set<(error: Error) => void>();\n const drainListeners = new Set<() => void>();\n let exitStatus: PtyExit | undefined;\n let fatalError: Error | undefined;\n let resolveEnded: (() => void) | undefined;\n const outputEnded = new Promise<void>((resolve) => {\n resolveEnded = resolve;\n });\n let ended = false;\n let endReason: number | undefined;\n let disposed = false;\n const writeEpoch = new NativeWriteDrainEpoch();\n\n const session = new (loadPtyBinding().PosixPtySession)(\n {\n command: [...options.command],\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n env: Object.entries(options.env).map(([key, value]) => `${key}=${value}`),\n columns: options.columns,\n rows: options.rows,\n },\n (event) => {\n switch (event.type) {\n case 'data':\n for (const listener of [...dataListeners]) listener(event.data);\n return;\n case 'exit': {\n exitStatus =\n event.signal === 0\n ? { code: event.exitCode, signal: null }\n : {\n code: null,\n signal: signalNames[event.signal] ?? `SIG${event.signal}`,\n };\n for (const listener of [...exitListeners]) listener(exitStatus);\n return;\n }\n case 'eof':\n endReason = event.code;\n ended = event.code === 0;\n resolveEnded?.();\n return;\n case 'drain':\n if (!writeEpoch.isCurrent(event.generation)) return;\n for (const listener of [...drainListeners]) listener();\n return;\n case 'error': {\n const code = getSystemErrorName(-event.code);\n const guidance =\n code === 'EMFILE'\n ? \" Raise this process's open-file limit (for example with `ulimit -n`) and retry.\"\n : code === 'ENFILE'\n ? ' The host-wide open-file table is exhausted; raise the system limit or reduce concurrent processes.'\n : '';\n fatalError ??= Object.assign(new Error(`${event.message}${guidance}`), {\n code,\n errno: event.code,\n });\n for (const listener of [...errorListeners]) listener(fatalError);\n return;\n }\n }\n },\n );\n\n return {\n get pid(): number {\n return session.pid;\n },\n get sawRealEof(): boolean {\n return ended;\n },\n get endReason(): number | undefined {\n return endReason;\n },\n outputEnded,\n write(data): void {\n if (disposed) throw new Error('PTY input is closed');\n const bytes = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n writeEpoch.admit(bytes, (admitted) => session.write(admitted));\n },\n resize(columns, rows): boolean {\n if (\n !Number.isInteger(columns) ||\n !Number.isInteger(rows) ||\n columns < 1 ||\n rows < 1 ||\n columns > 32_767 ||\n rows > 32_767\n )\n return false;\n return !disposed && session.resize(columns, rows);\n },\n signal(signal): boolean {\n if (disposed) return false;\n const code = session.signal(signalNumbers[signal]);\n if (code === 0) return true;\n throw Object.assign(new Error(`kill(PTY process group) failed with errno ${code}`), {\n code: getSystemErrorName(-code),\n errno: code,\n });\n },\n treeState(): 'alive' | 'gone' | 'unsupported' {\n const state = disposed ? -1 : session.treeState();\n return state > 0 ? 'alive' : state === 0 ? 'gone' : 'unsupported';\n },\n onData(listener): () => void {\n dataListeners.add(listener);\n return () => dataListeners.delete(listener);\n },\n onExit(listener): () => void {\n exitListeners.add(listener);\n const observed = exitStatus;\n if (observed !== undefined)\n queueMicrotask(() => {\n if (exitListeners.has(listener)) listener(observed);\n });\n return () => exitListeners.delete(listener);\n },\n onError(listener): () => void {\n errorListeners.add(listener);\n const observed = fatalError;\n if (observed !== undefined)\n queueMicrotask(() => {\n if (errorListeners.has(listener)) listener(observed);\n });\n return () => errorListeners.delete(listener);\n },\n onDrain(listener): () => void {\n drainListeners.add(listener);\n return () => drainListeners.delete(listener);\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n session.dispose();\n resolveEnded?.();\n dataListeners.clear();\n exitListeners.clear();\n errorListeners.clear();\n drainListeners.clear();\n },\n };\n}\n","/**\n * Termwright's Windows PTY backend.\n *\n * One native session owns the pseudoconsole, both host pipe ends, the root\n * process and thread, and the job object holding the tree. Two facts follow\n * from that ownership and are the reason this package exists:\n *\n * - a session ends when the output pipe actually ends, never when a timer says\n * nothing has arrived lately;\n * - the process tree is a job object from before the root can run, so proving\n * it empty is a query rather than a race against process enumeration.\n */\n\nimport { createRequire } from 'node:module';\nimport { NativeWriteDrainEpoch } from './write-drain-epoch.js';\nimport {\n ConPtyControlPlaneNormalizer,\n ConPtyTerminalResponseRouter,\n ConPtyTerminalResponseTransport,\n encodeConPtyApplicationInput,\n type ConPtyTerminalResponseRoute,\n} from './windows-output-normalizer.js';\n\n/** Ordered messages the native session emits. Data always precedes the end. */\ntype NativeEvent =\n | { readonly type: 'data'; readonly data: Buffer }\n | { readonly type: 'exit'; readonly exitCode: number }\n | { readonly type: 'eof'; readonly code: number }\n | { readonly type: 'drain'; readonly generation: bigint }\n | { readonly type: 'notice'; readonly message: string }\n | { readonly type: 'error'; readonly message: string; readonly code: number };\n\ninterface NativeSession {\n readonly pid: number;\n write(data: Buffer): void;\n closeInput(): void;\n resize(columns: number, rows: number): boolean;\n terminateTree(): void;\n activeProcesses(): number;\n dispose(): void;\n}\n\ninterface NativeBindingConstructor {\n new (\n options: {\n readonly commandLine: string;\n readonly cwd?: string;\n readonly env?: readonly string[];\n readonly columns: number;\n readonly rows: number;\n },\n onEvent: (event: NativeEvent) => void,\n ): NativeSession;\n}\n\ninterface LoadedWindowsBinding {\n readonly ConPtySession: NativeBindingConstructor;\n conPtyRuntimeInfo(): WindowsConPtyRuntimeInfo;\n writeWindowsConsoleMarker(fd: number, marker: string): void;\n}\n\n/** Provenance and behavioral contract of the loaded Windows pseudoconsole. */\nexport interface WindowsConPtyRuntimeInfo {\n readonly provider: 'termwright-patched-openconsole';\n readonly upstreamCommit: 'dd494ac79a82a04e1e7252a91c8939a3c3039908';\n readonly patchSha256: 'eae93025548fe697fa08242587e28abaeb06cc5ca7646fff0d9bef280c77770c';\n readonly hostCursorRpc: 'twh-cpr-v1';\n readonly applicationReplyRpc: 'twh-app-reply-v1';\n readonly mode: 'ordered-vt-passthrough';\n readonly policy: 'strict';\n readonly selectedHostArchitecture: '' | 'x64' | 'arm64';\n readonly failureCode: string;\n readonly failureWin32: number;\n readonly assetsValidated: boolean;\n readonly coreExports: boolean;\n readonly orderedMarkerSemantics: 'marker-authoritative-after-behavioral-certification';\n}\n\nfunction assertRuntimeInfoShape(value: WindowsConPtyRuntimeInfo): WindowsConPtyRuntimeInfo {\n if (\n value.provider !== 'termwright-patched-openconsole' ||\n value.upstreamCommit !== 'dd494ac79a82a04e1e7252a91c8939a3c3039908' ||\n value.patchSha256 !== 'eae93025548fe697fa08242587e28abaeb06cc5ca7646fff0d9bef280c77770c' ||\n value.hostCursorRpc !== 'twh-cpr-v1' ||\n value.applicationReplyRpc !== 'twh-app-reply-v1' ||\n Object.hasOwn(value, 'package') ||\n Object.hasOwn(value, 'version') ||\n value.mode !== 'ordered-vt-passthrough' ||\n value.policy !== 'strict' ||\n (value.selectedHostArchitecture !== '' &&\n value.selectedHostArchitecture !== 'x64' &&\n value.selectedHostArchitecture !== 'arm64') ||\n typeof value.failureCode !== 'string' ||\n typeof value.failureWin32 !== 'number' ||\n typeof value.assetsValidated !== 'boolean' ||\n typeof value.coreExports !== 'boolean' ||\n value.orderedMarkerSemantics !== 'marker-authoritative-after-behavioral-certification'\n ) {\n throw new Error(`invalid vendored ConPTY capability report: ${JSON.stringify(value)}`);\n }\n return value;\n}\n\nfunction assertCertifiedRuntimeInfo(value: WindowsConPtyRuntimeInfo): WindowsConPtyRuntimeInfo {\n assertRuntimeInfoShape(value);\n if (\n (value.selectedHostArchitecture !== 'x64' && value.selectedHostArchitecture !== 'arm64') ||\n value.failureCode !== '' ||\n value.failureWin32 !== 0 ||\n value.assetsValidated !== true ||\n value.coreExports !== true\n ) {\n throw new Error(`uncertified vendored ConPTY runtime: ${JSON.stringify(value)}`);\n }\n return value;\n}\n\nlet cachedBinding: LoadedWindowsBinding | undefined;\nlet cachedDiagnosticBinding: LoadedWindowsBinding | undefined;\n\n/**\n * Where the addon is looked for, in order.\n *\n * The locally compiled binary comes first so that a working tree tests what it\n * just built rather than a published prebuild that happens to be installed\n * beside it — the alternative is a change to this addon that CI certifies\n * against the previous release.\n */\nexport function windowsCandidatePaths(architecture: string): readonly string[] {\n return [\n '../build/Release/termwright_pty.node',\n `@termwright/pty-win32-${architecture}/termwright_pty.node`,\n ];\n}\n\n/** Loads the compiled addon, or explains why this platform has none. */\nexport function loadWindowsBinding(): LoadedWindowsBinding {\n if (cachedBinding !== undefined) return cachedBinding;\n if (process.platform !== 'win32') {\n throw new Error('@termwright/pty Windows binding cannot load on a non-Windows host');\n }\n const require = createRequire(import.meta.url);\n const attempts: string[] = [];\n for (const candidate of windowsCandidatePaths(process.arch)) {\n try {\n const resolved = require.resolve(candidate);\n const loaded = require(resolved) as LoadedWindowsBinding;\n assertCertifiedRuntimeInfo(loaded.conPtyRuntimeInfo());\n cachedBinding = loaded;\n return cachedBinding;\n } catch (error) {\n // Kept per candidate. \"No addon\" is the same sentence whether the\n // prebuild for this architecture was never published, the install\n // skipped it, or it is present and failed to load — and those are three\n // different things to do next.\n attempts.push(\n `${candidate}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n );\n }\n }\n throw new Error(\n `no termwright ConPTY addon could be loaded for win32-${process.arch}. Tried:\\n ${attempts.join('\\n ')}`,\n );\n}\n\n/**\n * Returns a capability report even when strict runtime initialization failed.\n * A healthy candidate is preferred over an earlier diagnostic-only candidate.\n */\nexport function windowsConPtyRuntimeInfo(): WindowsConPtyRuntimeInfo {\n if (cachedBinding !== undefined) {\n return assertRuntimeInfoShape(cachedBinding.conPtyRuntimeInfo());\n }\n if (process.platform !== 'win32') {\n throw new Error('@termwright/pty Windows binding cannot load on a non-Windows host');\n }\n const require = createRequire(import.meta.url);\n const attempts: string[] = [];\n for (const candidate of windowsCandidatePaths(process.arch)) {\n try {\n const resolved = require.resolve(candidate);\n const loaded = require(resolved) as LoadedWindowsBinding;\n const runtime = assertRuntimeInfoShape(loaded.conPtyRuntimeInfo());\n if (\n runtime.failureCode === '' &&\n runtime.failureWin32 === 0 &&\n runtime.assetsValidated &&\n runtime.coreExports\n ) {\n cachedBinding = loaded;\n return runtime;\n }\n cachedDiagnosticBinding ??= loaded;\n } catch (error) {\n attempts.push(\n `${candidate}: ${error instanceof Error ? error.message.split('\\n')[0] : String(error)}`,\n );\n }\n }\n if (cachedDiagnosticBinding !== undefined) {\n return assertRuntimeInfoShape(cachedDiagnosticBinding.conPtyRuntimeInfo());\n }\n throw new Error(\n `no termwright ConPTY addon could be loaded for win32-${process.arch}. Tried:\\n ${attempts.join('\\n ')}`,\n );\n}\n\nlet unavailableReason: string | undefined;\n\n/** True when the addon is present and usable in this process. */\nexport function windowsPtyAvailable(): boolean {\n try {\n loadWindowsBinding();\n unavailableReason = undefined;\n return true;\n } catch (error) {\n // Kept, because \"not available\" is the least useful half of the answer.\n // A missing file, an ABI mismatch and a load-time failure inside the addon\n // all arrive here, and they are three different pieces of work.\n unavailableReason = error instanceof Error ? error.message : String(error);\n return false;\n }\n}\n\n/** Why the addon could not be loaded, as the loader reported it. */\nexport function windowsPtyUnavailableReason(): string | undefined {\n return unavailableReason;\n}\n\n/**\n * Writes an in-band marker to a real Windows console without inheriting a\n * framework's possibly-disabled VT output mode.\n *\n * The native primitive restores the exact original console mode before it\n * returns or throws. A successful return means WriteConsoleW accepted every\n * UTF-16 code unit synchronously.\n */\nexport function writeWindowsConsoleMarker(fd: number, marker: string): void {\n if (!Number.isInteger(fd) || fd < 0) {\n throw new RangeError('Windows console marker fd must be a non-negative integer');\n }\n if (typeof marker !== 'string' || marker.length === 0) {\n throw new TypeError('Windows console marker must be a non-empty string');\n }\n loadWindowsBinding().writeWindowsConsoleMarker(fd, marker);\n}\n\n/**\n * Quotes one argument the way CommandLineToArgvW parses it.\n *\n * Windows has no argv: the child re-parses a single string, so the caller's\n * exact arguments only survive if they are quoted to that specific grammar.\n * Backslashes are literal except immediately before a quote, where they are\n * doubled — including the run that precedes the closing quote.\n */\nexport function quoteWindowsArgument(argument: string): string {\n if (argument.length > 0 && !/[\\s\"]/u.test(argument)) return argument;\n let quoted = '\"';\n let backslashes = 0;\n for (const character of argument) {\n if (character === '\\\\') {\n backslashes += 1;\n continue;\n }\n if (character === '\"') {\n quoted += '\\\\'.repeat(backslashes * 2 + 1);\n quoted += '\"';\n backslashes = 0;\n continue;\n }\n quoted += '\\\\'.repeat(backslashes);\n quoted += character;\n backslashes = 0;\n }\n quoted += '\\\\'.repeat(backslashes * 2);\n return `${quoted}\"`;\n}\n\n/** Joins a command into the single string CreateProcessW takes. */\nexport function buildCommandLine(command: readonly string[]): string {\n if (command.length === 0) throw new TypeError('a ConPTY command needs at least an executable');\n return command.map(quoteWindowsArgument).join(' ');\n}\n\n/** Renders an environment map as the block CreateProcessW expects. */\nexport function buildEnvironment(env: Readonly<Record<string, string>>): readonly string[] {\n return Object.entries(env)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}=${value}`);\n}\n\nexport interface WindowsPtySpawnOptions {\n readonly command: readonly string[];\n readonly cwd?: string;\n readonly env: Readonly<Record<string, string>>;\n readonly columns: number;\n readonly rows: number;\n}\n\nexport interface WindowsPtyExit {\n readonly code: number | null;\n readonly signal: string | null;\n}\n\n/**\n * A live ConPTY session.\n *\n * `exited` and `outputEnded` are deliberately separate. A root process can\n * finish while its descendants still hold the pseudoconsole, so the last byte\n * of a session routinely arrives after the process that started it is gone.\n */\nexport interface WindowsPtyHandle {\n readonly pid: number;\n readonly runtimeInfo: WindowsConPtyRuntimeInfo;\n readonly outputEnded: Promise<void>;\n /**\n * True only when the output pipe actually ended.\n *\n * `outputEnded` also settles on disposal so a teardown cannot hang, which\n * means resolving it is not by itself evidence of EOF. This is the flag that\n * separates the two, and nothing but the reader sets it.\n *\n * The end itself is reached by the tree emptying: the job reports zero\n * active processes, which means no byte can follow, and the console is\n * closed only then. The reader still ends on the pipe rather than on a\n * timer — what changed is that the moment is chosen by evidence.\n */\n readonly sawRealEof: boolean;\n /**\n * The Win32 code the terminating read reported, or 0 for a clean end.\n *\n * A stream that ended for the wrong reason looks exactly like one that ended\n * properly, and telling them apart is the claim this backend exists to make.\n */\n readonly endReason: number | undefined;\n /**\n * The session's own account of its lifecycle, oldest first.\n *\n * Root exit, what the job said, and when the console was closed. These\n * moments are only observable while they happen: the console takes its\n * evidence with it when it goes, so anything reconstructed afterwards is\n * inference. Kept bounded, because a session is not a log file.\n */\n readonly notices: readonly string[];\n write(data: Uint8Array): void;\n /**\n * Stops further terminal input and closes only that pipe side. The process,\n * pseudoconsole and authoritative output stream stay alive.\n */\n closeInput(): void;\n writeApplicationInput(data: Uint8Array, kind: 'key' | 'mouse' | 'paste' | 'raw'): void;\n writeTerminalResponse(data: Uint8Array): ConPtyTerminalResponseRoute;\n resize(columns: number, rows: number): boolean;\n terminateTree(): void;\n activeProcesses(): number;\n onData(listener: (data: Uint8Array) => void): () => void;\n onExit(listener: (status: WindowsPtyExit) => void): () => void;\n onError(listener: (error: Error) => void): () => void;\n onDrain(listener: () => void): () => void;\n /**\n * Lifecycle notices as they are recorded.\n *\n * A notice describing an instant arrives after the event it follows, so\n * reading `notices` inside an exit listener sees the state before it. This\n * is how a caller waits for the account rather than racing it.\n */\n onNotice(listener: (message: string) => void): () => void;\n dispose(): void;\n}\n\nexport function spawnWindowsPty(options: WindowsPtySpawnOptions): WindowsPtyHandle {\n const binding = loadWindowsBinding();\n const dataListeners = new Set<(data: Uint8Array) => void>();\n const exitListeners = new Set<(status: WindowsPtyExit) => void>();\n const errorListeners = new Set<(error: Error) => void>();\n const drainListeners = new Set<() => void>();\n const noticeListeners = new Set<(message: string) => void>();\n\n let resolveEnded: (() => void) | undefined;\n const outputEnded = new Promise<void>((resolve) => {\n resolveEnded = resolve;\n });\n let ended = false;\n let endReason: number | undefined;\n let disposed = false;\n let inputClosed = false;\n const writeEpoch = new NativeWriteDrainEpoch();\n const terminalResponseRouter = new ConPtyTerminalResponseRouter();\n const terminalResponseTransport = new ConPtyTerminalResponseTransport();\n const outputNormalizer = new ConPtyControlPlaneNormalizer((query) =>\n terminalResponseRouter.noteHostQuery(query),\n );\n const notices: string[] = [];\n const NOTICE_LIMIT = 64;\n\n const write = (data: Uint8Array): void => {\n if (disposed || inputClosed) throw new Error('ConPTY input is closed');\n const bytes = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n writeEpoch.admit(bytes, (admitted) => session.write(admitted));\n };\n\n const session = new binding.ConPtySession(\n {\n commandLine: buildCommandLine(options.command),\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n env: buildEnvironment(options.env),\n columns: options.columns,\n rows: options.rows,\n },\n (event) => {\n switch (event.type) {\n case 'data':\n {\n const data = outputNormalizer.push(event.data);\n if (data.length > 0) {\n for (const listener of [...dataListeners]) listener(data);\n }\n }\n return;\n case 'exit': {\n // A Windows exit code is not a signal. Reporting it as one would\n // invent POSIX semantics the platform does not have.\n const status: WindowsPtyExit = { code: event.exitCode, signal: null };\n for (const listener of [...exitListeners]) listener(status);\n return;\n }\n case 'eof':\n {\n // A possible prefix withheld across a ReadFile boundary is child\n // output unless the rest of the host structure actually arrives.\n // Release it on the same ordered channel, before authoritative EOF.\n const tail = outputNormalizer.finish();\n if (tail.length > 0) {\n for (const listener of [...dataListeners]) listener(tail);\n }\n }\n endReason = event.code;\n // Delivered on the same ordered channel as the data before it, so\n // every chunk has already reached its listeners by now.\n ended = true;\n resolveEnded?.();\n return;\n case 'drain':\n if (!writeEpoch.isCurrent(event.generation)) return;\n for (const listener of [...drainListeners]) listener();\n return;\n case 'notice':\n // Oldest dropped first: a session that somehow produces more of\n // these than the bound must not grow without limit, and the last\n // ones are the ones that describe how it ended.\n if (notices.length >= NOTICE_LIMIT) notices.shift();\n notices.push(event.message);\n for (const listener of [...noticeListeners]) listener(event.message);\n return;\n case 'error': {\n const failure = Object.assign(new Error(event.message), {\n win32: event.code,\n });\n for (const listener of [...errorListeners]) listener(failure);\n return;\n }\n }\n },\n );\n\n return {\n get pid(): number {\n return session.pid;\n },\n get runtimeInfo(): WindowsConPtyRuntimeInfo {\n return windowsConPtyRuntimeInfo();\n },\n get sawRealEof(): boolean {\n return ended;\n },\n get endReason(): number | undefined {\n return endReason;\n },\n get notices(): readonly string[] {\n return [...notices];\n },\n outputEnded,\n write(data: Uint8Array): void {\n write(data);\n },\n closeInput(): void {\n if (disposed || inputClosed) return;\n inputClosed = true;\n session.closeInput();\n },\n writeApplicationInput(data, kind): void {\n write(encodeConPtyApplicationInput(data, kind));\n },\n writeTerminalResponse(data: Uint8Array): ConPtyTerminalResponseRoute {\n const route = terminalResponseRouter.route(data);\n write(terminalResponseTransport.encode(route, data));\n return route;\n },\n resize(columns: number, rows: number): boolean {\n return disposed ? false : session.resize(columns, rows);\n },\n terminateTree(): void {\n if (!disposed) session.terminateTree();\n },\n activeProcesses(): number {\n return disposed ? -1 : session.activeProcesses();\n },\n onData(listener): () => void {\n dataListeners.add(listener);\n return () => dataListeners.delete(listener);\n },\n onExit(listener): () => void {\n exitListeners.add(listener);\n return () => exitListeners.delete(listener);\n },\n onError(listener): () => void {\n errorListeners.add(listener);\n return () => errorListeners.delete(listener);\n },\n onDrain(listener): () => void {\n drainListeners.add(listener);\n return () => drainListeners.delete(listener);\n },\n onNotice(listener): () => void {\n noticeListeners.add(listener);\n return () => noticeListeners.delete(listener);\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n session.dispose();\n // Disposal is not evidence of EOF. It unblocks anyone waiting only so a\n // teardown cannot hang; whether the stream truly ended is recorded by\n // `ended`, which nothing but the reader sets.\n resolveEnded?.();\n dataListeners.clear();\n exitListeners.clear();\n errorListeners.clear();\n drainListeners.clear();\n noticeListeners.clear();\n },\n };\n}\n","/** Keeps native drain edges tied to the writes they actually completed. */\nexport class NativeWriteDrainEpoch {\n #generation = 0n;\n\n admit<T extends Uint8Array>(data: T, write: (data: T) => void): void {\n // Advance only after native admission succeeds. Rejected and zero-length\n // writes therefore leave the JavaScript and native generations aligned.\n write(data);\n if (data.byteLength > 0) this.#generation += 1n;\n }\n\n isCurrent(generation: bigint): boolean {\n return generation === this.#generation;\n }\n}\n","/**\n * Removes control-plane modes injected by the vendored ConPTY host.\n *\n * The passthrough ConPTY deliberately enables focus and Win32 input modes for\n * its own input transport. Those bytes describe the host, not the child, and\n * must not reach the terminal emulator as application-owned mode evidence.\n * The transform is byte based: VT control sequences are ASCII and can be\n * divided at any byte by the anonymous output pipe.\n */\n\nimport { parseConPtyHostCursorResponse } from '@termwright/protocol';\n\nconst ESC = 0x1b;\n\nconst bytes = (...values: number[]): Buffer => Buffer.from(values);\n\nconst DA1 = bytes(ESC, 0x5b, 0x63);\nconst WINDOW_DEICONIFY = bytes(ESC, 0x5b, 0x31, 0x74);\nconst WINDOW_ICONIFY = bytes(ESC, 0x5b, 0x32, 0x74);\nconst FOCUS_ON = bytes(ESC, 0x5b, 0x3f, 0x31, 0x30, 0x30, 0x34, 0x68);\nconst FOCUS_OFF = bytes(ESC, 0x5b, 0x3f, 0x31, 0x30, 0x30, 0x34, 0x6c);\nconst WIN32_ON = bytes(ESC, 0x5b, 0x3f, 0x39, 0x30, 0x30, 0x31, 0x68);\nconst WIN32_OFF = bytes(ESC, 0x5b, 0x3f, 0x39, 0x30, 0x30, 0x31, 0x6c);\nconst RIS = bytes(ESC, 0x63);\nconst HOST_CURSOR_REQUEST_PREFIX = Buffer.from('\\x1b]8488;twh-cpr-v1:q:', 'ascii');\nconst HOST_CURSOR_REQUEST_TOKEN_BYTES = 32;\nconst HOST_CURSOR_REPLY_NAMESPACE = Buffer.from('\\x1b]8488;twh-cpr-v1:r:', 'ascii');\nconst APPLICATION_REPLY_PREFIX = Buffer.from('\\x1b]8488;twh-app-reply-v1:', 'ascii');\nconst OSC_TERMINATOR = Buffer.from('\\x07', 'ascii');\nconst MAX_APPLICATION_REPLY_BYTES = 4_096;\n\ninterface Rewrite {\n readonly input: Buffer;\n readonly output: Buffer;\n readonly hostQueries?: readonly ConPtyHostQuery[];\n}\n\nexport type ConPtyHostQuery = 'primary-device-attributes';\nexport type ConPtyTerminalResponseRoute = 'host-control' | 'application-envelope';\n\nexport function encodeConPtyApplicationTerminalResponse(data: Uint8Array): Buffer {\n if (data.byteLength === 0 || data.byteLength > MAX_APPLICATION_REPLY_BYTES) {\n throw new RangeError(\n `terminal response must contain between 1 and ${MAX_APPLICATION_REPLY_BYTES} bytes`,\n );\n }\n for (const byte of data) {\n if (byte > 0x7f) {\n throw new TypeError(\n `terminal response contains non-ASCII byte 0x${byte.toString(16).padStart(2, '0')}`,\n );\n }\n }\n const bytes = Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n return Buffer.concat([\n APPLICATION_REPLY_PREFIX,\n Buffer.from(`${bytes.byteLength}:${bytes.toString('hex')}`, 'ascii'),\n OSC_TERMINATOR,\n ]);\n}\n\nexport class ConPtyTerminalResponseTransport {\n encode(route: ConPtyTerminalResponseRoute, data: Uint8Array): Buffer {\n return route === 'application-envelope'\n ? encodeConPtyApplicationTerminalResponse(data)\n : Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n }\n}\n\nexport function encodeConPtyApplicationInput(\n data: Uint8Array,\n kind: 'key' | 'mouse' | 'paste' | 'raw',\n): Buffer {\n // Preserve the complete physical Escape event. Reusing the byte-oriented\n // terminal-response encoder would deliver UnicodeChar=ESC but erase the\n // VK/scan identity observed by ReadConsoleInput applications.\n return kind === 'key' && data.byteLength === 1 && data[0] === 0x1b\n ? Buffer.from('\\x1b[27;1;27;1;0;1_', 'ascii')\n : Buffer.from(data.buffer, data.byteOffset, data.byteLength);\n}\n\nfunction isHostResponse(response: Buffer): boolean {\n const text = response.toString('ascii');\n return /^\\x1b\\[\\?[\\d;]*c$/u.test(text);\n}\n\n/**\n * Preserves the ownership of startup queries emitted by ConPTY itself.\n *\n * Host-control replies travel raw to OpenConsole. Application replies use the\n * private atomic envelope so OpenConsole can commit the decoded bytes to the\n * child in one input-buffer operation. The route keeps that ownership\n * explicit and is populated by the same split-safe startup rewrite that\n * exposes each host query to the emulator.\n */\nexport class ConPtyTerminalResponseRouter {\n readonly #hostQueries: ConPtyHostQuery[] = [];\n\n noteHostQuery(query: ConPtyHostQuery): void {\n this.#hostQueries.push(query);\n }\n\n route(response: Uint8Array): ConPtyTerminalResponseRoute {\n const bytes = Buffer.from(response.buffer, response.byteOffset, response.byteLength);\n const query = this.#hostQueries[0];\n // Cursor synchronization is a private request-addressed OSC RPC in the\n // pinned host. Standard CPR is therefore always application-owned and can\n // never be stolen by a host capture state.\n if (parseConPtyHostCursorResponse(bytes) !== null) return 'host-control';\n // The versioned reply prefix is reserved to the pinned host. A stale or\n // malformed reply must still travel raw to OpenConsole, which consumes it\n // fail-closed; encoding it as W32IM would expose host control bytes to the\n // application input queue. Other OSC 8488 payloads remain application-owned.\n if (bytes.subarray(0, HOST_CURSOR_REPLY_NAMESPACE.length).equals(HOST_CURSOR_REPLY_NAMESPACE)) {\n return 'host-control';\n }\n // A terminal reply is one control-plane transaction. The private envelope\n // makes OpenConsole buffer the complete payload through the OSC terminator,\n // then commit it with one InputBuffer::WriteString call. Sending raw CSI\n // is not sufficient: with VT input disabled OpenConsole can interpret a\n // CPR as F3. Encoding each byte as a separate KEY_EVENT is also invalid:\n // it exposes a printable tail when a VT reader resolves ESC too early.\n if (query === undefined) return 'application-envelope';\n if (!isHostResponse(bytes)) {\n throw new Error(`terminal answered ${query} ConPTY host query with an unexpected response`);\n }\n this.#hostQueries.shift();\n return 'host-control';\n }\n}\n\nconst STARTUP_REWRITES: readonly Rewrite[] = [\n {\n // VtIo's ordinary startup handshake.\n input: Buffer.concat([DA1, FOCUS_ON, WIN32_ON]),\n output: DA1,\n hostQueries: ['primary-device-attributes'],\n },\n];\n\ntype StartupPassThrough =\n | { readonly kind: 'complete'; readonly length: number }\n | {\n readonly kind: 'partial';\n }\n | null;\n\nfunction startupPassThrough(input: Buffer, offset: number): StartupPassThrough {\n for (const fixed of [WINDOW_DEICONIFY, WINDOW_ICONIFY]) {\n if (!hasPrefixAt(input, offset, fixed)) continue;\n return input.length - offset < fixed.length\n ? { kind: 'partial' }\n : { kind: 'complete', length: fixed.length };\n }\n if (!hasPrefixAt(input, offset, HOST_CURSOR_REQUEST_PREFIX)) return null;\n const remaining = input.length - offset;\n if (remaining < HOST_CURSOR_REQUEST_PREFIX.length) return { kind: 'partial' };\n const tokenStart = offset + HOST_CURSOR_REQUEST_PREFIX.length;\n const availableToken = Math.min(HOST_CURSOR_REQUEST_TOKEN_BYTES, input.length - tokenStart);\n for (let index = 0; index < availableToken; index += 1) {\n const byte = input[tokenStart + index]!;\n const hexadecimal = (byte >= 0x30 && byte <= 0x39) || (byte >= 0x61 && byte <= 0x66);\n if (!hexadecimal) return null;\n }\n const total = HOST_CURSOR_REQUEST_PREFIX.length + HOST_CURSOR_REQUEST_TOKEN_BYTES + 1;\n if (remaining < total) return { kind: 'partial' };\n if (input[offset + total - 1] !== 0x07) return null;\n return { kind: 'complete', length: total };\n}\n\nconst HOST_REWRITES: readonly Rewrite[] = [\n // AdaptDispatch reinjects these immediately after the child reset that\n // caused them. Keeping the reset preserves the child's original bytes.\n { input: Buffer.concat([FOCUS_OFF, FOCUS_ON]), output: FOCUS_OFF },\n { input: Buffer.concat([WIN32_OFF, WIN32_ON]), output: WIN32_OFF },\n { input: Buffer.concat([RIS, FOCUS_ON, WIN32_ON]), output: RIS },\n];\n\nfunction hasPrefixAt(input: Buffer, offset: number, pattern: Buffer): boolean {\n const available = Math.min(input.length - offset, pattern.length);\n for (let index = 0; index < available; index += 1) {\n if (input[offset + index] !== pattern[index]) return false;\n }\n return true;\n}\n\n/**\n * A deterministic streaming transducer for one ConPTY output stream.\n *\n * `push()` may retain only a suffix which could still become a host rewrite.\n * `finish()` releases that suffix verbatim, so a truncated or merely similar\n * child sequence is never lost at authoritative EOF.\n */\nexport class ConPtyControlPlaneNormalizer {\n #pending = Buffer.alloc(0);\n #atStreamStart = true;\n #finished = false;\n\n constructor(readonly onHostQuery: (query: ConPtyHostQuery) => void = () => undefined) {}\n\n push(chunk: Uint8Array): Buffer {\n if (this.#finished) {\n throw new Error('ConPTY output arrived after authoritative EOF');\n }\n if (chunk.byteLength === 0) return Buffer.alloc(0);\n\n const incoming = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);\n const input = this.#pending.length === 0 ? incoming : Buffer.concat([this.#pending, incoming]);\n this.#pending = Buffer.alloc(0);\n\n const output: Buffer[] = [];\n let literalStart = 0;\n let offset = 0;\n\n while (offset < input.length) {\n if (this.#atStreamStart) {\n const passThrough = startupPassThrough(input, offset);\n if (passThrough?.kind === 'partial') {\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n this.#pending = Buffer.from(input.subarray(offset));\n return output.length === 0 ? Buffer.alloc(0) : Buffer.concat(output);\n }\n if (passThrough?.kind === 'complete') {\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n output.push(input.subarray(offset, offset + passThrough.length));\n offset += passThrough.length;\n literalStart = offset;\n continue;\n }\n }\n const rewrites = this.#atStreamStart\n ? [...STARTUP_REWRITES, ...HOST_REWRITES]\n : HOST_REWRITES;\n let rewritten = false;\n let awaitingSuffix = false;\n\n for (const rewrite of rewrites) {\n if (!hasPrefixAt(input, offset, rewrite.input)) continue;\n const remaining = input.length - offset;\n if (remaining < rewrite.input.length) {\n awaitingSuffix = true;\n break;\n }\n\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n output.push(rewrite.output);\n for (const query of rewrite.hostQueries ?? []) this.onHostQuery(query);\n offset += rewrite.input.length;\n literalStart = offset;\n this.#atStreamStart = false;\n rewritten = true;\n break;\n }\n\n if (rewritten) continue;\n if (awaitingSuffix) {\n if (literalStart < offset) output.push(input.subarray(literalStart, offset));\n this.#pending = Buffer.from(input.subarray(offset));\n return output.length === 0 ? Buffer.alloc(0) : Buffer.concat(output);\n }\n\n // This byte cannot begin any host-owned structure. It is child output.\n this.#atStreamStart = false;\n offset += 1;\n }\n\n if (literalStart < input.length) output.push(input.subarray(literalStart));\n return output.length === 0 ? Buffer.alloc(0) : Buffer.concat(output);\n }\n\n finish(): Buffer {\n if (this.#finished) return Buffer.alloc(0);\n this.#finished = true;\n const tail = this.#pending;\n this.#pending = Buffer.alloc(0);\n return tail;\n }\n}\n"],"mappings":"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","names":["createRequire","bytes","require","bytes","cachedBinding","require","createRequire","unavailableReason","writeWindowsConsoleMarker","session","bytes"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@termwright/pty",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Termwright's native PTY backend with authoritative output EOF and owned process trees",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,21 +22,21 @@
22
22
  "dist"
23
23
  ],
24
24
  "dependencies": {
25
- "@termwright/protocol": "0.3.0"
25
+ "@termwright/protocol": "0.3.2"
26
26
  },
27
27
  "optionalDependencies": {
28
- "@termwright/pty-darwin-x64": "0.3.0",
29
- "@termwright/pty-darwin-arm64": "0.3.0",
30
- "@termwright/pty-linux-arm64": "0.3.0",
31
- "@termwright/pty-linux-x64": "0.3.0",
32
- "@termwright/pty-win32-arm64": "0.3.0",
33
- "@termwright/pty-win32-x64": "0.3.0"
28
+ "@termwright/pty-darwin-arm64": "0.3.2",
29
+ "@termwright/pty-darwin-x64": "0.3.2",
30
+ "@termwright/pty-linux-x64": "0.3.2",
31
+ "@termwright/pty-linux-arm64": "0.3.2",
32
+ "@termwright/pty-win32-arm64": "0.3.2",
33
+ "@termwright/pty-win32-x64": "0.3.2"
34
34
  },
35
35
  "devDependencies": {
36
36
  "node-addon-api": "^8.3.0",
37
37
  "node-gyp": "^12.3.0",
38
38
  "vitest": "4.1.11",
39
- "@termwright/resource-broker": "0.3.0"
39
+ "@termwright/resource-broker": "0.3.2"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsup src/index.ts --format esm --dts --sourcemap --clean",