@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.
@@ -182,13 +182,13 @@ var IndexedDbMeta = class {
182
182
  return [transaction, transaction.objectStore(META_STORE)];
183
183
  }
184
184
  async get(paths) {
185
- const missing5 = paths.filter((path) => !this.cache.has(path));
186
- if (missing5.length > 0) {
185
+ const missing6 = paths.filter((path) => !this.cache.has(path));
186
+ if (missing6.length > 0) {
187
187
  this.settleRemoves();
188
188
  const generation = this.generation;
189
189
  const [transaction, store] = this.transaction("readonly");
190
190
  const found = /* @__PURE__ */ new Map();
191
- for (const path of missing5) {
191
+ for (const path of missing6) {
192
192
  const request3 = store.get(path);
193
193
  request3.onsuccess = () => void found.set(path, request3.result ?? null);
194
194
  }
@@ -1237,10 +1237,10 @@ var RemoteWatch = class {
1237
1237
  });
1238
1238
  }
1239
1239
  }
1240
- heldBy({ tab, holds: holds2, seq: seq2 }) {
1240
+ heldBy({ tab, holds: holds3, seq: seq2 }) {
1241
1241
  const from = tab;
1242
- const { add, drop } = holds2;
1243
- if (holds2?.instance !== void 0) this.instances.set(from, holds2.instance);
1242
+ const { add, drop } = holds3;
1243
+ if (holds3?.instance !== void 0) this.instances.set(from, holds3.instance);
1244
1244
  const held = this.peerHolds.get(from) ?? /* @__PURE__ */ new Map();
1245
1245
  for (const path of drop) held.delete(path);
1246
1246
  for (const [path, fid] of add) held.set(path, fid);
@@ -1524,11 +1524,11 @@ var META_OPS = ["get", "update", "move", "remove", "links", "under", "all"];
1524
1524
  var FILE_ID_TRIES = 3;
1525
1525
  function sidecar(meta) {
1526
1526
  const pathOf = ([first]) => [first, "/"].flat().find((p) => typeof p === "string");
1527
- const guarded2 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
1527
+ const guarded3 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
1528
1528
  throw translate(err, pathOf(args), "sidecar", false);
1529
1529
  });
1530
1530
  const names2 = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
1531
- const ops = Object.fromEntries(names2.map((op) => [op, guarded2(op)]));
1531
+ const ops = Object.fromEntries(names2.map((op) => [op, guarded3(op)]));
1532
1532
  const { updateMany } = meta;
1533
1533
  ops.updateMany = updateMany ? (changes) => updateMany.call(meta, changes).catch((err) => {
1534
1534
  throw translate(err, changes[0]?.path ?? "/", "sidecar", false);
@@ -3638,12 +3638,12 @@ var OpfsFs = class {
3638
3638
  if (!move) return false;
3639
3639
  for (let attempt = 0; ; attempt++) {
3640
3640
  this.others++;
3641
- const failed3 = await move.call(handle, dir, name2).then(
3641
+ const failed4 = await move.call(handle, dir, name2).then(
3642
3642
  () => void 0,
3643
3643
  (err) => ({ err })
3644
3644
  );
3645
- if (!failed3) return true;
3646
- const error = failed3.err?.name;
3645
+ if (!failed4) return true;
3646
+ const error = failed4.err?.name;
3647
3647
  if (handle.kind !== "file" || !LOCKED.has(error)) return false;
3648
3648
  const delay2 = SYNC_BACKOFF_MS[attempt];
3649
3649
  if (delay2 === void 0) throw fsError("EBUSY", name2);
@@ -6842,9 +6842,9 @@ var KernelSocket = class _KernelSocket {
6842
6842
  case SO_TYPE:
6843
6843
  return SOCK_STREAM;
6844
6844
  case SO_ERROR: {
6845
- const failed3 = this.failed;
6845
+ const failed4 = this.failed;
6846
6846
  this.failed = void 0;
6847
- return failed3 ? wasiErrno(failed3) : 0;
6847
+ return failed4 ? wasiErrno(failed4) : 0;
6848
6848
  }
6849
6849
  case SO_ACCEPTCONN:
6850
6850
  return this.state === "listening" ? 1 : 0;
@@ -6924,6 +6924,7 @@ var LoopbackNet = class {
6924
6924
  internal = /* @__PURE__ */ new Set();
6925
6925
  reserved = /* @__PURE__ */ new Set();
6926
6926
  facades = /* @__PURE__ */ new Map();
6927
+ proxyStamped;
6927
6928
  nextEphemeral = EPHEMERAL_FIRST;
6928
6929
  route;
6929
6930
  origins;
@@ -6998,9 +6999,15 @@ var LoopbackNet = class {
6998
6999
  this.kernelOnly(port, true);
6999
7000
  this.facades.set(port, name2);
7000
7001
  }
7001
- facadeAt(addr) {
7002
- if (addr.family !== "inet" || !isLoopback(canonicalHost(addr.host))) return void 0;
7003
- return this.facades.get(addr.port);
7002
+ stampProxy(port) {
7003
+ this.proxyStamped = port;
7004
+ }
7005
+ get originsStamped() {
7006
+ return this.proxyStamped !== void 0;
7007
+ }
7008
+ stampsPeers(addr) {
7009
+ if (addr.family !== "inet" || !isLoopback(canonicalHost(addr.host))) return false;
7010
+ return this.facades.has(addr.port) || this.proxyStamped === addr.port;
7004
7011
  }
7005
7012
  activate(addr, start2) {
7006
7013
  this.activators.set(keyOf(addr), start2);
@@ -7323,7 +7330,21 @@ function headOf(nid, response) {
7323
7330
  headers: response.headers
7324
7331
  };
7325
7332
  }
7326
- function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {}) {
7333
+ function requestOf(call, signal, uploads) {
7334
+ const { url, method, headers, streamed, body, redirect, nid } = call;
7335
+ return {
7336
+ url,
7337
+ method,
7338
+ headers,
7339
+ ...streamed ? { bodyStream: uploads.of(nid, signal) } : body ? { body } : {},
7340
+ ...redirect !== void 0 ? { redirect } : {},
7341
+ signal
7342
+ };
7343
+ }
7344
+ function serveTransport(peer, transport, {
7345
+ closeWaitMs = CLOSE_WAIT_MS2,
7346
+ attributed = false
7347
+ } = {}) {
7327
7348
  const open2 = /* @__PURE__ */ new Map();
7328
7349
  const fail2 = (nid, e) => {
7329
7350
  open2.delete(nid);
@@ -7343,14 +7364,11 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS2 } = {})
7343
7364
  const entry = { abort };
7344
7365
  open2.set(call.nid, entry);
7345
7366
  try {
7346
- const response = await transport.fetch({
7347
- url: call.url,
7348
- method: call.method,
7349
- headers: call.headers,
7350
- ...call.streamed ? { bodyStream: uploads.of(call.nid, abort.signal) } : call.body ? { body: call.body } : {},
7351
- ...call.redirect !== void 0 ? { redirect: call.redirect } : {},
7352
- signal: abort.signal
7353
- });
7367
+ const response = await transport.fetch(
7368
+ requestOf(call, abort.signal, uploads),
7369
+ attributed ? call.owner : void 0,
7370
+ attributed ? call.stamp : void 0
7371
+ );
7354
7372
  if (!open2.has(call.nid)) {
7355
7373
  await response.cancel();
7356
7374
  return;
@@ -8504,7 +8522,7 @@ function satisfies(version, range2) {
8504
8522
  }
8505
8523
 
8506
8524
  // src/version.ts
8507
- var KERNEL_VERSION = true ? "1.171.0" : "0.0.0-dev";
8525
+ var KERNEL_VERSION = true ? "1.172.1" : "0.0.0-dev";
8508
8526
  var OS_RELEASE = "6.0.0-slicc";
8509
8527
  function procVersion() {
8510
8528
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9161,32 +9179,32 @@ function nextFire(schedule, after, utc = false) {
9161
9179
  }
9162
9180
  return null;
9163
9181
  }
9164
- function missedFires(schedule, from, until, utc = false, cap = MISSED_CAP) {
9182
+ function missedFires(schedule, from, until2, utc = false, cap = MISSED_CAP) {
9165
9183
  let count2 = 0;
9166
9184
  let last = null;
9167
9185
  let at = from;
9168
9186
  while (count2 < cap) {
9169
9187
  at = nextFire(schedule, at, utc);
9170
- if (at === null || at > until) return { count: count2, last, more: false };
9188
+ if (at === null || at > until2) return { count: count2, last, more: false };
9171
9189
  last = at;
9172
9190
  count2++;
9173
9191
  }
9174
9192
  const next3 = nextFire(schedule, last, utc);
9175
- if (next3 === null || next3 > until) return { count: count2, last, more: false };
9176
- return { count: count2, last: latestFire(schedule, last, until, utc), more: true };
9193
+ if (next3 === null || next3 > until2) return { count: count2, last, more: false };
9194
+ return { count: count2, last: latestFire(schedule, last, until2, utc), more: true };
9177
9195
  }
9178
- function latestFire(schedule, from, until, utc = false) {
9196
+ function latestFire(schedule, from, until2, utc = false) {
9179
9197
  let found = from;
9180
9198
  for (let span = 6e4; ; span *= 2) {
9181
- const start2 = Math.max(from, until - span);
9199
+ const start2 = Math.max(from, until2 - span);
9182
9200
  const first = nextFire(schedule, start2, utc);
9183
- if (first !== null && first <= until) {
9201
+ if (first !== null && first <= until2) {
9184
9202
  found = first;
9185
9203
  break;
9186
9204
  }
9187
9205
  if (start2 === from) return from;
9188
9206
  }
9189
- for (let at = nextFire(schedule, found, utc); at !== null && at <= until; ) {
9207
+ for (let at = nextFire(schedule, found, utc); at !== null && at <= until2; ) {
9190
9208
  found = at;
9191
9209
  at = nextFire(schedule, at, utc);
9192
9210
  }
@@ -9898,12 +9916,12 @@ var UnlinkedKeeper = class {
9898
9916
  return this.locks;
9899
9917
  }
9900
9918
  async undoing(op, peers, sends, heard, shared2 = []) {
9901
- let failed3;
9919
+ let failed4;
9902
9920
  let out;
9903
9921
  try {
9904
9922
  out = await op();
9905
9923
  } catch (err) {
9906
- failed3 = err ?? new Error("failed");
9924
+ failed4 = err ?? new Error("failed");
9907
9925
  await this.rollBackAsides(sends, shared2);
9908
9926
  }
9909
9927
  const hiddenShared = new Set(shared2.map((one) => one.hidden));
@@ -9924,7 +9942,7 @@ var UnlinkedKeeper = class {
9924
9942
  const done5 = () => one.release().then(() => this.dropIfLast(one.hidden));
9925
9943
  void Promise.all(waits.map(({ told }) => told)).then(done5, done5);
9926
9944
  }
9927
- if (failed3 !== void 0) throw failed3;
9945
+ if (failed4 !== void 0) throw failed4;
9928
9946
  return out;
9929
9947
  }
9930
9948
  async rollBackAsides(sends, shared2) {
@@ -10071,7 +10089,7 @@ var UnlinkedKeeper = class {
10071
10089
  // src/cron/clock.ts
10072
10090
  var systemCronClock = {
10073
10091
  now: () => Date.now(),
10074
- sleep(until, signal) {
10092
+ sleep(until2, signal) {
10075
10093
  if (signal.aborted) return Promise.resolve();
10076
10094
  return new Promise((resolve2) => {
10077
10095
  const done5 = () => {
@@ -10079,7 +10097,7 @@ var systemCronClock = {
10079
10097
  signal.removeEventListener("abort", done5);
10080
10098
  resolve2();
10081
10099
  };
10082
- const timer = setTimeout(done5, Math.max(0, until - Date.now()));
10100
+ const timer = setTimeout(done5, Math.max(0, until2 - Date.now()));
10083
10101
  timer.unref?.();
10084
10102
  signal.addEventListener("abort", done5, { once: true });
10085
10103
  });
@@ -10183,15 +10201,15 @@ var CronService = class {
10183
10201
  async pass() {
10184
10202
  if (this.wake.signal.aborted) this.wake = new AbortController();
10185
10203
  const wake = this.wake;
10186
- let until;
10204
+ let until2;
10187
10205
  try {
10188
- until = await this.tick();
10206
+ until2 = await this.tick();
10189
10207
  } catch (err) {
10190
10208
  await this.error(`cron: ${messageOf(err)}`);
10191
- until = this.clock.now() + WAKE_MS;
10209
+ until2 = this.clock.now() + WAKE_MS;
10192
10210
  }
10193
10211
  if (this.stopping.signal.aborted) return;
10194
- await this.clock.sleep(until, wake.signal);
10212
+ await this.clock.sleep(until2, wake.signal);
10195
10213
  }
10196
10214
  async provision() {
10197
10215
  const { fs, owners } = this.host;
@@ -10408,14 +10426,17 @@ var PLACEHOLDER_REFUSED = "refused: this request has a sealed placeholder in its
10408
10426
  var PlaceholderRefused = class extends Error {
10409
10427
  status = 403;
10410
10428
  code = "EACCES";
10411
- constructor() {
10412
- super(PLACEHOLDER_REFUSED);
10429
+ constructor(reason = PLACEHOLDER_REFUSED) {
10430
+ super(reason);
10413
10431
  }
10414
10432
  };
10415
- function carries(text) {
10433
+ function holds2(text, known) {
10434
+ return PLACEHOLDER.test(text) || known.some((placeholder) => text.includes(placeholder));
10435
+ }
10436
+ function carries(text, known) {
10416
10437
  let layer = text;
10417
10438
  for (let i = 0; i < PERCENT_LAYERS; i++) {
10418
- if (PLACEHOLDER.test(layer)) return true;
10439
+ if (holds2(layer, known)) return true;
10419
10440
  const next3 = layer.replace(
10420
10441
  ESCAPE,
10421
10442
  (_, hex4) => String.fromCharCode(Number.parseInt(hex4, 16))
@@ -10423,35 +10444,36 @@ function carries(text) {
10423
10444
  if (next3 === layer) return false;
10424
10445
  layer = next3;
10425
10446
  }
10426
- return PLACEHOLDER.test(layer);
10447
+ return holds2(layer, known);
10427
10448
  }
10428
- function basicCarries(value2) {
10449
+ function basicCarries(value2, known) {
10429
10450
  const credential = BASIC.exec(value2)?.[1];
10430
10451
  if (credential === void 0) return false;
10431
10452
  const letters = credential.replace(/[^A-Za-z0-9+/_-]/g, "").replaceAll("-", "+").replaceAll("_", "/");
10432
10453
  for (let shift = 0; shift < BASE64_GROUP; shift++) {
10433
10454
  const part = letters.slice(shift);
10434
10455
  const whole = part.length % BASE64_GROUP === 1 ? part.slice(0, -1) : part;
10435
- if (carries(atob(whole))) return true;
10456
+ if (carries(atob(whole), known)) return true;
10436
10457
  }
10437
10458
  return false;
10438
10459
  }
10439
- function headersCarry(headers) {
10460
+ function headersCarry(headers, known) {
10440
10461
  return headers.some(
10441
- ([name2, value2]) => carries(name2.toLowerCase()) || carries(value2) || basicCarries(value2)
10462
+ ([name2, value2]) => carries(name2, known) || carries(name2.toLowerCase(), known) || carries(value2, known) || basicCarries(value2, known)
10442
10463
  );
10443
10464
  }
10444
- function urlCarries(url) {
10445
- return carries(url) || URL.canParse(url) && carries(new URL(url).href);
10465
+ function urlCarries(url, known) {
10466
+ return carries(url, known) || URL.canParse(url) && carries(new URL(url).href, known);
10446
10467
  }
10447
- function refuse(request3) {
10448
- if (urlCarries(request3.url) || headersCarry(request3.headers)) throw new PlaceholderRefused();
10468
+ function detected(request3, known) {
10469
+ return urlCarries(request3.url, known) || headersCarry(request3.headers, known);
10449
10470
  }
10450
- function refuseSocket(request3) {
10451
- refuse(request3);
10452
- if (request3.protocols.some(carries)) throw new PlaceholderRefused();
10471
+ function refuseSocket(request3, known) {
10472
+ if (detected(request3, known) || request3.protocols.some((p) => carries(p, known))) {
10473
+ throw new PlaceholderRefused();
10474
+ }
10453
10475
  }
10454
- function placeholderFloor(inner) {
10476
+ function placeholderFloor(inner, { known = () => [], fill: fill2 } = {}) {
10455
10477
  const open2 = inner.websocket?.bind(inner);
10456
10478
  return {
10457
10479
  get traits() {
@@ -10459,13 +10481,14 @@ function placeholderFloor(inner) {
10459
10481
  },
10460
10482
  ...open2 ? {
10461
10483
  websocket: async (request3) => {
10462
- refuseSocket(request3);
10484
+ refuseSocket(request3, known());
10463
10485
  return open2(request3);
10464
10486
  }
10465
10487
  } : {},
10466
- async fetch(request3, owner) {
10467
- refuse(request3);
10468
- return inner.fetch(request3, owner);
10488
+ async fetch(request3, owner, stamp) {
10489
+ if (!detected(request3, known())) return inner.fetch(request3, owner, stamp);
10490
+ if (!fill2 || !stamp) throw new PlaceholderRefused();
10491
+ return fill2(request3, stamp);
10469
10492
  }
10470
10493
  };
10471
10494
  }
@@ -10638,14 +10661,14 @@ function tunnelTarget(req) {
10638
10661
  }
10639
10662
  return { host, port };
10640
10663
  }
10641
- async function watchHangup(conn, abort, until) {
10642
- while (!until.aborted && !abort.signal.aborted) {
10664
+ async function watchHangup(conn, abort, until2) {
10665
+ while (!until2.aborted && !abort.signal.aborted) {
10643
10666
  if (conn.poll().hangup) {
10644
10667
  abort.abort(new KernelError("EPIPE"));
10645
10668
  return;
10646
10669
  }
10647
10670
  try {
10648
- await conn.changed(until);
10671
+ await conn.changed(until2);
10649
10672
  } catch {
10650
10673
  return;
10651
10674
  }
@@ -10836,7 +10859,7 @@ var RealmProxy = class {
10836
10859
  const waiting = new AbortController();
10837
10860
  void watchHangup(ctx.socket, abort, waiting.signal);
10838
10861
  try {
10839
- response = await this.upstream(req, url, body, abort.signal, ctx.socket.peerCred?.pid);
10862
+ response = await this.upstream(req, url, body, abort.signal, ctx.socket);
10840
10863
  } finally {
10841
10864
  waiting.abort();
10842
10865
  }
@@ -10863,7 +10886,7 @@ var RealmProxy = class {
10863
10886
  await conn.write(latin1Bytes("HTTP/1.1 100 Continue\r\n\r\n"), this.stop.signal);
10864
10887
  }
10865
10888
  }
10866
- async upstream(req, url, body, signal, owner) {
10889
+ async upstream(req, url, body, signal, socket) {
10867
10890
  const sent = BODILESS_METHODS.has(req.method) ? void 0 : body;
10868
10891
  try {
10869
10892
  const fetching = this.options.transport.fetch(
@@ -10874,7 +10897,8 @@ var RealmProxy = class {
10874
10897
  ...sent instanceof Uint8Array ? { body: sent } : sent ? { bodyStream: sent } : {},
10875
10898
  signal
10876
10899
  },
10877
- owner
10900
+ socket.peerCred?.pid,
10901
+ socket.peerStamp
10878
10902
  );
10879
10903
  return await untilAborted(fetching, signal);
10880
10904
  } catch (e) {
@@ -11191,7 +11215,7 @@ async function relay(socket, conn) {
11191
11215
  // src/fs/attest.ts
11192
11216
  var ATTEST_MAX = 1024 * 1024;
11193
11217
  var UNOWNED = 1e3;
11194
- function refuse2(code, path, why) {
11218
+ function refuse(code, path, why) {
11195
11219
  throw Object.assign(new Error(`attest ${path}: ${why}`), { code });
11196
11220
  }
11197
11221
  function chainOf(path) {
@@ -11233,39 +11257,49 @@ async function trustedParents(fs, path, o) {
11233
11257
  const parents = [];
11234
11258
  for (const dir of chainOf(path).slice(0, -1)) {
11235
11259
  const st = await fs.lstat(dir);
11236
- if (st.isSymbolicLink) refuse2("EACCES", path, `${dir} is a symlink`);
11237
- if (!st.isDirectory) refuse2("ENOTDIR", path, `${dir} is not a directory`);
11260
+ if (st.isSymbolicLink) refuse("EACCES", path, `${dir} is a symlink`);
11261
+ if (!st.isDirectory) refuse("ENOTDIR", path, `${dir} is not a directory`);
11238
11262
  const perm = owned(dir, st);
11239
11263
  if (o.users !== "off" && (perm.uid !== 0 || (perm.mode & 18) !== 0)) {
11240
- refuse2("EACCES", path, `${dir} is not root-owned or is writable by group or others`);
11264
+ refuse("EACCES", path, `${dir} is not root-owned or is writable by group or others`);
11241
11265
  }
11242
11266
  parents.push(perm);
11243
11267
  }
11244
11268
  return parents;
11245
11269
  }
11270
+ function missing3(e) {
11271
+ return e?.code === "ENOENT";
11272
+ }
11246
11273
  async function attest(fs, asked, o) {
11274
+ if (o.absent !== void 0 && o.absent !== "allow") {
11275
+ refuse("EINVAL", String(asked), "absent takes only allow");
11276
+ }
11247
11277
  if (typeof asked !== "string" || !asked.startsWith("/")) {
11248
- refuse2("EINVAL", String(asked), "not an absolute path");
11278
+ refuse("EINVAL", String(asked), "not an absolute path");
11249
11279
  }
11250
11280
  const path = normalizePath(asked);
11251
11281
  const mount = o.mounts.find((target) => {
11252
11282
  const at = normalizePath(target);
11253
11283
  return at === "/" || under2(path, at);
11254
11284
  });
11255
- if (mount !== void 0) refuse2("EACCES", path, `under the mount ${mount}`);
11285
+ if (mount !== void 0) refuse("EACCES", path, `under the mount ${mount}`);
11256
11286
  const parents = await trustedParents(fs, path, o);
11257
11287
  for (let tries = 0; ; tries++) {
11258
- const before = await fs.lstat(path);
11259
- if (before.isSymbolicLink) refuse2("EACCES", path, "is a symlink");
11288
+ const before = await fs.lstat(path).catch((e) => {
11289
+ if (o.absent === "allow" && missing3(e)) return void 0;
11290
+ throw e;
11291
+ });
11292
+ if (!before) return { path, absent: true, users: o.users, onRootFs: true, parents };
11293
+ if (before.isSymbolicLink) refuse("EACCES", path, "is a symlink");
11260
11294
  if (!before.isFile)
11261
- refuse2(before.isDirectory ? "EISDIR" : "EINVAL", path, "is not a regular file");
11262
- if (before.size > ATTEST_MAX) refuse2("EFBIG", path, `is over ${ATTEST_MAX} bytes`);
11295
+ refuse(before.isDirectory ? "EISDIR" : "EINVAL", path, "is not a regular file");
11296
+ if (before.size > ATTEST_MAX) refuse("EFBIG", path, `is over ${ATTEST_MAX} bytes`);
11263
11297
  const bytes = (await fs.readFileBuffer(path)).slice();
11264
11298
  const after = await fs.lstat(path);
11265
11299
  if (unchanged(before, after, bytes)) {
11266
11300
  return attested(path, after, bytes, await sha2562(bytes), o, parents);
11267
11301
  }
11268
- if (tries >= 1) refuse2("EAGAIN", path, "changed while it was read");
11302
+ if (tries >= 1) refuse("EAGAIN", path, "changed while it was read");
11269
11303
  }
11270
11304
  }
11271
11305
  var WATCH_DEBOUNCE_MS = 50;
@@ -11324,7 +11358,7 @@ var S_IFREG2 = 32768;
11324
11358
  var COMMAND = /^\/(?:usr\/)?bin\/([^/]+)$/;
11325
11359
  var MAX_LINKS6 = 40;
11326
11360
  var BIN_ENTRY = /\/bin\/[^/]+$/;
11327
- function missing3(err) {
11361
+ function missing4(err) {
11328
11362
  return err?.code === "ENOENT";
11329
11363
  }
11330
11364
  function synthetic(directory, path) {
@@ -11428,7 +11462,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
11428
11462
  }
11429
11463
  async function entryTarget(path) {
11430
11464
  if (!BIN_ENTRY.test(path) || !(await virtual(path))?.isFile) return void 0;
11431
- if (!await fs.lstat(path).then(() => false, missing3)) return void 0;
11465
+ if (!await fs.lstat(path).then(() => false, missing4)) return void 0;
11432
11466
  const target = await targetOf2(path);
11433
11467
  return target?.path === path ? void 0 : target;
11434
11468
  }
@@ -11440,11 +11474,11 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
11440
11474
  return target?.path;
11441
11475
  }
11442
11476
  const absent2 = (err) => {
11443
- if (missing3(err)) return EMPTY2;
11477
+ if (missing4(err)) return EMPTY2;
11444
11478
  throw err;
11445
11479
  };
11446
11480
  async function content(path, err) {
11447
- if (!missing3(err) || !(await linked2(path))?.isFile) throw err;
11481
+ if (!missing4(err) || !(await linked2(path))?.isFile) throw err;
11448
11482
  const target = await redirected2(path);
11449
11483
  return target === void 0 ? EMPTY2 : fs.readFileBuffer(target).catch(absent2);
11450
11484
  }
@@ -11453,7 +11487,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
11453
11487
  try {
11454
11488
  return await real(path);
11455
11489
  } catch (err) {
11456
- const found = missing3(err) ? await linked2(path) : void 0;
11490
+ const found = missing4(err) ? await linked2(path) : void 0;
11457
11491
  if (found) return found;
11458
11492
  throw err;
11459
11493
  }
@@ -11478,7 +11512,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
11478
11512
  const extra = await children3(path);
11479
11513
  if (!extra) return fs.readdir(path);
11480
11514
  const real = await fs.readdir(path).catch((err) => {
11481
- if (missing3(err)) return [];
11515
+ if (missing4(err)) return [];
11482
11516
  throw err;
11483
11517
  });
11484
11518
  return [.../* @__PURE__ */ new Set([...real, ...extra])].sort();
@@ -11487,7 +11521,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
11487
11521
  const extra = await children3(path);
11488
11522
  if (!extra) return fs.readdirStat(path);
11489
11523
  const real = await fs.readdirStat(path).catch((err) => {
11490
- if (missing3(err)) return [];
11524
+ if (missing4(err)) return [];
11491
11525
  throw err;
11492
11526
  });
11493
11527
  const seen = new Set(real.map(([name2]) => name2));
@@ -11521,7 +11555,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
11521
11555
  ...ranged2 ? {
11522
11556
  ...ranged2,
11523
11557
  pread: (path, offset, length2, version) => ranged2.pread(path, offset, length2, version).catch(async (err) => {
11524
- const target = missing3(err) ? await redirected2(path) : void 0;
11558
+ const target = missing4(err) ? await redirected2(path) : void 0;
11525
11559
  if (target === void 0) throw err;
11526
11560
  return ranged2.pread(target, offset, length2).catch(absent2);
11527
11561
  })
@@ -11552,7 +11586,7 @@ var S_IFREG3 = 32768;
11552
11586
  var MAX_HOPS2 = 40;
11553
11587
  var parentOf6 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
11554
11588
  var baseOf2 = (path) => path.slice(path.lastIndexOf("/") + 1);
11555
- function missing4(err) {
11589
+ function missing5(err) {
11556
11590
  return err?.code === "ENOENT";
11557
11591
  }
11558
11592
  function statOf(path, bytes) {
@@ -11605,11 +11639,11 @@ function withEtcFiles(fs, files) {
11605
11639
  const text = files.get(path)?.();
11606
11640
  return text === void 0 ? void 0 : new TextEncoder().encode(text);
11607
11641
  };
11608
- const absent2 = (path) => fs.lstat(path).then(() => false, missing4);
11642
+ const absent2 = (path) => fs.lstat(path).then(() => false, missing5);
11609
11643
  const follow2 = linkFollower(fs, files);
11610
11644
  const listedAbsent = async (path) => files.has(path) && await absent2(path) ? bytesOf2(path) : void 0;
11611
11645
  const fallback = (path, make) => async (err) => {
11612
- const at = missing4(err) ? await follow2(path) : void 0;
11646
+ const at = missing5(err) ? await follow2(path) : void 0;
11613
11647
  const bytes = at === void 0 ? void 0 : await listedAbsent(at);
11614
11648
  if (bytes === void 0 || at === void 0) throw err;
11615
11649
  return make(bytes, at);
@@ -13509,29 +13543,29 @@ var HeldSet = class extends Set {
13509
13543
  this.idle = idle2;
13510
13544
  this.moved = moved2;
13511
13545
  }
13512
- add(holds2) {
13513
- holds2.onIdle = this.idle;
13514
- holds2.onMoved = this.moved;
13515
- return super.add(holds2);
13546
+ add(holds3) {
13547
+ holds3.onIdle = this.idle;
13548
+ holds3.onMoved = this.moved;
13549
+ return super.add(holds3);
13516
13550
  }
13517
13551
  doubt(paths, over) {
13518
- for (const holds2 of this) {
13519
- for (const path of paths) holds2.doubt(path, true);
13520
- if (over !== void 0) holds2.doubt(over);
13552
+ for (const holds3 of this) {
13553
+ for (const path of paths) holds3.doubt(path, true);
13554
+ if (over !== void 0) holds3.doubt(over);
13521
13555
  }
13522
13556
  }
13523
13557
  async bindIds(id2) {
13524
- for (const holds2 of [...this]) await holds2.bindIds(id2);
13558
+ for (const holds3 of [...this]) await holds3.bindIds(id2);
13525
13559
  }
13526
13560
  heldIds() {
13527
13561
  const out = /* @__PURE__ */ new Map();
13528
- for (const holds2 of this) for (const [path, fid] of holds2.heldIds()) out.set(path, fid);
13562
+ for (const holds3 of this) for (const [path, fid] of holds3.heldIds()) out.set(path, fid);
13529
13563
  return [...out];
13530
13564
  }
13531
- delete(holds2) {
13532
- const removed = super.delete(holds2);
13533
- for (const path of /* @__PURE__ */ new Set([...holds2.keys(), ...holds2.opens.keys()])) this.idle(path);
13534
- holds2.releaseAll();
13565
+ delete(holds3) {
13566
+ const removed = super.delete(holds3);
13567
+ for (const path of /* @__PURE__ */ new Set([...holds3.keys(), ...holds3.opens.keys()])) this.idle(path);
13568
+ holds3.releaseAll();
13535
13569
  return removed;
13536
13570
  }
13537
13571
  };
@@ -16422,9 +16456,9 @@ var SYS_TREE = {
16422
16456
  `,
16423
16457
  slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
16424
16458
  `,
16425
- slicc_peer_holds: ({ holds: holds2 }) => `${holds2?.mine ?? 0} ${holds2?.peers ?? 0} ${holds2?.sent ?? 0}
16459
+ slicc_peer_holds: ({ holds: holds3 }) => `${holds3?.mine ?? 0} ${holds3?.peers ?? 0} ${holds3?.sent ?? 0}
16426
16460
  `,
16427
- slicc_peer_held: ({ holds: holds2 }) => (holds2?.held ?? []).map((path) => `${path}
16461
+ slicc_peer_held: ({ holds: holds3 }) => (holds3?.held ?? []).map((path) => `${path}
16428
16462
  `).join(""),
16429
16463
  slicc_rename_acks: (listing) => {
16430
16464
  const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
@@ -17165,11 +17199,11 @@ var EpollFile = class _EpollFile {
17165
17199
  const round = new AbortController();
17166
17200
  const stop = () => round.abort();
17167
17201
  signal.addEventListener("abort", stop, { once: true });
17168
- let failed3 = false;
17202
+ let failed4 = false;
17169
17203
  try {
17170
17204
  await file.changed(round.signal);
17171
17205
  } catch {
17172
- failed3 = true;
17206
+ failed4 = true;
17173
17207
  } finally {
17174
17208
  round.abort();
17175
17209
  signal.removeEventListener("abort", stop);
@@ -17177,7 +17211,7 @@ var EpollFile = class _EpollFile {
17177
17211
  if (signal.aborted) return;
17178
17212
  reg.gen++;
17179
17213
  this.changes.wake();
17180
- if (failed3) await pause(RETRY_MS, signal);
17214
+ if (failed4) await pause(RETRY_MS, signal);
17181
17215
  }
17182
17216
  }
17183
17217
  };
@@ -18158,11 +18192,11 @@ function ipv6(host) {
18158
18192
  const back = halves.length === 2 ? groups(halves[1]) : [];
18159
18193
  if (![...head, ...back].every((g) => /^[0-9A-Fa-f]{1,4}$/.test(g))) return void 0;
18160
18194
  const words2 = [...head, ...back].map((g) => Number.parseInt(g, 16));
18161
- const missing5 = 8 - words2.length - tail2.length;
18162
- if (halves.length === 2 ? missing5 < 1 : missing5 !== 0) return void 0;
18195
+ const missing6 = 8 - words2.length - tail2.length;
18196
+ if (halves.length === 2 ? missing6 < 1 : missing6 !== 0) return void 0;
18163
18197
  const all = [
18164
18198
  ...head.map((g) => Number.parseInt(g, 16)),
18165
- ...new Array(halves.length === 2 ? missing5 : 0).fill(0),
18199
+ ...new Array(halves.length === 2 ? missing6 : 0).fill(0),
18166
18200
  ...back.map((g) => Number.parseInt(g, 16)),
18167
18201
  ...tail2
18168
18202
  ];
@@ -19207,10 +19241,12 @@ var HttpHandles = class {
19207
19241
  ws;
19208
19242
  owner;
19209
19243
  local;
19210
- constructor(transport, owner, local2) {
19244
+ stamp;
19245
+ constructor(transport, owner, local2, stamp) {
19211
19246
  this.transport = transport;
19212
19247
  this.owner = owner;
19213
19248
  this.local = local2;
19249
+ this.stamp = stamp;
19214
19250
  this.ws = new WsHandles(transport, () => ++this.nextHandle, local2);
19215
19251
  }
19216
19252
  syscall(req) {
@@ -19286,7 +19322,7 @@ var HttpHandles = class {
19286
19322
  ...entry.upload ? { bodyStream: entry.upload } : req.body ? { body: req.body } : {},
19287
19323
  signal: entry.abort.signal
19288
19324
  };
19289
- const response = port === void 0 ? await this.transport.fetch(request3, this.owner) : await this.local.fetch(request3, port);
19325
+ const response = port === void 0 ? await this.transport.fetch(request3, this.owner, await this.stamp?.()) : await this.local.fetch(request3, port);
19290
19326
  entry.body = response.body[Symbol.asyncIterator]();
19291
19327
  entry.cancel = () => response.cancel();
19292
19328
  if (!this.open.has(handle)) await entry.cancel().catch(() => void 0);
@@ -19308,8 +19344,8 @@ var HttpHandles = class {
19308
19344
  if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
19309
19345
  const code = codeOf2(e);
19310
19346
  const errno3 = text === NO_TRANSPORT ? "ENETUNREACH" : code !== "EIO" ? code : "ECONNREFUSED";
19311
- const failed3 = e.detail === "transport";
19312
- return { ok: false, errno: errno3, message: text, ...failed3 ? { detail: "transport" } : {} };
19347
+ const failed4 = e.detail === "transport";
19348
+ return { ok: false, errno: errno3, message: text, ...failed4 ? { detail: "transport" } : {} };
19313
19349
  }
19314
19350
  entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
19315
19351
  return this.headOf(handle, req.url, {
@@ -21216,7 +21252,7 @@ function pass(c, input, final) {
21216
21252
  const partials = [];
21217
21253
  scanMain(c, input, best, partials);
21218
21254
  scanWrapped(c, input, best, partials);
21219
- const holds2 = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
21255
+ const holds3 = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
21220
21256
  const starts = [...best.keys()].sort((a, b) => a - b);
21221
21257
  const parts2 = [];
21222
21258
  const hits = /* @__PURE__ */ new Map();
@@ -21226,8 +21262,8 @@ function pass(c, input, final) {
21226
21262
  let h = 0;
21227
21263
  for (; ; ) {
21228
21264
  while (s < starts.length && starts[s] < pos) s++;
21229
- while (h < holds2.length && holds2[h] < pos) h++;
21230
- const hold = h < holds2.length ? holds2[h] : Infinity;
21265
+ while (h < holds3.length && holds3[h] < pos) h++;
21266
+ const hold = h < holds3.length ? holds3[h] : Infinity;
21231
21267
  const next3 = s < starts.length ? starts[s] : Infinity;
21232
21268
  if (hold <= next3) {
21233
21269
  cut = Math.min(hold, input.length);
@@ -21329,23 +21365,23 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
21329
21365
  let pending = 0;
21330
21366
  let busy = false;
21331
21367
  let timer;
21332
- let failed3;
21368
+ let failed4;
21333
21369
  const waiters = /* @__PURE__ */ new Set();
21334
21370
  const quiet2 = () => !busy && pending === 0;
21335
21371
  const wake = () => {
21336
21372
  for (const waiter of [...waiters]) waiter();
21337
21373
  };
21338
21374
  const raise = () => {
21339
- if (failed3 === void 0) return;
21340
- const err = failed3;
21341
- failed3 = void 0;
21375
+ if (failed4 === void 0) return;
21376
+ const err = failed4;
21377
+ failed4 = void 0;
21342
21378
  throw err;
21343
21379
  };
21344
21380
  const later = (bytes) => {
21345
21381
  if (bytes.length === 0) return;
21346
21382
  pending += 1;
21347
21383
  tail2 = tail2.then(() => writeAll3(file, bytes)).catch((err) => {
21348
- if (failed3 === void 0) failed3 = err;
21384
+ if (failed4 === void 0) failed4 = err;
21349
21385
  }).finally(() => {
21350
21386
  pending -= 1;
21351
21387
  if (quiet2()) wake();
@@ -24420,7 +24456,7 @@ async function connect(req, proc) {
24420
24456
  }
24421
24457
  const path = filePath(req.addr);
24422
24458
  const name2 = path !== void 0 ? await proc.names?.find(path) : void 0;
24423
- const stamp = proc.net.facadeAt(req.addr) && await proc.stamp?.();
24459
+ const stamp = proc.net.stampsPeers(req.addr) && await proc.stamp?.();
24424
24460
  const dialing = target.connect(req.addr, true, proc.cred?.(), stamp || void 0, true, name2);
24425
24461
  if (req.nonblock) {
24426
24462
  dialing?.catch(() => void 0);
@@ -24542,7 +24578,7 @@ async function secureConnect(req, proc) {
24542
24578
  delete req.clientCert;
24543
24579
  throw new KernelError("ENOTSUP");
24544
24580
  }
24545
- return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
24581
+ return { ...await tlsOverTransport(req, proc), path: "transport", substitutes: true };
24546
24582
  }
24547
24583
  const socket = proc.net.socket("inet");
24548
24584
  const fd = proc.fds.install(new OpenFile(socket), 3);
@@ -24561,7 +24597,7 @@ async function uplinked(proc, host) {
24561
24597
  return false;
24562
24598
  }
24563
24599
  }
24564
- function tlsOverTransport(req, proc) {
24600
+ async function tlsOverTransport(req, proc) {
24565
24601
  if (req.ca) throw new KernelError("ENOTSUP");
24566
24602
  if (req.alpn && req.alpn.length > 0 && !req.alpn.includes("http/1.1")) {
24567
24603
  throw new KernelError("EPROTONOSUPPORT");
@@ -24574,7 +24610,9 @@ function tlsOverTransport(req, proc) {
24574
24610
  if (isLoopbackHost(servername) || isLoopbackHost(req.host)) throw new KernelError("ENOTSUP");
24575
24611
  const host = servername.includes(":") && !servername.startsWith("[") ? `[${servername}]` : servername;
24576
24612
  const origin = req.port === 443 ? `https://${host}` : `https://${host}:${req.port}`;
24613
+ const stamp = proc.net.originsStamped ? await proc.stamp?.() : void 0;
24577
24614
  const [mine, theirs] = KernelSocket.pair(proc.net, "inet", proc.cred?.());
24615
+ theirs.peerStamp = stamp;
24578
24616
  mine.peer = { family: "inet", host: req.host, port: req.port };
24579
24617
  try {
24580
24618
  proc.net.serveOrigin(theirs, origin);
@@ -27733,13 +27771,13 @@ function inherited(opts) {
27733
27771
  ...opts.cred ? { cred: opts.cred } : {}
27734
27772
  };
27735
27773
  }
27736
- function heldBy(process, holds2, replacements) {
27737
- process.keptPath = (path) => holds2.keptAt(path)?.hidden;
27738
- process.keptHandle = (handle) => holds2.keptFor(handle)?.hidden;
27739
- process.holdsHandle = (handle) => holds2.holdsHandle(handle);
27774
+ function heldBy(process, holds3, replacements) {
27775
+ process.keptPath = (path) => holds3.keptAt(path)?.hidden;
27776
+ process.keptHandle = (handle) => holds3.keptFor(handle)?.hidden;
27777
+ process.holdsHandle = (handle) => holds3.holdsHandle(handle);
27740
27778
  if (replacements) process.replacements = replacements;
27741
27779
  }
27742
- function holdingToken(opts, holds2, caller) {
27780
+ function holdingToken(opts, holds3, caller) {
27743
27781
  return mintSyncFsToken({
27744
27782
  ...opts.owners ? caller : { umask: caller.umask },
27745
27783
  ...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
@@ -27756,16 +27794,16 @@ function holdingToken(opts, holds2, caller) {
27756
27794
  ...opts.fileId ? { fileId: opts.fileId } : {},
27757
27795
  ...opts.announceHold ? { announceHold: opts.announceHold } : {},
27758
27796
  ...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
27759
- hold: (path, on, open2, real, handle, ino, fid) => holds2.hold(path, on, open2, real, handle, ino, fid),
27760
- boundIno: holds2.boundIno.bind(holds2),
27761
- trust: holds2.trust.bind(holds2),
27762
- keptFor: (handle) => holds2.keptFor(handle),
27763
- heldAt: (handle) => holds2.pathOf(handle),
27764
- unlinked: (path) => holds2.keptAt(path),
27765
- gate: (path, op) => opts.unlinkGate && holds2.holding(path) ? opts.unlinkGate.run(holds2.keyOf(path), op) : op(),
27766
- own: (path, op) => holds2.own(path, op),
27767
- revoked: (path) => holds2.isRevoked(path),
27768
- renamed: (from, to) => holds2.renamed(from, to)
27797
+ hold: (path, on, open2, real, handle, ino, fid) => holds3.hold(path, on, open2, real, handle, ino, fid),
27798
+ boundIno: holds3.boundIno.bind(holds3),
27799
+ trust: holds3.trust.bind(holds3),
27800
+ keptFor: (handle) => holds3.keptFor(handle),
27801
+ heldAt: (handle) => holds3.pathOf(handle),
27802
+ unlinked: (path) => holds3.keptAt(path),
27803
+ gate: (path, op) => opts.unlinkGate && holds3.holding(path) ? opts.unlinkGate.run(holds3.keyOf(path), op) : op(),
27804
+ own: (path, op) => holds3.own(path, op),
27805
+ revoked: (path) => holds3.isRevoked(path),
27806
+ renamed: (from, to) => holds3.renamed(from, to)
27769
27807
  });
27770
27808
  }
27771
27809
  function linksOf(opts) {
@@ -27922,15 +27960,15 @@ function spawnWasmProcess(opts) {
27922
27960
  )
27923
27961
  );
27924
27962
  publishStops(process, header4);
27925
- const holds2 = new HeldPaths();
27926
- opts.held?.add(holds2);
27927
- const token = holdingToken(opts, holds2, {
27963
+ const holds3 = new HeldPaths();
27964
+ opts.held?.add(holds3);
27965
+ const token = holdingToken(opts, holds3, {
27928
27966
  cred: () => process.cred,
27929
27967
  umask: () => process.umask,
27930
27968
  created: created4,
27931
- holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds2.keeps(path) || await process.holds(path))
27969
+ holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds3.keeps(path) || await process.holds(path))
27932
27970
  });
27933
- heldBy(process, holds2, opts.replacements);
27971
+ heldBy(process, holds3, opts.replacements);
27934
27972
  const worker = opts.createWorker();
27935
27973
  const dying = new Dying();
27936
27974
  const dispatch2 = (req, block) => dying.serve(
@@ -27962,7 +28000,7 @@ function spawnWasmProcess(opts) {
27962
28000
  responder.dispose();
27963
28001
  lane?.dispose();
27964
28002
  revokeSyncFsToken(token);
27965
- opts.held?.delete(holds2);
28003
+ opts.held?.delete(holds3);
27966
28004
  worker.terminate();
27967
28005
  settleExit(process.exit(), settle3, code);
27968
28006
  };
@@ -29148,7 +29186,7 @@ var RemoteTransport = class {
29148
29186
  waiter?.reject(new TransportError("the request was cancelled"));
29149
29187
  this.port.postMessage({ net: "cancel", nid });
29150
29188
  }
29151
- async fetch(request3) {
29189
+ async fetch(request3, owner, stamp) {
29152
29190
  const nid = ++this.nextId;
29153
29191
  const { signal, redirect } = request3;
29154
29192
  signal.throwIfAborted();
@@ -29178,7 +29216,9 @@ var RemoteTransport = class {
29178
29216
  method: request3.method,
29179
29217
  headers: request3.headers,
29180
29218
  ...request3.bodyStream ? { streamed: true } : request3.body ? { body: request3.body } : {},
29181
- ...redirect !== void 0 ? { redirect } : {}
29219
+ ...redirect !== void 0 ? { redirect } : {},
29220
+ ...owner !== void 0 ? { owner } : {},
29221
+ ...stamp ? { stamp } : {}
29182
29222
  });
29183
29223
  } catch (e) {
29184
29224
  finish();
@@ -29369,6 +29409,143 @@ function replayingHops(inner, heldMs = HELD_MS) {
29369
29409
  };
29370
29410
  }
29371
29411
 
29412
+ // src/kernel/net/sealed-fetch.ts
29413
+ var UNSAFE_FIELD = /[\r\n\0]/;
29414
+ function headerList(headers) {
29415
+ return Array.isArray(headers) && headers.every(
29416
+ (field4) => Array.isArray(field4) && field4.length === 2 && field4.every((text) => typeof text === "string" && !UNSAFE_FIELD.test(text))
29417
+ );
29418
+ }
29419
+ function sealedReplyValid(reply) {
29420
+ if (typeof reply !== "object" || reply === null) return false;
29421
+ const { redirects, redirected: redirected2, status, statusText, headers, url, body, cancel } = reply;
29422
+ 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";
29423
+ }
29424
+ function dropSealedReply(reply) {
29425
+ const { cancel } = reply ?? {};
29426
+ if (typeof cancel !== "function") return;
29427
+ void Promise.resolve().then(() => cancel.call(reply)).catch(() => void 0);
29428
+ }
29429
+ function failed2(reason) {
29430
+ const text = reason instanceof Error ? reason.message : String(reason);
29431
+ return new PlaceholderRefused(
29432
+ `refused: the request with a sealed placeholder was not completed: ${text}`
29433
+ );
29434
+ }
29435
+ var Stall = class {
29436
+ idle = new AbortController();
29437
+ ms;
29438
+ timer;
29439
+ signal;
29440
+ constructor(signals, ms) {
29441
+ this.ms = ms;
29442
+ this.signal = AbortSignal.any([...signals, this.idle.signal]);
29443
+ }
29444
+ arm() {
29445
+ clearTimeout(this.timer);
29446
+ this.timer = setTimeout(() => this.idle.abort("timeout"), this.ms);
29447
+ this.timer.unref?.();
29448
+ }
29449
+ touch() {
29450
+ if (this.timer !== void 0) this.arm();
29451
+ }
29452
+ rest() {
29453
+ clearTimeout(this.timer);
29454
+ this.timer = void 0;
29455
+ }
29456
+ };
29457
+ async function until(work, signal) {
29458
+ const stopped = Promise.withResolvers();
29459
+ const stop = () => stopped.reject(signal.reason);
29460
+ if (signal.aborted) stop();
29461
+ else signal.addEventListener("abort", stop, { once: true });
29462
+ try {
29463
+ return await Promise.race([work, stopped.promise]);
29464
+ } finally {
29465
+ signal.removeEventListener("abort", stop);
29466
+ }
29467
+ }
29468
+ async function* ticking(stream, stall) {
29469
+ for await (const chunk2 of stream) {
29470
+ stall.touch();
29471
+ yield chunk2;
29472
+ }
29473
+ }
29474
+ function sealedRequest(request3, stamp, stall) {
29475
+ const { method, url, headers, body, bodyStream } = request3;
29476
+ return {
29477
+ v: 1,
29478
+ caller: structuredClone(stamp),
29479
+ method,
29480
+ url,
29481
+ headers: headers.map(([name2, value2]) => [name2, value2]),
29482
+ redirect: "manual",
29483
+ ...bodyStream ? { bodyStream: ticking(bodyStream, stall) } : body ? { body } : {}
29484
+ };
29485
+ }
29486
+ function guarded2(reply, stall) {
29487
+ let finished = false;
29488
+ const cancel = async () => {
29489
+ stall.signal.removeEventListener("abort", dropped2);
29490
+ stall.rest();
29491
+ if (finished) return;
29492
+ finished = true;
29493
+ await reply.cancel().catch(() => void 0);
29494
+ };
29495
+ const dropped2 = () => void cancel();
29496
+ stall.signal.addEventListener("abort", dropped2, { once: true });
29497
+ const source = reply.body[Symbol.asyncIterator]();
29498
+ const body = (async function* () {
29499
+ try {
29500
+ for (; ; ) {
29501
+ stall.arm();
29502
+ const next3 = await until(source.next(), stall.signal);
29503
+ stall.rest();
29504
+ if (next3.done) {
29505
+ finished = true;
29506
+ return;
29507
+ }
29508
+ if (!(next3.value instanceof Uint8Array)) throw failed2("a body chunk is not bytes");
29509
+ if (next3.value.byteLength > 0) yield next3.value;
29510
+ }
29511
+ } finally {
29512
+ await cancel();
29513
+ }
29514
+ })();
29515
+ return {
29516
+ ...reply.url !== void 0 ? { url: reply.url } : {},
29517
+ status: reply.status,
29518
+ statusText: reply.statusText,
29519
+ headers: reply.headers,
29520
+ body,
29521
+ cancel
29522
+ };
29523
+ }
29524
+ function sealedFetcher(hook, stop, idleMs = BODY_IDLE_MS) {
29525
+ return async (request3, stamp) => {
29526
+ const stall = new Stall([request3.signal, stop], idleMs);
29527
+ const { signal } = stall;
29528
+ if (signal.aborted) throw failed2(signal.reason);
29529
+ stall.arm();
29530
+ const asked = Promise.resolve().then(() => {
29531
+ signal.throwIfAborted();
29532
+ return hook(sealedRequest(request3, stamp, stall), { signal });
29533
+ });
29534
+ let reply;
29535
+ try {
29536
+ reply = await until(asked, signal);
29537
+ } catch (e) {
29538
+ void asked.then(dropSealedReply, () => void 0);
29539
+ throw failed2(e);
29540
+ } finally {
29541
+ stall.rest();
29542
+ }
29543
+ if (sealedReplyValid(reply)) return guarded2(reply, stall);
29544
+ dropSealedReply(reply);
29545
+ throw failed2("the reply is not a scrubbed response");
29546
+ };
29547
+ }
29548
+
29372
29549
  // src/kernel/package-swaps.ts
29373
29550
  var SWAP_GAP_MS = 2e3;
29374
29551
  var STAGES = ["_tmp_", "_pacquet-stage_"];
@@ -29541,11 +29718,11 @@ var PackageLocks = class {
29541
29718
  if (!locks) return Promise.resolve(() => {
29542
29719
  });
29543
29720
  const { promise: held, resolve: release } = Promise.withResolvers();
29544
- return new Promise((granted2, failed3) => {
29721
+ return new Promise((granted2, failed4) => {
29545
29722
  locks.request(replacingLock(this.metadata, root), { mode: "exclusive" }, () => {
29546
29723
  granted2(() => release());
29547
29724
  return held;
29548
- }).catch(failed3);
29725
+ }).catch(failed4);
29549
29726
  });
29550
29727
  }
29551
29728
  };
@@ -30147,22 +30324,22 @@ async function mountFstab(lines2, mount, signal, retries = FSTAB_RETRIES, discar
30147
30324
  );
30148
30325
  }
30149
30326
  async function mountLine({ line, spec, invalid }, mount, signal, retries, discard) {
30150
- let failed3 = invalid;
30327
+ let failed4 = invalid;
30151
30328
  for (let attempt = 0; !invalid && attempt <= retries.length && !signal.aborted; attempt++) {
30152
30329
  try {
30153
30330
  const entry = await mount(spec);
30154
30331
  if (!signal.aborted) return { line, target: spec.target, entry };
30155
30332
  discard(entry);
30156
- failed3 = Object.assign(new Error("the kernel stopped"), { code: "ECANCELED" });
30333
+ failed4 = Object.assign(new Error("the kernel stopped"), { code: "ECANCELED" });
30157
30334
  break;
30158
30335
  } catch (err) {
30159
- failed3 = err;
30336
+ failed4 = err;
30160
30337
  if (FINAL.has(codeOf6(err)) || attempt === retries.length) break;
30161
30338
  await wait(retries[attempt], signal);
30162
30339
  }
30163
30340
  }
30164
- const code = codeOf6(failed3);
30165
- return { line, target: spec.target, code, error: String(failed3?.message ?? code) };
30341
+ const code = codeOf6(failed4);
30342
+ return { line, target: spec.target, code, error: String(failed4?.message ?? code) };
30166
30343
  }
30167
30344
 
30168
30345
  // src/mount/hostfs.ts
@@ -31336,7 +31513,7 @@ var RULE = new RegExp(
31336
31513
  var TERM = /^[A-Za-z0-9._+-]+$/;
31337
31514
  var PLAIN3 = /^[A-Za-z0-9_@%+=:,./-]+$/;
31338
31515
  var USAGE = "usage: sudo [-n] [-u user] [--] command [args...]\n sudo -l";
31339
- function failed2(errno3, error) {
31516
+ function failed3(errno3, error) {
31340
31517
  return { error, errno: errno3 };
31341
31518
  }
31342
31519
  function unescaped(double) {
@@ -31515,10 +31692,10 @@ var Sudo = class {
31515
31692
  }
31516
31693
  async untrusted(path, cwd, word) {
31517
31694
  const files = this.o.backing ? await this.o.backing(path, cwd) : [];
31518
- if (!files) return failed2("ENOENT", `sudo: ${word}: command not found`);
31695
+ if (!files) return failed3("ENOENT", `sudo: ${word}: command not found`);
31519
31696
  for (const file of [path, ...files]) {
31520
31697
  if (!await this.trusted(file)) {
31521
- return failed2("EPERM", `sudo: ${file} must be root's, and writable by root only`);
31698
+ return failed3("EPERM", `sudo: ${file} must be root's, and writable by root only`);
31522
31699
  }
31523
31700
  }
31524
31701
  return void 0;
@@ -31535,7 +31712,7 @@ var Sudo = class {
31535
31712
  }
31536
31713
  async request(caller, call, signal) {
31537
31714
  const parsed2 = parseArgs(call.args);
31538
- if (typeof parsed2 === "string") return failed2("EINVAL", parsed2);
31715
+ if (typeof parsed2 === "string") return failed3("EINVAL", parsed2);
31539
31716
  if (this.o.mode !== "enforce") {
31540
31717
  const mode = this.o.mode;
31541
31718
  if (parsed2.list) return { list: `sudo: users are '${mode}': commands run as the caller
@@ -31544,9 +31721,9 @@ var Sudo = class {
31544
31721
  }
31545
31722
  const { cred } = caller;
31546
31723
  const self = await this.o.users.lookup(cred.ruid);
31547
- if (!self) return failed2("EPERM", `sudo: uid ${cred.ruid} is not in the passwd database`);
31724
+ if (!self) return failed3("EPERM", `sudo: uid ${cred.ruid} is not in the passwd database`);
31548
31725
  const target = await this.lookup(parsed2.user);
31549
- if (!target) return failed2("ENOENT", `sudo: unknown user ${parsed2.user}`);
31726
+ if (!target) return failed3("ENOENT", `sudo: unknown user ${parsed2.user}`);
31550
31727
  const root = cred.euid === 0;
31551
31728
  const rules = root ? [] : await this.policy();
31552
31729
  const applies = await this.applies(self, cred);
@@ -31554,13 +31731,13 @@ var Sudo = class {
31554
31731
  const [word = "", ...args] = parsed2.command;
31555
31732
  const cwd = await this.canonical(call.cwd);
31556
31733
  if (cwd === void 0 || !await this.reachable(cred, cwd)) {
31557
- return failed2(
31734
+ return failed3(
31558
31735
  "EACCES",
31559
31736
  `sudo: cannot run in ${call.cwd}: it isn't a directory you can enter`
31560
31737
  );
31561
31738
  }
31562
31739
  const path = await this.locate(word, cwd);
31563
- if (!path) return failed2("ENOENT", `sudo: ${word}: command not found`);
31740
+ if (!path) return failed3("ENOENT", `sudo: ${word}: command not found`);
31564
31741
  const untrusted2 = await this.untrusted(path, cwd, word);
31565
31742
  if (untrusted2) return untrusted2;
31566
31743
  const argv = [path, ...args];
@@ -31571,24 +31748,24 @@ var Sudo = class {
31571
31748
  if (root || matching.some((rule) => rule.nopasswd)) return grant();
31572
31749
  const quoted = argv.map(quoteWord).join(" ");
31573
31750
  if (matching.length === 0) {
31574
- return failed2(
31751
+ return failed3(
31575
31752
  "EPERM",
31576
31753
  `sudo: ${self.name} is not allowed to run ${quoted} as ${target.name}`
31577
31754
  );
31578
31755
  }
31579
- if (parsed2.nonInteractive) return failed2("EPERM", "sudo: a password is required");
31580
- if (this.pending.has(cred.ruid)) return failed2("EBUSY", "sudo: another request is pending");
31756
+ if (parsed2.nonInteractive) return failed3("EPERM", "sudo: a password is required");
31757
+ if (this.pending.has(cred.ruid)) return failed3("EBUSY", "sudo: another request is pending");
31581
31758
  this.pending.add(cred.ruid);
31582
31759
  try {
31583
31760
  const answer2 = await this.ask(caller, self, target, parsed2.command, path, cwd, signal);
31584
31761
  if (typeof answer2 !== "string") return answer2;
31585
31762
  if (await this.canonical(call.cwd) !== cwd || !await this.reachable(cred, cwd)) {
31586
- return failed2("EACCES", `sudo: ${call.cwd} changed while the request waited`);
31763
+ return failed3("EACCES", `sudo: ${call.cwd} changed while the request waited`);
31587
31764
  }
31588
31765
  const changed = await this.untrusted(path, cwd, word);
31589
31766
  if (changed) return changed;
31590
31767
  if (answer2 === "always" && !await this.remember(self, target, cwd, argv)) {
31591
- return failed2("EIO", "sudo: the rule could not be recorded");
31768
+ return failed3("EIO", "sudo: the rule could not be recorded");
31592
31769
  }
31593
31770
  return grant();
31594
31771
  } finally {
@@ -31605,7 +31782,7 @@ var Sudo = class {
31605
31782
  };
31606
31783
  }
31607
31784
  if (rules.length === 0) {
31608
- return failed2("EPERM", `User ${self.name} is not allowed to run sudo on ${host}.`);
31785
+ return failed3("EPERM", `User ${self.name} is not allowed to run sudo on ${host}.`);
31609
31786
  }
31610
31787
  const lines2 = rules.map(described).join("\n");
31611
31788
  return { list: `User ${self.name} may run the following commands on ${host}:
@@ -31614,7 +31791,7 @@ ${lines2}
31614
31791
  }
31615
31792
  async ask(caller, self, target, argv, path, cwd, requester) {
31616
31793
  const { approve } = this.o;
31617
- if (!approve || requester.aborted) return failed2("EACCES", "sudo: approval denied");
31794
+ if (!approve || requester.aborted) return failed3("EACCES", "sudo: approval denied");
31618
31795
  const createdAt = Date.now();
31619
31796
  const timeout = this.o.timeoutMs ?? SUDO_TIMEOUT_MS;
31620
31797
  const req = {
@@ -31644,9 +31821,9 @@ ${lines2}
31644
31821
  const answered2 = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
31645
31822
  const answer2 = await Promise.race([answered2, aborted3]);
31646
31823
  if (answer2 === "aborted" || control.signal.aborted) {
31647
- return control.signal.reason === "expired" ? failed2("ETIMEDOUT", "sudo: the request expired") : failed2("EINTR", "sudo: the request was withdrawn");
31824
+ return control.signal.reason === "expired" ? failed3("ETIMEDOUT", "sudo: the request expired") : failed3("EINTR", "sudo: the request was withdrawn");
31648
31825
  }
31649
- return answer2 === "once" || answer2 === "always" ? answer2 : failed2("EACCES", "sudo: approval denied");
31826
+ return answer2 === "once" || answer2 === "always" ? answer2 : failed3("EACCES", "sudo: approval denied");
31650
31827
  } finally {
31651
31828
  clearTimeout(timer);
31652
31829
  requester.removeEventListener("abort", withdraw);
@@ -31937,13 +32114,13 @@ function interpreter(head) {
31937
32114
  function expandDefaults(defaults2, env) {
31938
32115
  const out = {};
31939
32116
  for (const [key, value2] of Object.entries(defaults2 ?? {})) {
31940
- let missing5 = false;
32117
+ let missing6 = false;
31941
32118
  const expanded = value2.replace(ENV_REFERENCE, (_, name2) => {
31942
32119
  const set3 = Object.hasOwn(env, name2) ? env[name2] : void 0;
31943
- if (set3 === void 0) missing5 = true;
32120
+ if (set3 === void 0) missing6 = true;
31944
32121
  return set3 ?? "";
31945
32122
  });
31946
- if (!missing5) out[key] = expanded;
32123
+ if (!missing6) out[key] = expanded;
31947
32124
  }
31948
32125
  return out;
31949
32126
  }
@@ -32118,6 +32295,9 @@ var Launcher = class {
32118
32295
  usersMode;
32119
32296
  dac;
32120
32297
  sealed;
32298
+ fill;
32299
+ fills = new AbortController();
32300
+ placeholders = [];
32121
32301
  scrubs = /* @__PURE__ */ new Map();
32122
32302
  clipboard;
32123
32303
  embedder;
@@ -32199,7 +32379,7 @@ var Launcher = class {
32199
32379
  ...options.env
32200
32380
  };
32201
32381
  this.ca = kernelCa(options.caStore ?? memoryCaStore());
32202
- this.transport = placeholderFloor(replayingHops(options.transport ?? missingTransport()));
32382
+ this.transport = this.floored(options);
32203
32383
  this.announcedTraits = JSON.stringify(this.transport.traits);
32204
32384
  this.uplink = options.uplink;
32205
32385
  this.routes = new Routes(options.uplink?.traits.ipv6 === true);
@@ -33261,6 +33441,19 @@ var Launcher = class {
33261
33441
  groupSession(pgid) {
33262
33442
  return this.jobs.sessionOf(pgid);
33263
33443
  }
33444
+ floored(options) {
33445
+ const { sealedFetch } = options;
33446
+ this.fill = sealedFetch && this.usersMode === "enforce" ? sealedFetcher(sealedFetch, this.fills.signal) : void 0;
33447
+ if (this.fill) this.net.stampProxy(REALM_PROXY_PORT);
33448
+ return placeholderFloor(replayingHops(options.transport ?? missingTransport()), {
33449
+ known: () => this.placeholders,
33450
+ ...this.fill ? { fill: this.fill } : {}
33451
+ });
33452
+ }
33453
+ httpFor(pid) {
33454
+ const stamp = this.fill ? () => this.liveStamp(pid) : void 0;
33455
+ return new HttpHandles(this.transport, pid, this.loopbackFor(pid), stamp);
33456
+ }
33264
33457
  loopbackFor(pid) {
33265
33458
  return new KernelLoopback(
33266
33459
  this.net,
@@ -33268,7 +33461,7 @@ var Launcher = class {
33268
33461
  const cred = this.credOf(pid);
33269
33462
  return { pid, uid: cred.euid, gid: cred.egid };
33270
33463
  },
33271
- () => this.connectorStamp(pid)
33464
+ () => this.liveStamp(pid)
33272
33465
  );
33273
33466
  }
33274
33467
  sourceCheck(pid, writer) {
@@ -33433,7 +33626,7 @@ var Launcher = class {
33433
33626
  jobs: this.jobs,
33434
33627
  ptys: this.ptys,
33435
33628
  net: this.net,
33436
- http: new HttpHandles(this.transport, pid, this.loopbackFor(pid)),
33629
+ http: this.httpFor(pid),
33437
33630
  locks: this.locks,
33438
33631
  fifos: this.fifos,
33439
33632
  sems: this.sems,
@@ -33748,6 +33941,19 @@ var Launcher = class {
33748
33941
  connectorStamp(pid) {
33749
33942
  return this.sealed.stamp(this.identityOf(pid), this.credOf(pid), this.tagsOf(pid));
33750
33943
  }
33944
+ async liveStamp(pid) {
33945
+ if (!this.creds.has(pid) || this.zombies.has(pid)) return void 0;
33946
+ return this.connectorStamp(pid);
33947
+ }
33948
+ setPlaceholders(list) {
33949
+ if (!Array.isArray(list) || !list.every((p) => typeof p === "string" && p !== "")) {
33950
+ throw fsError("EINVAL", "setPlaceholders takes a list of non-empty strings");
33951
+ }
33952
+ this.placeholders = [...list];
33953
+ }
33954
+ endFills() {
33955
+ this.fills.abort("terminated");
33956
+ }
33751
33957
  identityOf(pid) {
33752
33958
  const parent = this.jobs.shownParent(pid);
33753
33959
  const alive = parent !== void 0 && this.running(parent);
@@ -33870,7 +34076,7 @@ var Launcher = class {
33870
34076
  const at = normalizePath(path);
33871
34077
  this.unlinked.closed(at);
33872
34078
  this.writers?.unlinked.closed(at);
33873
- const holding = [...this.held].some((holds2) => holds2.holding(at)) || [...this.openFiles].some((open3) => open3.holdsAt(at));
34079
+ const holding = [...this.held].some((holds3) => holds3.holding(at)) || [...this.openFiles].some((open3) => open3.holdsAt(at));
33874
34080
  if (!holding) void this.rootFs.announceHolds?.([], [at], false);
33875
34081
  const open2 = [...this.openFiles].some((nodes) => nodes.writes(at)) || heldUnder(this.held, at);
33876
34082
  if (!open2) void this.mounts.commit(at).catch(() => void 0);
@@ -34033,8 +34239,9 @@ var Launcher = class {
34033
34239
  for (const root of roots) this.integrity.forget(root);
34034
34240
  this.resetCatalogs();
34035
34241
  }
34036
- attest(path) {
34242
+ attest(path, options = {}) {
34037
34243
  return attest(this.rootFs, path, {
34244
+ ...options,
34038
34245
  users: this.usersMode,
34039
34246
  mounts: this.mounts.list().map((entry) => entry.target).filter((target) => this.mounts.mounted(target) !== void 0)
34040
34247
  });
@@ -34091,8 +34298,8 @@ var Launcher = class {
34091
34298
  for (const name2 of names2 ?? []) {
34092
34299
  const path = joinName(real, name2);
34093
34300
  if (await this.base.hasOwner(path)) continue;
34094
- const failed3 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
34095
- if (failed3 === void 0) removed++;
34301
+ const failed4 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
34302
+ if (failed4 === void 0) removed++;
34096
34303
  else left++;
34097
34304
  }
34098
34305
  if (removed > 0) {
@@ -34187,7 +34394,7 @@ var Launcher = class {
34187
34394
  this.pnpmStale();
34188
34395
  if (!detach) return;
34189
34396
  for (const nodes of this.openFiles) nodes.revoke(at);
34190
- for (const holds2 of this.held) holds2.revoke(at);
34397
+ for (const holds3 of this.held) holds3.revoke(at);
34191
34398
  }
34192
34399
  unmountAll() {
34193
34400
  this.cron.stop();
@@ -34398,9 +34605,9 @@ var Launcher = class {
34398
34605
  }
34399
34606
  boundTo(path, hidden, fids) {
34400
34607
  const keeping = [...this.held].map(
34401
- (holds2) => [
34402
- holds2,
34403
- fids.flatMap((fid) => [...holds2.boundAt(path, fid), ...holds2.boundAt(hidden, fid)])
34608
+ (holds3) => [
34609
+ holds3,
34610
+ fids.flatMap((fid) => [...holds3.boundAt(path, fid), ...holds3.boundAt(hidden, fid)])
34404
34611
  ]
34405
34612
  ).filter(([, ids]) => ids.length > 0);
34406
34613
  const nodes = [...this.openFiles].filter(
@@ -34411,7 +34618,7 @@ var Launcher = class {
34411
34618
  (open2) => fids.some((fid) => open2.keepBound([hidden, path], fid, file))
34412
34619
  ).length;
34413
34620
  for (let i = kept; i < nodes.length; i++) file.release();
34414
- for (const [holds2, ids] of keeping) holds2.keepBound(ids, path, file);
34621
+ for (const [holds3, ids] of keeping) holds3.keepBound(ids, path, file);
34415
34622
  void this.rootFs.announceHolds?.([], [path, hidden], false);
34416
34623
  };
34417
34624
  return { keeping, nodes, keep: keep2 };
@@ -34571,7 +34778,7 @@ var Launcher = class {
34571
34778
  }
34572
34779
  moved(from, to, source) {
34573
34780
  this.renameLog.add(from, to);
34574
- for (const holds2 of this.held) holds2.renamed(from, to);
34781
+ for (const holds3 of this.held) holds3.renamed(from, to);
34575
34782
  if (source) return;
34576
34783
  for (const nodes of this.openFiles) nodes.renamed(from, to);
34577
34784
  this.watchers.moved(from, to);
@@ -34784,6 +34991,98 @@ function integrityAsker(port) {
34784
34991
  }
34785
34992
 
34786
34993
  // src/sealed-relay.ts
34994
+ function textOf(err) {
34995
+ return err instanceof Error ? err.message : String(err);
34996
+ }
34997
+ function sendBytes(port, bytes) {
34998
+ const copy = fresh(bytes);
34999
+ port.postMessage({ t: "chunk", bytes: copy }, [copy.buffer]);
35000
+ }
35001
+ function askFetch(port, req, signal) {
35002
+ signal.throwIfAborted();
35003
+ const { bodyStream, ...wire } = req;
35004
+ const { port1: near, port2: far } = new MessageChannel();
35005
+ const upload = bodyStream?.[Symbol.asyncIterator]();
35006
+ const head = Promise.withResolvers();
35007
+ let reading;
35008
+ let ended = false;
35009
+ const end = (failure2) => {
35010
+ if (ended) return;
35011
+ ended = true;
35012
+ signal.removeEventListener("abort", abort);
35013
+ near.close();
35014
+ void upload?.return?.().catch(() => void 0);
35015
+ head.reject(failure2);
35016
+ reading?.reject(failure2);
35017
+ reading = void 0;
35018
+ };
35019
+ const abort = () => {
35020
+ near.postMessage({ t: "cancel", reason: String(signal.reason) });
35021
+ end(new Error(String(signal.reason)));
35022
+ };
35023
+ const pull = async () => {
35024
+ try {
35025
+ const next3 = await upload.next();
35026
+ if (ended) return;
35027
+ if (next3.done) near.postMessage({ t: "end" });
35028
+ else sendBytes(near, next3.value);
35029
+ } catch (err) {
35030
+ if (!ended) near.postMessage({ t: "error", message: textOf(err) });
35031
+ }
35032
+ };
35033
+ const respond2 = (message3) => {
35034
+ const { status, statusText, headers, url } = message3;
35035
+ const body = {
35036
+ [Symbol.asyncIterator]: () => ({
35037
+ next: () => {
35038
+ if (ended) return Promise.resolve({ value: void 0, done: true });
35039
+ reading = Promise.withResolvers();
35040
+ near.postMessage({ t: "read" });
35041
+ return reading.promise;
35042
+ },
35043
+ return: async () => {
35044
+ await cancel();
35045
+ return { value: void 0, done: true };
35046
+ }
35047
+ })
35048
+ };
35049
+ const cancel = async () => {
35050
+ if (ended) return;
35051
+ near.postMessage({ t: "cancel", reason: "cancelled" });
35052
+ end(new Error("the request was cancelled"));
35053
+ };
35054
+ head.resolve({
35055
+ ...url !== void 0 ? { url } : {},
35056
+ status,
35057
+ statusText,
35058
+ headers,
35059
+ body,
35060
+ cancel
35061
+ });
35062
+ };
35063
+ near.addEventListener("message", ({ data }) => {
35064
+ if (data.t === "pull") void pull();
35065
+ else if (data.t === "stop") void upload?.return?.().catch(() => void 0);
35066
+ else if (data.t === "head") respond2(data);
35067
+ else if (data.t === "chunk") {
35068
+ reading?.resolve({ value: data.bytes, done: false });
35069
+ reading = void 0;
35070
+ } else if (data.t === "end") {
35071
+ reading?.resolve({ value: void 0, done: true });
35072
+ reading = void 0;
35073
+ end(new Error("the response ended"));
35074
+ } else end(new Error(data.message));
35075
+ });
35076
+ near.addEventListener("close", () => end(new Error("the sealed fetch relay closed")));
35077
+ near.start();
35078
+ signal.addEventListener("abort", abort, { once: true });
35079
+ const ask = {
35080
+ req: { ...wire, ...upload ? { streamed: true } : {} },
35081
+ port: far
35082
+ };
35083
+ port.postMessage({ sealedFetch: ask }, [far]);
35084
+ return head.promise;
35085
+ }
34787
35086
  function sealedAsker(port) {
34788
35087
  const asks = /* @__PURE__ */ new Map();
34789
35088
  let next3 = 0;
@@ -34807,7 +35106,7 @@ function sealedAsker(port) {
34807
35106
  if (reply) waiting.resolve(reply);
34808
35107
  else waiting.reject(new Error(error ?? "no reply"));
34809
35108
  };
34810
- return { hook, answer: answer2 };
35109
+ return { hook, fetch: (req, { signal }) => askFetch(port, req, signal), answer: answer2 };
34811
35110
  }
34812
35111
 
34813
35112
  // src/serve.ts
@@ -34965,13 +35264,15 @@ function transferOf2(req, result) {
34965
35264
  if (result instanceof MessagePort) return [result];
34966
35265
  const bound3 = result?.port;
34967
35266
  if (req.op === "connect" && bound3 instanceof MessagePort) return [bound3];
34968
- if (req.op === "attest") return [result.bytes.buffer];
35267
+ if (req.op === "attest" && "bytes" in result) {
35268
+ return [result.bytes.buffer];
35269
+ }
34969
35270
  return void 0;
34970
35271
  }
34971
35272
  function attestOps(port) {
34972
35273
  const watches = /* @__PURE__ */ new Map();
34973
35274
  return async (l, req) => {
34974
- if (req.op === "attest") return l.attest(req.path);
35275
+ if (req.op === "attest") return l.attest(req.path, req.options);
34975
35276
  if (req.op === "chmod") return l.fs.chmod(req.path, modeOption(req.mode)).then(() => true);
34976
35277
  if (req.op === "integrity-revoke") return l.revokeIntegrity(req.path).then(() => true);
34977
35278
  if (req.op === "unwatch-files") {
@@ -35026,7 +35327,7 @@ async function connectClient(deps, { user, tag, bind: bind2 }) {
35026
35327
  });
35027
35328
  return unbind ? { port: port2, client } : port2;
35028
35329
  }
35029
- function hostOptions(req, port, sealed, clipboard, lookup2, requests) {
35330
+ function hostOptions(req, port, sealed, sealedFetch, clipboard, lookup2, requests) {
35030
35331
  return {
35031
35332
  cron: { lock: `slicc-kernel-cron:${req.metadata ?? META_DB}` },
35032
35333
  ...req.hostname !== void 0 ? { hostname: req.hostname } : {},
@@ -35035,6 +35336,7 @@ function hostOptions(req, port, sealed, clipboard, lookup2, requests) {
35035
35336
  ...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {},
35036
35337
  ...req.protect ? { protect: hostProtect(req.protect, lookup2) } : {},
35037
35338
  ...req.sealed ? { sealed } : {},
35339
+ ...req.sealedFetch ? { sealedFetch } : {},
35038
35340
  ...req.clipboard ? { clipboard } : {},
35039
35341
  ...req.requests ? { embedder: requests.hookFor(0, req.requests) } : {}
35040
35342
  };
@@ -35125,7 +35427,15 @@ function serveKernel(port, deps) {
35125
35427
  ...req.modules ? { modules: req.modules } : {},
35126
35428
  ...req.commands ? { commands: req.commands } : {},
35127
35429
  ...req.env ? { env: req.env } : {},
35128
- ...hostOptions(req, port, sealed.hook, clipboard.hook, integrity.lookup, requests),
35430
+ ...hostOptions(
35431
+ req,
35432
+ port,
35433
+ sealed.hook,
35434
+ sealed.fetch,
35435
+ clipboard.hook,
35436
+ integrity.lookup,
35437
+ requests
35438
+ ),
35129
35439
  ...req.approve ? { approve: approvals.ask } : {},
35130
35440
  ...net,
35131
35441
  ...media ? { media } : {},
@@ -35152,6 +35462,7 @@ function serveKernel(port, deps) {
35152
35462
  async function handle(req) {
35153
35463
  if (req.op === "init") return init(req);
35154
35464
  if (isAttestRequest(req)) return attestOp(await ready2(), req);
35465
+ if (req.op === "sealed-placeholders") return (await ready2()).setPlaceholders(req.list);
35155
35466
  if (req.op === "open-terminal") return terminal(req);
35156
35467
  if (req.op === "connect") return connect2(req.user, req.tag, req.requests);
35157
35468
  if (isUsersRequest(req)) return usersOp(await ready2(), req);