@ai-ecoverse/slicc-kernel 1.82.0 → 1.83.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/node.js CHANGED
@@ -28,7 +28,7 @@ function serveCdpPort(port, hook, request, onDone) {
28
28
  }
29
29
  });
30
30
  port.start?.();
31
- new Promise((resolve) => resolve(hook(request))).then(
31
+ new Promise((resolve2) => resolve2(hook(request))).then(
32
32
  (opened2) => {
33
33
  conn = opened2;
34
34
  if (done4) return opened2.close();
@@ -51,7 +51,7 @@ function serveCdpPort(port, hook, request, onDone) {
51
51
  };
52
52
  }
53
53
  function portCdpHook(ask, gone) {
54
- return (request) => new Promise((resolve, reject) => {
54
+ return (request) => new Promise((resolve2, reject) => {
55
55
  const { port1, port2 } = new MessageChannel();
56
56
  let closed = false;
57
57
  const conn = {
@@ -69,7 +69,7 @@ function portCdpHook(ask, gone) {
69
69
  };
70
70
  port1.addEventListener("message", ({ data }) => {
71
71
  if ("m" in data) conn.onmessage?.(data.m);
72
- else if ("open" in data) resolve(conn);
72
+ else if ("open" in data) resolve2(conn);
73
73
  else if ("error" in data) {
74
74
  closed = true;
75
75
  port1.close();
@@ -671,9 +671,9 @@ var KernelPipe = class {
671
671
  let filled = 0;
672
672
  for (const chunk2 of this.chunks) {
673
673
  if (filled === out.length) break;
674
- const count = Math.min(chunk2.length, out.length - filled);
675
- out.set(chunk2.subarray(0, count), filled);
676
- filled += count;
674
+ const count2 = Math.min(chunk2.length, out.length - filled);
675
+ out.set(chunk2.subarray(0, count2), filled);
676
+ filled += count2;
677
677
  }
678
678
  return out;
679
679
  }
@@ -704,25 +704,25 @@ var KernelPipe = class {
704
704
  let filled = 0;
705
705
  while (filled < n) {
706
706
  const head = this.chunks[0];
707
- const count = Math.min(head.length, n - filled);
708
- out.set(head.subarray(0, count), filled);
709
- filled += count;
710
- if (count === head.length) this.chunks.shift();
711
- else this.chunks[0] = head.subarray(count);
707
+ const count2 = Math.min(head.length, n - filled);
708
+ out.set(head.subarray(0, count2), filled);
709
+ filled += count2;
710
+ if (count2 === head.length) this.chunks.shift();
711
+ else this.chunks[0] = head.subarray(count2);
712
712
  }
713
713
  this.size -= n;
714
714
  return out;
715
715
  }
716
716
  changed(signal) {
717
717
  if (signal?.aborted) return Promise.reject(new PipeError("EINTR"));
718
- return new Promise((resolve, reject) => {
718
+ return new Promise((resolve2, reject) => {
719
719
  const onAbort = () => {
720
720
  this.waiters = this.waiters.filter((w) => w !== waiter);
721
721
  reject(new PipeError("EINTR"));
722
722
  };
723
723
  const waiter = () => {
724
724
  signal?.removeEventListener("abort", onAbort);
725
- resolve();
725
+ resolve2();
726
726
  };
727
727
  this.waiters.push(waiter);
728
728
  signal?.addEventListener("abort", onAbort, { once: true });
@@ -731,7 +731,7 @@ var KernelPipe = class {
731
731
  wake() {
732
732
  const waiters = this.waiters;
733
733
  this.waiters = [];
734
- for (const resolve of waiters) resolve();
734
+ for (const resolve2 of waiters) resolve2();
735
735
  }
736
736
  };
737
737
 
@@ -1192,14 +1192,14 @@ var Changes = class {
1192
1192
  waiters = [];
1193
1193
  wait(signal) {
1194
1194
  if (signal?.aborted) return Promise.reject(new KernelError("EINTR"));
1195
- return new Promise((resolve, reject) => {
1195
+ return new Promise((resolve2, reject) => {
1196
1196
  const onAbort = () => {
1197
1197
  this.waiters = this.waiters.filter((w) => w !== waiter);
1198
1198
  reject(new KernelError("EINTR"));
1199
1199
  };
1200
1200
  const waiter = () => {
1201
1201
  signal?.removeEventListener("abort", onAbort);
1202
- resolve();
1202
+ resolve2();
1203
1203
  };
1204
1204
  this.waiters.push(waiter);
1205
1205
  signal?.addEventListener("abort", onAbort, { once: true });
@@ -1208,7 +1208,7 @@ var Changes = class {
1208
1208
  wake() {
1209
1209
  const waiters = this.waiters;
1210
1210
  this.waiters = [];
1211
- for (const resolve of waiters) resolve();
1211
+ for (const resolve2 of waiters) resolve2();
1212
1212
  }
1213
1213
  };
1214
1214
  function link(a, b) {
@@ -1376,7 +1376,7 @@ var KernelSocket = class _KernelSocket {
1376
1376
  });
1377
1377
  const { host, port } = addr;
1378
1378
  const dialled = new Promise(
1379
- (resolve) => resolve(route.uplink.dial({ network: "tcp", host, port, signal: abort.signal }))
1379
+ (resolve2) => resolve2(route.uplink.dial({ network: "tcp", host, port, signal: abort.signal }))
1380
1380
  );
1381
1381
  dialled.then(
1382
1382
  (conn) => abort.signal.aborted && conn.close(),
@@ -1747,8 +1747,8 @@ var MessageQueue = class {
1747
1747
  this.overflow = overflow;
1748
1748
  this.limit = limit;
1749
1749
  this.taken = taken;
1750
- this.closed = new Promise((resolve) => {
1751
- this.settle = resolve;
1750
+ this.closed = new Promise((resolve2) => {
1751
+ this.settle = resolve2;
1752
1752
  });
1753
1753
  }
1754
1754
  push(message3) {
@@ -1787,8 +1787,8 @@ var MessageQueue = class {
1787
1787
  continue;
1788
1788
  }
1789
1789
  if (this.ended) return;
1790
- await new Promise((resolve) => {
1791
- this.waiter = resolve;
1790
+ await new Promise((resolve2) => {
1791
+ this.waiter = resolve2;
1792
1792
  });
1793
1793
  }
1794
1794
  }
@@ -1837,7 +1837,7 @@ function openWebSocket(Socket, request, withHeaders) {
1837
1837
  }
1838
1838
  socket.binaryType = "arraybuffer";
1839
1839
  const queue = new MessageQueue(() => socket.close(1e3, "too many waiting messages"));
1840
- return new Promise((resolve, reject) => {
1840
+ return new Promise((resolve2, reject) => {
1841
1841
  let open = false;
1842
1842
  let settled = false;
1843
1843
  const fail3 = (error) => {
@@ -1856,7 +1856,7 @@ function openWebSocket(Socket, request, withHeaders) {
1856
1856
  open = true;
1857
1857
  settled = true;
1858
1858
  signal.removeEventListener("abort", abort);
1859
- resolve({
1859
+ resolve2({
1860
1860
  protocol: socket.protocol,
1861
1861
  get buffered() {
1862
1862
  return socket.bufferedAmount;
@@ -2047,8 +2047,8 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2047
2047
  const relay = async (nid, socket) => {
2048
2048
  let ending;
2049
2049
  let late;
2050
- const unanswered = new Promise((resolve) => {
2051
- late = () => resolve("late");
2050
+ const unanswered = new Promise((resolve2) => {
2051
+ late = () => resolve2("late");
2052
2052
  });
2053
2053
  const flow = {
2054
2054
  inflight: 0,
@@ -2076,8 +2076,8 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2076
2076
  }
2077
2077
  flow.inflight += payloadSize(data);
2078
2078
  while (flow.inflight > INBOUND_LIMIT && !flow.closing) {
2079
- await new Promise((resolve) => {
2080
- flow.wake = resolve;
2079
+ await new Promise((resolve2) => {
2080
+ flow.wake = resolve2;
2081
2081
  });
2082
2082
  }
2083
2083
  }
@@ -2096,7 +2096,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2096
2096
  if (!socket) return;
2097
2097
  socket.send(call.data);
2098
2098
  while (socket.buffered > SEND_BUFFER && sockets.has(call.nid)) {
2099
- await new Promise((resolve) => setTimeout(resolve, 10));
2099
+ await new Promise((resolve2) => setTimeout(resolve2, 10));
2100
2100
  }
2101
2101
  peer.postMessage({ net: "ws-acked", nid: call.nid, n: payloadSize(call.data) });
2102
2102
  };
@@ -3404,11 +3404,11 @@ var RemoteWatch = class {
3404
3404
  const seq2 = ++this.seq;
3405
3405
  this.channel.postMessage({ tab: this.tab, paths: this.mine, seq: seq2 });
3406
3406
  if (this.peers.size === 0) return Promise.resolve();
3407
- return new Promise((resolve) => {
3407
+ return new Promise((resolve2) => {
3408
3408
  const done4 = () => {
3409
3409
  clearTimeout(timer);
3410
3410
  this.waiting.delete(seq2);
3411
- resolve();
3411
+ resolve2();
3412
3412
  };
3413
3413
  const timer = setTimeout(() => {
3414
3414
  done4();
@@ -3504,7 +3504,7 @@ async function openSync(handle) {
3504
3504
  const delay = SYNC_BACKOFF_MS[attempt];
3505
3505
  if (!LOCKED.has(err?.name)) throw err;
3506
3506
  if (delay === void 0) return void 0;
3507
- await new Promise((resolve) => setTimeout(resolve, delay));
3507
+ await new Promise((resolve2) => setTimeout(resolve2, delay));
3508
3508
  }
3509
3509
  }
3510
3510
  }
@@ -3957,7 +3957,7 @@ var OpfsFs = class {
3957
3957
  const again = name2 === "NotReadableError" || locks && LOCKED.has(name2);
3958
3958
  if (!again || attempt >= READ_ATTEMPTS)
3959
3959
  throw translate(err, path, locks ? "write" : "read");
3960
- await new Promise((resolve) => setTimeout(resolve, attempt * 10));
3960
+ await new Promise((resolve2) => setTimeout(resolve2, attempt * 10));
3961
3961
  }
3962
3962
  }
3963
3963
  }
@@ -4014,8 +4014,8 @@ var OpfsFs = class {
4014
4014
  }
4015
4015
  async truncate(path, size) {
4016
4016
  const handle = await this.existing(path, true);
4017
- const resolve = this.ranged || this.remote?.watched();
4018
- const target = resolve ? (await this.locate(path, true)).path : path;
4017
+ const resolve2 = this.ranged || this.remote?.watched();
4018
+ const target = resolve2 ? (await this.locate(path, true)).path : path;
4019
4019
  await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
4020
4020
  this.written(target);
4021
4021
  }
@@ -4455,12 +4455,12 @@ var PathGate = class {
4455
4455
  tails = /* @__PURE__ */ new Map();
4456
4456
  async acquire(path) {
4457
4457
  const prev = this.tails.get(path) ?? Promise.resolve();
4458
- const { promise, resolve } = Promise.withResolvers();
4458
+ const { promise, resolve: resolve2 } = Promise.withResolvers();
4459
4459
  const tail = prev.then(() => promise);
4460
4460
  this.tails.set(path, tail);
4461
4461
  await prev;
4462
4462
  return () => {
4463
- resolve();
4463
+ resolve2();
4464
4464
  if (this.tails.get(path) === tail) this.tails.delete(path);
4465
4465
  };
4466
4466
  }
@@ -5224,7 +5224,7 @@ var CdpFacade = class {
5224
5224
  const conn = await this.host(runtime);
5225
5225
  try {
5226
5226
  const reply = await new Promise(
5227
- (resolve, reject) => {
5227
+ (resolve2, reject) => {
5228
5228
  const timer = setTimeout(
5229
5229
  () => reject(new HttpError(504, "the CDP host did not answer Target.getTargets")),
5230
5230
  this.options.listTimeout ?? LIST_TIMEOUT
@@ -5237,7 +5237,7 @@ var CdpFacade = class {
5237
5237
  const parsed2 = JSON.parse(message3);
5238
5238
  if (parsed2.id !== 1) return;
5239
5239
  clearTimeout(timer);
5240
- resolve(parsed2);
5240
+ resolve2(parsed2);
5241
5241
  };
5242
5242
  conn.send(JSON.stringify({ id: 1, method: "Target.getTargets" }));
5243
5243
  }
@@ -5297,9 +5297,9 @@ var Relay = class {
5297
5297
  }
5298
5298
  async start(head) {
5299
5299
  await this.send(head);
5300
- const hostGone = new Promise((resolve) => {
5300
+ const hostGone = new Promise((resolve2) => {
5301
5301
  this.host.onclose = (reason) => {
5302
- void this.end(reason ? CLOSE.error : CLOSE.normal, reason ?? "").then(() => resolve());
5302
+ void this.end(reason ? CLOSE.error : CLOSE.normal, reason ?? "").then(() => resolve2());
5303
5303
  };
5304
5304
  });
5305
5305
  this.host.onmessage = (message3) => {
@@ -5313,8 +5313,8 @@ var Relay = class {
5313
5313
  await Promise.race([pumping, hostGone]);
5314
5314
  await this.writes;
5315
5315
  let timer;
5316
- const waited = new Promise((resolve) => {
5317
- timer = setTimeout(resolve, this.closeWaitMs);
5316
+ const waited = new Promise((resolve2) => {
5317
+ timer = setTimeout(resolve2, this.closeWaitMs);
5318
5318
  });
5319
5319
  await Promise.race([pumping, waited]);
5320
5320
  clearTimeout(timer);
@@ -5964,16 +5964,16 @@ var FreshModules = class {
5964
5964
  if (head) await decide(path, head);
5965
5965
  };
5966
5966
  }
5967
- const bound = /* @__PURE__ */ new WeakMap();
5967
+ const bound2 = /* @__PURE__ */ new WeakMap();
5968
5968
  return new Proxy(fs, {
5969
5969
  get(target, key, receiver) {
5970
5970
  if (Object.hasOwn(overrides, key)) return overrides[key];
5971
5971
  const value = Reflect.get(target, key, receiver);
5972
5972
  if (typeof value !== "function") return value;
5973
- let method = bound.get(value);
5973
+ let method = bound2.get(value);
5974
5974
  if (method === void 0) {
5975
5975
  method = value.bind(target);
5976
- bound.set(value, method);
5976
+ bound2.set(value, method);
5977
5977
  }
5978
5978
  return method;
5979
5979
  }
@@ -6302,7 +6302,7 @@ var ChildTable = class {
6302
6302
  }
6303
6303
  async nextChange(candidates, flags2, interrupt) {
6304
6304
  let wake;
6305
- const stateChange = new Promise((resolve) => wake = resolve);
6305
+ const stateChange = new Promise((resolve2) => wake = resolve2);
6306
6306
  const watching = flags2.untraced || flags2.continued;
6307
6307
  if (watching && wake) this.stateChanged.push(wake);
6308
6308
  try {
@@ -6516,6 +6516,65 @@ var ClipboardBroker = class {
6516
6516
  }
6517
6517
  };
6518
6518
 
6519
+ // src/kernel/exec-ticket.ts
6520
+ var TICKET_ENV = "SLICC_SEALED_TICKET";
6521
+ var TICKET_TTL_MS = 3e4;
6522
+ var MAX_TICKETS = 256;
6523
+ var TICKET = /^[0-9a-f]{32}$/;
6524
+ async function argvDigest(argv) {
6525
+ const bytes = new TextEncoder().encode(JSON.stringify(argv));
6526
+ const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
6527
+ return [...hash].map((b) => b.toString(16).padStart(2, "0")).join("");
6528
+ }
6529
+ function isStrings(value) {
6530
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
6531
+ }
6532
+ function stringRecord(value) {
6533
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
6534
+ const entries = Object.entries(value);
6535
+ return entries.every(([, v]) => typeof v === "string") ? Object.fromEntries(entries) : void 0;
6536
+ }
6537
+ var TicketBook = class {
6538
+ booked = /* @__PURE__ */ new Map();
6539
+ now;
6540
+ normalise = async (path) => path;
6541
+ constructor(now = Date.now) {
6542
+ this.now = now;
6543
+ }
6544
+ get size() {
6545
+ return this.booked.size;
6546
+ }
6547
+ async record(req, reply, pid) {
6548
+ const { ticket, error } = reply;
6549
+ if (error !== void 0 || typeof ticket !== "string" || !TICKET.test(ticket)) return;
6550
+ const { path, argv, cwd } = req;
6551
+ const entry = {
6552
+ pid,
6553
+ path: await this.normalise(path),
6554
+ requested: path,
6555
+ requestedCwd: cwd,
6556
+ argv: await argvDigest(argv),
6557
+ cwd: await this.normalise(cwd),
6558
+ at: this.now()
6559
+ };
6560
+ this.prune();
6561
+ while (this.booked.size >= MAX_TICKETS)
6562
+ this.booked.delete(this.booked.keys().next().value);
6563
+ this.booked.set(ticket, entry);
6564
+ }
6565
+ take(ticket) {
6566
+ const booked = this.booked.get(ticket);
6567
+ this.booked.delete(ticket);
6568
+ return booked && this.now() - booked.at < TICKET_TTL_MS ? booked : void 0;
6569
+ }
6570
+ prune() {
6571
+ const now = this.now();
6572
+ for (const [ticket, booked] of this.booked) {
6573
+ if (now - booked.at >= TICKET_TTL_MS) this.booked.delete(ticket);
6574
+ }
6575
+ }
6576
+ };
6577
+
6519
6578
  // src/mount/protocol.ts
6520
6579
  var DRIVER_PROTOCOL = [1, 2];
6521
6580
  function driverVersionError(theirs) {
@@ -6586,7 +6645,7 @@ var DriverConnection = class _DriverConnection {
6586
6645
  call(call, transfer = []) {
6587
6646
  if (this.failure) return Promise.reject(this.failure);
6588
6647
  const id2 = ++this.nextId;
6589
- return new Promise((resolve, reject) => {
6648
+ return new Promise((resolve2, reject) => {
6590
6649
  const timer = unref(
6591
6650
  setTimeout(() => {
6592
6651
  this.waiting.delete(id2);
@@ -6599,7 +6658,7 @@ var DriverConnection = class _DriverConnection {
6599
6658
  this.onFail?.(error);
6600
6659
  }, this.timeoutMs)
6601
6660
  );
6602
- this.waiting.set(id2, { resolve, reject, timer });
6661
+ this.waiting.set(id2, { resolve: resolve2, reject, timer });
6603
6662
  this.port.postMessage({ ...call, id: id2 }, transfer);
6604
6663
  });
6605
6664
  }
@@ -6742,8 +6801,8 @@ var HeldPaths = class extends Map {
6742
6801
  this.keptHandles.delete(handle);
6743
6802
  if (kept) this.letGo(kept);
6744
6803
  }
6745
- const count = (this.opens.get(key) ?? 0) + (on ? 1 : -1);
6746
- if (count > 0) this.opens.set(key, count);
6804
+ const count2 = (this.opens.get(key) ?? 0) + (on ? 1 : -1);
6805
+ if (count2 > 0) this.opens.set(key, count2);
6747
6806
  else {
6748
6807
  this.opens.delete(key);
6749
6808
  for (const id2 of this.handlesAt(key)) this.handles.delete(id2);
@@ -6757,8 +6816,8 @@ var HeldPaths = class extends Map {
6757
6816
  return this.lastHandle;
6758
6817
  }
6759
6818
  holdWrite(path, on) {
6760
- const count = (this.get(path) ?? 0) + (on ? 1 : -1);
6761
- if (count > 0) this.set(path, count);
6819
+ const count2 = (this.get(path) ?? 0) + (on ? 1 : -1);
6820
+ if (count2 > 0) this.set(path, count2);
6762
6821
  else {
6763
6822
  this.delete(path);
6764
6823
  this.revoked.delete(path);
@@ -6780,18 +6839,18 @@ var HeldPaths = class extends Map {
6780
6839
  for (const path of this.keys()) if (within4(path, prefix)) this.revoked.add(path);
6781
6840
  }
6782
6841
  renamed(from, to) {
6783
- for (const [path, count] of [...this]) {
6842
+ for (const [path, count2] of [...this]) {
6784
6843
  if (!within4(path, from)) continue;
6785
6844
  const moved2 = to + path.slice(from.length);
6786
6845
  this.delete(path);
6787
- this.set(moved2, (this.get(moved2) ?? 0) + count);
6846
+ this.set(moved2, (this.get(moved2) ?? 0) + count2);
6788
6847
  if (this.revoked.delete(path)) this.revoked.add(moved2);
6789
6848
  }
6790
- for (const [path, count] of [...this.opens]) {
6849
+ for (const [path, count2] of [...this.opens]) {
6791
6850
  if (!within4(path, from)) continue;
6792
6851
  const moved2 = to + path.slice(from.length);
6793
6852
  this.opens.delete(path);
6794
- this.opens.set(moved2, (this.opens.get(moved2) ?? 0) + count);
6853
+ this.opens.set(moved2, (this.opens.get(moved2) ?? 0) + count2);
6795
6854
  }
6796
6855
  for (const [id2, key] of this.handles) {
6797
6856
  if (within4(key, from)) this.handles.set(id2, to + key.slice(from.length));
@@ -9112,7 +9171,7 @@ var AsyncOps = class {
9112
9171
  this.wake();
9113
9172
  }
9114
9173
  sleep(timeoutMs, signal) {
9115
- return new Promise((resolve, reject) => {
9174
+ return new Promise((resolve2, reject) => {
9116
9175
  let timer;
9117
9176
  const cleanup = () => {
9118
9177
  clearTimeout(timer);
@@ -9121,7 +9180,7 @@ var AsyncOps = class {
9121
9180
  };
9122
9181
  const wake = () => {
9123
9182
  cleanup();
9124
- resolve(true);
9183
+ resolve2(true);
9125
9184
  };
9126
9185
  const abort = () => {
9127
9186
  cleanup();
@@ -9132,7 +9191,7 @@ var AsyncOps = class {
9132
9191
  if (timeoutMs !== void 0) {
9133
9192
  timer = setTimeout(() => {
9134
9193
  cleanup();
9135
- resolve(false);
9194
+ resolve2(false);
9136
9195
  }, timeoutMs);
9137
9196
  }
9138
9197
  });
@@ -9216,10 +9275,10 @@ var Budget = class {
9216
9275
  async acquire(n, signal) {
9217
9276
  while (this.free < n) {
9218
9277
  signal.throwIfAborted();
9219
- await new Promise((resolve) => {
9278
+ await new Promise((resolve2) => {
9220
9279
  const done4 = () => {
9221
9280
  signal.removeEventListener("abort", done4);
9222
- resolve();
9281
+ resolve2();
9223
9282
  };
9224
9283
  this.waiters.push(done4);
9225
9284
  signal.addEventListener("abort", done4, { once: true });
@@ -9361,14 +9420,14 @@ async function watchHangup(conn, abort, until) {
9361
9420
  }
9362
9421
  }
9363
9422
  function untilAborted(response, signal) {
9364
- return new Promise((resolve, reject) => {
9423
+ return new Promise((resolve2, reject) => {
9365
9424
  const onAbort = () => {
9366
9425
  reject(signal.reason ?? new KernelError("EINTR"));
9367
9426
  response.then((late) => late.cancel()).catch(() => void 0);
9368
9427
  };
9369
9428
  if (signal.aborted) return onAbort();
9370
9429
  signal.addEventListener("abort", onAbort, { once: true });
9371
- response.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
9430
+ response.then(resolve2, reject).finally(() => signal.removeEventListener("abort", onAbort));
9372
9431
  });
9373
9432
  }
9374
9433
  function plainResponse(status, message3) {
@@ -9401,8 +9460,8 @@ function wireCode(code) {
9401
9460
  return sendableCode(code) ? code : 1011;
9402
9461
  }
9403
9462
  function quietly(ms) {
9404
- return new Promise((resolve) => {
9405
- AbortSignal.timeout(ms).addEventListener("abort", () => resolve(), { once: true });
9463
+ return new Promise((resolve2) => {
9464
+ AbortSignal.timeout(ms).addEventListener("abort", () => resolve2(), { once: true });
9406
9465
  });
9407
9466
  }
9408
9467
  var RealmProxy = class {
@@ -9500,7 +9559,7 @@ var RealmProxy = class {
9500
9559
  return false;
9501
9560
  }
9502
9561
  const url = ctx.origin ? tunnelRequestUrl(req, ctx.origin) : requestUrl(req);
9503
- const keep = keepsAlive(req);
9562
+ const keep2 = keepsAlive(req);
9504
9563
  const framing = requestFraming(req.headers);
9505
9564
  const reserve = framing.kind === "length" ? framing.length : framing.kind === "chunked" ? this.cap() : 0;
9506
9565
  if (reserve > this.cap()) throw new HttpError(413, `request body over ${this.cap()} bytes`);
@@ -9523,7 +9582,7 @@ var RealmProxy = class {
9523
9582
  } finally {
9524
9583
  this.bodies.release(reserve);
9525
9584
  }
9526
- return await this.relay(conn, req.method, req.minor, response, keep);
9585
+ return await this.relay(conn, req.method, req.minor, response, keep2);
9527
9586
  } finally {
9528
9587
  this.stop.signal.removeEventListener("abort", stopExchange);
9529
9588
  abort.abort();
@@ -9571,8 +9630,8 @@ var RealmProxy = class {
9571
9630
  bodiless: bodiless2
9572
9631
  });
9573
9632
  const chunked2 = !bodiless2 && minor >= 1;
9574
- const keep = keepAlive && (bodiless2 || chunked2);
9575
- headers.push(["Connection", keep ? "keep-alive" : "close"]);
9633
+ const keep2 = keepAlive && (bodiless2 || chunked2);
9634
+ headers.push(["Connection", keep2 ? "keep-alive" : "close"]);
9576
9635
  if (chunked2) headers.push(["Transfer-Encoding", "chunked"]);
9577
9636
  const signal = this.stop.signal;
9578
9637
  await conn.write(
@@ -9581,7 +9640,7 @@ var RealmProxy = class {
9581
9640
  );
9582
9641
  if (bodiless2) {
9583
9642
  await response.cancel();
9584
- return keep;
9643
+ return keep2;
9585
9644
  }
9586
9645
  try {
9587
9646
  for await (const piece of response.body) {
@@ -9592,7 +9651,7 @@ var RealmProxy = class {
9592
9651
  return false;
9593
9652
  }
9594
9653
  if (chunked2) await conn.write(LAST_CHUNK, signal);
9595
- return keep;
9654
+ return keep2;
9596
9655
  }
9597
9656
  async connect(conn, incoming, req, idle) {
9598
9657
  const target = tunnelTarget(req);
@@ -9815,10 +9874,10 @@ function header(der, at) {
9815
9874
  let len = der[at + 1];
9816
9875
  let start2 = at + 2;
9817
9876
  if (len & 128) {
9818
- const count = len & 127;
9877
+ const count2 = len & 127;
9819
9878
  len = 0;
9820
- for (let i = 0; i < count; i++) len = len * 256 + der[start2 + i];
9821
- start2 += count;
9879
+ for (let i = 0; i < count2; i++) len = len * 256 + der[start2 + i];
9880
+ start2 += count2;
9822
9881
  }
9823
9882
  if (start2 + len > der.length) throw new Error("truncated DER");
9824
9883
  return [tag, start2, start2 + len];
@@ -10875,7 +10934,7 @@ var Resolver = class {
10875
10934
  };
10876
10935
  function waitFor(lookup2, signal) {
10877
10936
  lookup2.waiters++;
10878
- return new Promise((resolve, reject) => {
10937
+ return new Promise((resolve2, reject) => {
10879
10938
  const abort = () => {
10880
10939
  if (--lookup2.waiters === 0) lookup2.abort.abort(new KernelError("EINTR"));
10881
10940
  reject(new KernelError("EINTR"));
@@ -10885,7 +10944,7 @@ function waitFor(lookup2, signal) {
10885
10944
  if (signal?.aborted) return;
10886
10945
  lookup2.waiters--;
10887
10946
  signal?.removeEventListener("abort", abort);
10888
- resolve(value);
10947
+ resolve2(value);
10889
10948
  });
10890
10949
  });
10891
10950
  }
@@ -11066,8 +11125,8 @@ var KernelTty = class {
11066
11125
  }
11067
11126
  rubOut(n) {
11068
11127
  const dropped2 = this.line.splice(this.line.length - n, n);
11069
- const utf82 = (this.termios.c_iflag & IUTF8) !== 0;
11070
- const cells = utf82 ? dropped2.filter((b) => !isContinuation(b)).length : dropped2.length;
11128
+ const utf83 = (this.termios.c_iflag & IUTF8) !== 0;
11129
+ const cells = utf83 ? dropped2.filter((b) => !isContinuation(b)).length : dropped2.length;
11071
11130
  if (cells > 0 && this.termios.c_lflag & ECHO) {
11072
11131
  this.output(encoder3.encode("\b \b".repeat(cells)), false);
11073
11132
  }
@@ -11137,14 +11196,14 @@ var KernelTty = class {
11137
11196
  }
11138
11197
  changed(signal) {
11139
11198
  if (signal?.aborted) return Promise.reject(new KernelError("EINTR"));
11140
- return new Promise((resolve, reject) => {
11199
+ return new Promise((resolve2, reject) => {
11141
11200
  const onAbort = () => {
11142
11201
  this.waiters = this.waiters.filter((w) => w !== waiter);
11143
11202
  reject(new KernelError("EINTR"));
11144
11203
  };
11145
11204
  const waiter = () => {
11146
11205
  signal?.removeEventListener("abort", onAbort);
11147
- resolve();
11206
+ resolve2();
11148
11207
  };
11149
11208
  this.waiters.push(waiter);
11150
11209
  signal?.addEventListener("abort", onAbort, { once: true });
@@ -11153,7 +11212,7 @@ var KernelTty = class {
11153
11212
  wake() {
11154
11213
  const waiters = this.waiters;
11155
11214
  this.waiters = [];
11156
- for (const resolve of waiters) resolve();
11215
+ for (const resolve2 of waiters) resolve2();
11157
11216
  }
11158
11217
  };
11159
11218
 
@@ -11252,14 +11311,14 @@ var PtyPair = class {
11252
11311
  }
11253
11312
  changed(signal) {
11254
11313
  if (signal?.aborted) return Promise.reject(new KernelError("EINTR"));
11255
- return new Promise((resolve, reject) => {
11314
+ return new Promise((resolve2, reject) => {
11256
11315
  const onAbort = () => {
11257
11316
  this.waiters = this.waiters.filter((w) => w !== waiter);
11258
11317
  reject(new KernelError("EINTR"));
11259
11318
  };
11260
11319
  const waiter = () => {
11261
11320
  signal?.removeEventListener("abort", onAbort);
11262
- resolve();
11321
+ resolve2();
11263
11322
  };
11264
11323
  this.waiters.push(waiter);
11265
11324
  signal?.addEventListener("abort", onAbort, { once: true });
@@ -11268,7 +11327,7 @@ var PtyPair = class {
11268
11327
  wake() {
11269
11328
  const waiters = this.waiters;
11270
11329
  this.waiters = [];
11271
- for (const resolve of waiters) resolve();
11330
+ for (const resolve2 of waiters) resolve2();
11272
11331
  }
11273
11332
  };
11274
11333
  var PtyTable = class {
@@ -11333,7 +11392,8 @@ function ptySyscall(req, ctx) {
11333
11392
  if (!ctx.ptys) throw new KernelError("ENOENT");
11334
11393
  const pair = ctx.ptys.get(req.n);
11335
11394
  ttyOpenable(ctx.guard, pair.slave);
11336
- const fd = ctx.fds.install(pair.openSlave(), 3);
11395
+ const slave = pair.openSlave();
11396
+ const fd = ctx.fds.install(ctx.ttyFilter?.(slave) ?? slave, 3);
11337
11397
  if (!req.noctty) ctx.jobs?.acquireTerminal(ctx.pid, pair.slave);
11338
11398
  return json4(fd);
11339
11399
  }
@@ -11406,8 +11466,8 @@ async function runChild(req, deps) {
11406
11466
  };
11407
11467
  const controls = [];
11408
11468
  const capture = () => {
11409
- const { promise, resolve } = Promise.withResolvers();
11410
- const control = { shut: false, ended: resolve, eof: promise };
11469
+ const { promise, resolve: resolve2 } = Promise.withResolvers();
11470
+ const control = { shut: false, ended: resolve2, eof: promise };
11411
11471
  controls.push(control);
11412
11472
  return { capture: true, max, overflow: () => stop("ENOBUFS"), control };
11413
11473
  };
@@ -11500,7 +11560,7 @@ async function waitReady(fds, read, write, deadline, interrupted2) {
11500
11560
  return file.changed === void 0 ? [] : [file.changed(round.signal).catch(() => void 0)];
11501
11561
  });
11502
11562
  let timer;
11503
- const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [new Promise((resolve) => timer = setTimeout(resolve, deadline - Date.now()))];
11563
+ const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [new Promise((resolve2) => timer = setTimeout(resolve2, deadline - Date.now()))];
11504
11564
  try {
11505
11565
  await Promise.race([...changes, ...expiry, interrupted2]);
11506
11566
  } finally {
@@ -11584,10 +11644,10 @@ async function socketSyscall(req, proc) {
11584
11644
  }
11585
11645
  }
11586
11646
  function interruptible2(dialing, signal) {
11587
- return new Promise((resolve, reject) => {
11647
+ return new Promise((resolve2, reject) => {
11588
11648
  const abort = () => reject(new KernelError("EINTR"));
11589
11649
  signal.addEventListener("abort", abort, { once: true });
11590
- dialing.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
11650
+ dialing.then(resolve2, reject).finally(() => signal.removeEventListener("abort", abort));
11591
11651
  });
11592
11652
  }
11593
11653
  function unnamed(domain) {
@@ -12434,7 +12494,7 @@ var WasmProcess = class {
12434
12494
  if (this.stopped) return "stop";
12435
12495
  this.stopped = sig;
12436
12496
  this.stops++;
12437
- this.resumed = new Promise((resolve) => this.wake = resolve);
12497
+ this.resumed = new Promise((resolve2) => this.wake = resolve2);
12438
12498
  const blocked = this.interrupt;
12439
12499
  this.interrupt = new AbortController();
12440
12500
  blocked.abort();
@@ -12499,7 +12559,9 @@ var WasmProcess = class {
12499
12559
  const { ptys, jobs } = this.options;
12500
12560
  const owner = this.options.owners ? this.ttyOwner() : void 0;
12501
12561
  const guard2 = this.guarded();
12502
- return ptySyscall(req, { pid: this.pid, fds: this.fds, ptys, jobs, guard: guard2, owner });
12562
+ const { ttyFilter } = this.options;
12563
+ const ctx = { pid: this.pid, fds: this.fds, ptys, jobs, guard: guard2, owner, ttyFilter };
12564
+ return ptySyscall(req, ctx);
12503
12565
  }
12504
12566
  return await this.procSyscall(req, cancelled);
12505
12567
  } catch (e) {
@@ -12674,7 +12736,8 @@ var WasmProcess = class {
12674
12736
  const tty = name2 === void 0 ? this.controllingTerminal() : this.options.jobs?.terminalNamed(name2);
12675
12737
  if (!tty) throw new KernelError("ENXIO");
12676
12738
  if (name2 !== void 0) ttyOpenable(this.guarded(), tty);
12677
- return this.fds.install(tty.file(), 3);
12739
+ const file = tty.file();
12740
+ return this.fds.install(this.options.ttyFilter?.(file) ?? file, 3);
12678
12741
  }
12679
12742
  openSealed() {
12680
12743
  const broker = this.options.sealed;
@@ -12714,15 +12777,8 @@ var WasmProcess = class {
12714
12777
  async sealedCaller() {
12715
12778
  const shown = await this.options.identity?.();
12716
12779
  const broker = this.options.sealed;
12717
- const tag = broker.tagOf(this.pid);
12718
- return {
12719
- pid: shown?.pid ?? this.pid,
12720
- ppid: shown?.ppid ?? 0,
12721
- uid: this.cred.euid,
12722
- gid: this.cred.egid,
12723
- ...tag !== void 0 ? { tag } : {},
12724
- users: broker.users
12725
- };
12780
+ const ids = { pid: shown?.pid ?? this.pid, ppid: shown?.ppid ?? 0 };
12781
+ return broker.stamp(ids, this.cred, broker.tagOf(this.pid));
12726
12782
  }
12727
12783
  guarded() {
12728
12784
  const { guard: guard2 } = this.options;
@@ -13230,13 +13286,13 @@ var WasmProcess = class {
13230
13286
  while (this.dlLock.depth > 0 && this.dlLock.owner !== owner) {
13231
13287
  if (this.dying) throw new KernelError("EINTR");
13232
13288
  const interrupt = this.interrupt.signal;
13233
- const gone = await new Promise((resolve) => {
13289
+ const gone = await new Promise((resolve2) => {
13234
13290
  const waiter = {
13235
13291
  owner,
13236
13292
  wake: (ended) => {
13237
13293
  this.dlLock.waiters.delete(waiter);
13238
13294
  interrupt.removeEventListener("abort", recheck);
13239
- resolve(ended);
13295
+ resolve2(ended);
13240
13296
  }
13241
13297
  };
13242
13298
  const recheck = () => waiter.wake(false);
@@ -13492,6 +13548,7 @@ function processOptions(opts, header4, hooks, created3) {
13492
13548
  ...inherited(opts),
13493
13549
  ...opts.owners ? { owners: true } : {},
13494
13550
  ...opts.sealed ? { sealed: opts.sealed } : {},
13551
+ ...opts.ttyFilter ? { ttyFilter: opts.ttyFilter } : {},
13495
13552
  ...opts.clipboard ? { clipboard: opts.clipboard, ...clipboardName(opts) } : {},
13496
13553
  ...opts.readonlyAt ? { readonlyAt: opts.readonlyAt } : {},
13497
13554
  ...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
@@ -13986,6 +14043,523 @@ function replayingHops(inner, heldMs = HELD_MS) {
13986
14043
  };
13987
14044
  }
13988
14045
 
14046
+ // node_modules/@ai-ecoverse/slicc-scrub/dist/index.js
14047
+ var FRAGMENT = 16;
14048
+ var MIN_VALUE = 8;
14049
+ var MIN_BASE64 = 8;
14050
+ var encoder4 = new TextEncoder();
14051
+ var STD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
14052
+ function utf82(text) {
14053
+ return encoder4.encode(text);
14054
+ }
14055
+ function base642(bytes, padded = true) {
14056
+ let out = "";
14057
+ for (let i = 0; i < bytes.length; i += 3) {
14058
+ const a = bytes[i];
14059
+ const b = i + 1 < bytes.length ? bytes[i + 1] : 0;
14060
+ const c = i + 2 < bytes.length ? bytes[i + 2] : 0;
14061
+ const triple = a << 16 | b << 8 | c;
14062
+ const left = bytes.length - i;
14063
+ out += STD[triple >> 18 & 63] + STD[triple >> 12 & 63];
14064
+ out += left > 1 ? STD[triple >> 6 & 63] : padded ? "=" : "";
14065
+ out += left > 2 ? STD[triple & 63] : padded ? "=" : "";
14066
+ }
14067
+ return out;
14068
+ }
14069
+ function urlSafe(text) {
14070
+ return text.replace(/\+/g, "-").replace(/\//g, "_");
14071
+ }
14072
+ function hex2(bytes) {
14073
+ let out = "";
14074
+ for (const byte of bytes) out += byte.toString(16).padStart(2, "0");
14075
+ return out;
14076
+ }
14077
+ function embedded(bytes, offset) {
14078
+ const shifted = new Uint8Array(offset + bytes.length);
14079
+ shifted.set(bytes, offset);
14080
+ const encoded = base642(shifted);
14081
+ const first = Math.ceil(8 * offset / 6);
14082
+ const last = Math.floor(8 * (offset + bytes.length) / 6);
14083
+ return encoded.slice(first, last);
14084
+ }
14085
+ function unicode(value, upper) {
14086
+ let out = "";
14087
+ for (let i = 0; i < value.length; i++) {
14088
+ const unit = value.charCodeAt(i);
14089
+ if (unit === 34) out += '\\"';
14090
+ else if (unit === 92) out += "\\\\";
14091
+ else if (unit < 32 || unit > 126) {
14092
+ const code = unit.toString(16).padStart(4, "0");
14093
+ out += `\\u${upper ? code.toUpperCase() : code}`;
14094
+ } else out += value[i];
14095
+ }
14096
+ return out;
14097
+ }
14098
+ function percent(value) {
14099
+ let component;
14100
+ try {
14101
+ component = encodeURIComponent(value);
14102
+ } catch {
14103
+ return [];
14104
+ }
14105
+ const lower = component.replace(/%[0-9A-F]{2}/g, (escape) => escape.toLowerCase());
14106
+ const plus = component.replace(/%20/g, "+");
14107
+ let form = "";
14108
+ for (const byte of utf82(value)) {
14109
+ const char = String.fromCharCode(byte);
14110
+ if (/[A-Za-z0-9*\-._]/.test(char)) form += char;
14111
+ else if (byte === 32) form += "+";
14112
+ else form += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
14113
+ }
14114
+ return [component, lower, plus, form];
14115
+ }
14116
+ function html(value, apostrophe) {
14117
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, apostrophe);
14118
+ }
14119
+ function encodings(bytes) {
14120
+ const standard = [base642(bytes), base642(bytes, false)];
14121
+ for (const offset of [0, 1, 2]) {
14122
+ const run2 = embedded(bytes, offset);
14123
+ if (run2.length >= MIN_BASE64) standard.push(run2);
14124
+ }
14125
+ return [...standard, ...standard.map(urlSafe)];
14126
+ }
14127
+ function shapes(value) {
14128
+ const raw = utf82(value);
14129
+ const seen = /* @__PURE__ */ new Set([value]);
14130
+ const out = [];
14131
+ if (raw.length < FRAGMENT) out.push({ bytes: raw, form: "raw" });
14132
+ for (let offset = 0; raw.length >= FRAGMENT && offset + FRAGMENT <= raw.length; offset++) {
14133
+ out.push({ bytes: raw.subarray(offset, offset + FRAGMENT), form: "fragment", offset });
14134
+ }
14135
+ const add = (text, form) => {
14136
+ if (seen.has(text)) return;
14137
+ seen.add(text);
14138
+ out.push({ bytes: utf82(text), form });
14139
+ };
14140
+ const json5 = JSON.stringify(value).slice(1, -1);
14141
+ for (const text of [
14142
+ json5,
14143
+ json5.replace(/\//g, "\\/"),
14144
+ unicode(value, false),
14145
+ unicode(value, true)
14146
+ ]) {
14147
+ add(text, "json");
14148
+ }
14149
+ for (const text of percent(value)) add(text, "percent");
14150
+ for (const text of [html(value, "&#39;"), html(value, "&#x27;")]) add(text, "html");
14151
+ for (const text of encodings(raw)) add(text, "base64");
14152
+ add(hex2(raw), "hex");
14153
+ add(hex2(raw).toUpperCase(), "hex");
14154
+ return out;
14155
+ }
14156
+ function wrappable(form) {
14157
+ return form === "base64" || form === "hex";
14158
+ }
14159
+ var Automaton = class {
14160
+ edges = /* @__PURE__ */ new Map();
14161
+ fail = [0];
14162
+ depth = [0];
14163
+ children = [0];
14164
+ out = [[]];
14165
+ dict = [-1];
14166
+ lengths = [];
14167
+ add(bytes) {
14168
+ let node = 0;
14169
+ for (const byte of bytes) {
14170
+ const key = node * 256 + byte;
14171
+ let next2 = this.edges.get(key);
14172
+ if (next2 === void 0) {
14173
+ next2 = this.depth.length;
14174
+ this.edges.set(key, next2);
14175
+ this.fail.push(0);
14176
+ this.depth.push(this.depth[node] + 1);
14177
+ this.children.push(0);
14178
+ this.children[node] += 1;
14179
+ this.out.push([]);
14180
+ this.dict.push(-1);
14181
+ }
14182
+ node = next2;
14183
+ }
14184
+ const id2 = this.lengths.length;
14185
+ this.lengths.push(bytes.length);
14186
+ this.out[node].push(id2);
14187
+ return id2;
14188
+ }
14189
+ build() {
14190
+ const queue = [];
14191
+ const byNode = /* @__PURE__ */ new Map();
14192
+ for (const [key, child] of this.edges) {
14193
+ const parent = Math.floor(key / 256);
14194
+ const list = byNode.get(parent) ?? [];
14195
+ list.push([key % 256, child]);
14196
+ byNode.set(parent, list);
14197
+ }
14198
+ for (const [, child] of byNode.get(0) ?? []) queue.push(child);
14199
+ for (let head = 0; head < queue.length; head++) {
14200
+ const node = queue[head];
14201
+ const fallback = this.fail[node];
14202
+ this.dict[node] = this.out[fallback].length > 0 ? fallback : this.dict[fallback];
14203
+ for (const [byte, child] of byNode.get(node) ?? []) {
14204
+ let state = fallback;
14205
+ let target = this.edges.get(state * 256 + byte);
14206
+ while (target === void 0 && state > 0) {
14207
+ state = this.fail[state];
14208
+ target = this.edges.get(state * 256 + byte);
14209
+ }
14210
+ this.fail[child] = target ?? 0;
14211
+ queue.push(child);
14212
+ }
14213
+ }
14214
+ }
14215
+ step(state, byte) {
14216
+ let current = state;
14217
+ for (; ; ) {
14218
+ const next2 = this.edges.get(current * 256 + byte);
14219
+ if (next2 !== void 0) return next2;
14220
+ if (current === 0) return 0;
14221
+ current = this.fail[current];
14222
+ }
14223
+ }
14224
+ matches(state, visit) {
14225
+ for (let node = state; node > 0; node = this.dict[node]) {
14226
+ for (const id2 of this.out[node]) visit(id2);
14227
+ }
14228
+ }
14229
+ partials(state, length2, visit) {
14230
+ for (let node = state; node > 0; node = this.fail[node]) {
14231
+ if (this.children[node] > 0) visit(length2 - this.depth[node]);
14232
+ }
14233
+ }
14234
+ };
14235
+ var RANK = {
14236
+ raw: 0,
14237
+ fragment: 1,
14238
+ json: 2,
14239
+ percent: 3,
14240
+ html: 4,
14241
+ base64: 5,
14242
+ hex: 6,
14243
+ wrapped: 7
14244
+ };
14245
+ var CR2 = 13;
14246
+ var LF2 = 10;
14247
+ var EMPTY2 = new Uint8Array(0);
14248
+ function register(automaton, sources, ids, bytes, source) {
14249
+ const key = Array.from(bytes).join(",");
14250
+ let id2 = ids.get(key);
14251
+ if (id2 === void 0) {
14252
+ id2 = automaton.add(bytes);
14253
+ ids.set(key, id2);
14254
+ sources[id2] = [];
14255
+ }
14256
+ sources[id2].push(source);
14257
+ }
14258
+ function prepare(secrets) {
14259
+ const main = new Automaton();
14260
+ const wrap = new Automaton();
14261
+ const sources = [];
14262
+ const wrapSources = [];
14263
+ const ids = /* @__PURE__ */ new Map();
14264
+ const wrapIds = /* @__PURE__ */ new Map();
14265
+ const values = secrets.map((secret) => utf82(secret.value));
14266
+ secrets.forEach((secret, index) => {
14267
+ if (typeof secret.value !== "string" || values[index].length < MIN_VALUE) {
14268
+ throw new RangeError(`the value of ${secret.name} is shorter than ${MIN_VALUE} bytes`);
14269
+ }
14270
+ for (const shape of shapes(secret.value)) {
14271
+ const source = { secret: index, form: shape.form, offset: shape.offset };
14272
+ register(main, sources, ids, shape.bytes, source);
14273
+ if (wrappable(shape.form)) register(wrap, wrapSources, wrapIds, shape.bytes, source);
14274
+ }
14275
+ });
14276
+ main.build();
14277
+ wrap.build();
14278
+ const replacements = secrets.map((secret) => [
14279
+ utf82(secret.placeholder),
14280
+ utf82(`[redacted:${secret.name}]`)
14281
+ ]);
14282
+ return { secrets, values, main, wrap, sources, wrapSources, replacements };
14283
+ }
14284
+ function better(a, b) {
14285
+ if (!b) return true;
14286
+ if (a.end !== b.end) return a.end > b.end;
14287
+ if (a.rank !== b.rank) return a.rank < b.rank;
14288
+ return a.secret < b.secret;
14289
+ }
14290
+ function resolve(c, input, start2, end, source) {
14291
+ if (source.form !== "fragment") {
14292
+ return {
14293
+ start: start2,
14294
+ end,
14295
+ secret: source.secret,
14296
+ form: source.form,
14297
+ rank: RANK[source.form],
14298
+ growing: false
14299
+ };
14300
+ }
14301
+ const value = c.values[source.secret];
14302
+ let stop = end;
14303
+ let at = source.offset + FRAGMENT;
14304
+ while (stop < input.length && at < value.length && input[stop] === value[at]) {
14305
+ stop++;
14306
+ at++;
14307
+ }
14308
+ const form = source.offset === 0 && at === value.length ? "raw" : "fragment";
14309
+ const growing = stop === input.length && at < value.length;
14310
+ return { start: start2, end: stop, secret: source.secret, form, rank: RANK[form], growing };
14311
+ }
14312
+ function keep(best, candidate) {
14313
+ if (better(candidate, best.get(candidate.start))) best.set(candidate.start, candidate);
14314
+ }
14315
+ function scanMain(c, input, best, partials) {
14316
+ let state = 0;
14317
+ for (let i = 0; i < input.length; i++) {
14318
+ state = c.main.step(state, input[i]);
14319
+ c.main.matches(state, (id2) => {
14320
+ const start2 = i + 1 - c.main.lengths[id2];
14321
+ for (const source of c.sources[id2]) {
14322
+ const candidate = resolve(c, input, start2, i + 1, source);
14323
+ if (candidate.growing) partials.push(candidate.start);
14324
+ keep(best, candidate);
14325
+ }
14326
+ });
14327
+ }
14328
+ c.main.partials(state, input.length, (start2) => partials.push(start2));
14329
+ }
14330
+ function scanWrapped(c, input, best, partials) {
14331
+ const map = [];
14332
+ for (let i = 0; i < input.length; i++) if (input[i] !== CR2 && input[i] !== LF2) map.push(i);
14333
+ if (map.length === input.length) return;
14334
+ let state = 0;
14335
+ for (let v = 0; v < map.length; v++) {
14336
+ state = c.wrap.step(state, input[map[v]]);
14337
+ c.wrap.matches(state, (id2) => {
14338
+ const first = v + 1 - c.wrap.lengths[id2];
14339
+ const start2 = map[first];
14340
+ const end = map[v] + 1;
14341
+ const wrapped = end - start2 !== c.wrap.lengths[id2];
14342
+ for (const source of c.wrapSources[id2]) {
14343
+ const form = wrapped ? "wrapped" : source.form;
14344
+ keep(best, { start: start2, end, secret: source.secret, form, rank: RANK[form], growing: false });
14345
+ }
14346
+ });
14347
+ }
14348
+ c.wrap.partials(state, map.length, (start2) => partials.push(map[start2]));
14349
+ }
14350
+ function count(c, hits, candidate) {
14351
+ const name2 = c.secrets[candidate.secret].name;
14352
+ const key = `${name2}\0${candidate.form}`;
14353
+ const hit = hits.get(key) ?? { name: name2, form: candidate.form, count: 0 };
14354
+ hit.count += 1;
14355
+ hits.set(key, hit);
14356
+ }
14357
+ function concat5(parts2) {
14358
+ let length2 = 0;
14359
+ for (const part of parts2) length2 += part.length;
14360
+ const out = new Uint8Array(length2);
14361
+ let at = 0;
14362
+ for (const part of parts2) {
14363
+ out.set(part, at);
14364
+ at += part.length;
14365
+ }
14366
+ return out;
14367
+ }
14368
+ function pass(c, input, final) {
14369
+ const best = /* @__PURE__ */ new Map();
14370
+ const partials = [];
14371
+ scanMain(c, input, best, partials);
14372
+ scanWrapped(c, input, best, partials);
14373
+ const holds = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
14374
+ const starts = [...best.keys()].sort((a, b) => a - b);
14375
+ const parts2 = [];
14376
+ const hits = /* @__PURE__ */ new Map();
14377
+ let pos = 0;
14378
+ let cut = input.length;
14379
+ let s = 0;
14380
+ let h = 0;
14381
+ for (; ; ) {
14382
+ while (s < starts.length && starts[s] < pos) s++;
14383
+ while (h < holds.length && holds[h] < pos) h++;
14384
+ const hold = h < holds.length ? holds[h] : Infinity;
14385
+ const next2 = s < starts.length ? starts[s] : Infinity;
14386
+ if (hold <= next2) {
14387
+ cut = Math.min(hold, input.length);
14388
+ break;
14389
+ }
14390
+ const candidate = best.get(next2);
14391
+ parts2.push(
14392
+ input.subarray(pos, next2),
14393
+ c.replacements[candidate.secret][candidate.form === "raw" ? 0 : 1]
14394
+ );
14395
+ count(c, hits, candidate);
14396
+ pos = candidate.end;
14397
+ }
14398
+ parts2.push(input.subarray(pos, cut));
14399
+ return { output: concat5(parts2), cut, hits };
14400
+ }
14401
+ function merge(into, from) {
14402
+ for (const [key, hit] of from) {
14403
+ const known = into.get(key);
14404
+ if (known) known.count += hit.count;
14405
+ else into.set(key, { ...hit });
14406
+ }
14407
+ }
14408
+ function compile(secrets, options = {}) {
14409
+ const c = prepare(secrets.map((secret) => ({ ...secret })));
14410
+ const decoder4 = new TextDecoder();
14411
+ const idleMs = options.idleMs ?? 250;
14412
+ const scrubBytes = (input) => {
14413
+ if (c.secrets.length === 0) return { bytes: input.slice(), hits: [] };
14414
+ const result = pass(c, input, true);
14415
+ return { bytes: result.output, hits: [...result.hits.values()] };
14416
+ };
14417
+ return {
14418
+ version: options.version ?? 0,
14419
+ idleMs,
14420
+ size: c.main.lengths.length,
14421
+ bytes: scrubBytes,
14422
+ text(input) {
14423
+ const { bytes, hits } = scrubBytes(utf82(input));
14424
+ return { text: decoder4.decode(bytes), hits };
14425
+ },
14426
+ stream() {
14427
+ let pending = EMPTY2;
14428
+ const hits = /* @__PURE__ */ new Map();
14429
+ const run2 = (final) => {
14430
+ if (c.secrets.length === 0 || pending.length === 0) {
14431
+ const out = pending;
14432
+ pending = EMPTY2;
14433
+ return out;
14434
+ }
14435
+ const result = pass(c, pending, final);
14436
+ merge(hits, result.hits);
14437
+ pending = pending.slice(result.cut);
14438
+ return result.output;
14439
+ };
14440
+ return {
14441
+ push(chunk2) {
14442
+ pending = concat5([pending, chunk2]);
14443
+ return run2(false);
14444
+ },
14445
+ idle() {
14446
+ return pending.length < FRAGMENT ? run2(true) : EMPTY2;
14447
+ },
14448
+ end() {
14449
+ return run2(true);
14450
+ },
14451
+ get hits() {
14452
+ return [...hits.values()];
14453
+ }
14454
+ };
14455
+ }
14456
+ };
14457
+ }
14458
+
14459
+ // src/kernel/scrub-file.ts
14460
+ var SCRUB_IDLE_MS = 50;
14461
+ var encoder5 = new TextEncoder();
14462
+ function scrubberOf(secrets) {
14463
+ const usable = secrets.filter((s) => encoder5.encode(s.value).length >= MIN_VALUE);
14464
+ return usable.length > 0 ? compile(usable, { idleMs: SCRUB_IDLE_MS }) : void 0;
14465
+ }
14466
+ async function writeAll2(file, bytes, signal) {
14467
+ const write = file.write;
14468
+ for (let at = 0; at < bytes.length; ) {
14469
+ at += await write.call(file, bytes.subarray(at), at === 0 ? signal : void 0);
14470
+ }
14471
+ }
14472
+ function bound(file, key) {
14473
+ const method = file[key];
14474
+ return typeof method === "function" ? { [key]: method.bind(file) } : {};
14475
+ }
14476
+ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
14477
+ const file = inner.file;
14478
+ const stream2 = scrubber.stream();
14479
+ let queue = Promise.resolve();
14480
+ let timer;
14481
+ let failed3;
14482
+ const raise = () => {
14483
+ if (failed3 === void 0) return;
14484
+ const err = failed3;
14485
+ failed3 = void 0;
14486
+ throw err;
14487
+ };
14488
+ const enqueue = (bytes, signal) => {
14489
+ const next2 = queue.then(() => bytes.length > 0 ? writeAll2(file, bytes, signal) : void 0);
14490
+ queue = next2.catch(() => void 0);
14491
+ return next2;
14492
+ };
14493
+ const release = () => {
14494
+ timer = void 0;
14495
+ enqueue(stream2.idle()).catch((err) => {
14496
+ failed3 = err;
14497
+ });
14498
+ };
14499
+ return new OpenFile({
14500
+ ...bound(file, "read"),
14501
+ ...bound(file, "peek"),
14502
+ ...bound(file, "poll"),
14503
+ ...bound(file, "changed"),
14504
+ ...bound(file, "stat"),
14505
+ ...file.tty ? { tty: file.tty } : {},
14506
+ ...file.clipboard ? { clipboard: file.clipboard } : {},
14507
+ ...file.write ? {
14508
+ write: async (bytes, signal) => {
14509
+ if (timer !== void 0) clearTimeout(timer);
14510
+ raise();
14511
+ await enqueue(stream2.push(bytes), signal);
14512
+ timer = setTimeout(release, idleMs);
14513
+ return bytes.length;
14514
+ }
14515
+ } : {},
14516
+ flush: async () => {
14517
+ await queue;
14518
+ raise();
14519
+ await file.flush?.();
14520
+ },
14521
+ close: async () => {
14522
+ if (timer !== void 0) clearTimeout(timer);
14523
+ let failure;
14524
+ try {
14525
+ await enqueue(stream2.end());
14526
+ raise();
14527
+ } catch (err) {
14528
+ failure = { err };
14529
+ }
14530
+ await inner.release();
14531
+ if (failure) throw failure.err;
14532
+ }
14533
+ });
14534
+ }
14535
+ function scrubbedAll(file, scrubbers) {
14536
+ return scrubbers.reduce((inner, scrubber) => scrubbed(inner, scrubber), file);
14537
+ }
14538
+ function stdioFiles(fds) {
14539
+ const files = /* @__PURE__ */ new Set();
14540
+ for (const fd of [1, 2]) {
14541
+ try {
14542
+ files.add(fds.get(fd));
14543
+ } catch {
14544
+ }
14545
+ }
14546
+ return files;
14547
+ }
14548
+ function scrubStdio(fds, scrubber) {
14549
+ const wrapped = /* @__PURE__ */ new Map();
14550
+ const stdio = stdioFiles(fds);
14551
+ for (const fd of fds.numbers()) {
14552
+ const original = fds.get(fd);
14553
+ if (!stdio.has(original) && !original.file.tty) continue;
14554
+ const known = wrapped.get(original);
14555
+ const flags2 = fds.statusFlags(fd);
14556
+ const wrapper = known ? known.retain() : scrubbed(original.retain(), scrubber);
14557
+ wrapped.set(original, wrapper);
14558
+ fds.installAt(fd, wrapper);
14559
+ if (flags2 !== void 0) fds.setStatusFlags(fd, flags2);
14560
+ }
14561
+ }
14562
+
13989
14563
  // src/kernel/sealed.ts
13990
14564
  var SEALED_MAX_BYTES = 64 * 1024;
13991
14565
  var SEALED_TIMEOUT_MS = 1e4;
@@ -13999,7 +14573,7 @@ var SEALED_OPS = /* @__PURE__ */ new Set([
13999
14573
  "cancel",
14000
14574
  "materialize"
14001
14575
  ]);
14002
- var encoder4 = new TextEncoder();
14576
+ var encoder6 = new TextEncoder();
14003
14577
  var decoder3 = new TextDecoder("utf-8", { fatal: true });
14004
14578
  function parseSealed(bytes) {
14005
14579
  try {
@@ -14015,11 +14589,16 @@ function parseSealed(bytes) {
14015
14589
  const req = parsed2;
14016
14590
  if (req.v !== 1 || typeof req.op !== "string" || !SEALED_OPS.has(req.op))
14017
14591
  throw new KernelError("EINVAL");
14592
+ if (req.op === "materialize" && !materializable(req)) throw new KernelError("EINVAL");
14018
14593
  return req;
14019
14594
  } finally {
14020
14595
  bytes.fill(0);
14021
14596
  }
14022
14597
  }
14598
+ function materializable(req) {
14599
+ if (req.shellGrants !== true && !isStrings(req.names)) return false;
14600
+ return isStrings(req.argv) && typeof req.path === "string" && typeof req.cwd === "string";
14601
+ }
14023
14602
  function errorReply(code, message3) {
14024
14603
  return { v: 1, error: { code, message: message3 } };
14025
14604
  }
@@ -14063,12 +14642,14 @@ var SealedChannel = class {
14063
14642
  const timer = setTimeout(() => control.abort("timeout"), this.broker.timeoutMs);
14064
14643
  const req = { ...fields, v: 1, op: fields.op, caller };
14065
14644
  const flight = { control, done: Promise.resolve() };
14066
- flight.done = this.answer(req, control.signal).then((reply) => {
14645
+ flight.done = this.answer(req, control.signal).then(async (reply) => {
14067
14646
  clearTimeout(timer);
14068
14647
  gone.removeEventListener("abort", withdraw);
14648
+ if (reply && req.op === "materialize")
14649
+ await this.broker.tickets.record(req, reply, caller.pid);
14069
14650
  if (this.inflight !== flight) return;
14070
14651
  this.inflight = void 0;
14071
- if (reply) this.reply = encoder4.encode(serialized(reply));
14652
+ if (reply) this.reply = encoder6.encode(serialized(reply));
14072
14653
  });
14073
14654
  this.inflight = flight;
14074
14655
  return length2;
@@ -14076,8 +14657,8 @@ var SealedChannel = class {
14076
14657
  async answer(req, signal) {
14077
14658
  const hook = this.broker.hook;
14078
14659
  if (!hook) return errorReply("ENOTCONN", "no vault is connected");
14079
- const stopped = new Promise((resolve) => {
14080
- signal.addEventListener("abort", () => resolve(void 0), { once: true });
14660
+ const stopped = new Promise((resolve2) => {
14661
+ signal.addEventListener("abort", () => resolve2(void 0), { once: true });
14081
14662
  });
14082
14663
  if (signal.aborted) return void 0;
14083
14664
  const asked = Promise.resolve().then(() => hook(req, { signal })).then(
@@ -14132,17 +14713,60 @@ var SealedChannel = class {
14132
14713
  this.reply = void 0;
14133
14714
  }
14134
14715
  };
14716
+ function swapOf(reply) {
14717
+ if (!isRecord(reply) || reply.error !== void 0) return void 0;
14718
+ const values = stringRecord(reply.values);
14719
+ const placeholders = stringRecord(reply.placeholders);
14720
+ return values && placeholders ? { values, placeholders } : void 0;
14721
+ }
14135
14722
  var SealedBroker = class {
14136
14723
  hook;
14137
14724
  users;
14138
14725
  timeoutMs;
14139
14726
  tagOf;
14727
+ tickets = new TicketBook();
14728
+ userOf = async () => void 0;
14140
14729
  constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
14141
14730
  this.hook = hook;
14142
14731
  this.users = users;
14143
14732
  this.timeoutMs = timeoutMs;
14144
14733
  this.tagOf = tagOf;
14145
14734
  }
14735
+ async stamp(ids, cred, tag) {
14736
+ const user = await this.userOf(cred.euid).catch(() => void 0);
14737
+ return {
14738
+ pid: ids.pid,
14739
+ ppid: ids.ppid,
14740
+ uid: cred.euid,
14741
+ gid: cred.egid,
14742
+ ...user !== void 0 ? { user } : {},
14743
+ groups: [...cred.groups],
14744
+ users: this.users,
14745
+ ...tag !== void 0 ? { tag } : {}
14746
+ };
14747
+ }
14748
+ async consume(fields) {
14749
+ const { hook } = this;
14750
+ if (!hook) return void 0;
14751
+ const control = new AbortController();
14752
+ const timer = setTimeout(() => control.abort("timeout"), this.timeoutMs);
14753
+ const stopped = new Promise((resolve2) => {
14754
+ control.signal.addEventListener("abort", () => resolve2(void 0), { once: true });
14755
+ });
14756
+ const req = {
14757
+ ...fields,
14758
+ v: 1,
14759
+ op: "materializeConsume",
14760
+ caller: fields.stamp
14761
+ };
14762
+ try {
14763
+ const asked = Promise.resolve().then(() => hook(req, { signal: control.signal })).then(swapOf, () => void 0);
14764
+ return await Promise.race([asked, stopped]);
14765
+ } finally {
14766
+ clearTimeout(timer);
14767
+ control.abort("done");
14768
+ }
14769
+ }
14146
14770
  open() {
14147
14771
  const channel = new SealedChannel(this);
14148
14772
  return new OpenFile({
@@ -14641,11 +15265,11 @@ function codeOf3(err) {
14641
15265
  }
14642
15266
  function wait(ms, signal) {
14643
15267
  if (signal.aborted) return Promise.resolve();
14644
- return new Promise((resolve) => {
15268
+ return new Promise((resolve2) => {
14645
15269
  const done4 = () => {
14646
15270
  clearTimeout(timer);
14647
15271
  signal.removeEventListener("abort", done4);
14648
- resolve();
15272
+ resolve2();
14649
15273
  };
14650
15274
  const timer = setTimeout(done4, ms);
14651
15275
  signal.addEventListener("abort", done4, { once: true });
@@ -14972,11 +15596,11 @@ async function resize(h, path, size) {
14972
15596
  }
14973
15597
  }
14974
15598
  function sleep(ms, signal) {
14975
- return new Promise((resolve) => {
15599
+ return new Promise((resolve2) => {
14976
15600
  const done4 = () => {
14977
15601
  clearTimeout(timer);
14978
15602
  signal.removeEventListener("abort", done4);
14979
- resolve();
15603
+ resolve2();
14980
15604
  };
14981
15605
  const timer = setTimeout(done4, ms);
14982
15606
  signal.addEventListener("abort", done4);
@@ -15059,7 +15683,7 @@ var PORT_DEAD_MS = 1e4;
15059
15683
  var PORT_LINGER_MS = 1e3;
15060
15684
  function timed(transport, ms) {
15061
15685
  const inflight = /* @__PURE__ */ new Set();
15062
- const guard2 = (name2, run2, late, expire) => new Promise((resolve, reject) => {
15686
+ const guard2 = (name2, run2, late, expire) => new Promise((resolve2, reject) => {
15063
15687
  let expired = false;
15064
15688
  const running = run2();
15065
15689
  inflight.add(running);
@@ -15076,7 +15700,7 @@ function timed(transport, ms) {
15076
15700
  (value) => {
15077
15701
  clearTimeout(timer);
15078
15702
  if (expired) late?.(value);
15079
- resolve(value);
15703
+ resolve2(value);
15080
15704
  },
15081
15705
  (err) => {
15082
15706
  clearTimeout(timer);
@@ -15211,7 +15835,7 @@ var PortTransport = class {
15211
15835
  ask(message3, bytes = 0, transfer = []) {
15212
15836
  const id2 = ++this.next;
15213
15837
  if (this.dead) return Promise.reject(fsError2("ENOTCONN", this.dead));
15214
- return new Promise((resolve, reject) => {
15838
+ return new Promise((resolve2, reject) => {
15215
15839
  const timer = setTimeout(
15216
15840
  () => {
15217
15841
  this.waiting.delete(id2);
@@ -15225,7 +15849,7 @@ var PortTransport = class {
15225
15849
  clearTimeout(timer);
15226
15850
  this.waiting.delete(id2);
15227
15851
  if (reply.error) reject(fsError2(reply.error.code ?? "EIO", reply.error.message ?? ""));
15228
- else resolve(reply);
15852
+ else resolve2(reply);
15229
15853
  });
15230
15854
  try {
15231
15855
  this.port.postMessage({ id: id2, ...message3 }, transfer);
@@ -15254,7 +15878,7 @@ var PortTransport = class {
15254
15878
  this.fail("the folder's watch ended");
15255
15879
  return Promise.resolve();
15256
15880
  }
15257
- return new Promise((resolve, reject) => {
15881
+ return new Promise((resolve2, reject) => {
15258
15882
  const finish = () => {
15259
15883
  this.waiting.delete(id2);
15260
15884
  signal.removeEventListener("abort", stop);
@@ -15265,7 +15889,7 @@ var PortTransport = class {
15265
15889
  this.port.postMessage({ id: id2, op: "unwatch" });
15266
15890
  } catch {
15267
15891
  }
15268
- resolve();
15892
+ resolve2();
15269
15893
  };
15270
15894
  this.watchBeat();
15271
15895
  this.waiting.set(id2, (reply) => {
@@ -15273,7 +15897,7 @@ var PortTransport = class {
15273
15897
  if (reply.event) return onEvent(reply.event);
15274
15898
  finish();
15275
15899
  if (reply.error) reject(fsError2(reply.error.code ?? "ENOTCONN", reply.error.message ?? ""));
15276
- else resolve();
15900
+ else resolve2();
15277
15901
  });
15278
15902
  signal.addEventListener("abort", stop, { once: true });
15279
15903
  try {
@@ -15489,10 +16113,10 @@ var ChunkedBytes = class {
15489
16113
  }
15490
16114
  truncate(size) {
15491
16115
  if (size < this.size) {
15492
- const keep = Math.ceil(size / CHUNK3);
15493
- this.chunks.length = Math.min(this.chunks.length, keep);
15494
- const tail = this.chunks[keep - 1];
15495
- const from = size - (keep - 1) * CHUNK3;
16116
+ const keep2 = Math.ceil(size / CHUNK3);
16117
+ this.chunks.length = Math.min(this.chunks.length, keep2);
16118
+ const tail = this.chunks[keep2 - 1];
16119
+ const from = size - (keep2 - 1) * CHUNK3;
15496
16120
  if (tail && from < tail.length) tail.fill(0, from);
15497
16121
  }
15498
16122
  this.size = size;
@@ -15737,8 +16361,8 @@ function importedMemory(bytes) {
15737
16361
  at = end;
15738
16362
  continue;
15739
16363
  }
15740
- const count = u32();
15741
- for (let i = 0; i < count; i++) {
16364
+ const count2 = u32();
16365
+ for (let i = 0; i < count2; i++) {
15742
16366
  const module = name2();
15743
16367
  const field3 = name2();
15744
16368
  const kind = bytes[at++];
@@ -16167,7 +16791,7 @@ ${lines2}
16167
16791
  const withdraw = () => control.abort("withdrawn");
16168
16792
  requester.addEventListener("abort", withdraw, { once: true });
16169
16793
  const aborted2 = new Promise(
16170
- (resolve) => control.signal.addEventListener("abort", () => resolve("aborted"), { once: true })
16794
+ (resolve2) => control.signal.addEventListener("abort", () => resolve2("aborted"), { once: true })
16171
16795
  );
16172
16796
  try {
16173
16797
  const answered = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
@@ -16293,7 +16917,7 @@ var LAYOUT = [
16293
16917
  ];
16294
16918
  var LOAD_SAMPLE_MS = 5e3;
16295
16919
  var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
16296
- var encoder5 = new TextEncoder();
16920
+ var encoder7 = new TextEncoder();
16297
16921
  var USERS_MODES = ["off", "report", "enforce"];
16298
16922
  function usersMode(mode = "off") {
16299
16923
  if (USERS_MODES.includes(mode)) return mode;
@@ -16324,6 +16948,30 @@ function shebang(head) {
16324
16948
  if (head[0] !== 35 || head[1] !== 33) return void 0;
16325
16949
  return new TextDecoder().decode(head.subarray(0, SHEBANG_MAX)).slice(2).split("\n")[0].trim().split(/[ \t]+/);
16326
16950
  }
16951
+ async function rootOnly(fs, path) {
16952
+ const names = chain(path);
16953
+ for (const [i, at] of names.entries()) {
16954
+ const st = await fs.lstat(at).catch(() => void 0);
16955
+ const kind = i === names.length - 1 ? st?.isFile : st?.isDirectory;
16956
+ if (!kind || st?.uid !== 0 || (st.mode & 18) !== 0) return false;
16957
+ }
16958
+ return true;
16959
+ }
16960
+ function plainEnv(words2) {
16961
+ const next2 = words2[1];
16962
+ if (baseName(words2[0] ?? "") !== "env" || next2 === void 0) return false;
16963
+ return next2 === "-S" || !next2.startsWith("-") && !next2.includes("=");
16964
+ }
16965
+ function shebangCommand(words2) {
16966
+ if (!plainEnv(words2)) {
16967
+ const arg2 = words2.slice(1).join(" ");
16968
+ return { interp: words2[0], args: arg2 ? [arg2] : [] };
16969
+ }
16970
+ const split2 = words2[1] === "-S";
16971
+ const [interp, ...rest2] = words2.slice(split2 ? 2 : 1);
16972
+ const arg = rest2.join(" ");
16973
+ return { interp, args: split2 ? rest2 : arg ? [arg] : [] };
16974
+ }
16327
16975
  function interpreter(head) {
16328
16976
  const words2 = shebang(head);
16329
16977
  if (!words2) return "node";
@@ -16377,7 +17025,7 @@ function childHandle(handle) {
16377
17025
  onState: (listener) => handle.onState(listener)
16378
17026
  };
16379
17027
  }
16380
- function concat5(chunks2) {
17028
+ function concat6(chunks2) {
16381
17029
  const out = new Uint8Array(chunks2.reduce((n, chunk2) => n + chunk2.length, 0));
16382
17030
  let offset = 0;
16383
17031
  for (const chunk2 of chunks2) {
@@ -16463,6 +17111,7 @@ var Launcher = class {
16463
17111
  usersMode;
16464
17112
  dac;
16465
17113
  sealed;
17114
+ scrubs = /* @__PURE__ */ new Map();
16466
17115
  clipboard;
16467
17116
  rootFs;
16468
17117
  fileWatches;
@@ -16486,6 +17135,8 @@ var Launcher = class {
16486
17135
  void 0,
16487
17136
  (pid) => this.tagOf(pid)
16488
17137
  );
17138
+ this.sealed.tickets.normalise = (path) => physicalPathAsync(this.base, path);
17139
+ this.sealed.userOf = async (uid) => (await this.users.lookup(uid))?.name;
16489
17140
  if (this.owners) options.fs.trackOwners?.();
16490
17141
  this.mounts = new MountTable({
16491
17142
  open: (type, spec) => this.driver(type, spec),
@@ -16734,13 +17385,12 @@ var Launcher = class {
16734
17385
  const binfmt = isWasm(head) ? void 0 : binfmtOf(await this.interpreters(scope), script);
16735
17386
  const words2 = shebang(head) ?? (binfmt ? [binfmt] : void 0);
16736
17387
  if (!words2) return void 0;
16737
- if (baseName(words2[0]) === "env") words2.shift();
16738
- const [interp, ...rest2] = words2;
16739
- const arg = rest2.join(" ");
16740
- const passed = [...arg ? [arg] : [], command ? script : file, ...argv.slice(1)];
16741
- const found = interp ? await this.resolve(interp, interp, cwd, scope) : void 0;
17388
+ const { interp, args } = shebangCommand(words2);
17389
+ const passed = [...args, command ? script : file, ...argv.slice(1)];
17390
+ if (!interp) return void 0;
17391
+ const found = await this.resolve(interp, interp, cwd, scope);
16742
17392
  if (!found) {
16743
- if (!interp || depth >= MAX_INTERPRETERS || !await this.scriptCommand(interp, cwd, scope)) {
17393
+ if (depth >= MAX_INTERPRETERS || !await this.scriptCommand(interp, cwd, scope)) {
16744
17394
  return void 0;
16745
17395
  }
16746
17396
  const inner = await this.interpreted(interp, [interp, ...passed], cwd, scope, depth + 1);
@@ -16780,6 +17430,99 @@ var Launcher = class {
16780
17430
  await need(g, "exec", this.fs.resolvePath(req.cwd, file), want);
16781
17431
  }
16782
17432
  }
17433
+ async checkedPlan(req, { ppid, cred, scope }, fds) {
17434
+ const planned = await this.plan(req.file, req.argv, req.cwd, scope, req.argv0);
17435
+ try {
17436
+ await this.mayExec(cred, { ...req, pid: ppid }, planned);
17437
+ } catch (err) {
17438
+ await fds.closeAll();
17439
+ throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
17440
+ }
17441
+ if (planned) return planned;
17442
+ await fds.closeAll();
17443
+ throw new SpawnError(await this.unrunnable(req.file, req.cwd, scope));
17444
+ }
17445
+ async ticketFile(req, fds) {
17446
+ if (req.file.startsWith("/")) return physicalPathAsync(this.base, req.file);
17447
+ await fds.closeAll();
17448
+ throw new SpawnError("EACCES");
17449
+ }
17450
+ takeTicket(req) {
17451
+ if (!(TICKET_ENV in req.env)) return void 0;
17452
+ return this.sealed.tickets.take(req.env[TICKET_ENV] ?? "") ?? null;
17453
+ }
17454
+ async redeemed(req, who, planned, fds) {
17455
+ if (who.booked === void 0) return { env: req.env };
17456
+ try {
17457
+ const redeemed = await this.redeem(req, who, planned);
17458
+ if (redeemed.scrub) scrubStdio(fds, redeemed.scrub);
17459
+ return redeemed;
17460
+ } catch {
17461
+ await fds.closeAll();
17462
+ throw new SpawnError("EACCES");
17463
+ }
17464
+ }
17465
+ async redeem(req, { ppid, cred, scope, booked }, planned) {
17466
+ const { [TICKET_ENV]: ticket = "", ...env } = req.env;
17467
+ const caller = this.jobs.shown(ppid);
17468
+ const named = typeof req.argv0 === "string" && !planned.script && !planned.target.fixed;
17469
+ const argv = named ? [req.argv0, ...req.argv.slice(1)] : req.argv;
17470
+ const exact = booked?.pid === caller && req.file === booked.path && await physicalPathAsync(this.base, req.cwd) === booked.cwd && await argvDigest(argv) === booked.argv;
17471
+ if (!exact) throw new SpawnError("EACCES");
17472
+ const { requested: path, requestedCwd: cwd, path: resolved2 } = booked;
17473
+ const pid = this.nextPid++;
17474
+ const ids = { pid: req.exec ? caller : pid, ppid: caller };
17475
+ const stamp = await this.sealed.stamp(ids, cred, this.tagOf(ppid));
17476
+ const interpreters = await this.interpreterChain(planned, booked.cwd, scope);
17477
+ const trusted = this.usersMode === "enforce" && await this.trustedFiles(planned, req.file, booked.cwd, scope);
17478
+ const swap = await this.sealed.consume({
17479
+ ticket,
17480
+ stamp,
17481
+ path,
17482
+ resolved: resolved2,
17483
+ argv,
17484
+ cwd,
17485
+ interpreters,
17486
+ trusted
17487
+ });
17488
+ if (!swap) throw new SpawnError("EACCES");
17489
+ const secrets = [];
17490
+ for (const [name2, placeholder] of Object.entries(swap.placeholders)) {
17491
+ const value = swap.values[name2];
17492
+ if (value === void 0 || env[name2] !== placeholder) continue;
17493
+ env[name2] = value;
17494
+ secrets.push({ name: name2, value, placeholder });
17495
+ }
17496
+ const scrub = scrubberOf(secrets);
17497
+ return { env, pid, cwd: booked.cwd, ...scrub ? { scrub } : {} };
17498
+ }
17499
+ async interpreterChain(planned, cwd, scope) {
17500
+ const out = [];
17501
+ for (const entry of planned.via ?? []) {
17502
+ if (entry.includes("/")) {
17503
+ out.push(await physicalPathAsync(this.base, this.fs.resolvePath(cwd, entry)));
17504
+ continue;
17505
+ }
17506
+ const script = (await this.scriptCommand(entry, cwd, scope))?.script;
17507
+ out.push(
17508
+ await physicalPathAsync(this.base, script ?? await this.commandFile(entry, cwd, scope))
17509
+ );
17510
+ }
17511
+ return out;
17512
+ }
17513
+ async commandFile(name2, cwd, scope) {
17514
+ const scoped = await this.resolve(name2, name2, cwd, scope);
17515
+ const system = scope === "" ? scoped : await this.resolve(name2, name2, cwd, "");
17516
+ if (!scoped || system?.glue === scoped.glue) return `/usr/bin/${name2}`;
17517
+ return scoped.glue;
17518
+ }
17519
+ async trustedFiles(planned, file, cwd, scope) {
17520
+ const files = await this.backingOf(planned, file, cwd, scope);
17521
+ for (const at of files) {
17522
+ if (!await rootOnly(this.base, await physicalPathAsync(this.base, at))) return false;
17523
+ }
17524
+ return true;
17525
+ }
16783
17526
  async grantedCwd(caller, cwd) {
16784
17527
  const real = await physicalPathAsync(this.base, cwd).catch(() => void 0);
16785
17528
  return real === cwd && await this.sudoer.reachable(caller, cwd);
@@ -16798,13 +17541,15 @@ var Launcher = class {
16798
17541
  }
16799
17542
  async backing(file, cwd) {
16800
17543
  const planned = await this.plan(file, [file], cwd, "");
16801
- if (!planned) return void 0;
17544
+ return planned && this.backingOf(planned, file, cwd, "");
17545
+ }
17546
+ async backingOf(planned, file, cwd, scope) {
16802
17547
  const { glue, wasm, imports } = planned.target;
16803
17548
  const files = [glue, wasm, ...imports ? [imports] : []];
16804
17549
  const scripts = [];
16805
17550
  for (const name2 of [file, ...planned.via ?? []]) {
16806
17551
  if (name2.includes("/") && !COMMAND2.test(name2)) scripts.push(this.fs.resolvePath(cwd, name2));
16807
- const script = (await this.scriptCommand(name2, cwd, ""))?.script;
17552
+ const script = (await this.scriptCommand(name2, cwd, scope))?.script;
16808
17553
  if (script) scripts.push(script);
16809
17554
  }
16810
17555
  files.push(...scripts, ...await this.binfmtManifests(scripts));
@@ -16933,6 +17678,7 @@ var Launcher = class {
16933
17678
  const seen = { ...req.env, HOSTNAME: this.hostname, cwd };
16934
17679
  const env = { ...expandDefaults(target.env, seen), ...req.env };
16935
17680
  for (const key of target.unset ?? []) delete env[key];
17681
+ delete env[TICKET_ENV];
16936
17682
  env.HOSTNAME = this.hostname;
16937
17683
  let program;
16938
17684
  try {
@@ -16948,16 +17694,23 @@ var Launcher = class {
16948
17694
  groupSession(pgid) {
16949
17695
  return this.jobs.sessionOf(pgid);
16950
17696
  }
17697
+ treeScrubs(pid, req) {
17698
+ const inherited2 = req.ppid !== void 0 ? this.scrubs.get(req.ppid) : void 0;
17699
+ const scrubs = req.scrub ? [...inherited2 ?? [], req.scrub] : inherited2;
17700
+ if (scrubs) this.scrubs.set(pid, scrubs);
17701
+ return scrubs;
17702
+ }
16951
17703
  start(req) {
16952
17704
  this.sampling();
16953
17705
  if (req.pgid !== void 0 && this.jobs.sessionOf(req.pgid) === void 0) {
16954
17706
  throw new SpawnError("ESRCH");
16955
17707
  }
16956
- const pid = this.nextPid++;
17708
+ const pid = req.pid ?? this.nextPid++;
17709
+ const scrubs = this.treeScrubs(pid, req);
16957
17710
  const stack = this.stackFor(req.tag);
16958
17711
  const terminal = req.fds.stdioTerminal();
16959
17712
  const decided = req.decided ?? Promise.resolve(true);
16960
- const count = (byParent) => {
17713
+ const count2 = (byParent) => {
16961
17714
  this.identities.asked++;
16962
17715
  if (!byParent) this.identities.timedOut++;
16963
17716
  };
@@ -16965,7 +17718,7 @@ var Launcher = class {
16965
17718
  const handle = spawnWasmProcess({
16966
17719
  pid,
16967
17720
  identity: async () => {
16968
- await (asked ??= decided.then(count));
17721
+ await (asked ??= decided.then(count2));
16969
17722
  return this.identityOf(pid);
16970
17723
  },
16971
17724
  onSyscall: (call) => {
@@ -16979,6 +17732,7 @@ var Launcher = class {
16979
17732
  ...this.owners && req.program.abi === "wasi" ? { fresh: (path, umask) => this.freshModules.add(path, umask, pid) } : {},
16980
17733
  ...this.owners ? { owners: true } : {},
16981
17734
  sealed: this.sealed,
17735
+ ...scrubs ? { ttyFilter: (file) => scrubbedAll(file, scrubs) } : {},
16982
17736
  clipboard: this.clipboard,
16983
17737
  ...this.dac ? { dac: this.dac } : {},
16984
17738
  program: req.program,
@@ -17045,6 +17799,7 @@ var Launcher = class {
17045
17799
  if (spent) addTimes(this.imageTimes, this.jobs.shown(pid), spent);
17046
17800
  this.stopped.delete(pid);
17047
17801
  this.processes.delete(pid);
17802
+ this.scrubs.delete(pid);
17048
17803
  if (this.processes.size === 0) {
17049
17804
  clearInterval(this.sampler);
17050
17805
  this.sampler = void 0;
@@ -17216,6 +17971,7 @@ var Launcher = class {
17216
17971
  }
17217
17972
  spawner(ppid, report) {
17218
17973
  return async (req, fds, grant) => {
17974
+ const booked = this.takeTicket(req);
17219
17975
  if (grant && !await this.grantedCwd(grant.caller, req.cwd)) {
17220
17976
  await fds.closeAll();
17221
17977
  throw new SpawnError("EACCES");
@@ -17227,23 +17983,20 @@ var Launcher = class {
17227
17983
  }
17228
17984
  const cred = grant ? grant.cred : this.credOf(ppid);
17229
17985
  const scope = grant ? "" : await this.scopeOf(cred.euid);
17230
- const planned = await this.plan(req.file, req.argv, req.cwd, scope, req.argv0);
17231
- try {
17232
- await this.mayExec(cred, { ...req, pid: ppid }, planned);
17233
- } catch (err) {
17234
- await fds.closeAll();
17235
- throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
17236
- }
17237
- if (!planned) {
17238
- await fds.closeAll();
17239
- throw new SpawnError(await this.unrunnable(req.file, req.cwd, scope));
17240
- }
17986
+ const file = booked === void 0 ? req.file : await this.ticketFile(req, fds);
17987
+ const planned = await this.checkedPlan({ ...req, file }, { ppid, cred, scope }, fds);
17988
+ const redeemed = await this.redeemed(
17989
+ { ...req, file },
17990
+ { ppid, cred, scope, booked },
17991
+ planned,
17992
+ fds
17993
+ );
17241
17994
  const exec = req.exec ? { exec: true } : {};
17242
17995
  const deciding = req.exec ? void 0 : this.undecided(ppid);
17243
17996
  const handle = await this.launch(planned, {
17244
17997
  ...deciding ? { decided: deciding.promise } : {},
17245
- env: req.env,
17246
17998
  cwd: req.cwd,
17999
+ ...redeemed,
17247
18000
  fds,
17248
18001
  report,
17249
18002
  ppid,
@@ -17296,11 +18049,11 @@ var Launcher = class {
17296
18049
  if (!waiting) return;
17297
18050
  this.deciding.delete(ppid);
17298
18051
  setTimeout(() => {
17299
- for (const resolve of waiting) resolve(true);
18052
+ for (const resolve2 of waiting) resolve2(true);
17300
18053
  }, 0);
17301
18054
  }
17302
18055
  forker(ppid, parent) {
17303
- const { exec: _exec, pgid: _pgid, group: _group, ...image } = parent;
18056
+ const { exec: _exec, pgid: _pgid, group: _group, pid: _pid, scrub: _scrub, ...image } = parent;
17304
18057
  return async (state, fds) => childHandle(
17305
18058
  this.start({
17306
18059
  ...image,
@@ -17677,7 +18430,14 @@ var Launcher = class {
17677
18430
  );
17678
18431
  }
17679
18432
  environment(cwd, extra, account) {
17680
- return { ...this.env, ...userEnv(account, this.pnpmHome), PWD: cwd, ...extra };
18433
+ const env = {
18434
+ ...this.env,
18435
+ ...userEnv(account, this.pnpmHome),
18436
+ PWD: cwd,
18437
+ ...extra
18438
+ };
18439
+ delete env[TICKET_ENV];
18440
+ return env;
17681
18441
  }
17682
18442
  async account(user) {
17683
18443
  if (typeof user === "object") return user;
@@ -17773,7 +18533,7 @@ var Launcher = class {
17773
18533
  },
17774
18534
  account
17775
18535
  );
17776
- const report = (message3) => options.onData(encoder5.encode(`${message3}\r
18536
+ const report = (message3) => options.onData(encoder7.encode(`${message3}\r
17777
18537
  `));
17778
18538
  const handle = await this.launch(planned, {
17779
18539
  env,
@@ -17804,18 +18564,18 @@ var Launcher = class {
17804
18564
  const env = this.environment(cwd, options.env, account);
17805
18565
  const out = [];
17806
18566
  const err = [];
17807
- const keep = options.collect !== false;
18567
+ const keep2 = options.collect !== false;
17808
18568
  const collect = (chunks2, tee) => (bytes) => {
17809
- if (keep) chunks2.push(bytes);
18569
+ if (keep2) chunks2.push(bytes);
17810
18570
  tee?.(bytes);
17811
18571
  };
17812
18572
  const stdout = collect(out, options.onStdout);
17813
18573
  const stderr = collect(err, options.onStderr);
17814
- const report = (message3) => stderr(encoder5.encode(`${message3}
18574
+ const report = (message3) => stderr(encoder7.encode(`${message3}
17815
18575
  `));
17816
18576
  if (!planned) {
17817
18577
  report(`${file}: command not found`);
17818
- return { status: NOT_FOUND, stdout: concat5(out), stderr: concat5(err) };
18578
+ return { status: NOT_FOUND, stdout: concat6(out), stderr: concat6(err) };
17819
18579
  }
17820
18580
  const fds = new FdTable();
17821
18581
  fds.installAt(0, options.stdin ? bytesSource(options.stdin) : deviceFile("null"));
@@ -17833,7 +18593,7 @@ var Launcher = class {
17833
18593
  options.onStarted?.(handle.pid);
17834
18594
  const status = await handle.exited;
17835
18595
  const signal = handle.termsig();
17836
- return { status, ...signal ? { signal } : {}, stdout: concat5(out), stderr: concat5(err) };
18596
+ return { status, ...signal ? { signal } : {}, stdout: concat6(out), stderr: concat6(err) };
17837
18597
  }
17838
18598
  };
17839
18599
 
@@ -17902,10 +18662,10 @@ var Chunks = class {
17902
18662
  this.grow(size);
17903
18663
  return;
17904
18664
  }
17905
- const keep = Math.ceil(size / CHUNK4);
17906
- this.blobs.length = keep;
17907
- if (keep > 0)
17908
- this.blobs[keep - 1] = this.blobs[keep - 1].slice(0, size - (keep - 1) * CHUNK4);
18665
+ const keep2 = Math.ceil(size / CHUNK4);
18666
+ this.blobs.length = keep2;
18667
+ if (keep2 > 0)
18668
+ this.blobs[keep2 - 1] = this.blobs[keep2 - 1].slice(0, size - (keep2 - 1) * CHUNK4);
17909
18669
  this.size = size;
17910
18670
  }
17911
18671
  };
@@ -18054,12 +18814,12 @@ function codeOf5(e) {
18054
18814
  return typeof code === "string" ? code : void 0;
18055
18815
  }
18056
18816
  function probe(secure, host, port, ms) {
18057
- return new Promise((resolve) => {
18817
+ return new Promise((resolve2) => {
18058
18818
  const socket = secure ? tls({ host, port, ...isIP(host) ? {} : { servername: host } }) : tcp({ host, port });
18059
18819
  const done4 = (code) => {
18060
18820
  clearTimeout(timer);
18061
18821
  socket.destroy();
18062
- resolve(code);
18822
+ resolve2(code);
18063
18823
  };
18064
18824
  const timer = setTimeout(() => done4("ETIMEDOUT"), ms);
18065
18825
  socket.once(secure ? "secureConnect" : "connect", () => done4("EPROTO"));
@@ -18151,8 +18911,8 @@ var RemoteTransport = class {
18151
18911
  }
18152
18912
  ask(call) {
18153
18913
  if (this.failure) return Promise.reject(this.failure);
18154
- return new Promise((resolve, reject) => {
18155
- this.waiting.set(call.nid, { resolve, reject });
18914
+ return new Promise((resolve2, reject) => {
18915
+ this.waiting.set(call.nid, { resolve: resolve2, reject });
18156
18916
  this.port.postMessage(call);
18157
18917
  });
18158
18918
  }
@@ -18332,7 +19092,7 @@ function dialStream(port, onClose) {
18332
19092
  write(chunk2) {
18333
19093
  if (closed) throw errorWithCode("EPIPE: the connection is closed");
18334
19094
  const copy = fresh(chunk2);
18335
- const acked = new Promise((resolve, reject) => acks.push({ resolve, reject }));
19095
+ const acked = new Promise((resolve2, reject) => acks.push({ resolve: resolve2, reject }));
18336
19096
  port.postMessage(copy, [copy.buffer]);
18337
19097
  return acked;
18338
19098
  },
@@ -18352,7 +19112,7 @@ function dialStream(port, onClose) {
18352
19112
 
18353
19113
  // src/client/loopback-fetch.ts
18354
19114
  var OWN_HEADERS = /* @__PURE__ */ new Set(["host", "connection", "content-length", "transfer-encoding"]);
18355
- var encoder6 = new TextEncoder();
19115
+ var encoder8 = new TextEncoder();
18356
19116
  var latin12 = new TextDecoder("latin1");
18357
19117
  var ByteSource = class {
18358
19118
  buffered = new Uint8Array(0);
@@ -18370,7 +19130,7 @@ var ByteSource = class {
18370
19130
  return true;
18371
19131
  }
18372
19132
  async until(marker) {
18373
- const needle = encoder6.encode(marker);
19133
+ const needle = encoder8.encode(marker);
18374
19134
  for (; ; ) {
18375
19135
  const at = indexOf(this.buffered, needle);
18376
19136
  if (at >= 0) return this.take(at + needle.length);
@@ -18381,13 +19141,13 @@ var ByteSource = class {
18381
19141
  if (this.buffered.length === 0 && !await this.more()) return void 0;
18382
19142
  return this.take(Math.min(max, this.buffered.length));
18383
19143
  }
18384
- async exactly(count) {
18385
- while (this.buffered.length < count) if (!await this.more()) return void 0;
18386
- return this.take(count);
19144
+ async exactly(count2) {
19145
+ while (this.buffered.length < count2) if (!await this.more()) return void 0;
19146
+ return this.take(count2);
18387
19147
  }
18388
- take(count) {
18389
- const out = this.buffered.slice(0, count);
18390
- this.buffered = this.buffered.slice(count);
19148
+ take(count2) {
19149
+ const out = this.buffered.slice(0, count2);
19150
+ this.buffered = this.buffered.slice(count2);
18391
19151
  return out;
18392
19152
  }
18393
19153
  };
@@ -18478,7 +19238,7 @@ async function requestBytes(request) {
18478
19238
  });
18479
19239
  if (body) lines2.push(`Content-Length: ${body.length}`);
18480
19240
  lines2.push("Connection: close", "", "");
18481
- const head = encoder6.encode(lines2.join("\r\n"));
19241
+ const head = encoder8.encode(lines2.join("\r\n"));
18482
19242
  const out = new Uint8Array(head.length + (body?.length ?? 0));
18483
19243
  out.set(head);
18484
19244
  if (body) out.set(body, head.length);
@@ -18532,8 +19292,8 @@ var KernelCallError = class extends Error {
18532
19292
  this.code = code;
18533
19293
  }
18534
19294
  };
18535
- var encoder7 = new TextEncoder();
18536
- var bytesOf2 = (data) => typeof data === "string" ? encoder7.encode(data) : data;
19295
+ var encoder9 = new TextEncoder();
19296
+ var bytesOf2 = (data) => typeof data === "string" ? encoder9.encode(data) : data;
18537
19297
  var UNAVAILABLE = {
18538
19298
  manualRedirects: false,
18539
19299
  encodedBodies: false,
@@ -18553,7 +19313,7 @@ async function holdLock(locks) {
18553
19313
  await granted2.promise;
18554
19314
  return { name: name2, release: () => held.resolve() };
18555
19315
  }
18556
- function concat6(chunks2) {
19316
+ function concat7(chunks2) {
18557
19317
  const out = new Uint8Array(chunks2.reduce((n, c) => n + c.length, 0));
18558
19318
  let at = 0;
18559
19319
  for (const chunk2 of chunks2) {
@@ -18604,8 +19364,8 @@ var Channel = class {
18604
19364
  const id2 = ++this.nextId;
18605
19365
  const { failure } = this;
18606
19366
  if (failure) return { id: id2, done: Promise.reject(failure) };
18607
- const done4 = new Promise((resolve, reject) => {
18608
- this.pending.set(id2, { resolve, reject, ...handlers });
19367
+ const done4 = new Promise((resolve2, reject) => {
19368
+ this.pending.set(id2, { resolve: resolve2, reject, ...handlers });
18609
19369
  this.port.postMessage({ ...call, id: id2 });
18610
19370
  });
18611
19371
  return { id: id2, done: done4 };
@@ -18743,7 +19503,7 @@ async function runOn(channel, argv, opts) {
18743
19503
  onStderr: tee(2, onStderr)
18744
19504
  });
18745
19505
  const { status, signal } = await child.ended;
18746
- const text = (fd) => new TextDecoder().decode(concat6(chunks2[fd]));
19506
+ const text = (fd) => new TextDecoder().decode(concat7(chunks2[fd]));
18747
19507
  return {
18748
19508
  pid: child.pid,
18749
19509
  status,
@@ -19022,10 +19782,10 @@ async function createNodeKernel(options = {}) {
19022
19782
  ...options.approve ? { approve: options.approve } : {}
19023
19783
  });
19024
19784
  await launcher.prepare();
19025
- const guard2 = (work) => new Promise((resolve, reject) => {
19785
+ const guard2 = (work) => new Promise((resolve2, reject) => {
19026
19786
  if (terminated) return reject(new Error(TERMINATED));
19027
19787
  pending.add(reject);
19028
- work().then(resolve, reject).finally(() => pending.delete(reject));
19788
+ work().then(resolve2, reject).finally(() => pending.delete(reject));
19029
19789
  });
19030
19790
  const decoder4 = new TextDecoder();
19031
19791
  return {