@ai-ecoverse/slicc-jsh 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/jsh.mjs CHANGED
@@ -1536,10 +1536,56 @@ ${e3}`;
1536
1536
  }
1537
1537
  });
1538
1538
 
1539
+ // src/runtime/exit.mjs
1540
+ var NodeExitError = class extends Error {
1541
+ constructor(code) {
1542
+ super(`Process exited with code ${code}`);
1543
+ this.name = "NodeExitError";
1544
+ this.code = code;
1545
+ }
1546
+ };
1547
+ function numericExitCode(value) {
1548
+ const n = Number(value);
1549
+ return Number.isFinite(n) ? n & 255 : 0;
1550
+ }
1551
+ function describeReceived(value) {
1552
+ if (typeof value === "string") return `type string ('${value}')`;
1553
+ if (typeof value === "boolean") return `type boolean (${value})`;
1554
+ if (typeof value === "bigint") return `type bigint (${value}n)`;
1555
+ if (Array.isArray(value)) return "an instance of Array";
1556
+ if (typeof value === "object" && value !== null) return "an instance of Object";
1557
+ return `type ${typeof value}`;
1558
+ }
1559
+ function assignProcessExitCode(value) {
1560
+ if (value === null || value === void 0) return void 0;
1561
+ if (typeof value === "string") {
1562
+ const n = Number(value);
1563
+ if (value !== "" && Number.isInteger(n)) return n === 0 ? 0 : n;
1564
+ const err2 = new TypeError(
1565
+ `The "code" argument must be of type number. Received ${describeReceived(value)}`
1566
+ );
1567
+ err2.code = "ERR_INVALID_ARG_TYPE";
1568
+ throw err2;
1569
+ }
1570
+ if (typeof value === "number") {
1571
+ if (Number.isInteger(value)) return value === 0 ? 0 : value;
1572
+ const err2 = new RangeError(
1573
+ `The value of "code" is out of range. It must be an integer. Received ${String(value)}`
1574
+ );
1575
+ err2.code = "ERR_OUT_OF_RANGE";
1576
+ throw err2;
1577
+ }
1578
+ const err = new TypeError(
1579
+ `The "code" argument must be of type number. Received ${describeReceived(value)}`
1580
+ );
1581
+ err.code = "ERR_INVALID_ARG_TYPE";
1582
+ throw err;
1583
+ }
1584
+
1539
1585
  // package.json
1540
1586
  var package_default = {
1541
1587
  name: "@ai-ecoverse/slicc-jsh",
1542
- version: "0.2.0",
1588
+ version: "0.3.0",
1543
1589
  description: "Node.js-compatible runtime for slicc-kernel: the node and jsh commands (abi: js)",
1544
1590
  type: "module",
1545
1591
  license: "Apache-2.0",
@@ -1560,8 +1606,13 @@ var package_default = {
1560
1606
  },
1561
1607
  publishConfig: {
1562
1608
  access: "public",
1563
- provenance: true,
1564
- tag: "latest"
1609
+ provenance: true
1610
+ },
1611
+ fledgling: {
1612
+ provider: "github",
1613
+ workflow: "release.yml",
1614
+ repo: "ai-ecoverse/slicc-jsh",
1615
+ publish: true
1565
1616
  },
1566
1617
  files: [
1567
1618
  "LICENSE",
@@ -1598,16 +1649,21 @@ var package_default = {
1598
1649
  "test:node-parallel": "node --max-old-space-size=512 test/node-parallel/run.mjs",
1599
1650
  "golden:record": "node --max-old-space-size=512 scripts/golden.mjs record",
1600
1651
  "test:jsh": "node --max-old-space-size=512 scripts/jsh-golden.mjs check",
1601
- "jsh:record": "node --max-old-space-size=512 scripts/jsh-golden.mjs record"
1652
+ "jsh:record": "node --max-old-space-size=512 scripts/jsh-golden.mjs record",
1653
+ release: "semantic-release",
1654
+ trust: "npx fledgling sync -y --skip-publish",
1655
+ "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
1602
1656
  },
1603
1657
  devDependencies: {
1604
- "@ai-ecoverse/slicc-kernel": "1.56.2",
1658
+ "@ai-ecoverse/slicc-kernel": "1.59.0",
1659
+ "@ai-ecoverse/wasi-pnpm": "12.9.1-8",
1605
1660
  "abort-controller": "3.0.0",
1606
1661
  acorn: "8.19.0",
1607
1662
  esbuild: "0.28.2",
1608
1663
  "node-inspect-extracted": "3.3.4",
1609
1664
  process: "0.11.10",
1610
1665
  "readable-stream": "4.8.0",
1666
+ "semantic-release": "25.0.9",
1611
1667
  string_decoder: "1.3.0",
1612
1668
  ws: "8.22.0"
1613
1669
  }
@@ -2275,50 +2331,155 @@ async function runJsh({ filename, engine, process: process2, console: console2 }
2275
2331
  return void 0;
2276
2332
  }
2277
2333
 
2278
- // src/runtime/exit.mjs
2279
- var NodeExitError = class extends Error {
2280
- constructor(code) {
2281
- super(`Process exited with code ${code}`);
2282
- this.name = "NodeExitError";
2283
- this.code = code;
2334
+ // src/jsh/kernel.mjs
2335
+ var JSH_HANDOFF = /* @__PURE__ */ Symbol.for("slicc-jsh.kernel");
2336
+ var decoder = new TextDecoder();
2337
+ var encoder = new TextEncoder();
2338
+ var AsyncFunction = Object.getPrototypeOf(async () => {
2339
+ }).constructor;
2340
+ async function readAll(stream) {
2341
+ if (!stream) return new Uint8Array(0);
2342
+ const chunks = [];
2343
+ let size = 0;
2344
+ const reader = stream.getReader();
2345
+ for (; ; ) {
2346
+ const { done, value } = await reader.read();
2347
+ if (done) break;
2348
+ const bytes = typeof value === "string" ? encoder.encode(value) : value;
2349
+ chunks.push(bytes);
2350
+ size += bytes.length;
2284
2351
  }
2285
- };
2286
- function numericExitCode(value) {
2287
- const n = Number(value);
2288
- return Number.isFinite(n) ? n & 255 : 0;
2289
- }
2290
- function describeReceived(value) {
2291
- if (typeof value === "string") return `type string ('${value}')`;
2292
- if (typeof value === "boolean") return `type boolean (${value})`;
2293
- if (typeof value === "bigint") return `type bigint (${value}n)`;
2294
- if (Array.isArray(value)) return "an instance of Array";
2295
- if (typeof value === "object" && value !== null) return "an instance of Object";
2296
- return `type ${typeof value}`;
2352
+ const out = new Uint8Array(size);
2353
+ let off = 0;
2354
+ for (const c of chunks) {
2355
+ out.set(c, off);
2356
+ off += c.length;
2357
+ }
2358
+ return out;
2297
2359
  }
2298
- function assignProcessExitCode(value) {
2299
- if (value === null || value === void 0) return void 0;
2300
- if (typeof value === "string") {
2301
- const n = Number(value);
2302
- if (value !== "" && Number.isInteger(n)) return n === 0 ? 0 : n;
2303
- const err2 = new TypeError(
2304
- `The "code" argument must be of type number. Received ${describeReceived(value)}`
2305
- );
2306
- err2.code = "ERR_INVALID_ARG_TYPE";
2307
- throw err2;
2360
+ async function writeAll(stream, data2) {
2361
+ const writer = stream.getWriter();
2362
+ try {
2363
+ await writer.write(typeof data2 === "string" ? encoder.encode(data2) : data2);
2364
+ await writer.close();
2365
+ } catch {
2308
2366
  }
2309
- if (typeof value === "number") {
2310
- if (Number.isInteger(value)) return value === 0 ? 0 : value;
2311
- const err2 = new RangeError(
2312
- `The value of "code" is out of range. It must be an integer. Received ${String(value)}`
2367
+ }
2368
+ function kernelSpawn(ctx, process2) {
2369
+ return (argv, { stdin } = {}) => {
2370
+ let child = null;
2371
+ const done = (async () => {
2372
+ try {
2373
+ child = await ctx.spawn({
2374
+ argv,
2375
+ cwd: process2.cwd(),
2376
+ env: { ...process2.env },
2377
+ stdin: stdin === void 0 ? "null" : "pipe",
2378
+ stdout: "pipe",
2379
+ stderr: "pipe"
2380
+ });
2381
+ } catch (err2) {
2382
+ if (err2?.code === "ENOENT") {
2383
+ return { stdout: "", stderr: `${argv[0]}: command not found
2384
+ `, exitCode: 127 };
2385
+ }
2386
+ return { stdout: "", stderr: `${argv[0]}: ${err2?.message ?? err2}
2387
+ `, exitCode: 126 };
2388
+ }
2389
+ const [out, err, status] = await Promise.all([
2390
+ readAll(child.stdout),
2391
+ readAll(child.stderr),
2392
+ child.wait(),
2393
+ stdin === void 0 ? void 0 : writeAll(child.stdin, stdin)
2394
+ ]);
2395
+ return { stdout: decoder.decode(out), stderr: decoder.decode(err), exitCode: status.status };
2396
+ })();
2397
+ return {
2398
+ kill: async (sig = "SIGTERM") => child ? child.kill(sig) : false,
2399
+ done
2400
+ };
2401
+ };
2402
+ }
2403
+ function compiler(rt) {
2404
+ return (body, filename) => {
2405
+ const head = "(async function () {";
2406
+ const { code, changed, binding = "__import" } = rt.rewriteDynamicImports(
2407
+ `${head}${body}
2408
+ })`
2313
2409
  );
2314
- err2.code = "ERR_OUT_OF_RANGE";
2315
- throw err2;
2410
+ const text = changed ? code.slice(head.length, -3) : body;
2411
+ const params = changed ? [...JSH_PARAMS, binding] : [...JSH_PARAMS];
2412
+ const fn = new AsyncFunction(...params, `${text}
2413
+ //# sourceURL=${filename}`);
2414
+ if (!changed) return fn;
2415
+ const importFrom = (specifier) => rt.importModule(specifier, filename);
2416
+ return (...args) => fn(...args.slice(0, JSH_PARAMS.length), importFrom);
2417
+ };
2418
+ }
2419
+ async function runKernelJsh(ctx, rt, filename) {
2420
+ const { process: process2, console: console2 } = rt;
2421
+ let stdoutIsTTY = false;
2422
+ try {
2423
+ stdoutIsTTY = !!await ctx.isatty?.(1);
2424
+ } catch {
2425
+ stdoutIsTTY = false;
2426
+ }
2427
+ const engine = {
2428
+ readSource: (path) => decoder.decode(ctx.sync.fs.readFile(path)),
2429
+ compile: compiler(rt),
2430
+ createRequire: (path) => rt.createRequire(path),
2431
+ selfRequire: rt.createRequire("/node_modules/@ai-ecoverse/slicc-jsh/package.json"),
2432
+ writeStdout: (s) => process2.stdout.write(String(s)),
2433
+ writeStderr: (s) => process2.stderr.write(String(s)),
2434
+ stdoutIsTTY,
2435
+ spawn: kernelSpawn(ctx, process2),
2436
+ shell: ["sh", "-c"],
2437
+ fetch: rt.fetch,
2438
+ isExit: (err) => err instanceof NodeExitError,
2439
+ exit: (code) => process2.exit(code)
2440
+ };
2441
+ await runJsh({ filename, engine, process: process2, console: console2 });
2442
+ }
2443
+ function installJshHandoff(ctx, rt) {
2444
+ const handoff = Object.freeze({
2445
+ version: JSH_VERSION,
2446
+ async runJsh(args) {
2447
+ const { process: process2 } = rt;
2448
+ const parsed = parseJshArgv([...args]);
2449
+ if (parsed.action === "version") return void process2.stdout.write(`${JSH_VERSION}
2450
+ `);
2451
+ if (parsed.action === "help") return void process2.stdout.write(JSH_USAGE);
2452
+ if (parsed.action === "usage") {
2453
+ process2.stderr.write(JSH_USAGE);
2454
+ return process2.exit(2);
2455
+ }
2456
+ if (parsed.action === "error") {
2457
+ process2.stderr.write(`${parsed.message}
2458
+ ${JSH_USAGE}`);
2459
+ return process2.exit(parsed.status);
2460
+ }
2461
+ const filename = ctx.resolve(parsed.script);
2462
+ process2.argv = ["jsh", filename, ...parsed.args];
2463
+ return runKernelJsh(ctx, rt, filename);
2464
+ }
2465
+ });
2466
+ try {
2467
+ Object.defineProperty(globalThis, JSH_HANDOFF, {
2468
+ value: handoff,
2469
+ enumerable: false,
2470
+ configurable: true,
2471
+ writable: false
2472
+ });
2473
+ } catch {
2474
+ return () => {
2475
+ };
2316
2476
  }
2317
- const err = new TypeError(
2318
- `The "code" argument must be of type number. Received ${describeReceived(value)}`
2319
- );
2320
- err.code = "ERR_INVALID_ARG_TYPE";
2321
- throw err;
2477
+ return () => {
2478
+ try {
2479
+ delete globalThis[JSH_HANDOFF];
2480
+ } catch {
2481
+ }
2482
+ };
2322
2483
  }
2323
2484
 
2324
2485
  // src/runtime/async-handles.mjs
@@ -2377,8 +2538,8 @@ async function drainLoop(handles, nextTick, { onBeforeExit, shouldStop } = {}) {
2377
2538
  }
2378
2539
 
2379
2540
  // src/runtime/buffer.mjs
2380
- var encoder = new TextEncoder();
2381
- var decoder = new TextDecoder();
2541
+ var encoder2 = new TextEncoder();
2542
+ var decoder2 = new TextDecoder();
2382
2543
  var INSPECT_CUSTOM = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
2383
2544
  function normalizeEncoding(enc) {
2384
2545
  if (!enc) return "utf8";
@@ -2450,7 +2611,7 @@ function asUint8(value, encoding = "utf8") {
2450
2611
  for (let i2 = 0; i2 < value.length; i2++) out[i2] = value.charCodeAt(i2) & 255;
2451
2612
  return out;
2452
2613
  }
2453
- return encoder.encode(value);
2614
+ return encoder2.encode(value);
2454
2615
  }
2455
2616
  if (typeof value === "number") return new Uint8Array([value & 255]);
2456
2617
  if (ArrayBuffer.isView(value)) {
@@ -2458,7 +2619,7 @@ function asUint8(value, encoding = "utf8") {
2458
2619
  }
2459
2620
  if (value instanceof ArrayBuffer) return new Uint8Array(value);
2460
2621
  if (Array.isArray(value)) return Uint8Array.from(value);
2461
- return encoder.encode(String(value));
2622
+ return encoder2.encode(String(value));
2462
2623
  }
2463
2624
  function toStringOf(bytes, encoding = "utf8", start = 0, end = bytes.length) {
2464
2625
  const slice = bytes.subarray(start, end);
@@ -2482,7 +2643,7 @@ function toStringOf(bytes, encoding = "utf8", start = 0, end = bytes.length) {
2482
2643
  for (const b of slice) out += String.fromCharCode(b);
2483
2644
  return out;
2484
2645
  }
2485
- return decoder.decode(slice);
2646
+ return decoder2.decode(slice);
2486
2647
  }
2487
2648
  var float32Array = new Float32Array(1);
2488
2649
  var uInt8Float32Array = new Uint8Array(float32Array.buffer);
@@ -10632,9 +10793,418 @@ function createEvents() {
10632
10793
  });
10633
10794
  }
10634
10795
 
10796
+ // src/runtime/builtins/child-process.mjs
10797
+ var SIGNAL_NAMES = {
10798
+ 1: "SIGHUP",
10799
+ 2: "SIGINT",
10800
+ 3: "SIGQUIT",
10801
+ 6: "SIGABRT",
10802
+ 9: "SIGKILL",
10803
+ 10: "SIGUSR1",
10804
+ 12: "SIGUSR2",
10805
+ 13: "SIGPIPE",
10806
+ 14: "SIGALRM",
10807
+ 15: "SIGTERM",
10808
+ 17: "SIGCHLD",
10809
+ 18: "SIGCONT",
10810
+ 19: "SIGSTOP",
10811
+ 20: "SIGTSTP"
10812
+ };
10813
+ var SIGNAL_NUMBERS = Object.fromEntries(
10814
+ Object.entries(SIGNAL_NAMES).map(([n, name]) => [name, Number(n)])
10815
+ );
10816
+ function notSupported(name) {
10817
+ const err = new Error(`slicc-jsh: child_process.${name} is not supported yet`);
10818
+ err.code = "ERR_NOT_SUPPORTED";
10819
+ throw err;
10820
+ }
10821
+ function normalizeArgs(file, args, options, callback) {
10822
+ if (typeof args === "function") {
10823
+ return { args: [], options: {}, callback: args };
10824
+ }
10825
+ if (typeof options === "function") {
10826
+ return { args: Array.isArray(args) ? args : [], options: {}, callback: options };
10827
+ }
10828
+ if (args != null && !Array.isArray(args) && typeof args === "object") {
10829
+ return { args: [], options: args, callback: typeof options === "function" ? options : callback };
10830
+ }
10831
+ return {
10832
+ args: Array.isArray(args) ? args.map(String) : [],
10833
+ options: options && typeof options === "object" ? options : {},
10834
+ callback: typeof callback === "function" ? callback : void 0
10835
+ };
10836
+ }
10837
+ function normalizeStdio(stdio) {
10838
+ if (stdio === void 0) return ["pipe", "pipe", "pipe"];
10839
+ if (typeof stdio === "string") return [stdio, stdio, stdio];
10840
+ if (Array.isArray(stdio)) {
10841
+ return [stdio[0] ?? "pipe", stdio[1] ?? "pipe", stdio[2] ?? "pipe"];
10842
+ }
10843
+ return ["pipe", "pipe", "pipe"];
10844
+ }
10845
+ function toKernelStdio(mode) {
10846
+ if (mode === "pipe" || mode === "overlapped") return "pipe";
10847
+ if (mode === "ignore" || mode === null || mode === void 0 || mode === "null") return "null";
10848
+ if (mode === "inherit") return "inherit";
10849
+ if (typeof mode === "number") return mode;
10850
+ const err = new Error(`The argument 'stdio' is invalid. Received ${String(mode)}`);
10851
+ err.code = "ERR_INVALID_ARG_VALUE";
10852
+ throw err;
10853
+ }
10854
+ function signalName(sig) {
10855
+ if (sig == null) return null;
10856
+ if (typeof sig === "string") return sig.startsWith("SIG") ? sig : `SIG${sig}`;
10857
+ if (typeof sig === "number") return SIGNAL_NAMES[sig] ?? String(sig);
10858
+ return null;
10859
+ }
10860
+ function spawnError(command, args, code, message) {
10861
+ const err = new Error(message ?? `spawn ${command} ${code}`);
10862
+ err.code = code;
10863
+ err.errno = code === "ENOENT" ? -2 : void 0;
10864
+ err.syscall = "spawn";
10865
+ err.path = command;
10866
+ err.spawnargs = args;
10867
+ return err;
10868
+ }
10869
+ function createChildProcess({ ctx, process: process2, Buffer: Buffer2, handles, getStream }) {
10870
+ class ChildProcess extends EventEmitter {
10871
+ constructor() {
10872
+ super();
10873
+ this.stdin = null;
10874
+ this.stdout = null;
10875
+ this.stderr = null;
10876
+ this.pid = void 0;
10877
+ this.exitCode = null;
10878
+ this.signalCode = null;
10879
+ this.killed = false;
10880
+ this.connected = false;
10881
+ this.spawnfile = "";
10882
+ this.spawnargs = [];
10883
+ this.#kernel = null;
10884
+ this.#handle = null;
10885
+ this.#closing = false;
10886
+ }
10887
+ #kernel;
10888
+ #handle;
10889
+ #closing;
10890
+ kill(signal = "SIGTERM") {
10891
+ const name = signalName(signal) ?? "SIGTERM";
10892
+ this.killed = true;
10893
+ if (!this.#kernel) return false;
10894
+ try {
10895
+ const ret = this.#kernel.kill(name);
10896
+ return ret !== false;
10897
+ } catch {
10898
+ return false;
10899
+ }
10900
+ }
10901
+ ref() {
10902
+ if (this.#handle) handles.add(this.#handle);
10903
+ return this;
10904
+ }
10905
+ unref() {
10906
+ if (this.#handle) handles.delete(this.#handle);
10907
+ return this;
10908
+ }
10909
+ /** @internal */
10910
+ _bindKernel(child) {
10911
+ this.#kernel = child;
10912
+ this.pid = child.pid;
10913
+ this.#handle = { kind: "child", pid: child.pid };
10914
+ handles.add(this.#handle);
10915
+ }
10916
+ /** @internal */
10917
+ _release() {
10918
+ if (this.#handle) {
10919
+ handles.delete(this.#handle);
10920
+ this.#handle = null;
10921
+ }
10922
+ }
10923
+ /** @internal */
10924
+ _markClosing() {
10925
+ this.#closing = true;
10926
+ }
10927
+ get _closing() {
10928
+ return this.#closing;
10929
+ }
10930
+ }
10931
+ function createPipeReadable() {
10932
+ const { Readable } = getStream();
10933
+ const r = new Readable({ read() {
10934
+ } });
10935
+ r._sliccPump = async (webStream) => {
10936
+ if (!webStream) {
10937
+ r.push(null);
10938
+ return;
10939
+ }
10940
+ try {
10941
+ const reader = webStream.getReader();
10942
+ for (; ; ) {
10943
+ const { done, value } = await reader.read();
10944
+ if (done) break;
10945
+ const chunk = value instanceof Uint8Array ? Buffer2.from(value) : Buffer2.from(String(value));
10946
+ r.push(chunk);
10947
+ }
10948
+ r.push(null);
10949
+ } catch (err) {
10950
+ r.destroy(err);
10951
+ }
10952
+ };
10953
+ return r;
10954
+ }
10955
+ function createPipeWritable() {
10956
+ const { Writable } = getStream();
10957
+ let writer = null;
10958
+ const pending = [];
10959
+ let ended = false;
10960
+ const w = new Writable({
10961
+ write(chunk, _enc, cb) {
10962
+ const bytes = typeof chunk === "string" ? Buffer2.from(chunk) : chunk;
10963
+ if (!writer) {
10964
+ pending.push({ bytes, cb });
10965
+ return;
10966
+ }
10967
+ writer.write(bytes).then(() => cb(), cb);
10968
+ },
10969
+ final(cb) {
10970
+ ended = true;
10971
+ if (!writer) {
10972
+ pending.push({ end: true, cb });
10973
+ return;
10974
+ }
10975
+ writer.close().then(() => cb(), cb);
10976
+ },
10977
+ destroy(err, cb) {
10978
+ if (writer) writer.abort(err).then(() => cb(err), () => cb(err));
10979
+ else cb(err);
10980
+ }
10981
+ });
10982
+ w._sliccAttach = (webStream) => {
10983
+ if (!webStream) {
10984
+ for (const p of pending) p.cb?.(new Error("stdin not available"));
10985
+ pending.length = 0;
10986
+ return;
10987
+ }
10988
+ writer = webStream.getWriter();
10989
+ for (const p of pending) {
10990
+ if (p.end) writer.close().then(() => p.cb(), p.cb);
10991
+ else writer.write(p.bytes).then(() => p.cb(), p.cb);
10992
+ }
10993
+ pending.length = 0;
10994
+ if (ended && pending.length === 0) {
10995
+ }
10996
+ };
10997
+ return w;
10998
+ }
10999
+ function prepareStdio(child, stdio) {
11000
+ const [inMode, outMode, errMode] = stdio;
11001
+ if (toKernelStdio(inMode) === "pipe") child.stdin = createPipeWritable();
11002
+ if (toKernelStdio(outMode) === "pipe") child.stdout = createPipeReadable();
11003
+ if (toKernelStdio(errMode) === "pipe") child.stderr = createPipeReadable();
11004
+ }
11005
+ function connectStdio(child, kernelChild) {
11006
+ child.stdin?._sliccAttach?.(kernelChild.stdin);
11007
+ const pumps = [];
11008
+ if (child.stdout?._sliccPump) pumps.push(child.stdout._sliccPump(kernelChild.stdout));
11009
+ if (child.stderr?._sliccPump) pumps.push(child.stderr._sliccPump(kernelChild.stderr));
11010
+ child._stdioPumps = Promise.all(pumps);
11011
+ }
11012
+ function finish(child, code, signal) {
11013
+ if (child._closing) return;
11014
+ child._markClosing();
11015
+ child.exitCode = code;
11016
+ child.signalCode = signal;
11017
+ child.emit("exit", code, signal);
11018
+ const after = child._stdioPumps ?? Promise.resolve();
11019
+ trackPromise(handles, after);
11020
+ after.finally(() => {
11021
+ child.emit("close", code, signal);
11022
+ child._release();
11023
+ handles.notify?.();
11024
+ });
11025
+ }
11026
+ function startSpawn(child, file, args, options, stdio) {
11027
+ const cwd = options.cwd != null ? String(options.cwd) : process2.cwd();
11028
+ const env = options.env ? { ...options.env } : { ...process2.env };
11029
+ const argv = [file, ...args];
11030
+ child.spawnfile = file;
11031
+ child.spawnargs = argv;
11032
+ const spawnPromise = ctx.spawn({
11033
+ argv,
11034
+ cwd,
11035
+ env,
11036
+ stdin: toKernelStdio(stdio[0]),
11037
+ stdout: toKernelStdio(stdio[1]),
11038
+ stderr: toKernelStdio(stdio[2])
11039
+ });
11040
+ trackPromise(handles, spawnPromise);
11041
+ spawnPromise.then(
11042
+ (kernelChild) => {
11043
+ child._bindKernel(kernelChild);
11044
+ connectStdio(child, kernelChild);
11045
+ child.emit("spawn");
11046
+ const waitP = kernelChild.wait();
11047
+ trackPromise(handles, waitP);
11048
+ waitP.then(
11049
+ (status) => {
11050
+ const sigNum = status?.signal;
11051
+ if (sigNum != null && sigNum !== 0) {
11052
+ const name = SIGNAL_NAMES[sigNum] ?? String(sigNum);
11053
+ finish(child, null, name);
11054
+ } else {
11055
+ const code = typeof status?.status === "number" ? status.status : 0;
11056
+ finish(child, code, null);
11057
+ }
11058
+ },
11059
+ (err) => {
11060
+ child.emit("error", err);
11061
+ finish(child, 1, null);
11062
+ }
11063
+ );
11064
+ },
11065
+ (err) => {
11066
+ const code = err?.code === "ENOENT" ? "ENOENT" : err?.code ?? "ERR_SPAWN_FAILED";
11067
+ const error = code === "ENOENT" ? spawnError(file, args, "ENOENT", `spawn ${file} ENOENT`) : spawnError(file, args, code, err?.message ?? String(err));
11068
+ try {
11069
+ child.stdout?.push?.(null);
11070
+ } catch {
11071
+ }
11072
+ try {
11073
+ child.stderr?.push?.(null);
11074
+ } catch {
11075
+ }
11076
+ process2.nextTick(() => {
11077
+ child.emit("error", error);
11078
+ if (code === "ENOENT") {
11079
+ child.exitCode = -2;
11080
+ child.emit("close", -2, null);
11081
+ } else {
11082
+ finish(child, 1, null);
11083
+ }
11084
+ child._release();
11085
+ handles.notify?.();
11086
+ });
11087
+ }
11088
+ );
11089
+ }
11090
+ function spawn(command, args, options) {
11091
+ let file = command;
11092
+ let argv = args;
11093
+ let opts = options;
11094
+ if (argv != null && !Array.isArray(argv) && typeof argv === "object") {
11095
+ opts = argv;
11096
+ argv = [];
11097
+ }
11098
+ argv = Array.isArray(argv) ? argv.map(String) : [];
11099
+ opts = opts && typeof opts === "object" ? opts : {};
11100
+ file = String(file);
11101
+ if (opts.shell) {
11102
+ const shell = typeof opts.shell === "string" ? opts.shell : "sh";
11103
+ const line = argv.length ? [file, ...argv].join(" ") : file;
11104
+ file = shell;
11105
+ argv = ["-c", line];
11106
+ }
11107
+ const stdio = normalizeStdio(opts.stdio);
11108
+ const child = new ChildProcess();
11109
+ prepareStdio(child, stdio);
11110
+ process2.nextTick(() => startSpawn(child, file, argv, opts, stdio));
11111
+ return child;
11112
+ }
11113
+ function execFile(file, args, options, callback) {
11114
+ const norm = normalizeArgs(file, args, options, callback);
11115
+ const opts = { ...norm.options };
11116
+ if (opts.stdio === void 0) opts.stdio = ["pipe", "pipe", "pipe"];
11117
+ const child = spawn(String(file), norm.args, opts);
11118
+ if (!norm.callback) return child;
11119
+ const maxBuffer = opts.maxBuffer ?? 1024 * 1024;
11120
+ let stdout = Buffer2.alloc(0);
11121
+ let stderr = Buffer2.alloc(0);
11122
+ let exited = false;
11123
+ const done = (err) => {
11124
+ if (exited) return;
11125
+ exited = true;
11126
+ const enc = opts.encoding;
11127
+ const out = enc ? stdout.toString(enc) : stdout;
11128
+ const errOut = enc ? stderr.toString(enc) : stderr;
11129
+ norm.callback(err, out, errOut);
11130
+ };
11131
+ if (child.stdout) {
11132
+ child.stdout.on("data", (chunk) => {
11133
+ stdout = Buffer2.concat([stdout, Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk)]);
11134
+ if (stdout.length > maxBuffer) {
11135
+ child.kill();
11136
+ const err = new Error("stdout maxBuffer exceeded");
11137
+ err.code = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
11138
+ done(err);
11139
+ }
11140
+ });
11141
+ }
11142
+ if (child.stderr) {
11143
+ child.stderr.on("data", (chunk) => {
11144
+ stderr = Buffer2.concat([stderr, Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk)]);
11145
+ if (stderr.length > maxBuffer) {
11146
+ child.kill();
11147
+ const err = new Error("stderr maxBuffer exceeded");
11148
+ err.code = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
11149
+ done(err);
11150
+ }
11151
+ });
11152
+ }
11153
+ child.on("error", (err) => done(err));
11154
+ child.on("close", (code, signal) => {
11155
+ if (exited) return;
11156
+ if (code === 0 && !signal) {
11157
+ done(null);
11158
+ return;
11159
+ }
11160
+ const err = new Error(`Command failed: ${file} ${norm.args.join(" ")}`);
11161
+ err.code = code;
11162
+ err.killed = child.killed;
11163
+ err.signal = signal;
11164
+ err.cmd = `${file} ${norm.args.join(" ")}`.trim();
11165
+ err.stdout = opts.encoding ? stdout.toString(opts.encoding) : stdout;
11166
+ err.stderr = opts.encoding ? stderr.toString(opts.encoding) : stderr;
11167
+ done(err);
11168
+ });
11169
+ return child;
11170
+ }
11171
+ function exec(command, options, callback) {
11172
+ let opts = options;
11173
+ let cb = callback;
11174
+ if (typeof options === "function") {
11175
+ cb = options;
11176
+ opts = {};
11177
+ }
11178
+ opts = opts && typeof opts === "object" ? opts : {};
11179
+ const shell = typeof opts.shell === "string" ? opts.shell : "sh";
11180
+ return execFile(shell, ["-c", String(command)], { ...opts, shell: false }, cb);
11181
+ }
11182
+ return {
11183
+ spawn,
11184
+ execFile,
11185
+ exec,
11186
+ spawnSync() {
11187
+ notSupported("spawnSync");
11188
+ },
11189
+ execSync() {
11190
+ notSupported("execSync");
11191
+ },
11192
+ execFileSync() {
11193
+ notSupported("execFileSync");
11194
+ },
11195
+ fork() {
11196
+ notSupported("fork");
11197
+ },
11198
+ ChildProcess,
11199
+ // Expose for tests / advanced callers
11200
+ _SIGNAL_NAMES: SIGNAL_NAMES,
11201
+ _SIGNAL_NUMBERS: SIGNAL_NUMBERS
11202
+ };
11203
+ }
11204
+
10635
11205
  // src/runtime/builtins/fs.mjs
10636
- var encoder2 = new TextEncoder();
10637
- var decoder2 = new TextDecoder();
11206
+ var encoder3 = new TextEncoder();
11207
+ var decoder3 = new TextDecoder();
10638
11208
  var ERRNO = {
10639
11209
  ENOENT: -2,
10640
11210
  EEXIST: -17,
@@ -10679,10 +11249,10 @@ function nodeFsError(code, syscall, pathArg, err, dest) {
10679
11249
  return e;
10680
11250
  }
10681
11251
  function toBytes(data2) {
10682
- if (typeof data2 === "string") return encoder2.encode(data2);
11252
+ if (typeof data2 === "string") return encoder3.encode(data2);
10683
11253
  if (data2 instanceof Uint8Array) return data2;
10684
11254
  if (ArrayBuffer.isView(data2)) return new Uint8Array(data2.buffer, data2.byteOffset, data2.byteLength);
10685
- return encoder2.encode(String(data2));
11255
+ return encoder3.encode(String(data2));
10686
11256
  }
10687
11257
  function statView(st) {
10688
11258
  const mtimeMs = st.mtimeMs ?? (st.mtime ? Number(st.mtime) : 0);
@@ -10866,11 +11436,11 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
10866
11436
  try {
10867
11437
  if (typeof process2?._readStdinSync === "function") {
10868
11438
  const out = process2._readStdinSync();
10869
- return encoding ? decoder2.decode(out) : wrapBuffer(out);
11439
+ return encoding ? decoder3.decode(out) : wrapBuffer(out);
10870
11440
  }
10871
11441
  if (typeof process2?.stdin?._readAllSync === "function") {
10872
11442
  const out = process2.stdin._readAllSync();
10873
- return encoding ? decoder2.decode(out) : wrapBuffer(out);
11443
+ return encoding ? decoder3.decode(out) : wrapBuffer(out);
10874
11444
  }
10875
11445
  if (typeof ctx.sync?.read === "function") {
10876
11446
  const chunks = [];
@@ -10887,7 +11457,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
10887
11457
  out.set(c, at2);
10888
11458
  at2 += c.length;
10889
11459
  }
10890
- return encoding ? decoder2.decode(out) : wrapBuffer(out);
11460
+ return encoding ? decoder3.decode(out) : wrapBuffer(out);
10891
11461
  }
10892
11462
  } catch {
10893
11463
  }
@@ -10959,7 +11529,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
10959
11529
  throw e;
10960
11530
  }
10961
11531
  const bytes = syncFs.readFile(target);
10962
- if (encoding) return decoder2.decode(bytes);
11532
+ if (encoding) return decoder3.decode(bytes);
10963
11533
  return wrapBuffer(bytes);
10964
11534
  } catch (err) {
10965
11535
  if (err?.code && err.syscall) throw err;
@@ -11026,6 +11596,21 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11026
11596
  throw nodeFsError(err?.code || "ENOENT", "lstat", pathArg, err);
11027
11597
  }
11028
11598
  },
11599
+ /**
11600
+ * Resolve to a canonical absolute path. Symlink walk is not implemented;
11601
+ * when the path exists we return the normalized absolute form (enough for
11602
+ * pnpm's cmd shims, which only need dirname(realpathSync(argv[1]))).
11603
+ */
11604
+ realpathSync(p) {
11605
+ const pathArg = p;
11606
+ const target = abs(p);
11607
+ try {
11608
+ syncFs.stat(target);
11609
+ return target;
11610
+ } catch (err) {
11611
+ throw nodeFsError(err?.code || "ENOENT", "realpath", pathArg, err);
11612
+ }
11613
+ },
11029
11614
  readdirSync,
11030
11615
  mkdirSync,
11031
11616
  rmdirSync(p, options = {}) {
@@ -11127,7 +11712,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11127
11712
  );
11128
11713
  if (fd === 0) {
11129
11714
  const data2 = readStdinSync(null);
11130
- const src = data2 instanceof Uint8Array ? data2 : encoder2.encode(String(data2));
11715
+ const src = data2 instanceof Uint8Array ? data2 : encoder3.encode(String(data2));
11131
11716
  const n = Math.min(len, src.length);
11132
11717
  buffer.set(src.subarray(0, n), bufOffset);
11133
11718
  return n;
@@ -11250,7 +11835,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11250
11835
  const encoding = typeof options === "string" ? options : options?.encoding;
11251
11836
  try {
11252
11837
  const bytes = await asyncFs.readFile(abs(p));
11253
- if (encoding) return decoder2.decode(bytes);
11838
+ if (encoding) return decoder3.decode(bytes);
11254
11839
  return wrapBuffer(bytes);
11255
11840
  } catch (err) {
11256
11841
  throw nodeFsError(err?.code || "ENOENT", "open", p, err);
@@ -11664,6 +12249,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
11664
12249
  access: callbackify(syncApi.accessSync),
11665
12250
  stat: callbackify(syncApi.statSync),
11666
12251
  lstat: callbackify(syncApi.lstatSync),
12252
+ realpath: callbackify(syncApi.realpathSync),
11667
12253
  readdir: callbackify(syncApi.readdirSync),
11668
12254
  mkdir: callbackify(syncApi.mkdirSync),
11669
12255
  rmdir: callbackify(syncApi.rmdirSync),
@@ -12524,7 +13110,7 @@ function createHttp2({ ctx, process: process2, Buffer: Buffer2, handles, getStre
12524
13110
 
12525
13111
  // src/runtime/builtins/https.mjs
12526
13112
  var TLS_CLIENT_OPTS = ["cert", "key", "pfx", "ca"];
12527
- function notSupported(what) {
13113
+ function notSupported2(what) {
12528
13114
  const err = new Error(`slicc-jsh: '${what}' is not supported yet (no TLS on ctx.net)`);
12529
13115
  err.code = "ERR_NOT_SUPPORTED";
12530
13116
  return err;
@@ -12538,7 +13124,7 @@ function isManualRedirectUnsupported(err) {
12538
13124
  function rejectTlsOptions(options) {
12539
13125
  for (const name of TLS_CLIENT_OPTS) {
12540
13126
  if (options?.[name] != null) {
12541
- throw notSupported(`https.request option '${name}'`);
13127
+ throw notSupported2(`https.request option '${name}'`);
12542
13128
  }
12543
13129
  }
12544
13130
  }
@@ -12572,7 +13158,7 @@ function createHttps({ ctx, Buffer: Buffer2, http, handles }) {
12572
13158
  }
12573
13159
  }
12574
13160
  function createServer() {
12575
- throw notSupported("https.createServer");
13161
+ throw notSupported2("https.createServer");
12576
13162
  }
12577
13163
  class ClientRequest extends EventEmitter {
12578
13164
  #ended = false;
@@ -12663,7 +13249,7 @@ function createHttps({ ctx, Buffer: Buffer2, http, handles }) {
12663
13249
  if (this.#sent || this.#destroyed) return;
12664
13250
  this.#sent = true;
12665
13251
  try {
12666
- if (typeof ctx.fetch !== "function") throw notSupported("https.request");
13252
+ if (typeof ctx.fetch !== "function") throw notSupported2("https.request");
12667
13253
  const opts = this.#opts;
12668
13254
  const method = (opts.method ?? "GET").toUpperCase();
12669
13255
  const host = opts.hostname ?? opts.host ?? "localhost";
@@ -13284,7 +13870,7 @@ function createQuerystring() {
13284
13870
  }
13285
13871
 
13286
13872
  // src/runtime/vendor-load.mjs
13287
- var decoder3 = new TextDecoder();
13873
+ var decoder4 = new TextDecoder();
13288
13874
  var cache = /* @__PURE__ */ new Map();
13289
13875
  function evalCjs(source, filename) {
13290
13876
  const module = { exports: {} };
@@ -13300,7 +13886,7 @@ function loadVendorCjs({ ctx, packageRoot, name, globals = {} }) {
13300
13886
  if (cache.has(key)) return cache.get(key);
13301
13887
  const path = `${packageRoot}/dist/vendor/${name}.cjs`;
13302
13888
  const bytes = ctx.sync.fs.readFile(path);
13303
- const source = typeof bytes === "string" ? bytes : decoder3.decode(bytes);
13889
+ const source = typeof bytes === "string" ? bytes : decoder4.decode(bytes);
13304
13890
  const saved = {};
13305
13891
  for (const [k, v] of Object.entries(globals)) {
13306
13892
  saved[k] = globalThis[k];
@@ -13552,6 +14138,7 @@ var BUILTIN_LIST = [
13552
14138
  "assert",
13553
14139
  "assert/strict",
13554
14140
  "buffer",
14141
+ "child_process",
13555
14142
  "console",
13556
14143
  "events",
13557
14144
  "fs",
@@ -13575,7 +14162,6 @@ var BUILTIN_LIST = [
13575
14162
  "util/types"
13576
14163
  ];
13577
14164
  var NOT_YET = [
13578
- "child_process",
13579
14165
  "http2",
13580
14166
  "crypto",
13581
14167
  "zlib",
@@ -13594,7 +14180,7 @@ var NOT_YET = [
13594
14180
  "v8",
13595
14181
  "was"
13596
14182
  ];
13597
- function notSupported2(id) {
14183
+ function notSupported3(id) {
13598
14184
  const err = new Error(`slicc-jsh: '${id}' is not supported yet`);
13599
14185
  err.code = "ERR_NOT_SUPPORTED";
13600
14186
  throw err;
@@ -13640,6 +14226,13 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
13640
14226
  if (!https) https = createHttps({ ctx, Buffer: Buffer2, http: getHttp(), handles });
13641
14227
  return https;
13642
14228
  };
14229
+ let childProcess;
14230
+ const getChildProcess = () => {
14231
+ if (!childProcess) {
14232
+ childProcess = createChildProcess({ ctx, process: process2, Buffer: Buffer2, handles, getStream });
14233
+ }
14234
+ return childProcess;
14235
+ };
13643
14236
  let ModuleExport = null;
13644
14237
  const implemented = {
13645
14238
  process: () => process2,
@@ -13665,7 +14258,8 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
13665
14258
  "timers/promises": () => timersPromises,
13666
14259
  net: () => getNet(),
13667
14260
  http: () => getHttp(),
13668
- https: () => getHttps()
14261
+ https: () => getHttps(),
14262
+ child_process: () => getChildProcess()
13669
14263
  };
13670
14264
  return {
13671
14265
  installModule(Module) {
@@ -13679,7 +14273,7 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
13679
14273
  },
13680
14274
  load(id) {
13681
14275
  const bare = id.startsWith("node:") ? id.slice(5) : id;
13682
- if (NOT_YET.includes(bare)) notSupported2(bare);
14276
+ if (NOT_YET.includes(bare)) notSupported3(bare);
13683
14277
  const factory = implemented[bare];
13684
14278
  if (!factory) {
13685
14279
  const err = new Error(`No such built-in module: ${id}`);
@@ -13986,7 +14580,7 @@ function isBuiltinName(name) {
13986
14580
  }
13987
14581
 
13988
14582
  // src/runtime/cjs/loader.mjs
13989
- var decoder4 = new TextDecoder();
14583
+ var decoder5 = new TextDecoder();
13990
14584
  function createCjs({
13991
14585
  ctx,
13992
14586
  process: process2,
@@ -14003,7 +14597,7 @@ function createCjs({
14003
14597
  const readPackageJson = (pkgPath) => {
14004
14598
  if (packageCache.has(pkgPath)) return packageCache.get(pkgPath);
14005
14599
  try {
14006
- const text = decoder4.decode(fs.readFile(pkgPath));
14600
+ const text = decoder5.decode(fs.readFile(pkgPath));
14007
14601
  const pkg = JSON.parse(text);
14008
14602
  packageCache.set(pkgPath, pkg);
14009
14603
  return pkg;
@@ -14090,14 +14684,14 @@ function createCjs({
14090
14684
  };
14091
14685
  Module._extensions = {
14092
14686
  ".js"(module, filename) {
14093
- const source = decoder4.decode(fs.readFile(filename));
14687
+ const source = decoder5.decode(fs.readFile(filename));
14094
14688
  compile(module, source, filename);
14095
14689
  },
14096
14690
  ".cjs"(module, filename) {
14097
14691
  Module._extensions[".js"](module, filename);
14098
14692
  },
14099
14693
  ".json"(module, filename) {
14100
- module.exports = JSON.parse(decoder4.decode(fs.readFile(filename)));
14694
+ module.exports = JSON.parse(decoder5.decode(fs.readFile(filename)));
14101
14695
  }
14102
14696
  };
14103
14697
  Module.Module = Module;
@@ -14581,7 +15175,7 @@ function createConsole(writeStdout, writeStderr, util2) {
14581
15175
  }
14582
15176
 
14583
15177
  // src/runtime/esm/loader.mjs
14584
- var decoder5 = new TextDecoder();
15178
+ var decoder6 = new TextDecoder();
14585
15179
  var IMPORT_CONDITIONS = ["slicc", "import", "node", "default"];
14586
15180
  function pathToFileURL2(filename) {
14587
15181
  if (filename.startsWith("file:")) return filename;
@@ -14625,7 +15219,7 @@ function createEsm({ ctx, process: process2, handles, builtins, cjs, trackPromis
14625
15219
  const readPackageJson = (pkgPath) => {
14626
15220
  if (packageCache.has(pkgPath)) return packageCache.get(pkgPath);
14627
15221
  try {
14628
- const pkg = JSON.parse(decoder5.decode(fs.readFile(pkgPath)));
15222
+ const pkg = JSON.parse(decoder6.decode(fs.readFile(pkgPath)));
14629
15223
  packageCache.set(pkgPath, pkg);
14630
15224
  return pkg;
14631
15225
  } catch {
@@ -14793,13 +15387,13 @@ ${parts.join("\n")}`
14793
15387
  }
14794
15388
  function loadFileSync(filename) {
14795
15389
  if (filename.endsWith(".json")) {
14796
- const data2 = JSON.parse(decoder5.decode(fs.readFile(filename)));
15390
+ const data2 = JSON.parse(decoder6.decode(fs.readFile(filename)));
14797
15391
  return cjsToNamespace(data2);
14798
15392
  }
14799
15393
  const cached3 = cache2.get(filename);
14800
15394
  if (cached3?.namespace) return cached3.namespace;
14801
15395
  if (cached3?.evaluating) return cached3.exportsObj;
14802
- const source = decoder5.decode(fs.readFile(filename));
15396
+ const source = decoder6.decode(fs.readFile(filename));
14803
15397
  if (!isEsmFilename(filename, source)) {
14804
15398
  const exports = cjs.loadFile(filename);
14805
15399
  const ns = cjsToNamespace(exports);
@@ -14810,14 +15404,14 @@ ${parts.join("\n")}`
14810
15404
  }
14811
15405
  async function loadFileAsync(filename) {
14812
15406
  if (filename.endsWith(".json")) {
14813
- const data2 = JSON.parse(decoder5.decode(fs.readFile(filename)));
15407
+ const data2 = JSON.parse(decoder6.decode(fs.readFile(filename)));
14814
15408
  return cjsToNamespace(data2);
14815
15409
  }
14816
15410
  const cached3 = cache2.get(filename);
14817
15411
  if (cached3?.namespace) return cached3.namespace;
14818
15412
  if (cached3?.evaluating && evaluatingStack.has(filename)) return cached3.exportsObj;
14819
15413
  if (cached3?.promise) return cached3.promise;
14820
- const source = decoder5.decode(fs.readFile(filename));
15414
+ const source = decoder6.decode(fs.readFile(filename));
14821
15415
  if (!isEsmFilename(filename, source)) {
14822
15416
  const exports = cjs.loadFile(filename);
14823
15417
  const ns = cjsToNamespace(exports);
@@ -14850,7 +15444,7 @@ ${parts.join("\n")}`
14850
15444
  return ns;
14851
15445
  }
14852
15446
  function runMain(filename, source) {
14853
- const src = source ?? decoder5.decode(fs.readFile(filename));
15447
+ const src = source ?? decoder6.decode(fs.readFile(filename));
14854
15448
  if (!isEsmFilename(filename, src)) {
14855
15449
  return cjs.runMain(filename, src);
14856
15450
  }
@@ -14875,7 +15469,7 @@ ${parts.join("\n")}`
14875
15469
  const cached3 = cache2.get(filename);
14876
15470
  if (cached3?.namespace) return cached3.namespace;
14877
15471
  if (cached3?.evaluating) return cached3.exportsObj;
14878
- const source = decoder5.decode(fs.readFile(filename));
15472
+ const source = decoder6.decode(fs.readFile(filename));
14879
15473
  const { hasTopLevelAwait } = transformEsm(source, filename);
14880
15474
  if (hasTopLevelAwait) {
14881
15475
  const err = new Error(
@@ -15731,6 +16325,42 @@ var Process = class extends EventEmitter {
15731
16325
  cwd() {
15732
16326
  return this._cwd;
15733
16327
  }
16328
+ /** Root (0) until credential plumbing is exposed on process. */
16329
+ getuid() {
16330
+ return 0;
16331
+ }
16332
+ geteuid() {
16333
+ return 0;
16334
+ }
16335
+ getgid() {
16336
+ return 0;
16337
+ }
16338
+ getegid() {
16339
+ return 0;
16340
+ }
16341
+ getgroups() {
16342
+ return [0];
16343
+ }
16344
+ /**
16345
+ * Minimal process.kill: only this process (pid === this.pid). Used by pnpm
16346
+ * cmd shims to re-raise a child's terminating signal. Unknown pids → ESRCH.
16347
+ */
16348
+ kill(pid, signal = "SIGTERM") {
16349
+ const target = Number(pid);
16350
+ if (target !== this.pid) {
16351
+ const err = new Error(`kill ESRCH`);
16352
+ err.code = "ESRCH";
16353
+ err.errno = -3;
16354
+ err.syscall = "kill";
16355
+ throw err;
16356
+ }
16357
+ const name = typeof signal === "string" ? signal.startsWith("SIG") ? signal : `SIG${signal}` : "SIGTERM";
16358
+ if (name === "SIGTERM" || name === "SIGINT" || name === "SIGHUP" || name === "SIGKILL") {
16359
+ const codes = { SIGTERM: 143, SIGINT: 130, SIGHUP: 129, SIGKILL: 137 };
16360
+ this.exit(codes[name] ?? 1);
16361
+ }
16362
+ return true;
16363
+ }
15734
16364
  chdir(path) {
15735
16365
  if (typeof path !== "string") {
15736
16366
  const err = new TypeError(
@@ -16199,7 +16829,7 @@ function createWebSocket(ctx, { handles, trackPromise: trackPromise2 } = {}) {
16199
16829
  }
16200
16830
 
16201
16831
  // src/runtime/run.mjs
16202
- var decoder6 = new TextDecoder();
16832
+ var decoder7 = new TextDecoder();
16203
16833
  function installJshGlobals(bindings) {
16204
16834
  const saved = /* @__PURE__ */ new Map();
16205
16835
  for (const name of Object.keys(bindings)) {
@@ -16238,6 +16868,8 @@ async function runNode(ctx, options = {}) {
16238
16868
  let lastEvalCode;
16239
16869
  let restoreGlobals = () => {
16240
16870
  };
16871
+ let removeJshHandoff = () => {
16872
+ };
16241
16873
  const removeCtxHooks = [];
16242
16874
  const util2 = createUtil();
16243
16875
  const printUncaught = (err) => {
@@ -16457,17 +17089,19 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
16457
17089
  cjs.setRequireEsmHook((filename) => esm.requireEsm(filename));
16458
17090
  cjs.setImportModuleHook((specifier, parent) => esm.importModule(specifier, parent));
16459
17091
  try {
17092
+ const rt = {
17093
+ process: process2,
17094
+ console: console2,
17095
+ Buffer: Buffer2,
17096
+ fetch,
17097
+ createRequire: cjs.createRequire,
17098
+ importModule: (specifier, parent) => esm.importModule(specifier, parent),
17099
+ rewriteDynamicImports
17100
+ };
17101
+ removeJshHandoff = installJshHandoff(ctx, rt);
16460
17102
  if (typeof options.main === "function") {
16461
17103
  try {
16462
- const result = options.main({
16463
- process: process2,
16464
- console: console2,
16465
- Buffer: Buffer2,
16466
- fetch,
16467
- createRequire: cjs.createRequire,
16468
- importModule: (specifier, parent) => esm.importModule(specifier, parent),
16469
- rewriteDynamicImports
16470
- });
17104
+ const result = options.main(rt);
16471
17105
  if (result != null && typeof result.then === "function") {
16472
17106
  trackPromise(handles, result).catch(() => {
16473
17107
  });
@@ -16515,7 +17149,7 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
16515
17149
  merged.set(c, off);
16516
17150
  off += c.byteLength;
16517
17151
  }
16518
- const source = decoder6.decode(merged);
17152
+ const source = decoder7.decode(merged);
16519
17153
  lastEvalCode = source;
16520
17154
  process2._evalCode = source;
16521
17155
  process2.argv[1] = "[stdin]";
@@ -16598,7 +17232,7 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
16598
17232
  const filePath = ctx.resolve(parsed.script);
16599
17233
  let source;
16600
17234
  try {
16601
- source = decoder6.decode(ctx.sync.fs.readFile(filePath));
17235
+ source = decoder7.decode(ctx.sync.fs.readFile(filePath));
16602
17236
  } catch (err) {
16603
17237
  const msg = err?.message ?? String(err);
16604
17238
  await ctx.write(2, `${ctx.argv[0]}: cannot open ${parsed.script}: ${msg}
@@ -16687,95 +17321,13 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
16687
17321
  }
16688
17322
  try {
16689
17323
  restoreGlobals();
17324
+ removeJshHandoff();
16690
17325
  } catch {
16691
17326
  }
16692
17327
  }
16693
17328
  }
16694
17329
 
16695
17330
  // src/jsh.mjs
16696
- var decoder7 = new TextDecoder();
16697
- var encoder3 = new TextEncoder();
16698
- var AsyncFunction = Object.getPrototypeOf(async () => {
16699
- }).constructor;
16700
- async function readAll(stream) {
16701
- if (!stream) return new Uint8Array(0);
16702
- const chunks = [];
16703
- let size = 0;
16704
- const reader = stream.getReader();
16705
- for (; ; ) {
16706
- const { done, value } = await reader.read();
16707
- if (done) break;
16708
- const bytes = typeof value === "string" ? encoder3.encode(value) : value;
16709
- chunks.push(bytes);
16710
- size += bytes.length;
16711
- }
16712
- const out = new Uint8Array(size);
16713
- let off = 0;
16714
- for (const c of chunks) {
16715
- out.set(c, off);
16716
- off += c.length;
16717
- }
16718
- return out;
16719
- }
16720
- async function writeAll(stream, data2) {
16721
- const writer = stream.getWriter();
16722
- try {
16723
- await writer.write(typeof data2 === "string" ? encoder3.encode(data2) : data2);
16724
- await writer.close();
16725
- } catch {
16726
- }
16727
- }
16728
- function kernelSpawn(ctx, process2) {
16729
- return (argv, { stdin } = {}) => {
16730
- let child = null;
16731
- const done = (async () => {
16732
- try {
16733
- child = await ctx.spawn({
16734
- argv,
16735
- cwd: process2.cwd(),
16736
- env: { ...process2.env },
16737
- stdin: stdin === void 0 ? "null" : "pipe",
16738
- stdout: "pipe",
16739
- stderr: "pipe"
16740
- });
16741
- } catch (err2) {
16742
- if (err2?.code === "ENOENT") {
16743
- return { stdout: "", stderr: `${argv[0]}: command not found
16744
- `, exitCode: 127 };
16745
- }
16746
- return { stdout: "", stderr: `${argv[0]}: ${err2?.message ?? err2}
16747
- `, exitCode: 126 };
16748
- }
16749
- const [out, err, status] = await Promise.all([
16750
- readAll(child.stdout),
16751
- readAll(child.stderr),
16752
- child.wait(),
16753
- stdin === void 0 ? void 0 : writeAll(child.stdin, stdin)
16754
- ]);
16755
- return { stdout: decoder7.decode(out), stderr: decoder7.decode(err), exitCode: status.status };
16756
- })();
16757
- return {
16758
- kill: async (sig = "SIGTERM") => child ? child.kill(sig) : false,
16759
- done
16760
- };
16761
- };
16762
- }
16763
- function compiler(rt) {
16764
- return (body, filename) => {
16765
- const head = "(async function () {";
16766
- const { code, changed, binding = "__import" } = rt.rewriteDynamicImports(
16767
- `${head}${body}
16768
- })`
16769
- );
16770
- const text = changed ? code.slice(head.length, -3) : body;
16771
- const params = changed ? [...JSH_PARAMS, binding] : [...JSH_PARAMS];
16772
- const fn = new AsyncFunction(...params, `${text}
16773
- //# sourceURL=${filename}`);
16774
- if (!changed) return fn;
16775
- const importFrom = (specifier) => rt.importModule(specifier, filename);
16776
- return (...args) => fn(...args.slice(0, JSH_PARAMS.length), importFrom);
16777
- };
16778
- }
16779
17331
  async function main(ctx) {
16780
17332
  const parsed = parseJshArgv([...ctx.argv].slice(1));
16781
17333
  if (parsed.action === "version") {
@@ -16801,32 +17353,7 @@ ${JSH_USAGE}`);
16801
17353
  const nodeCtx = Object.create(ctx, {
16802
17354
  argv: { value: [argv0, filename, ...parsed.args], enumerable: true }
16803
17355
  });
16804
- return runNode(nodeCtx, {
16805
- main: async (rt) => {
16806
- const { process: process2, console: console2 } = rt;
16807
- let stdoutIsTTY = false;
16808
- try {
16809
- stdoutIsTTY = !!await ctx.isatty?.(1);
16810
- } catch {
16811
- stdoutIsTTY = false;
16812
- }
16813
- const engine = {
16814
- readSource: (path) => decoder7.decode(ctx.sync.fs.readFile(path)),
16815
- compile: compiler(rt),
16816
- createRequire: (path) => rt.createRequire(path),
16817
- selfRequire: rt.createRequire("/node_modules/@ai-ecoverse/slicc-jsh/package.json"),
16818
- writeStdout: (s) => process2.stdout.write(String(s)),
16819
- writeStderr: (s) => process2.stderr.write(String(s)),
16820
- stdoutIsTTY,
16821
- spawn: kernelSpawn(ctx, process2),
16822
- shell: ["sh", "-c"],
16823
- fetch: rt.fetch,
16824
- isExit: (err) => err instanceof NodeExitError,
16825
- exit: (code) => process2.exit(code)
16826
- };
16827
- await runJsh({ filename, engine, process: process2, console: console2 });
16828
- }
16829
- });
17356
+ return runNode(nodeCtx, { main: (rt) => runKernelJsh(ctx, rt, filename) });
16830
17357
  }
16831
17358
  export {
16832
17359
  main as default