@ai-ecoverse/slicc-kernel 1.171.0 → 1.172.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.js CHANGED
@@ -2362,9 +2362,9 @@ var KernelSocket = class _KernelSocket {
2362
2362
  case SO_TYPE:
2363
2363
  return SOCK_STREAM;
2364
2364
  case SO_ERROR: {
2365
- const failed4 = this.failed;
2365
+ const failed5 = this.failed;
2366
2366
  this.failed = void 0;
2367
- return failed4 ? wasiErrno(failed4) : 0;
2367
+ return failed5 ? wasiErrno(failed5) : 0;
2368
2368
  }
2369
2369
  case SO_ACCEPTCONN:
2370
2370
  return this.state === "listening" ? 1 : 0;
@@ -2444,6 +2444,7 @@ var LoopbackNet = class {
2444
2444
  internal = /* @__PURE__ */ new Set();
2445
2445
  reserved = /* @__PURE__ */ new Set();
2446
2446
  facades = /* @__PURE__ */ new Map();
2447
+ proxyStamped;
2447
2448
  nextEphemeral = EPHEMERAL_FIRST;
2448
2449
  route;
2449
2450
  origins;
@@ -2518,9 +2519,15 @@ var LoopbackNet = class {
2518
2519
  this.kernelOnly(port, true);
2519
2520
  this.facades.set(port, name2);
2520
2521
  }
2521
- facadeAt(addr) {
2522
- if (addr.family !== "inet" || !isLoopback(canonicalHost(addr.host))) return void 0;
2523
- return this.facades.get(addr.port);
2522
+ stampProxy(port) {
2523
+ this.proxyStamped = port;
2524
+ }
2525
+ get originsStamped() {
2526
+ return this.proxyStamped !== void 0;
2527
+ }
2528
+ stampsPeers(addr) {
2529
+ if (addr.family !== "inet" || !isLoopback(canonicalHost(addr.host))) return false;
2530
+ return this.facades.has(addr.port) || this.proxyStamped === addr.port;
2524
2531
  }
2525
2532
  activate(addr, start2) {
2526
2533
  this.activators.set(keyOf(addr), start2);
@@ -3695,7 +3702,7 @@ function satisfies(version, range2) {
3695
3702
  }
3696
3703
 
3697
3704
  // src/version.ts
3698
- var KERNEL_VERSION = true ? "1.171.0" : "0.0.0-dev";
3705
+ var KERNEL_VERSION = true ? "1.172.1" : "0.0.0-dev";
3699
3706
  var OS_RELEASE = "6.0.0-slicc";
3700
3707
  function procVersion() {
3701
3708
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -4352,32 +4359,32 @@ function nextFire(schedule, after, utc = false) {
4352
4359
  }
4353
4360
  return null;
4354
4361
  }
4355
- function missedFires(schedule, from, until, utc = false, cap = MISSED_CAP) {
4362
+ function missedFires(schedule, from, until2, utc = false, cap = MISSED_CAP) {
4356
4363
  let count2 = 0;
4357
4364
  let last = null;
4358
4365
  let at = from;
4359
4366
  while (count2 < cap) {
4360
4367
  at = nextFire(schedule, at, utc);
4361
- if (at === null || at > until) return { count: count2, last, more: false };
4368
+ if (at === null || at > until2) return { count: count2, last, more: false };
4362
4369
  last = at;
4363
4370
  count2++;
4364
4371
  }
4365
4372
  const next3 = nextFire(schedule, last, utc);
4366
- if (next3 === null || next3 > until) return { count: count2, last, more: false };
4367
- return { count: count2, last: latestFire(schedule, last, until, utc), more: true };
4373
+ if (next3 === null || next3 > until2) return { count: count2, last, more: false };
4374
+ return { count: count2, last: latestFire(schedule, last, until2, utc), more: true };
4368
4375
  }
4369
- function latestFire(schedule, from, until, utc = false) {
4376
+ function latestFire(schedule, from, until2, utc = false) {
4370
4377
  let found = from;
4371
4378
  for (let span = 6e4; ; span *= 2) {
4372
- const start2 = Math.max(from, until - span);
4379
+ const start2 = Math.max(from, until2 - span);
4373
4380
  const first = nextFire(schedule, start2, utc);
4374
- if (first !== null && first <= until) {
4381
+ if (first !== null && first <= until2) {
4375
4382
  found = first;
4376
4383
  break;
4377
4384
  }
4378
4385
  if (start2 === from) return from;
4379
4386
  }
4380
- for (let at = nextFire(schedule, found, utc); at !== null && at <= until; ) {
4387
+ for (let at = nextFire(schedule, found, utc); at !== null && at <= until2; ) {
4381
4388
  found = at;
4382
4389
  at = nextFire(schedule, at, utc);
4383
4390
  }
@@ -5102,12 +5109,12 @@ var UnlinkedKeeper = class {
5102
5109
  return this.locks;
5103
5110
  }
5104
5111
  async undoing(op, peers, sends, heard, shared2 = []) {
5105
- let failed4;
5112
+ let failed5;
5106
5113
  let out;
5107
5114
  try {
5108
5115
  out = await op();
5109
5116
  } catch (err) {
5110
- failed4 = err ?? new Error("failed");
5117
+ failed5 = err ?? new Error("failed");
5111
5118
  await this.rollBackAsides(sends, shared2);
5112
5119
  }
5113
5120
  const hiddenShared = new Set(shared2.map((one) => one.hidden));
@@ -5128,7 +5135,7 @@ var UnlinkedKeeper = class {
5128
5135
  const done4 = () => one.release().then(() => this.dropIfLast(one.hidden));
5129
5136
  void Promise.all(waits.map(({ told }) => told)).then(done4, done4);
5130
5137
  }
5131
- if (failed4 !== void 0) throw failed4;
5138
+ if (failed5 !== void 0) throw failed5;
5132
5139
  return out;
5133
5140
  }
5134
5141
  async rollBackAsides(sends, shared2) {
@@ -5275,7 +5282,7 @@ var UnlinkedKeeper = class {
5275
5282
  // src/cron/clock.ts
5276
5283
  var systemCronClock = {
5277
5284
  now: () => Date.now(),
5278
- sleep(until, signal) {
5285
+ sleep(until2, signal) {
5279
5286
  if (signal.aborted) return Promise.resolve();
5280
5287
  return new Promise((resolve2) => {
5281
5288
  const done4 = () => {
@@ -5283,7 +5290,7 @@ var systemCronClock = {
5283
5290
  signal.removeEventListener("abort", done4);
5284
5291
  resolve2();
5285
5292
  };
5286
- const timer = setTimeout(done4, Math.max(0, until - Date.now()));
5293
+ const timer = setTimeout(done4, Math.max(0, until2 - Date.now()));
5287
5294
  timer.unref?.();
5288
5295
  signal.addEventListener("abort", done4, { once: true });
5289
5296
  });
@@ -5387,15 +5394,15 @@ var CronService = class {
5387
5394
  async pass() {
5388
5395
  if (this.wake.signal.aborted) this.wake = new AbortController();
5389
5396
  const wake = this.wake;
5390
- let until;
5397
+ let until2;
5391
5398
  try {
5392
- until = await this.tick();
5399
+ until2 = await this.tick();
5393
5400
  } catch (err) {
5394
5401
  await this.error(`cron: ${messageOf(err)}`);
5395
- until = this.clock.now() + WAKE_MS;
5402
+ until2 = this.clock.now() + WAKE_MS;
5396
5403
  }
5397
5404
  if (this.stopping.signal.aborted) return;
5398
- await this.clock.sleep(until, wake.signal);
5405
+ await this.clock.sleep(until2, wake.signal);
5399
5406
  }
5400
5407
  async provision() {
5401
5408
  const { fs, owners } = this.host;
@@ -5612,14 +5619,17 @@ var PLACEHOLDER_REFUSED = "refused: this request has a sealed placeholder in its
5612
5619
  var PlaceholderRefused = class extends Error {
5613
5620
  status = 403;
5614
5621
  code = "EACCES";
5615
- constructor() {
5616
- super(PLACEHOLDER_REFUSED);
5622
+ constructor(reason = PLACEHOLDER_REFUSED) {
5623
+ super(reason);
5617
5624
  }
5618
5625
  };
5619
- function carries(text) {
5626
+ function holds2(text, known) {
5627
+ return PLACEHOLDER.test(text) || known.some((placeholder) => text.includes(placeholder));
5628
+ }
5629
+ function carries(text, known) {
5620
5630
  let layer = text;
5621
5631
  for (let i = 0; i < PERCENT_LAYERS; i++) {
5622
- if (PLACEHOLDER.test(layer)) return true;
5632
+ if (holds2(layer, known)) return true;
5623
5633
  const next3 = layer.replace(
5624
5634
  ESCAPE,
5625
5635
  (_, hex4) => String.fromCharCode(Number.parseInt(hex4, 16))
@@ -5627,35 +5637,36 @@ function carries(text) {
5627
5637
  if (next3 === layer) return false;
5628
5638
  layer = next3;
5629
5639
  }
5630
- return PLACEHOLDER.test(layer);
5640
+ return holds2(layer, known);
5631
5641
  }
5632
- function basicCarries(value2) {
5642
+ function basicCarries(value2, known) {
5633
5643
  const credential = BASIC.exec(value2)?.[1];
5634
5644
  if (credential === void 0) return false;
5635
5645
  const letters = credential.replace(/[^A-Za-z0-9+/_-]/g, "").replaceAll("-", "+").replaceAll("_", "/");
5636
5646
  for (let shift = 0; shift < BASE64_GROUP; shift++) {
5637
5647
  const part = letters.slice(shift);
5638
5648
  const whole = part.length % BASE64_GROUP === 1 ? part.slice(0, -1) : part;
5639
- if (carries(atob(whole))) return true;
5649
+ if (carries(atob(whole), known)) return true;
5640
5650
  }
5641
5651
  return false;
5642
5652
  }
5643
- function headersCarry(headers) {
5653
+ function headersCarry(headers, known) {
5644
5654
  return headers.some(
5645
- ([name2, value2]) => carries(name2.toLowerCase()) || carries(value2) || basicCarries(value2)
5655
+ ([name2, value2]) => carries(name2, known) || carries(name2.toLowerCase(), known) || carries(value2, known) || basicCarries(value2, known)
5646
5656
  );
5647
5657
  }
5648
- function urlCarries(url) {
5649
- return carries(url) || URL.canParse(url) && carries(new URL(url).href);
5658
+ function urlCarries(url, known) {
5659
+ return carries(url, known) || URL.canParse(url) && carries(new URL(url).href, known);
5650
5660
  }
5651
- function refuse(request) {
5652
- if (urlCarries(request.url) || headersCarry(request.headers)) throw new PlaceholderRefused();
5661
+ function detected(request, known) {
5662
+ return urlCarries(request.url, known) || headersCarry(request.headers, known);
5653
5663
  }
5654
- function refuseSocket(request) {
5655
- refuse(request);
5656
- if (request.protocols.some(carries)) throw new PlaceholderRefused();
5664
+ function refuseSocket(request, known) {
5665
+ if (detected(request, known) || request.protocols.some((p) => carries(p, known))) {
5666
+ throw new PlaceholderRefused();
5667
+ }
5657
5668
  }
5658
- function placeholderFloor(inner) {
5669
+ function placeholderFloor(inner, { known = () => [], fill: fill2 } = {}) {
5659
5670
  const open = inner.websocket?.bind(inner);
5660
5671
  return {
5661
5672
  get traits() {
@@ -5663,13 +5674,14 @@ function placeholderFloor(inner) {
5663
5674
  },
5664
5675
  ...open ? {
5665
5676
  websocket: async (request) => {
5666
- refuseSocket(request);
5677
+ refuseSocket(request, known());
5667
5678
  return open(request);
5668
5679
  }
5669
5680
  } : {},
5670
- async fetch(request, owner) {
5671
- refuse(request);
5672
- return inner.fetch(request, owner);
5681
+ async fetch(request, owner, stamp) {
5682
+ if (!detected(request, known())) return inner.fetch(request, owner, stamp);
5683
+ if (!fill2 || !stamp) throw new PlaceholderRefused();
5684
+ return fill2(request, stamp);
5673
5685
  }
5674
5686
  };
5675
5687
  }
@@ -5910,14 +5922,14 @@ function tunnelTarget(req) {
5910
5922
  }
5911
5923
  return { host, port };
5912
5924
  }
5913
- async function watchHangup(conn, abort, until) {
5914
- while (!until.aborted && !abort.signal.aborted) {
5925
+ async function watchHangup(conn, abort, until2) {
5926
+ while (!until2.aborted && !abort.signal.aborted) {
5915
5927
  if (conn.poll().hangup) {
5916
5928
  abort.abort(new KernelError("EPIPE"));
5917
5929
  return;
5918
5930
  }
5919
5931
  try {
5920
- await conn.changed(until);
5932
+ await conn.changed(until2);
5921
5933
  } catch {
5922
5934
  return;
5923
5935
  }
@@ -6108,7 +6120,7 @@ var RealmProxy = class {
6108
6120
  const waiting = new AbortController();
6109
6121
  void watchHangup(ctx.socket, abort, waiting.signal);
6110
6122
  try {
6111
- response = await this.upstream(req, url, body, abort.signal, ctx.socket.peerCred?.pid);
6123
+ response = await this.upstream(req, url, body, abort.signal, ctx.socket);
6112
6124
  } finally {
6113
6125
  waiting.abort();
6114
6126
  }
@@ -6135,7 +6147,7 @@ var RealmProxy = class {
6135
6147
  await conn.write(latin1Bytes("HTTP/1.1 100 Continue\r\n\r\n"), this.stop.signal);
6136
6148
  }
6137
6149
  }
6138
- async upstream(req, url, body, signal, owner) {
6150
+ async upstream(req, url, body, signal, socket) {
6139
6151
  const sent = BODILESS_METHODS.has(req.method) ? void 0 : body;
6140
6152
  try {
6141
6153
  const fetching = this.options.transport.fetch(
@@ -6146,7 +6158,8 @@ var RealmProxy = class {
6146
6158
  ...sent instanceof Uint8Array ? { body: sent } : sent ? { bodyStream: sent } : {},
6147
6159
  signal
6148
6160
  },
6149
- owner
6161
+ socket.peerCred?.pid,
6162
+ socket.peerStamp
6150
6163
  );
6151
6164
  return await untilAborted(fetching, signal);
6152
6165
  } catch (e) {
@@ -6463,7 +6476,7 @@ async function relay(socket, conn) {
6463
6476
  // src/fs/attest.ts
6464
6477
  var ATTEST_MAX = 1024 * 1024;
6465
6478
  var UNOWNED = 1e3;
6466
- function refuse2(code, path, why) {
6479
+ function refuse(code, path, why) {
6467
6480
  throw Object.assign(new Error(`attest ${path}: ${why}`), { code });
6468
6481
  }
6469
6482
  function chainOf(path) {
@@ -6505,39 +6518,49 @@ async function trustedParents(fs, path, o) {
6505
6518
  const parents = [];
6506
6519
  for (const dir of chainOf(path).slice(0, -1)) {
6507
6520
  const st = await fs.lstat(dir);
6508
- if (st.isSymbolicLink) refuse2("EACCES", path, `${dir} is a symlink`);
6509
- if (!st.isDirectory) refuse2("ENOTDIR", path, `${dir} is not a directory`);
6521
+ if (st.isSymbolicLink) refuse("EACCES", path, `${dir} is a symlink`);
6522
+ if (!st.isDirectory) refuse("ENOTDIR", path, `${dir} is not a directory`);
6510
6523
  const perm = owned(dir, st);
6511
6524
  if (o.users !== "off" && (perm.uid !== 0 || (perm.mode & 18) !== 0)) {
6512
- refuse2("EACCES", path, `${dir} is not root-owned or is writable by group or others`);
6525
+ refuse("EACCES", path, `${dir} is not root-owned or is writable by group or others`);
6513
6526
  }
6514
6527
  parents.push(perm);
6515
6528
  }
6516
6529
  return parents;
6517
6530
  }
6531
+ function missing(e) {
6532
+ return e?.code === "ENOENT";
6533
+ }
6518
6534
  async function attest(fs, asked, o) {
6535
+ if (o.absent !== void 0 && o.absent !== "allow") {
6536
+ refuse("EINVAL", String(asked), "absent takes only allow");
6537
+ }
6519
6538
  if (typeof asked !== "string" || !asked.startsWith("/")) {
6520
- refuse2("EINVAL", String(asked), "not an absolute path");
6539
+ refuse("EINVAL", String(asked), "not an absolute path");
6521
6540
  }
6522
6541
  const path = normalizePath(asked);
6523
6542
  const mount = o.mounts.find((target) => {
6524
6543
  const at = normalizePath(target);
6525
6544
  return at === "/" || under(path, at);
6526
6545
  });
6527
- if (mount !== void 0) refuse2("EACCES", path, `under the mount ${mount}`);
6546
+ if (mount !== void 0) refuse("EACCES", path, `under the mount ${mount}`);
6528
6547
  const parents = await trustedParents(fs, path, o);
6529
6548
  for (let tries = 0; ; tries++) {
6530
- const before = await fs.lstat(path);
6531
- if (before.isSymbolicLink) refuse2("EACCES", path, "is a symlink");
6549
+ const before = await fs.lstat(path).catch((e) => {
6550
+ if (o.absent === "allow" && missing(e)) return void 0;
6551
+ throw e;
6552
+ });
6553
+ if (!before) return { path, absent: true, users: o.users, onRootFs: true, parents };
6554
+ if (before.isSymbolicLink) refuse("EACCES", path, "is a symlink");
6532
6555
  if (!before.isFile)
6533
- refuse2(before.isDirectory ? "EISDIR" : "EINVAL", path, "is not a regular file");
6534
- if (before.size > ATTEST_MAX) refuse2("EFBIG", path, `is over ${ATTEST_MAX} bytes`);
6556
+ refuse(before.isDirectory ? "EISDIR" : "EINVAL", path, "is not a regular file");
6557
+ if (before.size > ATTEST_MAX) refuse("EFBIG", path, `is over ${ATTEST_MAX} bytes`);
6535
6558
  const bytes = (await fs.readFileBuffer(path)).slice();
6536
6559
  const after = await fs.lstat(path);
6537
6560
  if (unchanged(before, after, bytes)) {
6538
6561
  return attested(path, after, bytes, await sha256(bytes), o, parents);
6539
6562
  }
6540
- if (tries >= 1) refuse2("EAGAIN", path, "changed while it was read");
6563
+ if (tries >= 1) refuse("EAGAIN", path, "changed while it was read");
6541
6564
  }
6542
6565
  }
6543
6566
  var WATCH_DEBOUNCE_MS = 50;
@@ -6708,7 +6731,7 @@ var S_IFREG = 32768;
6708
6731
  var COMMAND = /^\/(?:usr\/)?bin\/([^/]+)$/;
6709
6732
  var MAX_LINKS3 = 40;
6710
6733
  var BIN_ENTRY = /\/bin\/[^/]+$/;
6711
- function missing(err) {
6734
+ function missing2(err) {
6712
6735
  return err?.code === "ENOENT";
6713
6736
  }
6714
6737
  function synthetic(directory, path) {
@@ -6812,7 +6835,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6812
6835
  }
6813
6836
  async function entryTarget(path) {
6814
6837
  if (!BIN_ENTRY.test(path) || !(await virtual(path))?.isFile) return void 0;
6815
- if (!await fs.lstat(path).then(() => false, missing)) return void 0;
6838
+ if (!await fs.lstat(path).then(() => false, missing2)) return void 0;
6816
6839
  const target = await targetOf2(path);
6817
6840
  return target?.path === path ? void 0 : target;
6818
6841
  }
@@ -6824,11 +6847,11 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6824
6847
  return target?.path;
6825
6848
  }
6826
6849
  const absent2 = (err) => {
6827
- if (missing(err)) return EMPTY2;
6850
+ if (missing2(err)) return EMPTY2;
6828
6851
  throw err;
6829
6852
  };
6830
6853
  async function content(path, err) {
6831
- if (!missing(err) || !(await linked2(path))?.isFile) throw err;
6854
+ if (!missing2(err) || !(await linked2(path))?.isFile) throw err;
6832
6855
  const target = await redirected2(path);
6833
6856
  return target === void 0 ? EMPTY2 : fs.readFileBuffer(target).catch(absent2);
6834
6857
  }
@@ -6837,7 +6860,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6837
6860
  try {
6838
6861
  return await real(path);
6839
6862
  } catch (err) {
6840
- const found = missing(err) ? await linked2(path) : void 0;
6863
+ const found = missing2(err) ? await linked2(path) : void 0;
6841
6864
  if (found) return found;
6842
6865
  throw err;
6843
6866
  }
@@ -6862,7 +6885,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6862
6885
  const extra = await children3(path);
6863
6886
  if (!extra) return fs.readdir(path);
6864
6887
  const real = await fs.readdir(path).catch((err) => {
6865
- if (missing(err)) return [];
6888
+ if (missing2(err)) return [];
6866
6889
  throw err;
6867
6890
  });
6868
6891
  return [.../* @__PURE__ */ new Set([...real, ...extra])].sort();
@@ -6871,7 +6894,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6871
6894
  const extra = await children3(path);
6872
6895
  if (!extra) return fs.readdirStat(path);
6873
6896
  const real = await fs.readdirStat(path).catch((err) => {
6874
- if (missing(err)) return [];
6897
+ if (missing2(err)) return [];
6875
6898
  throw err;
6876
6899
  });
6877
6900
  const seen = new Set(real.map(([name2]) => name2));
@@ -6905,7 +6928,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6905
6928
  ...ranged2 ? {
6906
6929
  ...ranged2,
6907
6930
  pread: (path, offset, length2, version) => ranged2.pread(path, offset, length2, version).catch(async (err) => {
6908
- const target = missing(err) ? await redirected2(path) : void 0;
6931
+ const target = missing2(err) ? await redirected2(path) : void 0;
6909
6932
  if (target === void 0) throw err;
6910
6933
  return ranged2.pread(target, offset, length2).catch(absent2);
6911
6934
  })
@@ -6936,7 +6959,7 @@ var S_IFREG2 = 32768;
6936
6959
  var MAX_HOPS2 = 40;
6937
6960
  var parentOf3 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
6938
6961
  var baseOf = (path) => path.slice(path.lastIndexOf("/") + 1);
6939
- function missing2(err) {
6962
+ function missing3(err) {
6940
6963
  return err?.code === "ENOENT";
6941
6964
  }
6942
6965
  function statOf(path, bytes) {
@@ -6989,11 +7012,11 @@ function withEtcFiles(fs, files) {
6989
7012
  const text = files.get(path)?.();
6990
7013
  return text === void 0 ? void 0 : new TextEncoder().encode(text);
6991
7014
  };
6992
- const absent2 = (path) => fs.lstat(path).then(() => false, missing2);
7015
+ const absent2 = (path) => fs.lstat(path).then(() => false, missing3);
6993
7016
  const follow2 = linkFollower(fs, files);
6994
7017
  const listedAbsent = async (path) => files.has(path) && await absent2(path) ? bytesOf5(path) : void 0;
6995
7018
  const fallback = (path, make) => async (err) => {
6996
- const at = missing2(err) ? await follow2(path) : void 0;
7019
+ const at = missing3(err) ? await follow2(path) : void 0;
6997
7020
  const bytes = at === void 0 ? void 0 : await listedAbsent(at);
6998
7021
  if (bytes === void 0 || at === void 0) throw err;
6999
7022
  return make(bytes, at);
@@ -7203,7 +7226,7 @@ var MAX_LINKS4 = 40;
7203
7226
  function partsOf(path) {
7204
7227
  return path.split("/").filter((p) => p !== "" && p !== ".");
7205
7228
  }
7206
- function missing3(err) {
7229
+ function missing4(err) {
7207
7230
  const code = err?.code;
7208
7231
  return code === "ENOENT" || code === "ENOTDIR";
7209
7232
  }
@@ -7222,7 +7245,7 @@ async function resolved(fs, path, follow2, hops = []) {
7222
7245
  }
7223
7246
  const at = `/${[...done4, part].join("/")}`;
7224
7247
  const st = await fs.lstat(at).catch((err) => {
7225
- if (missing3(err)) return void 0;
7248
+ if (missing4(err)) return void 0;
7226
7249
  throw err;
7227
7250
  });
7228
7251
  if (!st) {
@@ -9451,29 +9474,29 @@ var HeldSet = class extends Set {
9451
9474
  this.idle = idle2;
9452
9475
  this.moved = moved2;
9453
9476
  }
9454
- add(holds2) {
9455
- holds2.onIdle = this.idle;
9456
- holds2.onMoved = this.moved;
9457
- return super.add(holds2);
9477
+ add(holds3) {
9478
+ holds3.onIdle = this.idle;
9479
+ holds3.onMoved = this.moved;
9480
+ return super.add(holds3);
9458
9481
  }
9459
9482
  doubt(paths, over) {
9460
- for (const holds2 of this) {
9461
- for (const path of paths) holds2.doubt(path, true);
9462
- if (over !== void 0) holds2.doubt(over);
9483
+ for (const holds3 of this) {
9484
+ for (const path of paths) holds3.doubt(path, true);
9485
+ if (over !== void 0) holds3.doubt(over);
9463
9486
  }
9464
9487
  }
9465
9488
  async bindIds(id2) {
9466
- for (const holds2 of [...this]) await holds2.bindIds(id2);
9489
+ for (const holds3 of [...this]) await holds3.bindIds(id2);
9467
9490
  }
9468
9491
  heldIds() {
9469
9492
  const out = /* @__PURE__ */ new Map();
9470
- for (const holds2 of this) for (const [path, fid] of holds2.heldIds()) out.set(path, fid);
9493
+ for (const holds3 of this) for (const [path, fid] of holds3.heldIds()) out.set(path, fid);
9471
9494
  return [...out];
9472
9495
  }
9473
- delete(holds2) {
9474
- const removed = super.delete(holds2);
9475
- for (const path of /* @__PURE__ */ new Set([...holds2.keys(), ...holds2.opens.keys()])) this.idle(path);
9476
- holds2.releaseAll();
9496
+ delete(holds3) {
9497
+ const removed = super.delete(holds3);
9498
+ for (const path of /* @__PURE__ */ new Set([...holds3.keys(), ...holds3.opens.keys()])) this.idle(path);
9499
+ holds3.releaseAll();
9477
9500
  return removed;
9478
9501
  }
9479
9502
  };
@@ -12364,9 +12387,9 @@ var SYS_TREE = {
12364
12387
  `,
12365
12388
  slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
12366
12389
  `,
12367
- slicc_peer_holds: ({ holds: holds2 }) => `${holds2?.mine ?? 0} ${holds2?.peers ?? 0} ${holds2?.sent ?? 0}
12390
+ slicc_peer_holds: ({ holds: holds3 }) => `${holds3?.mine ?? 0} ${holds3?.peers ?? 0} ${holds3?.sent ?? 0}
12368
12391
  `,
12369
- slicc_peer_held: ({ holds: holds2 }) => (holds2?.held ?? []).map((path) => `${path}
12392
+ slicc_peer_held: ({ holds: holds3 }) => (holds3?.held ?? []).map((path) => `${path}
12370
12393
  `).join(""),
12371
12394
  slicc_rename_acks: (listing) => {
12372
12395
  const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
@@ -13107,11 +13130,11 @@ var EpollFile = class _EpollFile {
13107
13130
  const round = new AbortController();
13108
13131
  const stop = () => round.abort();
13109
13132
  signal.addEventListener("abort", stop, { once: true });
13110
- let failed4 = false;
13133
+ let failed5 = false;
13111
13134
  try {
13112
13135
  await file.changed(round.signal);
13113
13136
  } catch {
13114
- failed4 = true;
13137
+ failed5 = true;
13115
13138
  } finally {
13116
13139
  round.abort();
13117
13140
  signal.removeEventListener("abort", stop);
@@ -13119,7 +13142,7 @@ var EpollFile = class _EpollFile {
13119
13142
  if (signal.aborted) return;
13120
13143
  reg.gen++;
13121
13144
  this.changes.wake();
13122
- if (failed4) await pause(RETRY_MS, signal);
13145
+ if (failed5) await pause(RETRY_MS, signal);
13123
13146
  }
13124
13147
  }
13125
13148
  };
@@ -14100,11 +14123,11 @@ function ipv6(host) {
14100
14123
  const back = halves.length === 2 ? groups(halves[1]) : [];
14101
14124
  if (![...head, ...back].every((g) => /^[0-9A-Fa-f]{1,4}$/.test(g))) return void 0;
14102
14125
  const words2 = [...head, ...back].map((g) => Number.parseInt(g, 16));
14103
- const missing5 = 8 - words2.length - tail2.length;
14104
- if (halves.length === 2 ? missing5 < 1 : missing5 !== 0) return void 0;
14126
+ const missing6 = 8 - words2.length - tail2.length;
14127
+ if (halves.length === 2 ? missing6 < 1 : missing6 !== 0) return void 0;
14105
14128
  const all = [
14106
14129
  ...head.map((g) => Number.parseInt(g, 16)),
14107
- ...new Array(halves.length === 2 ? missing5 : 0).fill(0),
14130
+ ...new Array(halves.length === 2 ? missing6 : 0).fill(0),
14108
14131
  ...back.map((g) => Number.parseInt(g, 16)),
14109
14132
  ...tail2
14110
14133
  ];
@@ -15101,10 +15124,12 @@ var HttpHandles = class {
15101
15124
  ws;
15102
15125
  owner;
15103
15126
  local;
15104
- constructor(transport, owner, local2) {
15127
+ stamp;
15128
+ constructor(transport, owner, local2, stamp) {
15105
15129
  this.transport = transport;
15106
15130
  this.owner = owner;
15107
15131
  this.local = local2;
15132
+ this.stamp = stamp;
15108
15133
  this.ws = new WsHandles(transport, () => ++this.nextHandle, local2);
15109
15134
  }
15110
15135
  syscall(req) {
@@ -15180,7 +15205,7 @@ var HttpHandles = class {
15180
15205
  ...entry.upload ? { bodyStream: entry.upload } : req.body ? { body: req.body } : {},
15181
15206
  signal: entry.abort.signal
15182
15207
  };
15183
- const response = port === void 0 ? await this.transport.fetch(request, this.owner) : await this.local.fetch(request, port);
15208
+ const response = port === void 0 ? await this.transport.fetch(request, this.owner, await this.stamp?.()) : await this.local.fetch(request, port);
15184
15209
  entry.body = response.body[Symbol.asyncIterator]();
15185
15210
  entry.cancel = () => response.cancel();
15186
15211
  if (!this.open.has(handle)) await entry.cancel().catch(() => void 0);
@@ -15202,8 +15227,8 @@ var HttpHandles = class {
15202
15227
  if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
15203
15228
  const code = codeOf2(e);
15204
15229
  const errno3 = text === NO_TRANSPORT ? "ENETUNREACH" : code !== "EIO" ? code : "ECONNREFUSED";
15205
- const failed4 = e.detail === "transport";
15206
- return { ok: false, errno: errno3, message: text, ...failed4 ? { detail: "transport" } : {} };
15230
+ const failed5 = e.detail === "transport";
15231
+ return { ok: false, errno: errno3, message: text, ...failed5 ? { detail: "transport" } : {} };
15207
15232
  }
15208
15233
  entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
15209
15234
  return this.headOf(handle, req.url, {
@@ -16998,7 +17023,7 @@ function pass(c, input, final) {
16998
17023
  const partials = [];
16999
17024
  scanMain(c, input, best, partials);
17000
17025
  scanWrapped(c, input, best, partials);
17001
- const holds2 = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
17026
+ const holds3 = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
17002
17027
  const starts = [...best.keys()].sort((a, b) => a - b);
17003
17028
  const parts2 = [];
17004
17029
  const hits = /* @__PURE__ */ new Map();
@@ -17008,8 +17033,8 @@ function pass(c, input, final) {
17008
17033
  let h = 0;
17009
17034
  for (; ; ) {
17010
17035
  while (s < starts.length && starts[s] < pos) s++;
17011
- while (h < holds2.length && holds2[h] < pos) h++;
17012
- const hold = h < holds2.length ? holds2[h] : Infinity;
17036
+ while (h < holds3.length && holds3[h] < pos) h++;
17037
+ const hold = h < holds3.length ? holds3[h] : Infinity;
17013
17038
  const next3 = s < starts.length ? starts[s] : Infinity;
17014
17039
  if (hold <= next3) {
17015
17040
  cut = Math.min(hold, input.length);
@@ -17111,23 +17136,23 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
17111
17136
  let pending = 0;
17112
17137
  let busy = false;
17113
17138
  let timer;
17114
- let failed4;
17139
+ let failed5;
17115
17140
  const waiters = /* @__PURE__ */ new Set();
17116
17141
  const quiet3 = () => !busy && pending === 0;
17117
17142
  const wake = () => {
17118
17143
  for (const waiter of [...waiters]) waiter();
17119
17144
  };
17120
17145
  const raise = () => {
17121
- if (failed4 === void 0) return;
17122
- const err = failed4;
17123
- failed4 = void 0;
17146
+ if (failed5 === void 0) return;
17147
+ const err = failed5;
17148
+ failed5 = void 0;
17124
17149
  throw err;
17125
17150
  };
17126
17151
  const later = (bytes) => {
17127
17152
  if (bytes.length === 0) return;
17128
17153
  pending += 1;
17129
17154
  tail2 = tail2.then(() => writeAll2(file, bytes)).catch((err) => {
17130
- if (failed4 === void 0) failed4 = err;
17155
+ if (failed5 === void 0) failed5 = err;
17131
17156
  }).finally(() => {
17132
17157
  pending -= 1;
17133
17158
  if (quiet3()) wake();
@@ -20202,7 +20227,7 @@ async function connect(req, proc) {
20202
20227
  }
20203
20228
  const path = filePath(req.addr);
20204
20229
  const name2 = path !== void 0 ? await proc.names?.find(path) : void 0;
20205
- const stamp = proc.net.facadeAt(req.addr) && await proc.stamp?.();
20230
+ const stamp = proc.net.stampsPeers(req.addr) && await proc.stamp?.();
20206
20231
  const dialing = target.connect(req.addr, true, proc.cred?.(), stamp || void 0, true, name2);
20207
20232
  if (req.nonblock) {
20208
20233
  dialing?.catch(() => void 0);
@@ -20324,7 +20349,7 @@ async function secureConnect(req, proc) {
20324
20349
  delete req.clientCert;
20325
20350
  throw new KernelError("ENOTSUP");
20326
20351
  }
20327
- return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
20352
+ return { ...await tlsOverTransport(req, proc), path: "transport", substitutes: true };
20328
20353
  }
20329
20354
  const socket = proc.net.socket("inet");
20330
20355
  const fd = proc.fds.install(new OpenFile(socket), 3);
@@ -20343,7 +20368,7 @@ async function uplinked(proc, host) {
20343
20368
  return false;
20344
20369
  }
20345
20370
  }
20346
- function tlsOverTransport(req, proc) {
20371
+ async function tlsOverTransport(req, proc) {
20347
20372
  if (req.ca) throw new KernelError("ENOTSUP");
20348
20373
  if (req.alpn && req.alpn.length > 0 && !req.alpn.includes("http/1.1")) {
20349
20374
  throw new KernelError("EPROTONOSUPPORT");
@@ -20356,7 +20381,9 @@ function tlsOverTransport(req, proc) {
20356
20381
  if (isLoopbackHost(servername) || isLoopbackHost(req.host)) throw new KernelError("ENOTSUP");
20357
20382
  const host = servername.includes(":") && !servername.startsWith("[") ? `[${servername}]` : servername;
20358
20383
  const origin = req.port === 443 ? `https://${host}` : `https://${host}:${req.port}`;
20384
+ const stamp = proc.net.originsStamped ? await proc.stamp?.() : void 0;
20359
20385
  const [mine, theirs] = KernelSocket.pair(proc.net, "inet", proc.cred?.());
20386
+ theirs.peerStamp = stamp;
20360
20387
  mine.peer = { family: "inet", host: req.host, port: req.port };
20361
20388
  try {
20362
20389
  proc.net.serveOrigin(theirs, origin);
@@ -23515,13 +23542,13 @@ function inherited(opts) {
23515
23542
  ...opts.cred ? { cred: opts.cred } : {}
23516
23543
  };
23517
23544
  }
23518
- function heldBy(process2, holds2, replacements) {
23519
- process2.keptPath = (path) => holds2.keptAt(path)?.hidden;
23520
- process2.keptHandle = (handle) => holds2.keptFor(handle)?.hidden;
23521
- process2.holdsHandle = (handle) => holds2.holdsHandle(handle);
23545
+ function heldBy(process2, holds3, replacements) {
23546
+ process2.keptPath = (path) => holds3.keptAt(path)?.hidden;
23547
+ process2.keptHandle = (handle) => holds3.keptFor(handle)?.hidden;
23548
+ process2.holdsHandle = (handle) => holds3.holdsHandle(handle);
23522
23549
  if (replacements) process2.replacements = replacements;
23523
23550
  }
23524
- function holdingToken(opts, holds2, caller) {
23551
+ function holdingToken(opts, holds3, caller) {
23525
23552
  return mintSyncFsToken({
23526
23553
  ...opts.owners ? caller : { umask: caller.umask },
23527
23554
  ...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
@@ -23538,16 +23565,16 @@ function holdingToken(opts, holds2, caller) {
23538
23565
  ...opts.fileId ? { fileId: opts.fileId } : {},
23539
23566
  ...opts.announceHold ? { announceHold: opts.announceHold } : {},
23540
23567
  ...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
23541
- hold: (path, on, open, real, handle, ino, fid) => holds2.hold(path, on, open, real, handle, ino, fid),
23542
- boundIno: holds2.boundIno.bind(holds2),
23543
- trust: holds2.trust.bind(holds2),
23544
- keptFor: (handle) => holds2.keptFor(handle),
23545
- heldAt: (handle) => holds2.pathOf(handle),
23546
- unlinked: (path) => holds2.keptAt(path),
23547
- gate: (path, op) => opts.unlinkGate && holds2.holding(path) ? opts.unlinkGate.run(holds2.keyOf(path), op) : op(),
23548
- own: (path, op) => holds2.own(path, op),
23549
- revoked: (path) => holds2.isRevoked(path),
23550
- renamed: (from, to) => holds2.renamed(from, to)
23568
+ hold: (path, on, open, real, handle, ino, fid) => holds3.hold(path, on, open, real, handle, ino, fid),
23569
+ boundIno: holds3.boundIno.bind(holds3),
23570
+ trust: holds3.trust.bind(holds3),
23571
+ keptFor: (handle) => holds3.keptFor(handle),
23572
+ heldAt: (handle) => holds3.pathOf(handle),
23573
+ unlinked: (path) => holds3.keptAt(path),
23574
+ gate: (path, op) => opts.unlinkGate && holds3.holding(path) ? opts.unlinkGate.run(holds3.keyOf(path), op) : op(),
23575
+ own: (path, op) => holds3.own(path, op),
23576
+ revoked: (path) => holds3.isRevoked(path),
23577
+ renamed: (from, to) => holds3.renamed(from, to)
23551
23578
  });
23552
23579
  }
23553
23580
  function linksOf(opts) {
@@ -23704,15 +23731,15 @@ function spawnWasmProcess(opts) {
23704
23731
  )
23705
23732
  );
23706
23733
  publishStops(process2, header5);
23707
- const holds2 = new HeldPaths();
23708
- opts.held?.add(holds2);
23709
- const token = holdingToken(opts, holds2, {
23734
+ const holds3 = new HeldPaths();
23735
+ opts.held?.add(holds3);
23736
+ const token = holdingToken(opts, holds3, {
23710
23737
  cred: () => process2.cred,
23711
23738
  umask: () => process2.umask,
23712
23739
  created: created4,
23713
- holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds2.keeps(path) || await process2.holds(path))
23740
+ holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds3.keeps(path) || await process2.holds(path))
23714
23741
  });
23715
- heldBy(process2, holds2, opts.replacements);
23742
+ heldBy(process2, holds3, opts.replacements);
23716
23743
  const worker = opts.createWorker();
23717
23744
  const dying = new Dying();
23718
23745
  const dispatch2 = (req, block) => dying.serve(
@@ -23744,7 +23771,7 @@ function spawnWasmProcess(opts) {
23744
23771
  responder.dispose();
23745
23772
  lane?.dispose();
23746
23773
  revokeSyncFsToken(token);
23747
- opts.held?.delete(holds2);
23774
+ opts.held?.delete(holds3);
23748
23775
  worker.terminate();
23749
23776
  settleExit(process2.exit(), settle, code);
23750
23777
  };
@@ -24310,10 +24337,10 @@ var RemoteWatch = class {
24310
24337
  });
24311
24338
  }
24312
24339
  }
24313
- heldBy({ tab, holds: holds2, seq: seq2 }) {
24340
+ heldBy({ tab, holds: holds3, seq: seq2 }) {
24314
24341
  const from = tab;
24315
- const { add, drop } = holds2;
24316
- if (holds2?.instance !== void 0) this.instances.set(from, holds2.instance);
24342
+ const { add, drop } = holds3;
24343
+ if (holds3?.instance !== void 0) this.instances.set(from, holds3.instance);
24317
24344
  const held = this.peerHolds.get(from) ?? /* @__PURE__ */ new Map();
24318
24345
  for (const path of drop) held.delete(path);
24319
24346
  for (const [path, fid] of add) held.set(path, fid);
@@ -25365,7 +25392,7 @@ var RemoteTransport = class {
25365
25392
  waiter?.reject(new TransportError("the request was cancelled"));
25366
25393
  this.port.postMessage({ net: "cancel", nid });
25367
25394
  }
25368
- async fetch(request) {
25395
+ async fetch(request, owner, stamp) {
25369
25396
  const nid = ++this.nextId;
25370
25397
  const { signal, redirect } = request;
25371
25398
  signal.throwIfAborted();
@@ -25395,7 +25422,9 @@ var RemoteTransport = class {
25395
25422
  method: request.method,
25396
25423
  headers: request.headers,
25397
25424
  ...request.bodyStream ? { streamed: true } : request.body ? { body: request.body } : {},
25398
- ...redirect !== void 0 ? { redirect } : {}
25425
+ ...redirect !== void 0 ? { redirect } : {},
25426
+ ...owner !== void 0 ? { owner } : {},
25427
+ ...stamp ? { stamp } : {}
25399
25428
  });
25400
25429
  } catch (e) {
25401
25430
  finish();
@@ -25586,6 +25615,173 @@ function replayingHops(inner, heldMs = HELD_MS) {
25586
25615
  };
25587
25616
  }
25588
25617
 
25618
+ // src/body-idle.ts
25619
+ var BODY_IDLE_MS = 5 * 60 * 1e3;
25620
+ function idleFailure(ms) {
25621
+ return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {
25622
+ code: "ETIMEDOUT"
25623
+ });
25624
+ }
25625
+ async function readWithin(reader, ms) {
25626
+ if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();
25627
+ let timer;
25628
+ const idle2 = new Promise((_, reject) => {
25629
+ timer = setTimeout(() => reject(idleFailure(ms)), ms);
25630
+ });
25631
+ try {
25632
+ return await Promise.race([reader.read(), idle2]);
25633
+ } finally {
25634
+ clearTimeout(timer);
25635
+ }
25636
+ }
25637
+
25638
+ // src/kernel/net/sealed-fetch.ts
25639
+ var SEALED_FETCH_VERSION = 1;
25640
+ var UNSAFE_FIELD = /[\r\n\0]/;
25641
+ function sealedHooks(option) {
25642
+ if (!option) return {};
25643
+ if (typeof option === "function") return { request: option };
25644
+ const { request, fetch: fetch2 } = option;
25645
+ if (typeof request !== "function" || fetch2 !== void 0 && typeof fetch2 !== "function") {
25646
+ throw new TypeError("sealed takes a function or { request, fetch? }");
25647
+ }
25648
+ return { request, ...fetch2 ? { fetch: fetch2 } : {} };
25649
+ }
25650
+ function headerList(headers) {
25651
+ return Array.isArray(headers) && headers.every(
25652
+ (field4) => Array.isArray(field4) && field4.length === 2 && field4.every((text) => typeof text === "string" && !UNSAFE_FIELD.test(text))
25653
+ );
25654
+ }
25655
+ function sealedReplyValid(reply) {
25656
+ if (typeof reply !== "object" || reply === null) return false;
25657
+ const { redirects, redirected: redirected2, status, statusText, headers, url, body, cancel } = reply;
25658
+ return redirects === void 0 && redirected2 !== true && Number.isInteger(status) && status >= 100 && status <= 599 && typeof statusText === "string" && !UNSAFE_FIELD.test(statusText) && headerList(headers) && (url === void 0 || typeof url === "string") && typeof body?.[Symbol.asyncIterator] === "function" && typeof cancel === "function";
25659
+ }
25660
+ function dropSealedReply(reply) {
25661
+ const { cancel } = reply ?? {};
25662
+ if (typeof cancel !== "function") return;
25663
+ void Promise.resolve().then(() => cancel.call(reply)).catch(() => void 0);
25664
+ }
25665
+ function failed2(reason) {
25666
+ const text = reason instanceof Error ? reason.message : String(reason);
25667
+ return new PlaceholderRefused(
25668
+ `refused: the request with a sealed placeholder was not completed: ${text}`
25669
+ );
25670
+ }
25671
+ var Stall = class {
25672
+ idle = new AbortController();
25673
+ ms;
25674
+ timer;
25675
+ signal;
25676
+ constructor(signals, ms) {
25677
+ this.ms = ms;
25678
+ this.signal = AbortSignal.any([...signals, this.idle.signal]);
25679
+ }
25680
+ arm() {
25681
+ clearTimeout(this.timer);
25682
+ this.timer = setTimeout(() => this.idle.abort("timeout"), this.ms);
25683
+ this.timer.unref?.();
25684
+ }
25685
+ touch() {
25686
+ if (this.timer !== void 0) this.arm();
25687
+ }
25688
+ rest() {
25689
+ clearTimeout(this.timer);
25690
+ this.timer = void 0;
25691
+ }
25692
+ };
25693
+ async function until(work, signal) {
25694
+ const stopped = Promise.withResolvers();
25695
+ const stop = () => stopped.reject(signal.reason);
25696
+ if (signal.aborted) stop();
25697
+ else signal.addEventListener("abort", stop, { once: true });
25698
+ try {
25699
+ return await Promise.race([work, stopped.promise]);
25700
+ } finally {
25701
+ signal.removeEventListener("abort", stop);
25702
+ }
25703
+ }
25704
+ async function* ticking(stream2, stall) {
25705
+ for await (const chunk2 of stream2) {
25706
+ stall.touch();
25707
+ yield chunk2;
25708
+ }
25709
+ }
25710
+ function sealedRequest(request, stamp, stall) {
25711
+ const { method, url, headers, body, bodyStream: bodyStream2 } = request;
25712
+ return {
25713
+ v: 1,
25714
+ caller: structuredClone(stamp),
25715
+ method,
25716
+ url,
25717
+ headers: headers.map(([name2, value2]) => [name2, value2]),
25718
+ redirect: "manual",
25719
+ ...bodyStream2 ? { bodyStream: ticking(bodyStream2, stall) } : body ? { body } : {}
25720
+ };
25721
+ }
25722
+ function guarded2(reply, stall) {
25723
+ let finished = false;
25724
+ const cancel = async () => {
25725
+ stall.signal.removeEventListener("abort", dropped2);
25726
+ stall.rest();
25727
+ if (finished) return;
25728
+ finished = true;
25729
+ await reply.cancel().catch(() => void 0);
25730
+ };
25731
+ const dropped2 = () => void cancel();
25732
+ stall.signal.addEventListener("abort", dropped2, { once: true });
25733
+ const source = reply.body[Symbol.asyncIterator]();
25734
+ const body = (async function* () {
25735
+ try {
25736
+ for (; ; ) {
25737
+ stall.arm();
25738
+ const next3 = await until(source.next(), stall.signal);
25739
+ stall.rest();
25740
+ if (next3.done) {
25741
+ finished = true;
25742
+ return;
25743
+ }
25744
+ if (!(next3.value instanceof Uint8Array)) throw failed2("a body chunk is not bytes");
25745
+ if (next3.value.byteLength > 0) yield next3.value;
25746
+ }
25747
+ } finally {
25748
+ await cancel();
25749
+ }
25750
+ })();
25751
+ return {
25752
+ ...reply.url !== void 0 ? { url: reply.url } : {},
25753
+ status: reply.status,
25754
+ statusText: reply.statusText,
25755
+ headers: reply.headers,
25756
+ body,
25757
+ cancel
25758
+ };
25759
+ }
25760
+ function sealedFetcher(hook, stop, idleMs = BODY_IDLE_MS) {
25761
+ return async (request, stamp) => {
25762
+ const stall = new Stall([request.signal, stop], idleMs);
25763
+ const { signal } = stall;
25764
+ if (signal.aborted) throw failed2(signal.reason);
25765
+ stall.arm();
25766
+ const asked = Promise.resolve().then(() => {
25767
+ signal.throwIfAborted();
25768
+ return hook(sealedRequest(request, stamp, stall), { signal });
25769
+ });
25770
+ let reply;
25771
+ try {
25772
+ reply = await until(asked, signal);
25773
+ } catch (e) {
25774
+ void asked.then(dropSealedReply, () => void 0);
25775
+ throw failed2(e);
25776
+ } finally {
25777
+ stall.rest();
25778
+ }
25779
+ if (sealedReplyValid(reply)) return guarded2(reply, stall);
25780
+ dropSealedReply(reply);
25781
+ throw failed2("the reply is not a scrubbed response");
25782
+ };
25783
+ }
25784
+
25589
25785
  // src/kernel/package-swaps.ts
25590
25786
  var SWAP_GAP_MS = 2e3;
25591
25787
  var STAGES = ["_tmp_", "_pacquet-stage_"];
@@ -25758,11 +25954,11 @@ var PackageLocks = class {
25758
25954
  if (!locks) return Promise.resolve(() => {
25759
25955
  });
25760
25956
  const { promise: held, resolve: release } = Promise.withResolvers();
25761
- return new Promise((granted2, failed4) => {
25957
+ return new Promise((granted2, failed5) => {
25762
25958
  locks.request(replacingLock(this.metadata, root), { mode: "exclusive" }, () => {
25763
25959
  granted2(() => release());
25764
25960
  return held;
25765
- }).catch(failed4);
25961
+ }).catch(failed5);
25766
25962
  });
25767
25963
  }
25768
25964
  };
@@ -26146,11 +26342,11 @@ var META_OPS = ["get", "update", "move", "remove", "links", "under", "all"];
26146
26342
  var FILE_ID_TRIES = 3;
26147
26343
  function sidecar(meta) {
26148
26344
  const pathOf = ([first]) => [first, "/"].flat().find((p) => typeof p === "string");
26149
- const guarded3 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
26345
+ const guarded4 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
26150
26346
  throw translate(err, pathOf(args), "sidecar", false);
26151
26347
  });
26152
26348
  const names2 = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
26153
- const ops = Object.fromEntries(names2.map((op) => [op, guarded3(op)]));
26349
+ const ops = Object.fromEntries(names2.map((op) => [op, guarded4(op)]));
26154
26350
  const { updateMany } = meta;
26155
26351
  ops.updateMany = updateMany ? (changes) => updateMany.call(meta, changes).catch((err) => {
26156
26352
  throw translate(err, changes[0]?.path ?? "/", "sidecar", false);
@@ -26174,7 +26370,7 @@ function occupied(entry) {
26174
26370
  function vacatedAt(path) {
26175
26371
  return { path, ino: inodeOf(`${path}\0${crypto.randomUUID()}`), vacated: true };
26176
26372
  }
26177
- function missing4(err) {
26373
+ function missing5(err) {
26178
26374
  const code = err?.code;
26179
26375
  return code === "ENOENT" || code === "ENOTDIR";
26180
26376
  }
@@ -26417,7 +26613,7 @@ var OpfsFs = class {
26417
26613
  if (there) return (await this.meta.get([found.path]))[0]?.fid ?? fid;
26418
26614
  const gone = await this.locate(found.path, true).then(
26419
26615
  () => false,
26420
- (err) => missing4(err)
26616
+ (err) => missing5(err)
26421
26617
  );
26422
26618
  if (gone) {
26423
26619
  await this.meta.update(found.path, (now) => {
@@ -26860,7 +27056,7 @@ var OpfsFs = class {
26860
27056
  try {
26861
27057
  return await op();
26862
27058
  } catch (err) {
26863
- if (attempt >= REPLACED_ATTEMPTS || !missing4(err)) throw err;
27059
+ if (attempt >= REPLACED_ATTEMPTS || !missing5(err)) throw err;
26864
27060
  await this.replacing;
26865
27061
  if (this.replacements === seen) throw err;
26866
27062
  }
@@ -26872,7 +27068,7 @@ var OpfsFs = class {
26872
27068
  try {
26873
27069
  return { path: current, handle: await this.handle(current) };
26874
27070
  } catch (err) {
26875
- if (!missing4(err)) throw err;
27071
+ if (!missing5(err)) throw err;
26876
27072
  const link2 = await this.linkAlong(current);
26877
27073
  if (!link2) throw err;
26878
27074
  if (link2.path === current && !follow2) return { path: current, link: link2 };
@@ -27108,7 +27304,7 @@ var OpfsFs = class {
27108
27304
  return this.locate(path, true).then(
27109
27305
  () => true,
27110
27306
  (err) => {
27111
- if (missing4(err)) return false;
27307
+ if (missing5(err)) return false;
27112
27308
  throw err;
27113
27309
  }
27114
27310
  );
@@ -27405,7 +27601,7 @@ var OpfsFs = class {
27405
27601
  try {
27406
27602
  return [(await this.locate(path, true)).path, true];
27407
27603
  } catch (err) {
27408
- if (!missing4(err)) throw err;
27604
+ if (!missing5(err)) throw err;
27409
27605
  }
27410
27606
  const [entry] = await this.meta.get([path]);
27411
27607
  const wanted = entry?.link === void 0 ? path : resolvePath(parentOf9(path), entry.link);
@@ -27497,7 +27693,7 @@ var OpfsFs = class {
27497
27693
  try {
27498
27694
  found = await this.exactly(() => this.locate(path, true));
27499
27695
  } catch (err) {
27500
- if (!missing4(err)) throw err;
27696
+ if (!missing5(err)) throw err;
27501
27697
  }
27502
27698
  if (found) {
27503
27699
  const directory = found.handle?.kind === "directory";
@@ -27633,7 +27829,7 @@ var OpfsFs = class {
27633
27829
  const taken = await this.exactly(() => this.lstat(to)).then(
27634
27830
  () => true,
27635
27831
  (err) => {
27636
- if (missing4(err)) return false;
27832
+ if (missing5(err)) return false;
27637
27833
  throw err;
27638
27834
  }
27639
27835
  );
@@ -27665,7 +27861,7 @@ var OpfsFs = class {
27665
27861
  const sourceStat = await this.describe(source);
27666
27862
  if (sourceStat.isDirectory && within9(destination, source.path)) throw fsError("EINVAL", to);
27667
27863
  const target = await this.exactly(() => this.locate(destination, false)).catch((err) => {
27668
- if (missing4(err)) return null;
27864
+ if (missing5(err)) return null;
27669
27865
  throw err;
27670
27866
  });
27671
27867
  const targetStat = target && await this.describe(target);
@@ -28256,12 +28452,12 @@ var OpfsFs = class {
28256
28452
  if (!move) return false;
28257
28453
  for (let attempt = 0; ; attempt++) {
28258
28454
  this.others++;
28259
- const failed4 = await move.call(handle, dir, name2).then(
28455
+ const failed5 = await move.call(handle, dir, name2).then(
28260
28456
  () => void 0,
28261
28457
  (err) => ({ err })
28262
28458
  );
28263
- if (!failed4) return true;
28264
- const error = failed4.err?.name;
28459
+ if (!failed5) return true;
28460
+ const error = failed5.err?.name;
28265
28461
  if (handle.kind !== "file" || !LOCKED.has(error)) return false;
28266
28462
  const delay2 = SYNC_BACKOFF_MS[attempt];
28267
28463
  if (delay2 === void 0) throw fsError("EBUSY", name2);
@@ -28302,7 +28498,7 @@ var OpfsFs = class {
28302
28498
  this.refuse(at);
28303
28499
  if (await this.exactly(() => this.locate(at, false)).then(
28304
28500
  () => true,
28305
- (err) => !missing4(err)
28501
+ (err) => !missing5(err)
28306
28502
  )) {
28307
28503
  throw fsError("EEXIST", path);
28308
28504
  }
@@ -28824,22 +29020,22 @@ async function mountFstab(lines2, mount, signal, retries = FSTAB_RETRIES, discar
28824
29020
  );
28825
29021
  }
28826
29022
  async function mountLine({ line, spec, invalid }, mount, signal, retries, discard) {
28827
- let failed4 = invalid;
29023
+ let failed5 = invalid;
28828
29024
  for (let attempt = 0; !invalid && attempt <= retries.length && !signal.aborted; attempt++) {
28829
29025
  try {
28830
29026
  const entry = await mount(spec);
28831
29027
  if (!signal.aborted) return { line, target: spec.target, entry };
28832
29028
  discard(entry);
28833
- failed4 = Object.assign(new Error("the kernel stopped"), { code: "ECANCELED" });
29029
+ failed5 = Object.assign(new Error("the kernel stopped"), { code: "ECANCELED" });
28834
29030
  break;
28835
29031
  } catch (err) {
28836
- failed4 = err;
29032
+ failed5 = err;
28837
29033
  if (FINAL.has(codeOf6(err)) || attempt === retries.length) break;
28838
29034
  await wait(retries[attempt], signal);
28839
29035
  }
28840
29036
  }
28841
- const code = codeOf6(failed4);
28842
- return { line, target: spec.target, code, error: String(failed4?.message ?? code) };
29037
+ const code = codeOf6(failed5);
29038
+ return { line, target: spec.target, code, error: String(failed5?.message ?? code) };
28843
29039
  }
28844
29040
 
28845
29041
  // src/mount/hostfs.ts
@@ -30441,7 +30637,7 @@ var RULE = new RegExp(
30441
30637
  var TERM = /^[A-Za-z0-9._+-]+$/;
30442
30638
  var PLAIN3 = /^[A-Za-z0-9_@%+=:,./-]+$/;
30443
30639
  var USAGE = "usage: sudo [-n] [-u user] [--] command [args...]\n sudo -l";
30444
- function failed2(errno3, error) {
30640
+ function failed3(errno3, error) {
30445
30641
  return { error, errno: errno3 };
30446
30642
  }
30447
30643
  function unescaped(double) {
@@ -30620,10 +30816,10 @@ var Sudo = class {
30620
30816
  }
30621
30817
  async untrusted(path, cwd, word) {
30622
30818
  const files = this.o.backing ? await this.o.backing(path, cwd) : [];
30623
- if (!files) return failed2("ENOENT", `sudo: ${word}: command not found`);
30819
+ if (!files) return failed3("ENOENT", `sudo: ${word}: command not found`);
30624
30820
  for (const file of [path, ...files]) {
30625
30821
  if (!await this.trusted(file)) {
30626
- return failed2("EPERM", `sudo: ${file} must be root's, and writable by root only`);
30822
+ return failed3("EPERM", `sudo: ${file} must be root's, and writable by root only`);
30627
30823
  }
30628
30824
  }
30629
30825
  return void 0;
@@ -30640,7 +30836,7 @@ var Sudo = class {
30640
30836
  }
30641
30837
  async request(caller, call, signal) {
30642
30838
  const parsed2 = parseArgs(call.args);
30643
- if (typeof parsed2 === "string") return failed2("EINVAL", parsed2);
30839
+ if (typeof parsed2 === "string") return failed3("EINVAL", parsed2);
30644
30840
  if (this.o.mode !== "enforce") {
30645
30841
  const mode = this.o.mode;
30646
30842
  if (parsed2.list) return { list: `sudo: users are '${mode}': commands run as the caller
@@ -30649,9 +30845,9 @@ var Sudo = class {
30649
30845
  }
30650
30846
  const { cred } = caller;
30651
30847
  const self = await this.o.users.lookup(cred.ruid);
30652
- if (!self) return failed2("EPERM", `sudo: uid ${cred.ruid} is not in the passwd database`);
30848
+ if (!self) return failed3("EPERM", `sudo: uid ${cred.ruid} is not in the passwd database`);
30653
30849
  const target = await this.lookup(parsed2.user);
30654
- if (!target) return failed2("ENOENT", `sudo: unknown user ${parsed2.user}`);
30850
+ if (!target) return failed3("ENOENT", `sudo: unknown user ${parsed2.user}`);
30655
30851
  const root = cred.euid === 0;
30656
30852
  const rules = root ? [] : await this.policy();
30657
30853
  const applies = await this.applies(self, cred);
@@ -30659,13 +30855,13 @@ var Sudo = class {
30659
30855
  const [word = "", ...args] = parsed2.command;
30660
30856
  const cwd = await this.canonical(call.cwd);
30661
30857
  if (cwd === void 0 || !await this.reachable(cred, cwd)) {
30662
- return failed2(
30858
+ return failed3(
30663
30859
  "EACCES",
30664
30860
  `sudo: cannot run in ${call.cwd}: it isn't a directory you can enter`
30665
30861
  );
30666
30862
  }
30667
30863
  const path = await this.locate(word, cwd);
30668
- if (!path) return failed2("ENOENT", `sudo: ${word}: command not found`);
30864
+ if (!path) return failed3("ENOENT", `sudo: ${word}: command not found`);
30669
30865
  const untrusted2 = await this.untrusted(path, cwd, word);
30670
30866
  if (untrusted2) return untrusted2;
30671
30867
  const argv = [path, ...args];
@@ -30676,24 +30872,24 @@ var Sudo = class {
30676
30872
  if (root || matching.some((rule) => rule.nopasswd)) return grant();
30677
30873
  const quoted = argv.map(quoteWord).join(" ");
30678
30874
  if (matching.length === 0) {
30679
- return failed2(
30875
+ return failed3(
30680
30876
  "EPERM",
30681
30877
  `sudo: ${self.name} is not allowed to run ${quoted} as ${target.name}`
30682
30878
  );
30683
30879
  }
30684
- if (parsed2.nonInteractive) return failed2("EPERM", "sudo: a password is required");
30685
- if (this.pending.has(cred.ruid)) return failed2("EBUSY", "sudo: another request is pending");
30880
+ if (parsed2.nonInteractive) return failed3("EPERM", "sudo: a password is required");
30881
+ if (this.pending.has(cred.ruid)) return failed3("EBUSY", "sudo: another request is pending");
30686
30882
  this.pending.add(cred.ruid);
30687
30883
  try {
30688
30884
  const answer2 = await this.ask(caller, self, target, parsed2.command, path, cwd, signal);
30689
30885
  if (typeof answer2 !== "string") return answer2;
30690
30886
  if (await this.canonical(call.cwd) !== cwd || !await this.reachable(cred, cwd)) {
30691
- return failed2("EACCES", `sudo: ${call.cwd} changed while the request waited`);
30887
+ return failed3("EACCES", `sudo: ${call.cwd} changed while the request waited`);
30692
30888
  }
30693
30889
  const changed = await this.untrusted(path, cwd, word);
30694
30890
  if (changed) return changed;
30695
30891
  if (answer2 === "always" && !await this.remember(self, target, cwd, argv)) {
30696
- return failed2("EIO", "sudo: the rule could not be recorded");
30892
+ return failed3("EIO", "sudo: the rule could not be recorded");
30697
30893
  }
30698
30894
  return grant();
30699
30895
  } finally {
@@ -30710,7 +30906,7 @@ var Sudo = class {
30710
30906
  };
30711
30907
  }
30712
30908
  if (rules.length === 0) {
30713
- return failed2("EPERM", `User ${self.name} is not allowed to run sudo on ${host}.`);
30909
+ return failed3("EPERM", `User ${self.name} is not allowed to run sudo on ${host}.`);
30714
30910
  }
30715
30911
  const lines2 = rules.map(described).join("\n");
30716
30912
  return { list: `User ${self.name} may run the following commands on ${host}:
@@ -30719,7 +30915,7 @@ ${lines2}
30719
30915
  }
30720
30916
  async ask(caller, self, target, argv, path, cwd, requester) {
30721
30917
  const { approve } = this.o;
30722
- if (!approve || requester.aborted) return failed2("EACCES", "sudo: approval denied");
30918
+ if (!approve || requester.aborted) return failed3("EACCES", "sudo: approval denied");
30723
30919
  const createdAt = Date.now();
30724
30920
  const timeout = this.o.timeoutMs ?? SUDO_TIMEOUT_MS;
30725
30921
  const req = {
@@ -30749,9 +30945,9 @@ ${lines2}
30749
30945
  const answered = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
30750
30946
  const answer2 = await Promise.race([answered, aborted3]);
30751
30947
  if (answer2 === "aborted" || control.signal.aborted) {
30752
- return control.signal.reason === "expired" ? failed2("ETIMEDOUT", "sudo: the request expired") : failed2("EINTR", "sudo: the request was withdrawn");
30948
+ return control.signal.reason === "expired" ? failed3("ETIMEDOUT", "sudo: the request expired") : failed3("EINTR", "sudo: the request was withdrawn");
30753
30949
  }
30754
- return answer2 === "once" || answer2 === "always" ? answer2 : failed2("EACCES", "sudo: approval denied");
30950
+ return answer2 === "once" || answer2 === "always" ? answer2 : failed3("EACCES", "sudo: approval denied");
30755
30951
  } finally {
30756
30952
  clearTimeout(timer);
30757
30953
  requester.removeEventListener("abort", withdraw);
@@ -31038,13 +31234,13 @@ function interpreter(head) {
31038
31234
  function expandDefaults(defaults2, env) {
31039
31235
  const out = {};
31040
31236
  for (const [key, value2] of Object.entries(defaults2 ?? {})) {
31041
- let missing5 = false;
31237
+ let missing6 = false;
31042
31238
  const expanded = value2.replace(ENV_REFERENCE, (_, name2) => {
31043
31239
  const set3 = Object.hasOwn(env, name2) ? env[name2] : void 0;
31044
- if (set3 === void 0) missing5 = true;
31240
+ if (set3 === void 0) missing6 = true;
31045
31241
  return set3 ?? "";
31046
31242
  });
31047
- if (!missing5) out[key] = expanded;
31243
+ if (!missing6) out[key] = expanded;
31048
31244
  }
31049
31245
  return out;
31050
31246
  }
@@ -31219,6 +31415,9 @@ var Launcher = class {
31219
31415
  usersMode;
31220
31416
  dac;
31221
31417
  sealed;
31418
+ fill;
31419
+ fills = new AbortController();
31420
+ placeholders = [];
31222
31421
  scrubs = /* @__PURE__ */ new Map();
31223
31422
  clipboard;
31224
31423
  embedder;
@@ -31300,7 +31499,7 @@ var Launcher = class {
31300
31499
  ...options.env
31301
31500
  };
31302
31501
  this.ca = kernelCa(options.caStore ?? memoryCaStore());
31303
- this.transport = placeholderFloor(replayingHops(options.transport ?? missingTransport()));
31502
+ this.transport = this.floored(options);
31304
31503
  this.announcedTraits = JSON.stringify(this.transport.traits);
31305
31504
  this.uplink = options.uplink;
31306
31505
  this.routes = new Routes(options.uplink?.traits.ipv6 === true);
@@ -32362,6 +32561,19 @@ var Launcher = class {
32362
32561
  groupSession(pgid) {
32363
32562
  return this.jobs.sessionOf(pgid);
32364
32563
  }
32564
+ floored(options) {
32565
+ const { sealedFetch } = options;
32566
+ this.fill = sealedFetch && this.usersMode === "enforce" ? sealedFetcher(sealedFetch, this.fills.signal) : void 0;
32567
+ if (this.fill) this.net.stampProxy(REALM_PROXY_PORT);
32568
+ return placeholderFloor(replayingHops(options.transport ?? missingTransport()), {
32569
+ known: () => this.placeholders,
32570
+ ...this.fill ? { fill: this.fill } : {}
32571
+ });
32572
+ }
32573
+ httpFor(pid) {
32574
+ const stamp = this.fill ? () => this.liveStamp(pid) : void 0;
32575
+ return new HttpHandles(this.transport, pid, this.loopbackFor(pid), stamp);
32576
+ }
32365
32577
  loopbackFor(pid) {
32366
32578
  return new KernelLoopback(
32367
32579
  this.net,
@@ -32369,7 +32581,7 @@ var Launcher = class {
32369
32581
  const cred = this.credOf(pid);
32370
32582
  return { pid, uid: cred.euid, gid: cred.egid };
32371
32583
  },
32372
- () => this.connectorStamp(pid)
32584
+ () => this.liveStamp(pid)
32373
32585
  );
32374
32586
  }
32375
32587
  sourceCheck(pid, writer) {
@@ -32534,7 +32746,7 @@ var Launcher = class {
32534
32746
  jobs: this.jobs,
32535
32747
  ptys: this.ptys,
32536
32748
  net: this.net,
32537
- http: new HttpHandles(this.transport, pid, this.loopbackFor(pid)),
32749
+ http: this.httpFor(pid),
32538
32750
  locks: this.locks,
32539
32751
  fifos: this.fifos,
32540
32752
  sems: this.sems,
@@ -32849,6 +33061,19 @@ var Launcher = class {
32849
33061
  connectorStamp(pid) {
32850
33062
  return this.sealed.stamp(this.identityOf(pid), this.credOf(pid), this.tagsOf(pid));
32851
33063
  }
33064
+ async liveStamp(pid) {
33065
+ if (!this.creds.has(pid) || this.zombies.has(pid)) return void 0;
33066
+ return this.connectorStamp(pid);
33067
+ }
33068
+ setPlaceholders(list) {
33069
+ if (!Array.isArray(list) || !list.every((p) => typeof p === "string" && p !== "")) {
33070
+ throw fsError("EINVAL", "setPlaceholders takes a list of non-empty strings");
33071
+ }
33072
+ this.placeholders = [...list];
33073
+ }
33074
+ endFills() {
33075
+ this.fills.abort("terminated");
33076
+ }
32852
33077
  identityOf(pid) {
32853
33078
  const parent = this.jobs.shownParent(pid);
32854
33079
  const alive = parent !== void 0 && this.running(parent);
@@ -32971,7 +33196,7 @@ var Launcher = class {
32971
33196
  const at = normalizePath(path);
32972
33197
  this.unlinked.closed(at);
32973
33198
  this.writers?.unlinked.closed(at);
32974
- const holding = [...this.held].some((holds2) => holds2.holding(at)) || [...this.openFiles].some((open2) => open2.holdsAt(at));
33199
+ const holding = [...this.held].some((holds3) => holds3.holding(at)) || [...this.openFiles].some((open2) => open2.holdsAt(at));
32975
33200
  if (!holding) void this.rootFs.announceHolds?.([], [at], false);
32976
33201
  const open = [...this.openFiles].some((nodes) => nodes.writes(at)) || heldUnder(this.held, at);
32977
33202
  if (!open) void this.mounts.commit(at).catch(() => void 0);
@@ -33134,8 +33359,9 @@ var Launcher = class {
33134
33359
  for (const root of roots) this.integrity.forget(root);
33135
33360
  this.resetCatalogs();
33136
33361
  }
33137
- attest(path) {
33362
+ attest(path, options = {}) {
33138
33363
  return attest(this.rootFs, path, {
33364
+ ...options,
33139
33365
  users: this.usersMode,
33140
33366
  mounts: this.mounts.list().map((entry) => entry.target).filter((target) => this.mounts.mounted(target) !== void 0)
33141
33367
  });
@@ -33192,8 +33418,8 @@ var Launcher = class {
33192
33418
  for (const name2 of names2 ?? []) {
33193
33419
  const path = joinName(real, name2);
33194
33420
  if (await this.base.hasOwner(path)) continue;
33195
- const failed4 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
33196
- if (failed4 === void 0) removed++;
33421
+ const failed5 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
33422
+ if (failed5 === void 0) removed++;
33197
33423
  else left++;
33198
33424
  }
33199
33425
  if (removed > 0) {
@@ -33288,7 +33514,7 @@ var Launcher = class {
33288
33514
  this.pnpmStale();
33289
33515
  if (!detach) return;
33290
33516
  for (const nodes of this.openFiles) nodes.revoke(at);
33291
- for (const holds2 of this.held) holds2.revoke(at);
33517
+ for (const holds3 of this.held) holds3.revoke(at);
33292
33518
  }
33293
33519
  unmountAll() {
33294
33520
  this.cron.stop();
@@ -33499,9 +33725,9 @@ var Launcher = class {
33499
33725
  }
33500
33726
  boundTo(path, hidden, fids) {
33501
33727
  const keeping = [...this.held].map(
33502
- (holds2) => [
33503
- holds2,
33504
- fids.flatMap((fid) => [...holds2.boundAt(path, fid), ...holds2.boundAt(hidden, fid)])
33728
+ (holds3) => [
33729
+ holds3,
33730
+ fids.flatMap((fid) => [...holds3.boundAt(path, fid), ...holds3.boundAt(hidden, fid)])
33505
33731
  ]
33506
33732
  ).filter(([, ids]) => ids.length > 0);
33507
33733
  const nodes = [...this.openFiles].filter(
@@ -33512,7 +33738,7 @@ var Launcher = class {
33512
33738
  (open) => fids.some((fid) => open.keepBound([hidden, path], fid, file))
33513
33739
  ).length;
33514
33740
  for (let i = kept; i < nodes.length; i++) file.release();
33515
- for (const [holds2, ids] of keeping) holds2.keepBound(ids, path, file);
33741
+ for (const [holds3, ids] of keeping) holds3.keepBound(ids, path, file);
33516
33742
  void this.rootFs.announceHolds?.([], [path, hidden], false);
33517
33743
  };
33518
33744
  return { keeping, nodes, keep: keep2 };
@@ -33672,7 +33898,7 @@ var Launcher = class {
33672
33898
  }
33673
33899
  moved(from, to, source) {
33674
33900
  this.renameLog.add(from, to);
33675
- for (const holds2 of this.held) holds2.renamed(from, to);
33901
+ for (const holds3 of this.held) holds3.renamed(from, to);
33676
33902
  if (source) return;
33677
33903
  for (const nodes of this.openFiles) nodes.renamed(from, to);
33678
33904
  this.watchers.moved(from, to);
@@ -33817,26 +34043,6 @@ function codeOf8(err) {
33817
34043
  return err?.code;
33818
34044
  }
33819
34045
 
33820
- // src/body-idle.ts
33821
- var BODY_IDLE_MS = 5 * 60 * 1e3;
33822
- function idleFailure(ms) {
33823
- return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {
33824
- code: "ETIMEDOUT"
33825
- });
33826
- }
33827
- async function readWithin(reader, ms) {
33828
- if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();
33829
- let timer;
33830
- const idle2 = new Promise((_, reject) => {
33831
- timer = setTimeout(() => reject(idleFailure(ms)), ms);
33832
- });
33833
- try {
33834
- return await Promise.race([reader.read(), idle2]);
33835
- } finally {
33836
- clearTimeout(timer);
33837
- }
33838
- }
33839
-
33840
34046
  // src/websocket-transport.ts
33841
34047
  var SENT_HEADERS_DROP = /* @__PURE__ */ new Set([
33842
34048
  "host",
@@ -33960,6 +34166,11 @@ async function* chunks(body, idleMs) {
33960
34166
  await reader.cancel().catch(() => void 0);
33961
34167
  }
33962
34168
  }
34169
+ function sentHeaders(headers, inPage) {
34170
+ const out = joinHeaders(headers);
34171
+ if (inPage) out.delete("user-agent");
34172
+ return out;
34173
+ }
33963
34174
  function streamOf(body) {
33964
34175
  const it = body[Symbol.asyncIterator]();
33965
34176
  return new ReadableStream(
@@ -33987,6 +34198,7 @@ function fetchTransport(options = {}) {
33987
34198
  const Socket = options.webSocket === true ? globalThis.WebSocket : options.webSocket || void 0;
33988
34199
  const headers = options.webSocketHeaders === true;
33989
34200
  const instance = options.redirect ?? "follow";
34201
+ const inPage = !options.fetch && "location" in globalThis;
33990
34202
  return {
33991
34203
  traits: {
33992
34204
  manualRedirects: instance === "manual",
@@ -34003,7 +34215,7 @@ function fetchTransport(options = {}) {
34003
34215
  try {
34004
34216
  response = await send2(request.url, {
34005
34217
  method: request.method,
34006
- headers: joinHeaders(request.headers),
34218
+ headers: sentHeaders(request.headers, inPage),
34007
34219
  ...requestBody(request),
34008
34220
  signal: request.signal,
34009
34221
  redirect: request.redirect ?? instance,
@@ -34079,7 +34291,21 @@ function headOf(nid, response) {
34079
34291
  headers: response.headers
34080
34292
  };
34081
34293
  }
34082
- function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS3 } = {}) {
34294
+ function requestOf(call, signal, uploads) {
34295
+ const { url, method, headers, streamed, body, redirect, nid } = call;
34296
+ return {
34297
+ url,
34298
+ method,
34299
+ headers,
34300
+ ...streamed ? { bodyStream: uploads.of(nid, signal) } : body ? { body } : {},
34301
+ ...redirect !== void 0 ? { redirect } : {},
34302
+ signal
34303
+ };
34304
+ }
34305
+ function serveTransport(peer, transport, {
34306
+ closeWaitMs = CLOSE_WAIT_MS3,
34307
+ attributed = false
34308
+ } = {}) {
34083
34309
  const open = /* @__PURE__ */ new Map();
34084
34310
  const fail3 = (nid, e) => {
34085
34311
  open.delete(nid);
@@ -34099,14 +34325,11 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS3 } = {})
34099
34325
  const entry = { abort };
34100
34326
  open.set(call.nid, entry);
34101
34327
  try {
34102
- const response = await transport.fetch({
34103
- url: call.url,
34104
- method: call.method,
34105
- headers: call.headers,
34106
- ...call.streamed ? { bodyStream: uploads.of(call.nid, abort.signal) } : call.body ? { body: call.body } : {},
34107
- ...call.redirect !== void 0 ? { redirect: call.redirect } : {},
34108
- signal: abort.signal
34109
- });
34328
+ const response = await transport.fetch(
34329
+ requestOf(call, abort.signal, uploads),
34330
+ attributed ? call.owner : void 0,
34331
+ attributed ? call.stamp : void 0
34332
+ );
34110
34333
  if (!open.has(call.nid)) {
34111
34334
  await response.cancel();
34112
34335
  return;
@@ -34770,21 +34993,21 @@ var BODY_HEADERS = /* @__PURE__ */ new Set([
34770
34993
  "content-type"
34771
34994
  ]);
34772
34995
  var CREDENTIALS = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2"]);
34773
- function failed3(message3) {
34996
+ function failed4(message3) {
34774
34997
  return Object.assign(new Error(message3), { status: 502, detail: "transport" });
34775
34998
  }
34776
34999
  function locationOf(headers) {
34777
35000
  return headers.find(([name2]) => name2.toLowerCase() === "location")?.[1];
34778
35001
  }
34779
35002
  function nextHop(hop, status, location) {
34780
- if (!URL.canParse(location, hop.url)) throw failed3(`a bad redirect from ${hop.url}`);
35003
+ if (!URL.canParse(location, hop.url)) throw failed4(`a bad redirect from ${hop.url}`);
34781
35004
  const next3 = new URL(location, hop.url);
34782
35005
  if (next3.protocol !== "http:" && next3.protocol !== "https:") {
34783
- throw failed3(`a redirect from ${hop.url} to ${next3.protocol}`);
35006
+ throw failed4(`a redirect from ${hop.url} to ${next3.protocol}`);
34784
35007
  }
34785
35008
  next3.hash = "";
34786
35009
  const toGet = (status === 301 || status === 302) && hop.method === "POST" || status === 303 && hop.method !== "GET" && hop.method !== "HEAD";
34787
- if (hop.bodyStream && !toGet) throw failed3(`a ${status} redirect would resend a streamed body`);
35010
+ if (hop.bodyStream && !toGet) throw failed4(`a ${status} redirect would resend a streamed body`);
34788
35011
  const crossOrigin = next3.origin !== new URL(hop.url).origin;
34789
35012
  const { body, bodyStream: bodyStream2, ...rest2 } = hop;
34790
35013
  return {
@@ -34806,7 +35029,7 @@ async function followRedirects(send2, request) {
34806
35029
  return hops > 0 ? { ...response, url: hop.url, redirected: true } : response;
34807
35030
  }
34808
35031
  await response.cancel();
34809
- if (hops >= MAX_REDIRECTS) throw failed3(`too many redirects from ${request.url}`);
35032
+ if (hops >= MAX_REDIRECTS) throw failed4(`too many redirects from ${request.url}`);
34810
35033
  hop = nextHop(hop, response.status, location);
34811
35034
  }
34812
35035
  }
@@ -34889,7 +35112,7 @@ async function checkDestination(target, policy, resolve2 = resolveHost) {
34889
35112
  throw refusal2(url, address, place);
34890
35113
  }
34891
35114
  }
34892
- function guarded2(check, signal) {
35115
+ function guarded3(check, signal) {
34893
35116
  if (!signal) return check;
34894
35117
  signal.throwIfAborted();
34895
35118
  let stop = () => {
@@ -34976,11 +35199,11 @@ function ensureSubscribed() {
34976
35199
  function guardedLoopback(transport, policy, resolve2) {
34977
35200
  ensureSubscribed();
34978
35201
  const open = transport.websocket?.bind(transport);
34979
- const send2 = async (request, owner) => {
34980
- await guarded2(checkDestination(request.url, policy, resolve2), request.signal);
35202
+ const send2 = async (request, owner, stamp) => {
35203
+ await guarded3(checkDestination(request.url, policy, resolve2), request.signal);
34981
35204
  const entry = { policy };
34982
35205
  try {
34983
- return await loopbackStore.run(entry, () => transport.fetch(request, owner));
35206
+ return await loopbackStore.run(entry, () => transport.fetch(request, owner, stamp));
34984
35207
  } catch (err) {
34985
35208
  throw entry.refused ?? err;
34986
35209
  }
@@ -34989,10 +35212,10 @@ function guardedLoopback(transport, policy, resolve2) {
34989
35212
  get traits() {
34990
35213
  return transport.traits;
34991
35214
  },
34992
- fetch: (request, owner) => request.redirect === "follow" ? followRedirects((hop) => send2(hop, owner), request) : send2(request, owner),
35215
+ fetch: (request, owner, stamp) => request.redirect === "follow" ? followRedirects((hop) => send2(hop, owner, stamp), request) : send2(request, owner, stamp),
34993
35216
  ...open ? {
34994
35217
  websocket: async (request) => {
34995
- await guarded2(checkDestination(request.url, policy, resolve2), request.signal);
35218
+ await guarded3(checkDestination(request.url, policy, resolve2), request.signal);
34996
35219
  const entry = { policy };
34997
35220
  try {
34998
35221
  return await loopbackStore.run(entry, () => open(request));
@@ -36376,6 +36599,7 @@ function checkedRequests(hook) {
36376
36599
  return { kinds, handle: (request) => hook.handle(request) };
36377
36600
  }
36378
36601
  async function createNodeKernel(options = {}) {
36602
+ const hooks = sealedHooks(options.sealed);
36379
36603
  const root = options.root ?? memoryRoot();
36380
36604
  const fs = new OpfsFs(root, void 0, void 0, { ranged: isMemoryRoot(root) });
36381
36605
  await fs.reconcile();
@@ -36414,7 +36638,8 @@ async function createNodeKernel(options = {}) {
36414
36638
  users: options.users === void 0 ? DEFAULT_USERS : options.users,
36415
36639
  ...options.onDenial ? { onDenial: options.onDenial } : {},
36416
36640
  ...options.protect ? { protect: options.protect } : {},
36417
- ...options.sealed ? { sealed: options.sealed } : {},
36641
+ ...hooks.request ? { sealed: hooks.request } : {},
36642
+ ...hooks.fetch ? { sealedFetch: hooks.fetch } : {},
36418
36643
  ...options.clipboard ? { clipboard: options.clipboard } : {},
36419
36644
  ...options.requests ? { embedder: checkedRequests(options.requests) } : {},
36420
36645
  ...options.approve ? { approve: options.approve } : {},
@@ -36490,6 +36715,8 @@ async function createNodeKernel(options = {}) {
36490
36715
  },
36491
36716
  chmod: async (path, mode) => launcher.fs.chmod(path, modeOption(mode)),
36492
36717
  integrity: { revoke: (path) => guard2(() => launcher.revokeIntegrity(path)) },
36718
+ sealed: { setPlaceholders: (list) => guard2(async () => launcher.setPlaceholders(list)) },
36719
+ attest: ((path, attestOptions) => guard2(() => launcher.attest(path, attestOptions))),
36493
36720
  readFile: async (path) => launcher.fs.readFileBuffer(path),
36494
36721
  mount: (spec) => guard2(() => launcher.mount(spec)),
36495
36722
  umount: (target) => guard2(async () => launcher.umount(target)),
@@ -36522,6 +36749,7 @@ async function createNodeKernel(options = {}) {
36522
36749
  for (const reject of [...pending]) reject(new Error(TERMINATED));
36523
36750
  for (const kill of [...live]) kill();
36524
36751
  launcher.cdp.close();
36752
+ launcher.endFills();
36525
36753
  launcher.unmountAll();
36526
36754
  dropCache(cache);
36527
36755
  }
@@ -36531,6 +36759,7 @@ export {
36531
36759
  KernelCallError,
36532
36760
  KernelGoneError,
36533
36761
  MAX_WARM_WORKERS,
36762
+ SEALED_FETCH_VERSION,
36534
36763
  WARM_IDLE_MS,
36535
36764
  attachKernel,
36536
36765
  createNodeKernel,