@ai-ecoverse/slicc-kernel 1.133.4 → 1.134.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.js CHANGED
@@ -5564,6 +5564,9 @@ var OpfsFs = class {
5564
5564
  }
5565
5565
  }
5566
5566
  await this.meta.remove([found.path]);
5567
+ if (found.handle?.kind === "directory") {
5568
+ await this.meta.update(found.path, (entry) => entry ?? vacatedAt(found.path));
5569
+ }
5567
5570
  this.touch(Date.now(), parentOf4(found.path));
5568
5571
  }
5569
5572
  links() {
@@ -7461,7 +7464,7 @@ function satisfies(version, range2) {
7461
7464
  }
7462
7465
 
7463
7466
  // src/version.ts
7464
- var KERNEL_VERSION = true ? "1.133.4" : "0.0.0-dev";
7467
+ var KERNEL_VERSION = true ? "1.134.0" : "0.0.0-dev";
7465
7468
  var OS_RELEASE = "6.0.0-slicc";
7466
7469
  function procVersion() {
7467
7470
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -10795,6 +10798,88 @@ var FifoTable = class {
10795
10798
  }
10796
10799
  };
10797
10800
 
10801
+ // src/kernel/held-cwd.ts
10802
+ var CWD_SLOTS = 1024;
10803
+ var UNTRACKED = CWD_SLOTS - 1;
10804
+ var under4 = (path, changed) => changed === "/" || path === changed || path.startsWith(`${changed}/`);
10805
+ var CwdTable = class {
10806
+ sab = new SharedArrayBuffer(CWD_SLOTS * 4);
10807
+ view = new Int32Array(this.sab);
10808
+ held = /* @__PURE__ */ new Map();
10809
+ free = [];
10810
+ next = 0;
10811
+ checks = 0;
10812
+ inodeOf;
10813
+ constructor(inodeOf2) {
10814
+ this.inodeOf = inodeOf2;
10815
+ }
10816
+ async hold(path, from) {
10817
+ const shared = from === void 0 ? void 0 : this.held.get(from);
10818
+ if (shared && shared.path === path) return this.share(from);
10819
+ const ino = await this.inodeOf(path).catch(() => void 0);
10820
+ const slot2 = this.free.pop() ?? (this.next < UNTRACKED ? this.next++ : UNTRACKED);
10821
+ if (slot2 === UNTRACKED) return slot2;
10822
+ this.held.set(slot2, {
10823
+ path,
10824
+ ino,
10825
+ refs: 1,
10826
+ dead: false,
10827
+ verified: Atomics.load(this.view, slot2)
10828
+ });
10829
+ return slot2;
10830
+ }
10831
+ share(slot2) {
10832
+ const held = slot2 === void 0 ? void 0 : this.held.get(slot2);
10833
+ if (!held) return UNTRACKED;
10834
+ held.refs++;
10835
+ return slot2;
10836
+ }
10837
+ release(slot2) {
10838
+ const held = slot2 === void 0 ? void 0 : this.held.get(slot2);
10839
+ if (!held || --held.refs > 0) return;
10840
+ this.held.delete(slot2);
10841
+ Atomics.add(this.view, slot2, 1);
10842
+ this.free.push(slot2);
10843
+ }
10844
+ stateOf(slot2) {
10845
+ const held = this.held.get(slot2);
10846
+ return { seen: held?.verified ?? Atomics.load(this.view, slot2), dead: held?.dead === true };
10847
+ }
10848
+ touched(paths, trees = []) {
10849
+ if (this.held.size === 0) return;
10850
+ for (const [slot2, held] of this.held) {
10851
+ if (held.dead) continue;
10852
+ if (paths.some((p) => under4(held.path, p)) || trees.some((t) => under4(held.path, t))) {
10853
+ Atomics.add(this.view, slot2, 1);
10854
+ }
10855
+ }
10856
+ }
10857
+ async check(slot2) {
10858
+ this.checks++;
10859
+ const gen = Atomics.load(this.view, slot2);
10860
+ const held = this.held.get(slot2);
10861
+ if (!held) return { gen, alive: true };
10862
+ if (!held.dead) {
10863
+ const ino = await this.inodeOf(held.path).catch(() => null);
10864
+ held.dead = ino === null || held.ino !== void 0 && ino !== held.ino;
10865
+ held.verified = gen;
10866
+ }
10867
+ return { gen, alive: !held.dead };
10868
+ }
10869
+ };
10870
+ function heldInit(o) {
10871
+ if (!o.cwds || o.cwdSlot === void 0) return {};
10872
+ const state = o.cwdState ?? { seen: 0, dead: false };
10873
+ return { held: { sab: o.cwds, slot: o.cwdSlot, ...state } };
10874
+ }
10875
+ function heldHooks(o) {
10876
+ if (!o.cwdCheck || !o.cwdChdir) return {};
10877
+ return { cwdCheck: o.cwdCheck, cwdChdir: o.cwdChdir };
10878
+ }
10879
+ function inheritedCwd(chdir, parent) {
10880
+ return chdir ? void 0 : parent;
10881
+ }
10882
+
10798
10883
  // src/fs/copy.ts
10799
10884
  async function present2(fs, path) {
10800
10885
  return fs.lstat(path).then(
@@ -14083,8 +14168,8 @@ var EventFd = class _EventFd {
14083
14168
  count;
14084
14169
  semaphore;
14085
14170
  changes = new Notifier();
14086
- constructor(initial, semaphore) {
14087
- this.count = initial;
14171
+ constructor(initial2, semaphore) {
14172
+ this.count = initial2;
14088
14173
  this.semaphore = semaphore;
14089
14174
  }
14090
14175
  async read(max, signal) {
@@ -17675,7 +17760,7 @@ var UNSAFE = /[\r\n\0]/;
17675
17760
  var POSITIONS = {
17676
17761
  http1: (position) => HEADER.test(position),
17677
17762
  smtp: (position) => position === "auth-plain" || position === "auth-login",
17678
- pg: (position) => position === "password-cleartext"
17763
+ pg: (position) => position === "password-cleartext" || position === "scram-sha-256"
17679
17764
  };
17680
17765
  function boundHost(servername) {
17681
17766
  const lower = servername.toLowerCase();
@@ -17690,6 +17775,15 @@ function placeholdersOk(list) {
17690
17775
  if (!Array.isArray(list) || list.length === 0 || list.length > SESSION_PLACEHOLDERS) return false;
17691
17776
  return new Set(list).size === list.length && list.every((p) => typeof p === "string" && SESSION_PLACEHOLDER.test(p));
17692
17777
  }
17778
+ var SCRAM_TEXT = /^[\x21-\x7e]{1,1024}$/;
17779
+ function scramOk(f) {
17780
+ if (f.position !== "scram-sha-256")
17781
+ return f.scram === void 0 && placeholdersOk(f.placeholders);
17782
+ const x = f.scram;
17783
+ if (f.placeholders !== void 0 || typeof x !== "object" || x === null) return false;
17784
+ const texts = [x.clientFirstBare, x.serverFirst, x.clientFinalBare, x.proof];
17785
+ return texts.every((t) => typeof t === "string" && SCRAM_TEXT.test(t));
17786
+ }
17693
17787
  function hostOk(host) {
17694
17788
  return typeof host === "string" && HOST.test(host) && boundHost(host) === host;
17695
17789
  }
@@ -17701,7 +17795,7 @@ function sessionAskable(f, now) {
17701
17795
  if (!Number.isInteger(f.port) || f.port < 1 || f.port > 65535) return false;
17702
17796
  const age = now - f.handshakeAt;
17703
17797
  if (!Number.isFinite(age) || age < 0 || age > SESSION_WINDOW_MS) return false;
17704
- return typeof f.exit === "string" && SESSION_EXIT.test(f.exit) && placeholdersOk(f.placeholders) && headOk(f);
17798
+ return typeof f.exit === "string" && SESSION_EXIT.test(f.exit) && scramOk(f) && headOk(f);
17705
17799
  }
17706
17800
  function sessionRequest(f) {
17707
17801
  return {
@@ -17717,8 +17811,16 @@ function sessionRequest(f) {
17717
17811
  verified: true,
17718
17812
  handshakeAt: f.handshakeAt,
17719
17813
  exit: f.exit,
17720
- placeholders: [...f.placeholders],
17721
- ...f.head ? { head: { method: f.head.method, path: f.head.path } } : {}
17814
+ ...f.placeholders ? { placeholders: [...f.placeholders] } : {},
17815
+ ...f.head ? { head: { method: f.head.method, path: f.head.path } } : {},
17816
+ ...f.scram ? {
17817
+ scram: {
17818
+ clientFirstBare: f.scram.clientFirstBare,
17819
+ serverFirst: f.scram.serverFirst,
17820
+ clientFinalBare: f.scram.clientFinalBare,
17821
+ proof: f.scram.proof
17822
+ }
17823
+ } : {}
17722
17824
  };
17723
17825
  }
17724
17826
  function sessionValues(reply, asked) {
@@ -17726,7 +17828,9 @@ function sessionValues(reply, asked) {
17726
17828
  const { error, values } = reply;
17727
17829
  if (error !== void 0 || typeof values !== "object" || values === null) return void 0;
17728
17830
  const out = {};
17729
- for (const ph of asked) {
17831
+ const keys = Object.keys(values);
17832
+ const wanted = asked ?? (keys.length === 1 && SESSION_PLACEHOLDER.test(keys[0]) ? keys : []);
17833
+ for (const ph of wanted) {
17730
17834
  const value2 = values[ph];
17731
17835
  if (typeof value2 === "string" && value2.length > 0 && !UNSAFE.test(value2)) out[ph] = value2;
17732
17836
  }
@@ -18418,6 +18522,104 @@ async function substituteHead(head, ask) {
18418
18522
  `, values };
18419
18523
  }
18420
18524
 
18525
+ // src/kernel/net/sealed-scram.ts
18526
+ var encoder8 = new TextEncoder();
18527
+ function base64Bytes(text) {
18528
+ try {
18529
+ return Uint8Array.from(atob(text), (c) => c.charCodeAt(0));
18530
+ } catch {
18531
+ return void 0;
18532
+ }
18533
+ }
18534
+ function base64Of(bytes) {
18535
+ let bin = "";
18536
+ for (const b of bytes) bin += String.fromCharCode(b);
18537
+ return btoa(bin);
18538
+ }
18539
+ function clientFirstBare(message3) {
18540
+ const m = /^n,,(n=[^,]*,r=[^,]+)$/.exec(message3);
18541
+ return m ? m[1] : void 0;
18542
+ }
18543
+ var SERVER_FIRST = /^r=([^,]+),s=([^,]+),i=(\d{1,6})$/;
18544
+ var CLIENT_FINAL = /^(c=biws,r=([^,]+)),p=([^,]+)$/;
18545
+ var SCRAM_MAX = 1024;
18546
+ function exchangeOf(clientFirst, serverFirst, clientFinal) {
18547
+ const bare = clientFirstBare(clientFirst);
18548
+ const sf = SERVER_FIRST.exec(serverFirst);
18549
+ const fin = CLIENT_FINAL.exec(clientFinal);
18550
+ if (!bare || !sf || !fin || [bare, serverFirst, clientFinal].some((t) => t.length > SCRAM_MAX))
18551
+ return void 0;
18552
+ const cnonce = bare.slice(bare.indexOf(",r=") + 3);
18553
+ const nonce = sf[1];
18554
+ const salt = base64Bytes(sf[2]);
18555
+ const iterations = Number(sf[3]);
18556
+ const proof = base64Bytes(fin[3]);
18557
+ const ok4 = fin[2] === nonce && nonce.startsWith(cnonce) && iterations >= 1 && iterations <= 1e5 && salt !== void 0 && proof?.length === 32;
18558
+ if (!ok4) return void 0;
18559
+ return {
18560
+ exchange: {
18561
+ clientFirstBare: bare,
18562
+ serverFirst,
18563
+ clientFinalBare: fin[1],
18564
+ salt,
18565
+ iterations
18566
+ },
18567
+ proof
18568
+ };
18569
+ }
18570
+ async function hmac(key, data) {
18571
+ const k = await crypto.subtle.importKey(
18572
+ "raw",
18573
+ key,
18574
+ { name: "HMAC", hash: "SHA-256" },
18575
+ false,
18576
+ ["sign"]
18577
+ );
18578
+ return new Uint8Array(await crypto.subtle.sign("HMAC", k, data));
18579
+ }
18580
+ async function scramKeys(password, x) {
18581
+ const base = await crypto.subtle.importKey("raw", encoder8.encode(password), "PBKDF2", false, [
18582
+ "deriveBits"
18583
+ ]);
18584
+ const salted = new Uint8Array(
18585
+ await crypto.subtle.deriveBits(
18586
+ {
18587
+ name: "PBKDF2",
18588
+ hash: "SHA-256",
18589
+ salt: x.salt,
18590
+ iterations: x.iterations
18591
+ },
18592
+ base,
18593
+ 256
18594
+ )
18595
+ );
18596
+ const clientKey = await hmac(salted, encoder8.encode("Client Key"));
18597
+ const stored = new Uint8Array(
18598
+ await crypto.subtle.digest("SHA-256", clientKey)
18599
+ );
18600
+ const auth = encoder8.encode(`${x.clientFirstBare},${x.serverFirst},${x.clientFinalBare}`);
18601
+ const signature = await hmac(stored, auth);
18602
+ const proof = clientKey.map((b, i) => b ^ signature[i]);
18603
+ const serverKey = await hmac(salted, encoder8.encode("Server Key"));
18604
+ const serverSignature = await hmac(serverKey, auth);
18605
+ for (const k of [salted, clientKey, stored, signature, serverKey]) k.fill(0);
18606
+ return { proof, serverSignature };
18607
+ }
18608
+ var SPACES = /[\u00A0\u1680\u2000-\u200B\u202F\u205F\u3000]/g;
18609
+ var NOTHING2 = /\u00AD|\u034F|\u1806|[\u180B-\u180D]|\u200C|\u200D|\u2060|[\uFE00-\uFE0F]|\uFEFF/g;
18610
+ var PROHIBITED = /[\u0000-\u001F\u007F-\u009F\uE000-\uF8FF\uFFFE\uFFFF]/;
18611
+ function saslprep(password) {
18612
+ if (/^[\x20-\x7e]*$/.test(password)) return password;
18613
+ const mapped = password.replace(SPACES, " ").replace(NOTHING2, "").normalize("NFKC");
18614
+ return PROHIBITED.test(mapped) ? password : mapped;
18615
+ }
18616
+ function sameBytes(a, b) {
18617
+ if (a.length !== b.length) return false;
18618
+ let d = 0;
18619
+ for (let i = 0; i < a.length; i++) d |= a[i] ^ b[i];
18620
+ return d === 0;
18621
+ }
18622
+
18421
18623
  // src/kernel/net/sealed-pg.ts
18422
18624
  var PG_MESSAGE_MAX = 16 * 1024;
18423
18625
  var PROTOCOL_3 = 196608;
@@ -18432,44 +18634,101 @@ function sniffPg(start2) {
18432
18634
  const length2 = int32(bytes, 0);
18433
18635
  return length2 >= 8 && length2 <= PG_MESSAGE_MAX && int32(bytes, 4) === PROTOCOL_3 ? "yes" : "no";
18434
18636
  }
18637
+ var PLUS = "SCRAM-SHA-256-PLUS";
18638
+ var SASL = 10;
18639
+ var SASL_CONTINUE = 11;
18640
+ var SASL_FINAL = 12;
18641
+ function latin(bytes) {
18642
+ let out = "";
18643
+ for (const b of bytes) out += String.fromCharCode(b);
18644
+ return out;
18645
+ }
18435
18646
  var PgServer = class {
18436
18647
  buffer = new Uint8Array(0);
18437
18648
  skip = 0;
18438
- lost = false;
18439
18649
  cleartext = false;
18440
- feed(bytes) {
18441
- if (this.lost) return;
18650
+ sasl = false;
18651
+ serverFirst;
18652
+ expect;
18653
+ failed = false;
18654
+ lost = false;
18655
+ auth(message3) {
18656
+ const code = message3.length >= 9 ? int32(message3, 5) : -1;
18657
+ if (this.expect && code !== SASL_FINAL) this.failed = true;
18658
+ this.cleartext = message3.length === 9 && code === CLEARTEXT;
18659
+ if (code === SASL) return this.mechanisms(message3);
18660
+ else if (code === SASL_CONTINUE) this.serverFirst = latin(message3.subarray(9));
18661
+ else if (code === SASL_FINAL) this.final(message3);
18662
+ return message3;
18663
+ }
18664
+ mechanisms(message3) {
18665
+ this.sasl = true;
18666
+ const names2 = latin(message3.subarray(9)).split("\0").filter((n) => n !== "" && n !== PLUS);
18667
+ return frame3(82, `${latin(message3.subarray(5, 9))}${names2.map((n) => `${n}\0`).join("")}\0`);
18668
+ }
18669
+ final(message3) {
18670
+ const expect = this.expect;
18671
+ if (!expect) return;
18672
+ this.expect = void 0;
18673
+ const data = latin(message3.subarray(9));
18674
+ if (data !== expect.real || expect.fake.length !== expect.real.length) {
18675
+ this.failed = true;
18676
+ return;
18677
+ }
18678
+ for (let i = 0; i < expect.fake.length; i++) message3[9 + i] = expect.fake.charCodeAt(i);
18679
+ }
18680
+ lose() {
18681
+ this.lost = true;
18682
+ this.cleartext = false;
18683
+ this.sasl = false;
18684
+ if (this.expect) this.failed = true;
18685
+ this.expect = void 0;
18686
+ }
18687
+ filter(bytes) {
18688
+ if (this.lost) return bytes;
18442
18689
  const data = new Uint8Array(this.buffer.length + bytes.length);
18443
18690
  data.set(this.buffer);
18444
18691
  data.set(bytes, this.buffer.length);
18692
+ const out = [];
18445
18693
  let at = 0;
18446
18694
  for (; ; ) {
18447
18695
  const left = data.length - at;
18448
18696
  if (this.skip > 0) {
18449
18697
  const n = Math.min(this.skip, left);
18698
+ out.push(data.subarray(at, at + n));
18450
18699
  this.skip -= n;
18451
18700
  at += n;
18452
18701
  if (this.skip > 0) break;
18453
18702
  continue;
18454
18703
  }
18455
18704
  if (left < 5) break;
18456
- const type = data[at];
18457
18705
  const whole = 1 + int32(data, at + 1);
18458
- if (whole < 5 || type === 82 && whole > PG_MESSAGE_MAX) {
18459
- this.lost = true;
18460
- this.cleartext = false;
18461
- this.buffer = new Uint8Array(0);
18462
- return;
18706
+ if (whole < 5 || data[at] === 82 && whole > PG_MESSAGE_MAX) {
18707
+ this.lose();
18708
+ out.push(data.subarray(at));
18709
+ at = data.length;
18710
+ break;
18463
18711
  }
18464
- if (type !== 82) {
18712
+ if (data[at] !== 82) {
18713
+ if (this.expect) {
18714
+ this.failed = true;
18715
+ break;
18716
+ }
18465
18717
  this.skip = whole;
18466
18718
  continue;
18467
18719
  }
18468
18720
  if (left < whole) break;
18469
- this.cleartext = whole === 9 && int32(data, at + 5) === CLEARTEXT;
18721
+ out.push(this.auth(data.slice(at, at + whole)));
18470
18722
  at += whole;
18471
18723
  }
18472
18724
  this.buffer = data.slice(at);
18725
+ const joined4 = new Uint8Array(out.reduce((n, b) => n + b.length, 0));
18726
+ let to = 0;
18727
+ for (const b of out) {
18728
+ joined4.set(b, to);
18729
+ to += b.length;
18730
+ }
18731
+ return joined4;
18473
18732
  }
18474
18733
  };
18475
18734
  function frame3(type, body) {
@@ -18486,21 +18745,76 @@ function pgLength(bytes, started) {
18486
18745
  const length2 = int32(bytes, started ? 1 : 0);
18487
18746
  return started ? 1 + length2 : length2;
18488
18747
  }
18489
- async function pgPassword(message3, server, ask) {
18490
- if (message3[0] !== 112 || !server.cleartext) return { bytes: message3, done: true };
18491
- server.cleartext = false;
18492
- let body = "";
18493
- for (const b of message3.subarray(5)) body += String.fromCharCode(b);
18748
+ var MECHANISMS = /* @__PURE__ */ new Set(["SCRAM-SHA-256"]);
18749
+ async function cleartext(message3, asks) {
18750
+ const body = latin(message3.subarray(5));
18494
18751
  if (!body.endsWith("\0") || body.indexOf("\0") !== body.length - 1)
18495
18752
  return { bytes: message3, done: true };
18496
18753
  const password = body.slice(0, -1);
18497
18754
  const placeholders = placeholdersIn(password);
18498
18755
  if (placeholders.length === 0 || placeholders.length > SESSION_PLACEHOLDERS)
18499
18756
  return { bytes: message3, done: true };
18500
- const values = usable(await ask(placeholders));
18757
+ const values = usable(await asks.cleartext(placeholders));
18501
18758
  if (Object.keys(values).length === 0) return { bytes: message3, done: true };
18502
18759
  return { bytes: frame3(112, `${replaced(password, values)}\0`), values, done: true };
18503
18760
  }
18761
+ function initial(message3) {
18762
+ const body = latin(message3.subarray(5));
18763
+ const nul = body.indexOf("\0");
18764
+ if (nul < 0 || !MECHANISMS.has(body.slice(0, nul)) || body.length < nul + 5) return void 0;
18765
+ const data = message3.subarray(5 + nul + 5);
18766
+ return int32(message3, 5 + nul + 1) === data.length ? latin(data) : void 0;
18767
+ }
18768
+ var PgClient = class {
18769
+ clientFirst;
18770
+ server;
18771
+ asks;
18772
+ constructor(server, asks) {
18773
+ this.server = server;
18774
+ this.asks = asks;
18775
+ }
18776
+ async message(message3) {
18777
+ const server = this.server;
18778
+ if (message3[0] !== 112) return { bytes: message3, done: true };
18779
+ if (server.cleartext) {
18780
+ server.cleartext = false;
18781
+ return cleartext(message3, this.asks);
18782
+ }
18783
+ if (server.sasl && this.clientFirst === void 0) {
18784
+ this.clientFirst = initial(message3);
18785
+ return { bytes: message3, done: this.clientFirst === void 0 };
18786
+ }
18787
+ if (this.clientFirst !== void 0 && server.serverFirst !== void 0)
18788
+ return this.final(message3, this.clientFirst, server.serverFirst);
18789
+ return { bytes: message3, done: true };
18790
+ }
18791
+ async final(message3, first, serverFirst) {
18792
+ const got = exchangeOf(first, serverFirst, latin(message3.subarray(5)));
18793
+ if (!got) return { bytes: message3, done: true };
18794
+ const x = got.exchange;
18795
+ const values = usable(
18796
+ await this.asks.scram({
18797
+ clientFirstBare: x.clientFirstBare,
18798
+ serverFirst: x.serverFirst,
18799
+ clientFinalBare: x.clientFinalBare,
18800
+ proof: base64Of(got.proof)
18801
+ })
18802
+ );
18803
+ const [entry, ...more] = Object.entries(values);
18804
+ if (!entry || more.length > 0) return { bytes: message3, done: true };
18805
+ const [placeholder, value2] = entry;
18806
+ const fake = await scramKeys(placeholder, x);
18807
+ if (!sameBytes(fake.proof, got.proof)) return { bytes: message3, done: true };
18808
+ const real = await scramKeys(saslprep(value2), x);
18809
+ this.server.expect = {
18810
+ real: `v=${base64Of(real.serverSignature)}`,
18811
+ fake: `v=${base64Of(fake.serverSignature)}`
18812
+ };
18813
+ const bytes = frame3(112, `${x.clientFinalBare},p=${base64Of(real.proof)}`);
18814
+ for (const k of [real.proof, real.serverSignature, fake.proof, fake.serverSignature]) k.fill(0);
18815
+ return { bytes, values, done: true };
18816
+ }
18817
+ };
18504
18818
 
18505
18819
  // src/kernel/net/sealed-smtp.ts
18506
18820
  var SMTP_LINE_MAX = 4096;
@@ -18645,17 +18959,21 @@ var SessionWriter = class {
18645
18959
  session = sessionId();
18646
18960
  smtp;
18647
18961
  pgStarted = false;
18962
+ sawPg = false;
18648
18963
  conn;
18649
18964
  s;
18650
- pg;
18965
+ pgClient;
18651
18966
  scope;
18652
18967
  constructor(conn, s, pg, scope) {
18653
18968
  this.conn = conn;
18654
18969
  this.s = s;
18655
- this.pg = pg;
18656
18970
  this.scope = scope;
18971
+ this.pgClient = new PgClient(pg, {
18972
+ cleartext: (placeholders) => this.ask("pg", "password-cleartext", { placeholders }),
18973
+ scram: (scram) => this.ask("pg", "scram-sha-256", { scram })
18974
+ });
18657
18975
  this.smtp = new SmtpClient(
18658
- (position, placeholders) => this.ask("smtp", position, placeholders)
18976
+ (position, placeholders) => this.ask("smtp", position, { placeholders })
18659
18977
  );
18660
18978
  }
18661
18979
  write(bytes) {
@@ -18666,7 +18984,7 @@ var SessionWriter = class {
18666
18984
  );
18667
18985
  return run2;
18668
18986
  }
18669
- async ask(protocol, position, placeholders, head) {
18987
+ async ask(protocol, position, extra) {
18670
18988
  const s = this.s;
18671
18989
  const values = await s.broker.sessionMaterialize({
18672
18990
  stamp: await s.stamp(),
@@ -18678,8 +18996,7 @@ var SessionWriter = class {
18678
18996
  verified: s.verified,
18679
18997
  handshakeAt: s.handshakeAt,
18680
18998
  exit: s.exit,
18681
- placeholders,
18682
- ...head ? { head } : {}
18999
+ ...extra
18683
19000
  });
18684
19001
  return values;
18685
19002
  }
@@ -18698,6 +19015,7 @@ var SessionWriter = class {
18698
19015
  this.buffer.fill(0);
18699
19016
  this.buffer = joined4;
18700
19017
  if (this.mode === "sniff") this.mode = modeOf(latin12(joined4.subarray(0, 8))) ?? "sniff";
19018
+ if (this.mode === "pg") this.sawPg = true;
18701
19019
  if (this.mode === "pass") await this.release();
18702
19020
  else if (this.mode === "http1") await this.http1();
18703
19021
  else if (this.mode === "smtp") await this.lines();
@@ -18744,11 +19062,7 @@ var SessionWriter = class {
18744
19062
  this.buffer = this.buffer.slice(whole);
18745
19063
  const started = this.pgStarted;
18746
19064
  this.pgStarted = true;
18747
- const out = started ? await pgPassword(
18748
- message3,
18749
- this.pg,
18750
- (placeholders) => this.ask("pg", "password-cleartext", placeholders)
18751
- ).catch(() => ({ bytes: message3, done: true })) : { bytes: message3, done: false };
19065
+ const out = started ? await this.pgClient.message(message3).catch(() => ({ bytes: message3, done: true })) : { bytes: message3, done: false };
18752
19066
  if ("values" in out && out.values) this.remember(out.values);
18753
19067
  try {
18754
19068
  await writeAll4(this.conn, out.bytes);
@@ -18780,7 +19094,7 @@ var SessionWriter = class {
18780
19094
  this.buffer = new Uint8Array(0);
18781
19095
  const done4 = await substituteHead(
18782
19096
  latin12(all.subarray(0, end)),
18783
- (position, placeholders, head2) => this.ask("http1", position, placeholders, head2)
19097
+ (position, placeholders, head2) => this.ask("http1", position, { placeholders, head: head2 })
18784
19098
  ).catch(() => void 0);
18785
19099
  const head = done4 ? bytesOf(done4.head) : all.subarray(0, end);
18786
19100
  if (done4) this.remember(done4.values);
@@ -18878,9 +19192,19 @@ function sealedConn(conn, s) {
18878
19192
  const observed = {
18879
19193
  ...conn,
18880
19194
  read: async () => {
18881
- const bytes = await conn.read();
18882
- if (bytes) pg.feed(bytes);
18883
- return bytes;
19195
+ for (; ; ) {
19196
+ const bytes = await conn.read();
19197
+ if (!bytes) return bytes;
19198
+ const out = writer?.sawPg ? pg.filter(bytes) : bytes;
19199
+ if (pg.failed) {
19200
+ conn.close();
19201
+ throw new KernelError(
19202
+ "EPROTO",
19203
+ "ERR_SSL_PROTOCOL_ERROR: the pg server failed the SCRAM proof"
19204
+ );
19205
+ }
19206
+ if (out.length > 0) return out;
19207
+ }
18884
19208
  }
18885
19209
  };
18886
19210
  const reader = new ScrubReader(writer ? observed : conn, scope);
@@ -20994,6 +21318,8 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
20994
21318
  "fd-list",
20995
21319
  "proc-alarm",
20996
21320
  "proc-umask",
21321
+ "cwd-check",
21322
+ "cwd-chdir",
20997
21323
  "proc-cred",
20998
21324
  "proc-setcred",
20999
21325
  "dl-log",
@@ -22319,6 +22645,14 @@ var WasmProcess = class {
22319
22645
  return { ok: true, kind: "void" };
22320
22646
  case "proc-umask":
22321
22647
  return { ok: true, kind: "json", json: this.setUmask(req.mask) };
22648
+ case "cwd-check":
22649
+ return {
22650
+ ok: true,
22651
+ kind: "json",
22652
+ json: await this.options.cwdCheck?.() ?? { gen: 0, alive: true }
22653
+ };
22654
+ case "cwd-chdir":
22655
+ return { ok: true, kind: "json", json: await this.options.cwdChdir?.(req.path) ?? {} };
22322
22656
  case "proc-cred":
22323
22657
  return { ok: true, kind: "json", json: copyCred(this.cred) };
22324
22658
  case "proc-setcred":
@@ -22868,6 +23202,7 @@ function processInit(opts, sab, umask, cred, lane) {
22868
23202
  umask,
22869
23203
  cred,
22870
23204
  ...opts.changes ? { changes: opts.changes } : {},
23205
+ ...heldInit(opts),
22871
23206
  ...opts.owners ? { owners: true } : {},
22872
23207
  ...opts.links !== void 0 ? { links: true } : {},
22873
23208
  ...opts.ppid !== void 0 ? { ppid: opts.ppid } : {}
@@ -22941,6 +23276,7 @@ function processOptions(opts, header4, hooks, created4) {
22941
23276
  ...opts.identity ? { identity: opts.identity } : {},
22942
23277
  ...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
22943
23278
  ...opts.settling ? { settling: opts.settling } : {},
23279
+ ...heldHooks(opts),
22944
23280
  spawner: opts.spawner,
22945
23281
  forker: opts.forker,
22946
23282
  ...opts.fork?.dl ? { dl: opts.fork.dl } : {},
@@ -22991,6 +23327,7 @@ function threadInit(opts, program, sab, cred, thread, main) {
22991
23327
  owners: opts.owners === true,
22992
23328
  ...opts.links !== void 0 ? { links: true } : {},
22993
23329
  ...opts.changes ? { changes: opts.changes } : {},
23330
+ ...heldInit(opts),
22994
23331
  ...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
22995
23332
  thread,
22996
23333
  signals: main
@@ -23947,7 +24284,7 @@ var SEALED_OPS = /* @__PURE__ */ new Set([
23947
24284
  "cancel",
23948
24285
  "materialize"
23949
24286
  ]);
23950
- var encoder8 = new TextEncoder();
24287
+ var encoder9 = new TextEncoder();
23951
24288
  var decoder3 = new TextDecoder("utf-8", { fatal: true });
23952
24289
  function parseSealed(bytes) {
23953
24290
  try {
@@ -24028,7 +24365,7 @@ var SealedChannel = class {
24028
24365
  await this.broker.tickets.record(req, reply, caller.pid);
24029
24366
  if (this.inflight !== flight) return;
24030
24367
  this.inflight = void 0;
24031
- if (reply) this.reply = encoder8.encode(serialized(reply));
24368
+ if (reply) this.reply = encoder9.encode(serialized(reply));
24032
24369
  });
24033
24370
  this.inflight = flight;
24034
24371
  return length2;
@@ -25836,9 +26173,9 @@ function importedMemory(bytes) {
25836
26173
  };
25837
26174
  const limits = () => {
25838
26175
  const flags2 = bytes[at++];
25839
- const initial = u32();
26176
+ const initial2 = u32();
25840
26177
  const maximum = flags2 & 1 ? u32() : void 0;
25841
- return { initial, maximum, shared: (flags2 & 2) !== 0 };
26178
+ return { initial: initial2, maximum, shared: (flags2 & 2) !== 0 };
25842
26179
  };
25843
26180
  while (at < bytes.length) {
25844
26181
  const id2 = bytes[at++];
@@ -26479,7 +26816,7 @@ var LAYOUT = [
26479
26816
  var IN_TREE = /* @__PURE__ */ new Set([SUDO_PATH, CRONTAB_PATH]);
26480
26817
  var LOAD_SAMPLE_MS = 5e3;
26481
26818
  var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
26482
- var encoder9 = new TextEncoder();
26819
+ var encoder10 = new TextEncoder();
26483
26820
  var USERS_MODES = ["off", "report", "enforce"];
26484
26821
  function usersMode(mode = "off") {
26485
26822
  if (USERS_MODES.includes(mode)) return mode;
@@ -26690,6 +27027,11 @@ var Launcher = class {
26690
27027
  hostname;
26691
27028
  watchers = new FsWatchers();
26692
27029
  changes = new FileChanges();
27030
+ cwds = new CwdTable(async (path) => {
27031
+ const { dev, ino } = await this.base.stat(path);
27032
+ return `${dev ?? 0}:${ino}`;
27033
+ });
27034
+ cwdSlots = /* @__PURE__ */ new Map();
26693
27035
  pnpmHome;
26694
27036
  pnpmChain;
26695
27037
  pnpmMade;
@@ -26746,7 +27088,10 @@ var Launcher = class {
26746
27088
  this.sealed.tickets.normalise = (path) => physicalPathAsync(this.base, path);
26747
27089
  this.sealed.userOf = async (uid) => (await this.users.lookup(uid))?.name;
26748
27090
  if (this.owners) options.fs.trackOwners?.();
26749
- this.watchers.tap((paths) => this.changes.publish(...paths));
27091
+ this.watchers.tap((paths) => {
27092
+ this.changes.publish(...paths);
27093
+ this.cwds.touched(paths);
27094
+ });
26750
27095
  this.watchers.onReshape(() => {
26751
27096
  for (const nodes of this.openFiles) nodes.reshaped();
26752
27097
  });
@@ -26816,6 +27161,7 @@ var Launcher = class {
26816
27161
  options.fs.onPeer?.(() => this.flushOpen());
26817
27162
  options.fs.remoteChanges?.((change) => {
26818
27163
  this.changes.flush();
27164
+ this.cwds.touched(change.paths, change.trees);
26819
27165
  this.rewritten(change.paths, change.trees);
26820
27166
  });
26821
27167
  const holders = [this.held, this.openFiles];
@@ -27598,11 +27944,12 @@ var Launcher = class {
27598
27944
  }
27599
27945
  const done4 = this.heldUrl(program);
27600
27946
  try {
27947
+ const cwdSlot = await this.cwds.hold(cwd, req.cwdFrom);
27601
27948
  const handle = await this.admitted(
27602
27949
  program.abi !== "js",
27603
27950
  req.fds,
27604
- (fds, quietOom) => this.start({ ...req, fds, quietOom, cwd, program, argv0: target.argv0, args, env })
27605
- );
27951
+ (fds, quietOom) => this.start({ ...req, fds, quietOom, cwd, program, argv0: target.argv0, args, env, cwdSlot })
27952
+ ).finally(() => this.cwds.release(cwdSlot));
27606
27953
  void handle.exited.finally(done4);
27607
27954
  return handle;
27608
27955
  } catch (err) {
@@ -27689,6 +28036,8 @@ var Launcher = class {
27689
28036
  throw new SpawnError("ESRCH");
27690
28037
  }
27691
28038
  const pid = req.pid ?? this.nextPid++;
28039
+ const cwdSlot = this.cwds.share(req.cwdSlot);
28040
+ this.cwdSlots.set(pid, cwdSlot);
27692
28041
  const scrubs = this.treeScrubs(req);
27693
28042
  const stack = this.stackFor(req.tag);
27694
28043
  const terminal = req.fds.stdioTerminal();
@@ -27723,6 +28072,7 @@ var Launcher = class {
27723
28072
  ...this.dac ? { dac: this.dac } : {},
27724
28073
  program: req.program,
27725
28074
  changes: this.changes.sab,
28075
+ ...this.heldFor(pid, cwdSlot),
27726
28076
  argv0: req.argv0,
27727
28077
  args: req.args,
27728
28078
  env: req.env,
@@ -27797,6 +28147,8 @@ var Launcher = class {
27797
28147
  (state) => state === "stopped" ? this.stopped.add(pid) : this.stopped.delete(pid)
27798
28148
  );
27799
28149
  void handle.exited.then(() => {
28150
+ this.cwds.release(this.cwdSlots.get(pid));
28151
+ this.cwdSlots.delete(pid);
27800
28152
  this.freshModules.forget(pid);
27801
28153
  const spent = handle.times?.();
27802
28154
  if (spent) this.spent.set(pid, spent);
@@ -28028,6 +28380,7 @@ var Launcher = class {
28028
28380
  const handle = await this.launch(planned, {
28029
28381
  ...deciding ? { decided: deciding.promise } : {},
28030
28382
  cwd: req.cwd,
28383
+ cwdFrom: inheritedCwd(req.chdir, this.cwdSlots.get(ppid)),
28031
28384
  ...redeemed,
28032
28385
  fds,
28033
28386
  report,
@@ -28089,6 +28442,24 @@ var Launcher = class {
28089
28442
  for (const resolve2 of waiting) resolve2(true);
28090
28443
  }, 0);
28091
28444
  }
28445
+ heldFor(pid, slot2) {
28446
+ return {
28447
+ cwds: this.cwds.sab,
28448
+ cwdSlot: slot2,
28449
+ cwdState: this.cwds.stateOf(slot2),
28450
+ cwdCheck: async () => {
28451
+ const current = this.cwdSlots.get(pid);
28452
+ return { ...await this.cwds.check(current), slot: current };
28453
+ },
28454
+ cwdChdir: (path) => this.chdirHeld(pid, path)
28455
+ };
28456
+ }
28457
+ async chdirHeld(pid, path) {
28458
+ this.cwds.release(this.cwdSlots.get(pid));
28459
+ const slot2 = await this.cwds.hold(path);
28460
+ this.cwdSlots.set(pid, slot2);
28461
+ return { slot: slot2, ...this.cwds.stateOf(slot2) };
28462
+ }
28092
28463
  forker(ppid, parent) {
28093
28464
  const { exec: _exec, pgid: _pgid, group: _group, pid: _pid, scrub: _scrub, ...image } = parent;
28094
28465
  return async (state, given) => {
@@ -28096,6 +28467,7 @@ var Launcher = class {
28096
28467
  ...image,
28097
28468
  quietOom,
28098
28469
  cwd: state.cwd ?? parent.cwd,
28470
+ cwdSlot: this.cwdSlots.get(ppid),
28099
28471
  fds,
28100
28472
  ppid,
28101
28473
  fork: state,
@@ -28719,7 +29091,7 @@ var Launcher = class {
28719
29091
  },
28720
29092
  account
28721
29093
  );
28722
- const report = (message3) => options.onData(encoder9.encode(`${message3}\r
29094
+ const report = (message3) => options.onData(encoder10.encode(`${message3}\r
28723
29095
  `));
28724
29096
  const handle = await this.launch(planned, {
28725
29097
  env,
@@ -28757,7 +29129,7 @@ var Launcher = class {
28757
29129
  };
28758
29130
  const stdout = collect(out, options.onStdout);
28759
29131
  const stderr = collect(err, options.onStderr);
28760
- const report = (message3) => stderr(encoder9.encode(`${message3}
29132
+ const report = (message3) => stderr(encoder10.encode(`${message3}
28761
29133
  `));
28762
29134
  if (!planned) {
28763
29135
  const directory = await this.directory(file, this.fs.resolvePath(cwd, file));
@@ -29561,7 +29933,7 @@ function dialStream(port, onClose) {
29561
29933
 
29562
29934
  // src/client/loopback-fetch.ts
29563
29935
  var OWN_HEADERS2 = /* @__PURE__ */ new Set(["host", "connection", "content-length", "transfer-encoding"]);
29564
- var encoder10 = new TextEncoder();
29936
+ var encoder11 = new TextEncoder();
29565
29937
  var latin13 = new TextDecoder("latin1");
29566
29938
  var ByteSource = class {
29567
29939
  buffered = new Uint8Array(0);
@@ -29579,7 +29951,7 @@ var ByteSource = class {
29579
29951
  return true;
29580
29952
  }
29581
29953
  async until(marker) {
29582
- const needle = encoder10.encode(marker);
29954
+ const needle = encoder11.encode(marker);
29583
29955
  for (; ; ) {
29584
29956
  const at = indexOf(this.buffered, needle);
29585
29957
  if (at >= 0) return this.take(at + needle.length);
@@ -29687,7 +30059,7 @@ async function requestBytes(request) {
29687
30059
  });
29688
30060
  if (body) lines2.push(`Content-Length: ${body.length}`);
29689
30061
  lines2.push("Connection: close", "", "");
29690
- const head = encoder10.encode(lines2.join("\r\n"));
30062
+ const head = encoder11.encode(lines2.join("\r\n"));
29691
30063
  const out = new Uint8Array(head.length + (body?.length ?? 0));
29692
30064
  out.set(head);
29693
30065
  if (body) out.set(body, head.length);
@@ -29741,8 +30113,8 @@ var KernelCallError = class extends Error {
29741
30113
  this.code = code;
29742
30114
  }
29743
30115
  };
29744
- var encoder11 = new TextEncoder();
29745
- var bytesOf3 = (data) => typeof data === "string" ? encoder11.encode(data) : data;
30116
+ var encoder12 = new TextEncoder();
30117
+ var bytesOf3 = (data) => typeof data === "string" ? encoder12.encode(data) : data;
29746
30118
  var UNAVAILABLE = {
29747
30119
  manualRedirects: false,
29748
30120
  encodedBodies: false,