@ai-ecoverse/slicc-kernel 1.130.2 → 1.132.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
@@ -3740,6 +3740,14 @@ var MemoryMeta = class {
3740
3740
  }
3741
3741
  };
3742
3742
 
3743
+ // src/fs/notice.ts
3744
+ function noticeOf(data) {
3745
+ if (Array.isArray(data)) return { paths: data.filter((p) => typeof p === "string"), trees: [] };
3746
+ const notice = data ?? {};
3747
+ const strings = (list) => Array.isArray(list) ? list.filter((p) => typeof p === "string") : [];
3748
+ return { paths: strings(notice.paths), trees: strings(notice.trees) };
3749
+ }
3750
+
3743
3751
  // src/fs/integrity.ts
3744
3752
  var SOURCE_SUFFIXES = [
3745
3753
  ".js",
@@ -4548,8 +4556,9 @@ var OpfsFs = class {
4548
4556
  for (const path of [...c.paths, ...c.trees]) this.forget(path);
4549
4557
  });
4550
4558
  this.channel.onmessage = ({ data }) => {
4551
- for (const path of data) this.forget(path);
4552
- remote?.emit({ paths: data, trees: [] });
4559
+ const { paths, trees } = noticeOf(data);
4560
+ for (const path of [...paths, ...trees]) this.forget(normalizePath(path));
4561
+ remote?.emit({ paths, trees });
4553
4562
  };
4554
4563
  this.channel.unref?.();
4555
4564
  }
@@ -7394,7 +7403,7 @@ function satisfies(version, range2) {
7394
7403
  }
7395
7404
 
7396
7405
  // src/version.ts
7397
- var KERNEL_VERSION = true ? "1.130.2" : "0.0.0-dev";
7406
+ var KERNEL_VERSION = true ? "1.132.0" : "0.0.0-dev";
7398
7407
  var OS_RELEASE = "6.0.0-slicc";
7399
7408
  function procVersion() {
7400
7409
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -17601,7 +17610,7 @@ var TOKEN5 = "[!#$%&'*+.^_`|~0-9a-z-]+";
17601
17610
  var HEADER = new RegExp(`^header:${TOKEN5}$`);
17602
17611
  var METHOD = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
17603
17612
  var TARGET = /^[\x21-\x7e]+$/;
17604
- var SESSION_EXIT = /^(tailscale|device:[A-Za-z0-9._-]+)$/;
17613
+ var SESSION_EXIT = /^(tailscale|device:[A-Za-z0-9._:-]+)$/;
17605
17614
  var HOST = /^[a-z0-9.:-]+$/;
17606
17615
  var UNSAFE = /[\r\n\0]/;
17607
17616
  var POSITIONS = {
@@ -18350,6 +18359,90 @@ async function substituteHead(head, ask) {
18350
18359
  `, values };
18351
18360
  }
18352
18361
 
18362
+ // src/kernel/net/sealed-pg.ts
18363
+ var PG_MESSAGE_MAX = 16 * 1024;
18364
+ var PROTOCOL_3 = 196608;
18365
+ var CLEARTEXT = 3;
18366
+ function int32(bytes, at) {
18367
+ return bytes[at] << 24 | bytes[at + 1] << 16 | bytes[at + 2] << 8 | bytes[at + 3];
18368
+ }
18369
+ function sniffPg(start2) {
18370
+ const bytes = Uint8Array.from(start2, (c) => c.charCodeAt(0));
18371
+ if (bytes.length === 0 || bytes[0] !== 0) return bytes.length === 0 ? "more" : "no";
18372
+ if (bytes.length < 8) return "more";
18373
+ const length2 = int32(bytes, 0);
18374
+ return length2 >= 8 && length2 <= PG_MESSAGE_MAX && int32(bytes, 4) === PROTOCOL_3 ? "yes" : "no";
18375
+ }
18376
+ var PgServer = class {
18377
+ buffer = new Uint8Array(0);
18378
+ skip = 0;
18379
+ lost = false;
18380
+ cleartext = false;
18381
+ feed(bytes) {
18382
+ if (this.lost) return;
18383
+ const data = new Uint8Array(this.buffer.length + bytes.length);
18384
+ data.set(this.buffer);
18385
+ data.set(bytes, this.buffer.length);
18386
+ let at = 0;
18387
+ for (; ; ) {
18388
+ const left = data.length - at;
18389
+ if (this.skip > 0) {
18390
+ const n = Math.min(this.skip, left);
18391
+ this.skip -= n;
18392
+ at += n;
18393
+ if (this.skip > 0) break;
18394
+ continue;
18395
+ }
18396
+ if (left < 5) break;
18397
+ const type = data[at];
18398
+ const whole = 1 + int32(data, at + 1);
18399
+ if (whole < 5 || type === 82 && whole > PG_MESSAGE_MAX) {
18400
+ this.lost = true;
18401
+ this.cleartext = false;
18402
+ this.buffer = new Uint8Array(0);
18403
+ return;
18404
+ }
18405
+ if (type !== 82) {
18406
+ this.skip = whole;
18407
+ continue;
18408
+ }
18409
+ if (left < whole) break;
18410
+ this.cleartext = whole === 9 && int32(data, at + 5) === CLEARTEXT;
18411
+ at += whole;
18412
+ }
18413
+ this.buffer = data.slice(at);
18414
+ }
18415
+ };
18416
+ function frame3(type, body) {
18417
+ const out = new Uint8Array(5 + body.length);
18418
+ out[0] = type;
18419
+ const length2 = 4 + body.length;
18420
+ out.set([length2 >>> 24 & 255, length2 >>> 16 & 255, length2 >>> 8 & 255, length2 & 255], 1);
18421
+ for (let i = 0; i < body.length; i++) out[5 + i] = body.charCodeAt(i);
18422
+ return out;
18423
+ }
18424
+ function pgLength(bytes, started) {
18425
+ const header4 = started ? 5 : 4;
18426
+ if (bytes.length < header4) return void 0;
18427
+ const length2 = int32(bytes, started ? 1 : 0);
18428
+ return started ? 1 + length2 : length2;
18429
+ }
18430
+ async function pgPassword(message3, server, ask) {
18431
+ if (message3[0] !== 112 || !server.cleartext) return { bytes: message3, done: true };
18432
+ server.cleartext = false;
18433
+ let body = "";
18434
+ for (const b of message3.subarray(5)) body += String.fromCharCode(b);
18435
+ if (!body.endsWith("\0") || body.indexOf("\0") !== body.length - 1)
18436
+ return { bytes: message3, done: true };
18437
+ const password = body.slice(0, -1);
18438
+ const placeholders = placeholdersIn(password);
18439
+ if (placeholders.length === 0 || placeholders.length > SESSION_PLACEHOLDERS)
18440
+ return { bytes: message3, done: true };
18441
+ const values = usable(await ask(placeholders));
18442
+ if (Object.keys(values).length === 0) return { bytes: message3, done: true };
18443
+ return { bytes: frame3(112, `${replaced(password, values)}\0`), values, done: true };
18444
+ }
18445
+
18353
18446
  // src/kernel/net/sealed-smtp.ts
18354
18447
  var SMTP_LINE_MAX = 4096;
18355
18448
  var GREETING = ["EHLO ", "HELO "];
@@ -18471,11 +18564,14 @@ function headEnd2(bytes) {
18471
18564
  return -1;
18472
18565
  }
18473
18566
  function modeOf(start2) {
18474
- const http = sniffHttp1(start2);
18475
- const smtp = sniffSmtp(start2);
18476
- if (http === "yes") return "http1";
18477
- if (smtp === "yes") return "smtp";
18478
- return http === "no" && smtp === "no" ? "pass" : void 0;
18567
+ const sniffs = [
18568
+ ["http1", sniffHttp1(start2)],
18569
+ ["smtp", sniffSmtp(start2)],
18570
+ ["pg", sniffPg(start2)]
18571
+ ];
18572
+ const hit = sniffs.find(([, v]) => v === "yes");
18573
+ if (hit) return hit[0];
18574
+ return sniffs.every(([, v]) => v === "no") ? "pass" : void 0;
18479
18575
  }
18480
18576
  function crlf(bytes) {
18481
18577
  for (let i = 0; i + 1 < bytes.length; i++) if (bytes[i] === 13 && bytes[i + 1] === 10) return i;
@@ -18489,12 +18585,15 @@ var SessionWriter = class {
18489
18585
  failed;
18490
18586
  session = sessionId();
18491
18587
  smtp;
18588
+ pgStarted = false;
18492
18589
  conn;
18493
18590
  s;
18591
+ pg;
18494
18592
  scope;
18495
- constructor(conn, s, scope) {
18593
+ constructor(conn, s, pg, scope) {
18496
18594
  this.conn = conn;
18497
18595
  this.s = s;
18596
+ this.pg = pg;
18498
18597
  this.scope = scope;
18499
18598
  this.smtp = new SmtpClient(
18500
18599
  (position, placeholders) => this.ask("smtp", position, placeholders)
@@ -18543,6 +18642,7 @@ var SessionWriter = class {
18543
18642
  if (this.mode === "pass") await this.release();
18544
18643
  else if (this.mode === "http1") await this.http1();
18545
18644
  else if (this.mode === "smtp") await this.lines();
18645
+ else if (this.mode === "pg") await this.messages();
18546
18646
  if (this.mode !== "pass" && this.buffer.length > 0)
18547
18647
  this.timer = setTimeout(() => this.idle(), HEAD_IDLE_MS);
18548
18648
  return bytes.length;
@@ -18573,6 +18673,33 @@ var SessionWriter = class {
18573
18673
  }
18574
18674
  if (this.buffer.length > SMTP_LINE_MAX) await this.release();
18575
18675
  }
18676
+ async messages() {
18677
+ for (; ; ) {
18678
+ const whole = pgLength(this.buffer, this.pgStarted);
18679
+ if (whole === void 0 || whole < 4 || whole > PG_MESSAGE_MAX) {
18680
+ if (whole !== void 0) await this.release();
18681
+ return;
18682
+ }
18683
+ if (this.buffer.length < whole) return;
18684
+ const message3 = this.buffer.slice(0, whole);
18685
+ this.buffer = this.buffer.slice(whole);
18686
+ const started = this.pgStarted;
18687
+ this.pgStarted = true;
18688
+ const out = started ? await pgPassword(
18689
+ message3,
18690
+ this.pg,
18691
+ (placeholders) => this.ask("pg", "password-cleartext", placeholders)
18692
+ ).catch(() => ({ bytes: message3, done: true })) : { bytes: message3, done: false };
18693
+ if ("values" in out && out.values) this.remember(out.values);
18694
+ try {
18695
+ await writeAll4(this.conn, out.bytes);
18696
+ } finally {
18697
+ out.bytes.fill(0);
18698
+ message3.fill(0);
18699
+ }
18700
+ if (out.done) return this.release();
18701
+ }
18702
+ }
18576
18703
  idle() {
18577
18704
  this.chain = this.chain.then(() => this.release()).catch((err) => {
18578
18705
  this.failed ??= err;
@@ -18686,9 +18813,18 @@ function idle() {
18686
18813
  return new Promise((resolve2) => setTimeout(() => resolve2(IDLE2), SCRUB_IDLE_MS));
18687
18814
  }
18688
18815
  function sealedConn(conn, s) {
18816
+ const pg = new PgServer();
18689
18817
  const scope = s.broker.sessions.scope(s.pid, s.host);
18690
- const writer = substitutes(s) ? new SessionWriter(conn, s, scope) : void 0;
18691
- const reader = new ScrubReader(conn, scope);
18818
+ const writer = substitutes(s) ? new SessionWriter(conn, s, pg, scope) : void 0;
18819
+ const observed = {
18820
+ ...conn,
18821
+ read: async () => {
18822
+ const bytes = await conn.read();
18823
+ if (bytes) pg.feed(bytes);
18824
+ return bytes;
18825
+ }
18826
+ };
18827
+ const reader = new ScrubReader(writer ? observed : conn, scope);
18692
18828
  return {
18693
18829
  localAddr: conn.localAddr,
18694
18830
  remoteAddr: conn.remoteAddr,
@@ -20332,6 +20468,9 @@ var VfsNodes = class {
20332
20468
  rewritten(path) {
20333
20469
  this.byPath.get(path)?.reread();
20334
20470
  }
20471
+ rewrittenUnder(tree2) {
20472
+ for (const [p, node] of this.byPath) if (within7(p, tree2)) node.reread();
20473
+ }
20335
20474
  doubted(path) {
20336
20475
  for (const [p, node] of this.byPath) if (within7(p, path)) node.doubted();
20337
20476
  }
@@ -26586,7 +26725,7 @@ var Launcher = class {
26586
26725
  options.fs.onPeer?.(() => this.flushOpen());
26587
26726
  options.fs.remoteChanges?.((change) => {
26588
26727
  this.changes.flush();
26589
- this.rewritten(change.paths);
26728
+ this.rewritten(change.paths, change.trees);
26590
26729
  });
26591
26730
  const holders = [this.held, this.openFiles];
26592
26731
  this.unlinked = new UnlinkedKeeper(
@@ -28372,8 +28511,11 @@ var Launcher = class {
28372
28511
  }
28373
28512
  };
28374
28513
  }
28375
- rewritten(paths) {
28376
- for (const nodes of this.openFiles) for (const path of paths) nodes.rewritten(path);
28514
+ rewritten(paths, trees = []) {
28515
+ for (const nodes of this.openFiles) {
28516
+ for (const path of paths) nodes.rewritten(path);
28517
+ for (const tree2 of trees) nodes.rewrittenUnder(tree2);
28518
+ }
28377
28519
  this.changes.publish(...paths);
28378
28520
  }
28379
28521
  async flushOpen() {