@bincat/cli 0.1.0-beta.1

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.
@@ -0,0 +1,1138 @@
1
+ // packages/kernel/src/subprocess-local/runner-launch.ts
2
+ import { accessSync, constants as fsConstants, existsSync, lstatSync, statSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ // packages/kernel/src/http-proxy/policy.ts
6
+ var POLICY_ENV_NAMES = {
7
+ httpProxy: ["http_proxy", "HTTP_PROXY"],
8
+ httpsProxy: ["https_proxy", "HTTPS_PROXY"],
9
+ noProxy: ["no_proxy", "NO_PROXY"]
10
+ };
11
+ var PROXY_ENV_NAMES = [
12
+ ...Object.values(POLICY_ENV_NAMES).flat(),
13
+ "all_proxy",
14
+ "ALL_PROXY"
15
+ ];
16
+ var OCTET = "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)";
17
+ var LOOPBACK_IPV4 = new RegExp(`^127\\.${OCTET}\\.${OCTET}\\.${OCTET}$`);
18
+
19
+ // packages/kernel/src/subprocess/control.ts
20
+ var SUBPROCESS_CONTROL_FD = 7;
21
+
22
+ // packages/kernel/src/lazy-require/index.ts
23
+ import { createRequire } from "node:module";
24
+ function createLazyRequire(specifier, parentURL) {
25
+ const require2 = createRequire(parentURL);
26
+ let loaded = false;
27
+ let value;
28
+ return () => {
29
+ if (!loaded) {
30
+ value = require2(specifier);
31
+ loaded = true;
32
+ }
33
+ return value;
34
+ };
35
+ }
36
+
37
+ // packages/kernel/src/subprocess-local/windows-inspector.ts
38
+ var requireKoffi = createLazyRequire("koffi", import.meta.url);
39
+
40
+ // packages/kernel/src/subprocess-local/process-inspector.ts
41
+ var SYSCALLS = {
42
+ x64: { read: 0, select: 23, pselect: 270, poll: 7, ppoll: 271, epollWait: 232, epollPwait: 281 },
43
+ arm64: { read: 63, pselect: 72, ppoll: 73, epollPwait: 22 }
44
+ };
45
+ var SUPPORTED_SYSCALL_TABLES = Object.values(SYSCALLS);
46
+
47
+ // packages/kernel/src/subprocess-local/output.ts
48
+ import { closeSync, mkdtempSync, openSync, rmdirSync, unlinkSync, writeSync } from "node:fs";
49
+ var defaultSpillDir;
50
+ process.once("exit", () => {
51
+ if (defaultSpillDir === void 0) return;
52
+ try {
53
+ rmdirSync(defaultSpillDir);
54
+ } catch {
55
+ }
56
+ });
57
+
58
+ // packages/kernel/src/subprocess-local/runner-launch.ts
59
+ var SUBPROCESS_RUNNER_ENV = "BINCAT_SUBPROCESS_RUNNER";
60
+ var WINDOWS_RUNNER_SELECTION = "windows";
61
+ var SOURCE_TSCONFIG_PATH = fileURLToPath(new URL("../../../../tsconfig.base.json", import.meta.url));
62
+ function consumeRunnerSelection(env = process.env) {
63
+ const selection = env[SUBPROCESS_RUNNER_ENV];
64
+ Reflect.deleteProperty(env, SUBPROCESS_RUNNER_ENV);
65
+ return selection;
66
+ }
67
+ function parseRunnerTargetArgv(argv) {
68
+ if (argv[0] !== "--" || argv.length < 2) {
69
+ throw new Error("subprocess runner requires target argv after a private -- delimiter");
70
+ }
71
+ return [...argv.slice(1)];
72
+ }
73
+ function windowsEnvironmentValue(env, name) {
74
+ for (const key of Object.keys(env).sort()) {
75
+ if (key.toUpperCase() === name) return env[key];
76
+ }
77
+ return void 0;
78
+ }
79
+ function executableCandidateExists(candidate) {
80
+ try {
81
+ return !statSync(candidate).isDirectory();
82
+ } catch {
83
+ try {
84
+ const entry = lstatSync(candidate);
85
+ return entry.isFile() || entry.isSymbolicLink();
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+ }
91
+ function windowsPathDirectories(path) {
92
+ const directories = [];
93
+ let start = 0;
94
+ while (start < path.length) {
95
+ if (path.charAt(start) === ";") {
96
+ start += 1;
97
+ continue;
98
+ }
99
+ const quote = path.charAt(start);
100
+ const quoted = quote === '"' || quote === "'";
101
+ const quoteEnd = quoted ? path.indexOf(quote, start + 1) : -1;
102
+ const separator = path.indexOf(";", quoted ? quoteEnd < 0 ? path.length : quoteEnd : start);
103
+ const end = separator < 0 ? path.length : separator;
104
+ let directory = path.slice(start, end);
105
+ if (directory.startsWith('"') || directory.startsWith("'")) directory = directory.slice(1);
106
+ if (directory.endsWith('"') || directory.endsWith("'")) directory = directory.slice(0, -1);
107
+ if (directory.length > 0) directories.push(directory);
108
+ start = end + 1;
109
+ }
110
+ return directories;
111
+ }
112
+ function windowsFileNameStart(command) {
113
+ let start = command.length;
114
+ while (start > 0 && !/[\\/:]/u.test(command.charAt(start - 1))) start -= 1;
115
+ return start;
116
+ }
117
+ function windowsSearchPathJoin(directory, name, cwd) {
118
+ let prefix = cwd;
119
+ let adjustedDirectory = directory;
120
+ const slash = (value) => value === "\\" || value === "/";
121
+ if (directory.length > 2 && slash(directory.charAt(0)) && slash(directory.charAt(1))) {
122
+ prefix = "";
123
+ } else if (directory.length >= 1 && slash(directory.charAt(0))) {
124
+ prefix = cwd.slice(0, 2);
125
+ } else if (directory.length >= 2 && directory.charAt(1) === ":" && (directory.length < 3 || !slash(directory.charAt(2)))) {
126
+ if (cwd.length < 2 || cwd.slice(0, 2).toLowerCase() !== directory.slice(0, 2).toLowerCase()) {
127
+ prefix = "";
128
+ } else {
129
+ adjustedDirectory = directory.slice(2);
130
+ }
131
+ } else if (directory.length > 2 && directory.charAt(1) === ":") {
132
+ prefix = "";
133
+ }
134
+ const append = (base, part) => {
135
+ if (base.length === 0 || part.length === 0) return base + part;
136
+ return /[\\/:]$/u.test(base) ? base + part : `${base}\\${part}`;
137
+ };
138
+ return append(append(prefix, adjustedDirectory), name);
139
+ }
140
+ function windowsExecutableNames(command, name) {
141
+ const dot = name.indexOf(".");
142
+ const hasExtension = dot >= 0 && dot < name.length - 1;
143
+ const separator = name.endsWith(".") ? "" : ".";
144
+ return [
145
+ ...hasExtension ? [command] : [],
146
+ `${command}${separator}com`,
147
+ `${command}${separator}exe`
148
+ ];
149
+ }
150
+ function resolveWindowsExecutable(command, cwd, env, exists = executableCandidateExists, currentEnv = process.env) {
151
+ const nameStart = windowsFileNameStart(command);
152
+ const directory = command.slice(0, nameStart);
153
+ const name = command.slice(nameStart);
154
+ const hasPath = nameStart !== 0;
155
+ const roots = [];
156
+ if (hasPath) {
157
+ roots.push(directory);
158
+ } else {
159
+ if (windowsEnvironmentValue(currentEnv, "NODEFAULTCURRENTDIRECTORYINEXEPATH") === void 0) {
160
+ roots.push("");
161
+ }
162
+ const path = windowsEnvironmentValue(env, "PATH") ?? windowsEnvironmentValue(currentEnv, "PATH") ?? "";
163
+ roots.push(...windowsPathDirectories(path));
164
+ }
165
+ for (const root of roots) {
166
+ const base = windowsSearchPathJoin(root, name, cwd);
167
+ for (const candidate of windowsExecutableNames(base, name)) {
168
+ if (exists(candidate)) return candidate;
169
+ }
170
+ }
171
+ return void 0;
172
+ }
173
+
174
+ // packages/kernel/src/subprocess-local/spawn-runner.ts
175
+ import { closeSync as closeSync2 } from "node:fs";
176
+
177
+ // packages/kernel/src/win32-process/abi.ts
178
+ var STARTF_USESTDHANDLES = 256;
179
+ var STARTF_USESHOWWINDOW = 1;
180
+ var SW_HIDE = 0;
181
+ var HANDLE_FLAG_INHERIT = 1;
182
+ var WAIT_TIMEOUT = 258;
183
+ var CREATE_SUSPENDED = 4;
184
+ var CREATE_UNICODE_ENVIRONMENT = 1024;
185
+ var FORMAT_MESSAGE_FROM_SYSTEM = 4096;
186
+ var FORMAT_MESSAGE_IGNORE_INSERTS = 512;
187
+ var JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 8192;
188
+ var JobObjectBasicAccountingInformation = 1;
189
+ var JobObjectExtendedLimitInformation = 9;
190
+ var JOBOBJECT_BASIC_ACCOUNTING_SIZE = 48;
191
+ var JOBOBJECT_BASIC_ACCOUNTING_ACTIVE_PROCESSES_OFFSET = 40;
192
+ var JOBOBJECT_EXTENDED_LIMIT_SIZE = 144;
193
+ var JOBOBJECT_EXTENDED_LIMIT_FLAGS_OFFSET = 16;
194
+ var STARTUPINFOW_SIZE = 104;
195
+ var PROCESS_INFORMATION_SIZE = 24;
196
+
197
+ // packages/kernel/src/win32-process/errors.ts
198
+ var Win32Error = class extends Error {
199
+ /** Win32 function whose checked result failed. */
200
+ api;
201
+ /** Exact GetLastError value or direct Win32 API error code. */
202
+ win32Code;
203
+ constructor(api, win32Code, detail) {
204
+ super(`${api} failed (Win32 ${win32Code})${detail === void 0 ? "" : `: ${detail}`}`);
205
+ this.name = "Win32Error";
206
+ this.api = api;
207
+ this.win32Code = win32Code;
208
+ }
209
+ };
210
+
211
+ // packages/kernel/src/win32-process/koffi.ts
212
+ var requireKoffi2 = createLazyRequire("koffi", import.meta.url);
213
+
214
+ // packages/kernel/src/win32-process/ffi.ts
215
+ function isNullPtr(value) {
216
+ return value === null || value === void 0 || value === 0n;
217
+ }
218
+ var cachedTypes;
219
+ function win32Types() {
220
+ if (cachedTypes !== void 0) return cachedTypes;
221
+ const koffi = requireKoffi2();
222
+ const PVOID = koffi.pointer("void");
223
+ const PPVOID = koffi.pointer(PVOID);
224
+ const STARTUPINFOW = koffi.struct("BINCAT_STARTUPINFOW", {
225
+ cb: "uint32",
226
+ lpReserved: "str16",
227
+ lpDesktop: "str16",
228
+ lpTitle: "str16",
229
+ dwX: "uint32",
230
+ dwY: "uint32",
231
+ dwXSize: "uint32",
232
+ dwYSize: "uint32",
233
+ dwXCountChars: "uint32",
234
+ dwYCountChars: "uint32",
235
+ dwFillAttribute: "uint32",
236
+ dwFlags: "uint32",
237
+ wShowWindow: "uint16",
238
+ cbReserved2: "uint16",
239
+ lpReserved2: koffi.pointer("uint8"),
240
+ hStdInput: PVOID,
241
+ hStdOutput: PVOID,
242
+ hStdError: PVOID
243
+ });
244
+ const PROCESS_INFORMATION = koffi.struct("BINCAT_PROCESS_INFORMATION", {
245
+ hProcess: PVOID,
246
+ hThread: PVOID,
247
+ dwProcessId: "uint32",
248
+ dwThreadId: "uint32"
249
+ });
250
+ if (STARTUPINFOW.size !== STARTUPINFOW_SIZE) {
251
+ throw new Error(`STARTUPINFOW layout mismatch: koffi computed ${STARTUPINFOW.size}, expected ${STARTUPINFOW_SIZE}`);
252
+ }
253
+ if (PROCESS_INFORMATION.size !== PROCESS_INFORMATION_SIZE) {
254
+ throw new Error(`PROCESS_INFORMATION layout mismatch: koffi computed ${PROCESS_INFORMATION.size}, expected ${PROCESS_INFORMATION_SIZE}`);
255
+ }
256
+ return cachedTypes = { PVOID, PPVOID, STARTUPINFOW, PROCESS_INFORMATION };
257
+ }
258
+ function allocUint32() {
259
+ return requireKoffi2().alloc("uint32", 1);
260
+ }
261
+ function decodeUint32(slot) {
262
+ return requireKoffi2().decode(slot, "uint32");
263
+ }
264
+ function allocStartupInfo() {
265
+ return requireKoffi2().alloc(win32Types().STARTUPINFOW, 1);
266
+ }
267
+ function encodeStartupInfo(startupInfo, fields) {
268
+ requireKoffi2().encode(startupInfo, win32Types().STARTUPINFOW, fields);
269
+ }
270
+ function allocProcessInfo() {
271
+ return requireKoffi2().alloc(win32Types().PROCESS_INFORMATION, 1);
272
+ }
273
+ function decodeProcessInfo(processInfo) {
274
+ return requireKoffi2().decode(processInfo, win32Types().PROCESS_INFORMATION);
275
+ }
276
+ var cachedContext;
277
+ var cached;
278
+ function bindingContext() {
279
+ if (cachedContext !== void 0) return cachedContext;
280
+ const koffi = requireKoffi2();
281
+ const kernel32 = koffi.load("kernel32.dll");
282
+ const advapi32 = koffi.load("advapi32.dll");
283
+ const bind = (lib, name, result, args) => lib.func("__stdcall", name, result, args);
284
+ cachedContext = { kernel32, advapi32, bind };
285
+ return cachedContext;
286
+ }
287
+ function bindings() {
288
+ if (cached !== void 0) return cached;
289
+ const koffi = requireKoffi2();
290
+ const { PVOID, PPVOID, STARTUPINFOW, PROCESS_INFORMATION } = win32Types();
291
+ const { kernel32, advapi32, bind } = bindingContext();
292
+ const node = koffi.load(null);
293
+ cached = {
294
+ closeHandle: bind(kernel32, "CloseHandle", "int", [PVOID]),
295
+ getLastError: bind(kernel32, "GetLastError", "uint32", []),
296
+ getFileType: bind(kernel32, "GetFileType", "uint32", [PVOID]),
297
+ formatMessageW: bind(kernel32, "FormatMessageW", "uint32", [
298
+ "uint32",
299
+ PVOID,
300
+ "uint32",
301
+ "uint32",
302
+ PVOID,
303
+ "uint32",
304
+ PVOID
305
+ ]),
306
+ createPipe: bind(kernel32, "CreatePipe", "int", [PPVOID, PPVOID, PVOID, "uint32"]),
307
+ setHandleInformation: bind(kernel32, "SetHandleInformation", "int", [PVOID, "uint32", "uint32"]),
308
+ createProcessAsUserW: bind(advapi32, "CreateProcessAsUserW", "int", [
309
+ PVOID,
310
+ "str16",
311
+ "str16",
312
+ PVOID,
313
+ PVOID,
314
+ "int",
315
+ "uint32",
316
+ PVOID,
317
+ "str16",
318
+ koffi.pointer(STARTUPINFOW),
319
+ koffi.pointer(PROCESS_INFORMATION)
320
+ ]),
321
+ createProcessW: bind(kernel32, "CreateProcessW", "int", [
322
+ "str16",
323
+ "str16",
324
+ PVOID,
325
+ PVOID,
326
+ "int",
327
+ "uint32",
328
+ PVOID,
329
+ "str16",
330
+ koffi.pointer(STARTUPINFOW),
331
+ koffi.pointer(PROCESS_INFORMATION)
332
+ ]),
333
+ readFile: bind(kernel32, "ReadFile", "int", [PVOID, PVOID, "uint32", koffi.pointer("uint32"), PVOID]),
334
+ peekNamedPipe: bind(kernel32, "PeekNamedPipe", "int", [
335
+ PVOID,
336
+ PVOID,
337
+ "uint32",
338
+ koffi.pointer("uint32"),
339
+ koffi.pointer("uint32"),
340
+ koffi.pointer("uint32")
341
+ ]),
342
+ waitForSingleObject: bind(kernel32, "WaitForSingleObject", "uint32", [PVOID, "uint32"]),
343
+ getExitCodeProcess: bind(kernel32, "GetExitCodeProcess", "int", [PVOID, koffi.pointer("uint32")]),
344
+ createJobObjectW: bind(kernel32, "CreateJobObjectW", PVOID, [PVOID, "str16"]),
345
+ setInformationJobObject: bind(kernel32, "SetInformationJobObject", "int", [PVOID, "int", PVOID, "uint32"]),
346
+ queryInformationJobObject: bind(kernel32, "QueryInformationJobObject", "int", [
347
+ PVOID,
348
+ "int",
349
+ PVOID,
350
+ "uint32",
351
+ PVOID
352
+ ]),
353
+ assignProcessToJobObject: bind(kernel32, "AssignProcessToJobObject", "int", [PVOID, PVOID]),
354
+ resumeThread: bind(kernel32, "ResumeThread", "uint32", [PVOID]),
355
+ terminateProcess: bind(kernel32, "TerminateProcess", "int", [PVOID, "uint32"]),
356
+ terminateJobObject: bind(kernel32, "TerminateJobObject", "int", [PVOID, "uint32"]),
357
+ getStdHandle: bind(kernel32, "GetStdHandle", PVOID, ["int"]),
358
+ uvGetOsfhandle: node.func("uv_get_osfhandle", PVOID, ["int"])
359
+ };
360
+ return cached;
361
+ }
362
+ function loadWin32ProcessBindings() {
363
+ return bindings();
364
+ }
365
+ function errorText(api, win32Code) {
366
+ const buffer = Buffer.alloc(1024);
367
+ const length = api.formatMessageW(
368
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
369
+ null,
370
+ win32Code,
371
+ 0,
372
+ buffer,
373
+ buffer.length / 2,
374
+ null
375
+ );
376
+ return length === 0 ? "" : buffer.subarray(0, length * 2).toString("utf16le").trim();
377
+ }
378
+ function throwLastError(api, name, detail) {
379
+ const win32Code = api.getLastError();
380
+ throw new Win32Error(name, win32Code, detail ?? errorText(api, win32Code));
381
+ }
382
+ function throwWin32(api, name, win32Code, detail) {
383
+ throw new Win32Error(name, win32Code, detail ?? errorText(api, win32Code));
384
+ }
385
+
386
+ // packages/kernel/src/win32-process/control-stdio.ts
387
+ var HANDLE_BYTES = 8;
388
+ var INVALID_HANDLE = 0xffffffffffffffffn;
389
+ var FOPEN = 1;
390
+ var FPIPE = 8;
391
+ var FDEV = 64;
392
+ var FILE_TYPE_CHAR = 2;
393
+ var FILE_TYPE_PIPE = 3;
394
+ function inheritedControlStdio(api, stdio) {
395
+ const count = stdio.control.fileDescriptor + 1;
396
+ const handleOffset = 4 + count;
397
+ const bytes = Buffer.alloc(handleOffset + count * HANDLE_BYTES);
398
+ bytes.writeUInt32LE(count, 0);
399
+ for (let index = 0; index < count; index++) {
400
+ bytes.writeBigUInt64LE(INVALID_HANDLE, handleOffset + index * HANDLE_BYTES);
401
+ }
402
+ const entries = [[0, stdio.stdin], [1, stdio.stdout], [2, stdio.stderr], [stdio.control.fileDescriptor, stdio.control.handle]];
403
+ for (const [fd, handle] of entries) {
404
+ const kind = api.getFileType(handle);
405
+ if (fd === stdio.control.fileDescriptor && kind !== FILE_TYPE_PIPE) {
406
+ throw new Error("subprocess control descriptor is not a Windows pipe");
407
+ }
408
+ bytes[4 + fd] = FOPEN | (kind === FILE_TYPE_PIPE ? FPIPE : kind === FILE_TYPE_CHAR ? FDEV : 0);
409
+ bytes.writeBigUInt64LE(handle, handleOffset + fd * HANDLE_BYTES);
410
+ }
411
+ return bytes;
412
+ }
413
+
414
+ // packages/kernel/src/win32-process/process.ts
415
+ function quoteArg(argument) {
416
+ if (argument === "") return '""';
417
+ if (!/[\s"]/u.test(argument)) return argument;
418
+ let quoted = '"';
419
+ for (let index = 0; index < argument.length; index++) {
420
+ let backslashes = 0;
421
+ while (index < argument.length && argument.charAt(index) === "\\") {
422
+ backslashes += 1;
423
+ index += 1;
424
+ }
425
+ if (index === argument.length) {
426
+ quoted += "\\".repeat(backslashes * 2);
427
+ } else if (argument.charAt(index) === '"') {
428
+ quoted += "\\".repeat(backslashes * 2 + 1) + '"';
429
+ } else {
430
+ quoted += "\\".repeat(backslashes) + argument.charAt(index);
431
+ }
432
+ }
433
+ return quoted + '"';
434
+ }
435
+ function buildCommandLine(program, args) {
436
+ return [program, ...args].map(quoteArg).join(" ");
437
+ }
438
+ function compareWindowsEnvironmentKeys([left], [right]) {
439
+ const foldedLeft = left.toUpperCase();
440
+ const foldedRight = right.toUpperCase();
441
+ return foldedLeft < foldedRight ? -1 : foldedLeft > foldedRight ? 1 : 0;
442
+ }
443
+ function encodeWindowsEnvironment(env) {
444
+ const entries = Object.entries(env).sort(compareWindowsEnvironmentKeys);
445
+ const strings = entries.map(([key, value]) => `${key}=${value}`);
446
+ return Buffer.from(`${strings.join("\0")}\0\0`, "utf16le");
447
+ }
448
+ function freeNative(pointer) {
449
+ if (pointer !== void 0) requireKoffi2().free(pointer);
450
+ }
451
+ function closeBestEffort(api, handle) {
452
+ if (!isNullPtr(handle)) api.closeHandle(handle);
453
+ }
454
+ function createKillOnCloseJob(api) {
455
+ const job = api.createJobObjectW(null, null);
456
+ if (isNullPtr(job)) throwLastError(api, "CreateJobObjectW");
457
+ const information = Buffer.alloc(JOBOBJECT_EXTENDED_LIMIT_SIZE);
458
+ information.writeUInt32LE(
459
+ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
460
+ JOBOBJECT_EXTENDED_LIMIT_FLAGS_OFFSET
461
+ );
462
+ if (api.setInformationJobObject(
463
+ job,
464
+ JobObjectExtendedLimitInformation,
465
+ information,
466
+ information.length
467
+ ) === 0) {
468
+ const win32Code = api.getLastError();
469
+ api.closeHandle(job);
470
+ throwWin32(api, "SetInformationJobObject", win32Code);
471
+ }
472
+ return job;
473
+ }
474
+ var UV_INVALID_OS_FILE_HANDLE = 0xffffffffffffffffn;
475
+ var UV_INVALID_FILE_DESCRIPTOR = 0xfffffffffffffffen;
476
+ function descriptorHandle(api, fileDescriptor, label) {
477
+ const handle = api.uvGetOsfhandle(fileDescriptor);
478
+ if (isNullPtr(handle) || handle === UV_INVALID_OS_FILE_HANDLE || handle === UV_INVALID_FILE_DESCRIPTOR) {
479
+ throw new Error(`uv_get_osfhandle returned an invalid handle for target ${label} fd ${String(fileDescriptor)}`);
480
+ }
481
+ return handle;
482
+ }
483
+ function targetCarrierHandles(api, descriptors) {
484
+ return {
485
+ stdin: descriptorHandle(api, descriptors.stdin, "stdin"),
486
+ stdout: descriptorHandle(api, descriptors.stdout, "stdout"),
487
+ stderr: descriptorHandle(api, descriptors.stderr, "stderr"),
488
+ ...descriptors.control === void 0 ? {} : {
489
+ control: { fileDescriptor: descriptors.control, handle: descriptorHandle(api, descriptors.control, "control") }
490
+ }
491
+ };
492
+ }
493
+ function spawnJobProcess(api, options, resolveStdio, createName, create) {
494
+ const job = createKillOnCloseJob(api);
495
+ const enabled = [];
496
+ let startupInfo;
497
+ let processInfo;
498
+ let controlDescriptorBlock;
499
+ let created = 0;
500
+ let createFailureCode = 0;
501
+ try {
502
+ const stdio = resolveStdio();
503
+ const inherited = [
504
+ [stdio.stdin, "stdin"],
505
+ [stdio.stdout, "stdout"],
506
+ [stdio.stderr, "stderr"]
507
+ ];
508
+ if (stdio.control !== void 0) inherited.push([stdio.control.handle, "control"]);
509
+ for (const [handle, label] of inherited) {
510
+ if (api.setHandleInformation(handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) === 0) {
511
+ throwLastError(api, "SetHandleInformation", `${label} (enable inherit)`);
512
+ }
513
+ enabled.push(handle);
514
+ }
515
+ const controlBytes = stdio.control === void 0 ? void 0 : inheritedControlStdio(api, { ...stdio, control: stdio.control });
516
+ if (controlBytes !== void 0) {
517
+ const koffi = requireKoffi2();
518
+ controlDescriptorBlock = { pointer: koffi.alloc("uint8", controlBytes.length), length: controlBytes.length };
519
+ koffi.encode(controlDescriptorBlock.pointer, "uint8", controlBytes, controlBytes.length);
520
+ }
521
+ startupInfo = allocStartupInfo();
522
+ encodeStartupInfo(startupInfo, {
523
+ cb: STARTUPINFOW_SIZE,
524
+ // Preserve console inheritance: CREATE_NO_WINDOW can fail restricted-token DLL initialization.
525
+ dwFlags: STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW,
526
+ wShowWindow: SW_HIDE,
527
+ hStdInput: stdio.stdin,
528
+ hStdOutput: stdio.stdout,
529
+ hStdError: stdio.stderr,
530
+ ...controlDescriptorBlock === void 0 ? {} : {
531
+ cbReserved2: controlDescriptorBlock.length,
532
+ lpReserved2: controlDescriptorBlock.pointer
533
+ }
534
+ });
535
+ processInfo = allocProcessInfo();
536
+ created = create(startupInfo, processInfo);
537
+ if (created === 0) createFailureCode = api.getLastError();
538
+ } catch (error) {
539
+ freeNative(processInfo);
540
+ api.closeHandle(job);
541
+ throw error;
542
+ } finally {
543
+ freeNative(startupInfo);
544
+ freeNative(controlDescriptorBlock?.pointer);
545
+ for (const handle of enabled) {
546
+ api.setHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
547
+ }
548
+ }
549
+ if (created === 0) {
550
+ freeNative(processInfo);
551
+ api.closeHandle(job);
552
+ throwWin32(
553
+ api,
554
+ createName,
555
+ createFailureCode,
556
+ `command: ${options.command}, cwd: ${options.cwd}`
557
+ );
558
+ }
559
+ let info;
560
+ try {
561
+ info = decodeProcessInfo(processInfo);
562
+ } finally {
563
+ freeNative(processInfo);
564
+ }
565
+ if (info.hProcess === null || info.hThread === null) {
566
+ if (info.hProcess !== null) api.terminateProcess(info.hProcess, 1);
567
+ api.closeHandle(job);
568
+ closeBestEffort(api, info.hThread);
569
+ closeBestEffort(api, info.hProcess);
570
+ throw new Error(`${createName} succeeded but returned null process/thread handles (pid ${info.dwProcessId})`);
571
+ }
572
+ if (api.assignProcessToJobObject(job, info.hProcess) === 0) {
573
+ const win32Code = api.getLastError();
574
+ api.terminateProcess(info.hProcess, 1);
575
+ closeBestEffort(api, info.hThread);
576
+ closeBestEffort(api, info.hProcess);
577
+ api.closeHandle(job);
578
+ throwWin32(api, "AssignProcessToJobObject", win32Code, `pid ${info.dwProcessId}`);
579
+ }
580
+ if (api.resumeThread(info.hThread) === 4294967295) {
581
+ const win32Code = api.getLastError();
582
+ closeBestEffort(api, info.hThread);
583
+ closeBestEffort(api, info.hProcess);
584
+ api.closeHandle(job);
585
+ throwWin32(api, "ResumeThread", win32Code, `pid ${info.dwProcessId}`);
586
+ }
587
+ closeBestEffort(api, info.hThread);
588
+ return { pid: info.dwProcessId, process: info.hProcess, job };
589
+ }
590
+ function spawnCurrentTokenJobProcess(api, options) {
591
+ const commandLine = buildCommandLine(options.command, options.args);
592
+ const environment = encodeWindowsEnvironment(options.env);
593
+ return spawnJobProcess(api, options, () => targetCarrierHandles(api, options.stdio), "CreateProcessW", (startupInfo, processInfo) => api.createProcessW(
594
+ options.applicationName,
595
+ commandLine,
596
+ null,
597
+ null,
598
+ 1,
599
+ CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT,
600
+ environment,
601
+ options.cwd,
602
+ startupInfo,
603
+ processInfo
604
+ ));
605
+ }
606
+ function pollProcessExit(api, process2) {
607
+ const waitResult = api.waitForSingleObject(process2, 0);
608
+ if (waitResult === WAIT_TIMEOUT) return void 0;
609
+ if (waitResult === 4294967295) throwLastError(api, "WaitForSingleObject");
610
+ const exitCodeSlot = allocUint32();
611
+ try {
612
+ if (api.getExitCodeProcess(process2, exitCodeSlot) === 0) throwLastError(api, "GetExitCodeProcess");
613
+ return decodeUint32(exitCodeSlot);
614
+ } finally {
615
+ requireKoffi2().free(exitCodeSlot);
616
+ }
617
+ }
618
+ function isJobEmpty(api, job) {
619
+ const information = Buffer.alloc(JOBOBJECT_BASIC_ACCOUNTING_SIZE);
620
+ if (api.queryInformationJobObject(
621
+ job,
622
+ JobObjectBasicAccountingInformation,
623
+ information,
624
+ information.length,
625
+ null
626
+ ) === 0) {
627
+ throwLastError(api, "QueryInformationJobObject", "active process count");
628
+ }
629
+ return information.readUInt32LE(JOBOBJECT_BASIC_ACCOUNTING_ACTIVE_PROCESSES_OFFSET) === 0;
630
+ }
631
+ function terminateJob(api, job, exitCode) {
632
+ if (api.terminateJobObject(job, exitCode) === 0) throwLastError(api, "TerminateJobObject");
633
+ }
634
+ function closeHandleChecked(api, handle, detail) {
635
+ if (api.closeHandle(handle) === 0) throwLastError(api, "CloseHandle", detail);
636
+ }
637
+
638
+ // packages/kernel/src/subprocess-local/linux-execve.ts
639
+ import { getSystemErrorMessage, getSystemErrorName } from "node:util";
640
+ var requireKoffi3 = createLazyRequire("koffi", import.meta.url);
641
+ var STANDARD_FILE_DESCRIPTORS = [0, 1, 2];
642
+ var F_GETFD = 1;
643
+ var F_SETFD = 2;
644
+ var FD_CLOEXEC = 1;
645
+ var cachedExecve;
646
+ function systemError(errno, syscall, path) {
647
+ const uvError = -errno;
648
+ const code = getSystemErrorName(uvError);
649
+ const detail = getSystemErrorMessage(uvError);
650
+ const subject = path === void 0 ? syscall : `${syscall} '${path}'`;
651
+ const error = Object.assign(new Error(`${code}: ${detail}, ${subject}`), {
652
+ code,
653
+ errno: uvError,
654
+ syscall
655
+ });
656
+ return path === void 0 ? error : Object.assign(error, { path });
657
+ }
658
+ function loadLinuxExecve() {
659
+ if (cachedExecve !== void 0) return cachedExecve;
660
+ const koffi = requireKoffi3();
661
+ const libc = koffi.load(null);
662
+ const nativeExecve = libc.func(
663
+ "int execve(const char *pathname, const char **argv, const char **envp)"
664
+ );
665
+ const nativeFcntl = libc.func(
666
+ "int fcntl(int fd, int cmd, int arg)"
667
+ );
668
+ cachedExecve = (file, argv, env, control) => {
669
+ const descriptors = control === "pipe" ? [...STANDARD_FILE_DESCRIPTORS, SUBPROCESS_CONTROL_FD] : STANDARD_FILE_DESCRIPTORS;
670
+ for (const fd of descriptors) {
671
+ const flags = nativeFcntl(fd, F_GETFD, 0);
672
+ if (flags === -1) throw systemError(koffi.errno(), "fcntl");
673
+ if ((flags & FD_CLOEXEC) === 0) continue;
674
+ if (nativeFcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) === -1) {
675
+ throw systemError(koffi.errno(), "fcntl");
676
+ }
677
+ }
678
+ nativeExecve(
679
+ file,
680
+ [...argv, null],
681
+ [...Object.entries(env).map(([key, value]) => `${key}=${value}`), null]
682
+ );
683
+ throw systemError(koffi.errno(), "execve", file);
684
+ };
685
+ return cachedExecve;
686
+ }
687
+
688
+ // packages/kernel/src/subprocess-local/runner-protocol.ts
689
+ import {
690
+ chmodSync,
691
+ existsSync as existsSync2,
692
+ lstatSync as lstatSync2,
693
+ mkdtempSync as mkdtempSync2,
694
+ readFileSync,
695
+ rmdirSync as rmdirSync2,
696
+ unlinkSync as unlinkSync2,
697
+ writeFileSync
698
+ } from "node:fs";
699
+ import { basename, dirname, isAbsolute, join } from "node:path";
700
+ function isRecord(value) {
701
+ return value !== null && typeof value === "object" && !Array.isArray(value);
702
+ }
703
+ function hasExactKeys(value, required, optional = []) {
704
+ const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
705
+ return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => allowed.has(key));
706
+ }
707
+ function isStringRecord(value) {
708
+ return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
709
+ }
710
+ function linuxLaunchFilesFromLocator(requestPath) {
711
+ if (!isAbsolute(requestPath) || basename(requestPath) !== "launch-request.json") {
712
+ throw new Error("subprocess runner received an invalid Linux launch-request locator");
713
+ }
714
+ const directory = dirname(requestPath);
715
+ return { directory, requestPath, startupErrorPath: join(directory, "startup-error.json") };
716
+ }
717
+ function consumeLinuxLaunchRequest(requestPath) {
718
+ const text = readFileSync(requestPath, "utf8");
719
+ unlinkSync2(requestPath);
720
+ const value = JSON.parse(text);
721
+ if (!isRecord(value) || !hasExactKeys(value, ["cwd", "env"], ["control"]) || typeof value.cwd !== "string" || !isStringRecord(value.env) || value.control !== void 0 && value.control !== "pipe") {
722
+ throw new Error("subprocess runner received an invalid Linux launch request");
723
+ }
724
+ return { cwd: value.cwd, env: value.env, ...value.control === "pipe" ? { control: "pipe" } : {} };
725
+ }
726
+ function writeLinuxStartupError(files, error) {
727
+ writeFileSync(files.startupErrorPath, JSON.stringify(error), { flag: "wx", mode: 384 });
728
+ }
729
+ function parseWindowsStartRequest(value) {
730
+ if (!isRecord(value) || !hasExactKeys(value, ["type", "cwd", "env"], ["control"]) || value.type !== "start" || typeof value.cwd !== "string" || !isStringRecord(value.env) || value.control !== void 0 && value.control !== "pipe") {
731
+ throw new Error("subprocess runner received an invalid Windows start request");
732
+ }
733
+ return { type: "start", cwd: value.cwd, env: value.env, ...value.control === "pipe" ? { control: "pipe" } : {} };
734
+ }
735
+ function isWindowsTerminateRequest(value) {
736
+ return isRecord(value) && hasExactKeys(value, ["type"]) && value.type === "terminate";
737
+ }
738
+ function serializeRunnerError(error) {
739
+ const source = error instanceof Error ? error : new Error(String(error));
740
+ const node = source;
741
+ return {
742
+ name: source.name,
743
+ message: source.message,
744
+ ...typeof node.code === "string" ? { code: node.code } : {},
745
+ ...typeof node.syscall === "string" ? { syscall: node.syscall } : {},
746
+ ...typeof node.path === "string" ? { path: node.path } : {}
747
+ };
748
+ }
749
+
750
+ // packages/kernel/src/subprocess-local/spawn-runner.ts
751
+ var defaultInternals = {
752
+ /* v8 ignore next -- source/built/packaged subprocess smoke executes this only in a replaceable child process. */
753
+ execve: (file, argv, env, control) => loadLinuxExecve()(file, argv, env, control),
754
+ loadWin32ProcessBindings,
755
+ spawnCurrentTokenJobProcess,
756
+ closeFileDescriptor: closeSync2,
757
+ resolveWindowsExecutable,
758
+ pollProcessExit,
759
+ isJobEmpty,
760
+ terminateJob,
761
+ closeHandleChecked
762
+ };
763
+ var NODE_SPAWN_DETAIL_CODES = /* @__PURE__ */ new Set(["EACCES", "ENOENT"]);
764
+ var WINDOWS_SPAWN_ERROR_CODES = /* @__PURE__ */ new Map([
765
+ [2, "ENOENT"],
766
+ [3, "ENOENT"],
767
+ [267, "ENOENT"],
768
+ [5, "EPERM"],
769
+ [193, "EFTYPE"],
770
+ [740, "EACCES"]
771
+ ]);
772
+ function nodeSpawnError(syscall, code, path) {
773
+ const message = `${syscall} ${code}`;
774
+ return {
775
+ name: "Error",
776
+ message,
777
+ code,
778
+ syscall,
779
+ ...path === void 0 ? {} : { path }
780
+ };
781
+ }
782
+ function asSpawnError(error, program) {
783
+ const serialized = serializeRunnerError(error);
784
+ if (!(error instanceof Win32Error)) {
785
+ return serialized.code === void 0 ? serialized : nodeSpawnError(`spawn ${program}`, serialized.code, program);
786
+ }
787
+ const code = WINDOWS_SPAWN_ERROR_CODES.get(error.win32Code) ?? "UNKNOWN";
788
+ if (NODE_SPAWN_DETAIL_CODES.has(code)) {
789
+ return nodeSpawnError(`spawn ${program}`, code, program);
790
+ }
791
+ return nodeSpawnError("spawn", code);
792
+ }
793
+ function windowsPathNotFoundError(program) {
794
+ return nodeSpawnError(`spawn ${program}`, "ENOENT", program);
795
+ }
796
+ function windowsStartCancelledError() {
797
+ return {
798
+ name: "Error",
799
+ message: "subprocess target start was cancelled"
800
+ };
801
+ }
802
+ function linuxPathNotFoundError(program) {
803
+ return Object.assign(new Error(`spawn ${program} ENOENT`), {
804
+ code: "ENOENT",
805
+ errno: -2,
806
+ syscall: `spawn ${program}`,
807
+ path: program,
808
+ spawnargs: []
809
+ });
810
+ }
811
+ function execLinuxFile(file, argv, env, internals, control) {
812
+ try {
813
+ return control === void 0 ? internals.execve(file, argv, env) : internals.execve(file, argv, env, control);
814
+ } catch (error) {
815
+ if (error.code !== "ENOEXEC") throw error;
816
+ return control === void 0 ? internals.execve("/bin/sh", ["/bin/sh", file, ...argv.slice(1)], env) : internals.execve("/bin/sh", ["/bin/sh", file, ...argv.slice(1)], env, control);
817
+ }
818
+ }
819
+ function execLinuxTarget(request, argv, internals) {
820
+ const program = argv[0];
821
+ if (program.includes("/")) return execLinuxFile(program, argv, request.env, internals, request.control);
822
+ const path = request.env.PATH ?? "/usr/bin:/bin";
823
+ let permissionFailure;
824
+ for (const directory of path.split(":")) {
825
+ const root = directory.startsWith("/") ? directory : `${request.cwd}${request.cwd.endsWith("/") ? "" : "/"}${directory}`;
826
+ const candidate = `${root}${root.endsWith("/") ? "" : "/"}${program}`;
827
+ try {
828
+ return execLinuxFile(candidate, argv, request.env, internals, request.control);
829
+ } catch (error) {
830
+ const code = error.code;
831
+ if (code === "EACCES") {
832
+ permissionFailure ??= error;
833
+ continue;
834
+ }
835
+ if (code === "ENOENT" || code === "ENOTDIR") continue;
836
+ throw error;
837
+ }
838
+ }
839
+ throw permissionFailure ?? linuxPathNotFoundError(program);
840
+ }
841
+ function runLinux(locator, argv, host, internals) {
842
+ const files = linuxLaunchFilesFromLocator(locator);
843
+ let request;
844
+ try {
845
+ request = consumeLinuxLaunchRequest(files.requestPath);
846
+ } catch (error) {
847
+ writeLinuxStartupError(files, { type: "error", error: serializeRunnerError(error) });
848
+ host.exitCode = 127;
849
+ return;
850
+ }
851
+ try {
852
+ host.chdir(request.cwd);
853
+ execLinuxTarget({ ...request, cwd: host.cwd() }, argv, internals);
854
+ } catch (error) {
855
+ writeLinuxStartupError(files, {
856
+ type: "error",
857
+ error: asSpawnError(error, argv[0])
858
+ });
859
+ host.exitCode = 127;
860
+ }
861
+ }
862
+ function sendMessage(host, result) {
863
+ return new Promise((resolve, reject) => {
864
+ if (!host.connected || host.send === void 0) {
865
+ reject(new Error("subprocess runner IPC is not connected"));
866
+ return;
867
+ }
868
+ try {
869
+ host.send(result, (error) => {
870
+ if (error === null) resolve();
871
+ else reject(error);
872
+ });
873
+ } catch (error) {
874
+ const failure = error instanceof Error ? error : new Error(String(error));
875
+ reject(failure);
876
+ }
877
+ });
878
+ }
879
+ var WindowsJobRunner = class {
880
+ constructor(argv, host, internals) {
881
+ this.argv = argv;
882
+ this.host = host;
883
+ this.internals = internals;
884
+ }
885
+ argv;
886
+ host;
887
+ internals;
888
+ api;
889
+ processHandle;
890
+ jobHandle;
891
+ pollTimer;
892
+ startSeen = false;
893
+ terminateRequested = false;
894
+ resultStarted = false;
895
+ resultDelivered = false;
896
+ finished = false;
897
+ completion = Promise.withResolvers();
898
+ run() {
899
+ if (!this.host.connected || this.host.send === void 0) {
900
+ this.finish(127);
901
+ return this.completion.promise;
902
+ }
903
+ this.host.on("message", this.onMessage);
904
+ this.host.once("disconnect", this.onDisconnect);
905
+ return this.completion.promise;
906
+ }
907
+ onMessage = (value) => {
908
+ if (this.finished) return;
909
+ if (isWindowsTerminateRequest(value)) {
910
+ this.requestTermination();
911
+ return;
912
+ }
913
+ if (this.startSeen) {
914
+ void this.runnerFailure(new Error("subprocess runner received more than one Windows start request"));
915
+ return;
916
+ }
917
+ let request;
918
+ try {
919
+ request = parseWindowsStartRequest(value);
920
+ } catch (error) {
921
+ void this.runnerFailure(error);
922
+ return;
923
+ }
924
+ this.startSeen = true;
925
+ void this.start(request);
926
+ };
927
+ onDisconnect = () => {
928
+ if (this.finished) return;
929
+ this.releaseOwnedJob();
930
+ this.finish(127, false);
931
+ };
932
+ async start(request) {
933
+ if (this.terminateRequested) {
934
+ await this.publishTerminalResult({ type: "error", error: windowsStartCancelledError() }, 0);
935
+ return;
936
+ }
937
+ await new Promise((resolveImmediate) => {
938
+ setImmediate(resolveImmediate);
939
+ });
940
+ if (this.finished) return;
941
+ if (this.terminateRequested) {
942
+ await this.publishTerminalResult({ type: "error", error: windowsStartCancelledError() }, 0);
943
+ return;
944
+ }
945
+ try {
946
+ const [command, ...args] = this.argv;
947
+ const applicationName = this.internals.resolveWindowsExecutable(
948
+ command,
949
+ request.cwd,
950
+ request.env,
951
+ void 0,
952
+ { ...this.host.env }
953
+ );
954
+ if (applicationName === void 0) {
955
+ await this.publishTerminalResult({
956
+ type: "error",
957
+ error: windowsPathNotFoundError(command)
958
+ }, 0);
959
+ return;
960
+ }
961
+ this.api = this.internals.loadWin32ProcessBindings();
962
+ const spawned = this.internals.spawnCurrentTokenJobProcess(this.api, {
963
+ command,
964
+ applicationName,
965
+ args,
966
+ cwd: request.cwd,
967
+ env: request.env,
968
+ stdio: { stdin: 4, stdout: 5, stderr: 6, ...request.control === "pipe" ? { control: SUBPROCESS_CONTROL_FD } : {} }
969
+ });
970
+ this.processHandle = spawned.process;
971
+ this.jobHandle = spawned.job;
972
+ for (const fileDescriptor of request.control === "pipe" ? [4, 5, 6, SUBPROCESS_CONTROL_FD] : [4, 5, 6]) {
973
+ this.internals.closeFileDescriptor(fileDescriptor);
974
+ }
975
+ this.pollTimer = setInterval(() => {
976
+ this.poll();
977
+ }, 10);
978
+ } catch (error) {
979
+ if (this.jobHandle === void 0 && error instanceof Win32Error && error.api === "CreateProcessW") {
980
+ await this.publishTerminalResult({
981
+ type: "error",
982
+ error: asSpawnError(error, this.argv[0])
983
+ }, 0);
984
+ return;
985
+ }
986
+ await this.runnerFailure(error);
987
+ }
988
+ }
989
+ requestTermination() {
990
+ if (this.terminateRequested) return;
991
+ this.terminateRequested = true;
992
+ try {
993
+ this.terminateOwnedJob();
994
+ } catch (error) {
995
+ void this.runnerFailure(error);
996
+ }
997
+ }
998
+ terminateOwnedJob() {
999
+ const job = this.jobHandle;
1000
+ if (job === void 0) return;
1001
+ if (this.api === void 0) return;
1002
+ this.internals.terminateJob(this.api, job, 1);
1003
+ }
1004
+ poll() {
1005
+ if (this.finished) return;
1006
+ if (this.api === void 0) return;
1007
+ try {
1008
+ if (this.processHandle !== void 0) {
1009
+ const exitCode = this.internals.pollProcessExit(this.api, this.processHandle);
1010
+ if (exitCode !== void 0) {
1011
+ this.internals.closeHandleChecked(this.api, this.processHandle, "ordinary direct process");
1012
+ this.processHandle = void 0;
1013
+ void this.publishTerminalResult({ type: "target-exit", exitCode });
1014
+ }
1015
+ }
1016
+ if (this.jobHandle !== void 0 && this.internals.isJobEmpty(this.api, this.jobHandle)) {
1017
+ this.internals.closeHandleChecked(this.api, this.jobHandle, "ordinary process Job");
1018
+ this.jobHandle = void 0;
1019
+ if (this.resultDelivered) this.finish(0);
1020
+ }
1021
+ } catch (error) {
1022
+ void this.runnerFailure(error);
1023
+ }
1024
+ }
1025
+ async publishTerminalResult(result, exitCode) {
1026
+ if (this.finished || this.resultStarted) return;
1027
+ this.resultStarted = true;
1028
+ try {
1029
+ await sendMessage(this.host, result);
1030
+ this.resultDelivered = true;
1031
+ } catch {
1032
+ this.releaseOwnedJob();
1033
+ this.finish(127, false);
1034
+ return;
1035
+ }
1036
+ if (exitCode !== void 0) {
1037
+ this.finish(exitCode);
1038
+ return;
1039
+ }
1040
+ if (this.jobHandle === void 0) this.finish(0);
1041
+ }
1042
+ async runnerFailure(error) {
1043
+ if (this.finished) return;
1044
+ if (!this.resultStarted) {
1045
+ this.resultStarted = true;
1046
+ try {
1047
+ await sendMessage(this.host, { type: "error", error: serializeRunnerError(error) });
1048
+ this.resultDelivered = true;
1049
+ } catch {
1050
+ }
1051
+ }
1052
+ this.releaseOwnedJob();
1053
+ this.finish(127);
1054
+ }
1055
+ releaseOwnedJob() {
1056
+ if (this.pollTimer !== void 0) clearInterval(this.pollTimer);
1057
+ this.pollTimer = void 0;
1058
+ const api = this.api;
1059
+ if (api === void 0) return;
1060
+ if (this.jobHandle !== void 0) {
1061
+ try {
1062
+ this.internals.terminateJob(api, this.jobHandle, 1);
1063
+ } catch {
1064
+ }
1065
+ try {
1066
+ this.internals.closeHandleChecked(api, this.jobHandle, "ordinary process Job cleanup");
1067
+ } catch {
1068
+ }
1069
+ this.jobHandle = void 0;
1070
+ }
1071
+ if (this.processHandle !== void 0) {
1072
+ try {
1073
+ this.internals.closeHandleChecked(api, this.processHandle, "ordinary direct process cleanup");
1074
+ } catch {
1075
+ }
1076
+ this.processHandle = void 0;
1077
+ }
1078
+ }
1079
+ finish(exitCode, disconnect = true) {
1080
+ if (this.finished) return;
1081
+ this.finished = true;
1082
+ if (this.pollTimer !== void 0) clearInterval(this.pollTimer);
1083
+ this.pollTimer = void 0;
1084
+ this.host.off("message", this.onMessage);
1085
+ this.host.off("disconnect", this.onDisconnect);
1086
+ this.host.exitCode = exitCode;
1087
+ if (disconnect && this.host.connected) this.host.disconnect();
1088
+ this.completion.resolve();
1089
+ }
1090
+ };
1091
+ async function runSpawnRunner(selection, argv, host = process, internals = defaultInternals) {
1092
+ Reflect.deleteProperty(host.env, SUBPROCESS_RUNNER_ENV);
1093
+ const targetArgv = parseRunnerTargetArgv(argv);
1094
+ if (selection === WINDOWS_RUNNER_SELECTION) {
1095
+ await new WindowsJobRunner(targetArgv, host, internals).run();
1096
+ return;
1097
+ }
1098
+ runLinux(selection, targetArgv, host, internals);
1099
+ }
1100
+ async function reportSpawnRunnerFailure(selection, error, host = process) {
1101
+ if (selection === WINDOWS_RUNNER_SELECTION) {
1102
+ try {
1103
+ await sendMessage(host, { type: "error", error: serializeRunnerError(error) });
1104
+ } catch {
1105
+ }
1106
+ host.exitCode = 127;
1107
+ if (host.connected) host.disconnect();
1108
+ return;
1109
+ }
1110
+ if (selection !== void 0) {
1111
+ try {
1112
+ const files = linuxLaunchFilesFromLocator(selection);
1113
+ writeLinuxStartupError(files, { type: "error", error: serializeRunnerError(error) });
1114
+ } catch {
1115
+ }
1116
+ }
1117
+ host.exitCode = 127;
1118
+ }
1119
+
1120
+ // packages/kernel/src/subprocess-local/bin.ts
1121
+ async function runSelectedSubprocessRunner(selection) {
1122
+ try {
1123
+ await runSpawnRunner(selection, process.argv.slice(2));
1124
+ } catch (error) {
1125
+ await reportSpawnRunnerFailure(selection, error);
1126
+ }
1127
+ }
1128
+ if (true) {
1129
+ const selection = consumeRunnerSelection();
1130
+ if (selection === void 0) {
1131
+ process.exitCode = 127;
1132
+ } else {
1133
+ void runSelectedSubprocessRunner(selection);
1134
+ }
1135
+ }
1136
+ export {
1137
+ runSelectedSubprocessRunner
1138
+ };