@ai-ecoverse/slicc-kernel 1.82.0 → 1.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/kernel-worker.js +940 -180
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node.js +948 -188
- package/dist/node.js.map +4 -4
- package/package.json +3 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -131,8 +131,8 @@ function descendants(path) {
|
|
|
131
131
|
return IDBKeyRange.bound(`${path}/`, `${path}0`, false, true);
|
|
132
132
|
}
|
|
133
133
|
function settle(transaction, value) {
|
|
134
|
-
return new Promise((
|
|
135
|
-
transaction.oncomplete = () =>
|
|
134
|
+
return new Promise((resolve2, reject) => {
|
|
135
|
+
transaction.oncomplete = () => resolve2(value());
|
|
136
136
|
transaction.onabort = () => reject(transaction.error ?? new Error("metadata transaction aborted"));
|
|
137
137
|
});
|
|
138
138
|
}
|
|
@@ -249,14 +249,14 @@ var IndexedDbMeta = class {
|
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
251
|
function openMeta(name2, factory) {
|
|
252
|
-
return new Promise((
|
|
252
|
+
return new Promise((resolve2, reject) => {
|
|
253
253
|
const request2 = factory.open(name2, META_VERSION);
|
|
254
254
|
request2.onupgradeneeded = (event) => {
|
|
255
255
|
if (event.oldVersion < 1) {
|
|
256
256
|
request2.result.createObjectStore(META_STORE, { keyPath: "path" }).createIndex("dir", "dir");
|
|
257
257
|
}
|
|
258
258
|
};
|
|
259
|
-
request2.onsuccess = () =>
|
|
259
|
+
request2.onsuccess = () => resolve2(new IndexedDbMeta(request2.result));
|
|
260
260
|
request2.onerror = () => reject(request2.error);
|
|
261
261
|
});
|
|
262
262
|
}
|
|
@@ -740,11 +740,11 @@ var RemoteWatch = class {
|
|
|
740
740
|
const seq2 = ++this.seq;
|
|
741
741
|
this.channel.postMessage({ tab: this.tab, paths: this.mine, seq: seq2 });
|
|
742
742
|
if (this.peers.size === 0) return Promise.resolve();
|
|
743
|
-
return new Promise((
|
|
743
|
+
return new Promise((resolve2) => {
|
|
744
744
|
const done4 = () => {
|
|
745
745
|
clearTimeout(timer);
|
|
746
746
|
this.waiting.delete(seq2);
|
|
747
|
-
|
|
747
|
+
resolve2();
|
|
748
748
|
};
|
|
749
749
|
const timer = setTimeout(() => {
|
|
750
750
|
done4();
|
|
@@ -840,7 +840,7 @@ async function openSync(handle) {
|
|
|
840
840
|
const delay = SYNC_BACKOFF_MS[attempt];
|
|
841
841
|
if (!LOCKED.has(err?.name)) throw err;
|
|
842
842
|
if (delay === void 0) return void 0;
|
|
843
|
-
await new Promise((
|
|
843
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
844
844
|
}
|
|
845
845
|
}
|
|
846
846
|
}
|
|
@@ -1297,7 +1297,7 @@ var OpfsFs = class {
|
|
|
1297
1297
|
const again = name2 === "NotReadableError" || locks && LOCKED.has(name2);
|
|
1298
1298
|
if (!again || attempt >= READ_ATTEMPTS)
|
|
1299
1299
|
throw translate(err, path, locks ? "write" : "read");
|
|
1300
|
-
await new Promise((
|
|
1300
|
+
await new Promise((resolve2) => setTimeout(resolve2, attempt * 10));
|
|
1301
1301
|
}
|
|
1302
1302
|
}
|
|
1303
1303
|
}
|
|
@@ -1354,8 +1354,8 @@ var OpfsFs = class {
|
|
|
1354
1354
|
}
|
|
1355
1355
|
async truncate(path, size) {
|
|
1356
1356
|
const handle = await this.existing(path, true);
|
|
1357
|
-
const
|
|
1358
|
-
const target =
|
|
1357
|
+
const resolve2 = this.ranged || this.remote?.watched();
|
|
1358
|
+
const target = resolve2 ? (await this.locate(path, true)).path : path;
|
|
1359
1359
|
await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
|
|
1360
1360
|
this.written(target);
|
|
1361
1361
|
}
|
|
@@ -1779,8 +1779,8 @@ function memoryMedia() {
|
|
|
1779
1779
|
};
|
|
1780
1780
|
}
|
|
1781
1781
|
function settle2(request2, value) {
|
|
1782
|
-
return new Promise((
|
|
1783
|
-
request2.onsuccess = () =>
|
|
1782
|
+
return new Promise((resolve2, reject) => {
|
|
1783
|
+
request2.onsuccess = () => resolve2(value());
|
|
1784
1784
|
request2.onerror = () => reject(request2.error);
|
|
1785
1785
|
});
|
|
1786
1786
|
}
|
|
@@ -1818,7 +1818,7 @@ function pinScript(url) {
|
|
|
1818
1818
|
|
|
1819
1819
|
// src/cdp/port.ts
|
|
1820
1820
|
function portCdpHook(ask, gone) {
|
|
1821
|
-
return (request2) => new Promise((
|
|
1821
|
+
return (request2) => new Promise((resolve2, reject) => {
|
|
1822
1822
|
const { port1, port2 } = new MessageChannel();
|
|
1823
1823
|
let closed = false;
|
|
1824
1824
|
const conn = {
|
|
@@ -1836,7 +1836,7 @@ function portCdpHook(ask, gone) {
|
|
|
1836
1836
|
};
|
|
1837
1837
|
port1.addEventListener("message", ({ data }) => {
|
|
1838
1838
|
if ("m" in data) conn.onmessage?.(data.m);
|
|
1839
|
-
else if ("open" in data)
|
|
1839
|
+
else if ("open" in data) resolve2(conn);
|
|
1840
1840
|
else if ("error" in data) {
|
|
1841
1841
|
closed = true;
|
|
1842
1842
|
port1.close();
|
|
@@ -2370,9 +2370,9 @@ var KernelPipe = class {
|
|
|
2370
2370
|
let filled = 0;
|
|
2371
2371
|
for (const chunk2 of this.chunks) {
|
|
2372
2372
|
if (filled === out.length) break;
|
|
2373
|
-
const
|
|
2374
|
-
out.set(chunk2.subarray(0,
|
|
2375
|
-
filled +=
|
|
2373
|
+
const count2 = Math.min(chunk2.length, out.length - filled);
|
|
2374
|
+
out.set(chunk2.subarray(0, count2), filled);
|
|
2375
|
+
filled += count2;
|
|
2376
2376
|
}
|
|
2377
2377
|
return out;
|
|
2378
2378
|
}
|
|
@@ -2403,25 +2403,25 @@ var KernelPipe = class {
|
|
|
2403
2403
|
let filled = 0;
|
|
2404
2404
|
while (filled < n) {
|
|
2405
2405
|
const head = this.chunks[0];
|
|
2406
|
-
const
|
|
2407
|
-
out.set(head.subarray(0,
|
|
2408
|
-
filled +=
|
|
2409
|
-
if (
|
|
2410
|
-
else this.chunks[0] = head.subarray(
|
|
2406
|
+
const count2 = Math.min(head.length, n - filled);
|
|
2407
|
+
out.set(head.subarray(0, count2), filled);
|
|
2408
|
+
filled += count2;
|
|
2409
|
+
if (count2 === head.length) this.chunks.shift();
|
|
2410
|
+
else this.chunks[0] = head.subarray(count2);
|
|
2411
2411
|
}
|
|
2412
2412
|
this.size -= n;
|
|
2413
2413
|
return out;
|
|
2414
2414
|
}
|
|
2415
2415
|
changed(signal) {
|
|
2416
2416
|
if (signal?.aborted) return Promise.reject(new PipeError("EINTR"));
|
|
2417
|
-
return new Promise((
|
|
2417
|
+
return new Promise((resolve2, reject) => {
|
|
2418
2418
|
const onAbort = () => {
|
|
2419
2419
|
this.waiters = this.waiters.filter((w) => w !== waiter);
|
|
2420
2420
|
reject(new PipeError("EINTR"));
|
|
2421
2421
|
};
|
|
2422
2422
|
const waiter = () => {
|
|
2423
2423
|
signal?.removeEventListener("abort", onAbort);
|
|
2424
|
-
|
|
2424
|
+
resolve2();
|
|
2425
2425
|
};
|
|
2426
2426
|
this.waiters.push(waiter);
|
|
2427
2427
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -2430,7 +2430,7 @@ var KernelPipe = class {
|
|
|
2430
2430
|
wake() {
|
|
2431
2431
|
const waiters = this.waiters;
|
|
2432
2432
|
this.waiters = [];
|
|
2433
|
-
for (const
|
|
2433
|
+
for (const resolve2 of waiters) resolve2();
|
|
2434
2434
|
}
|
|
2435
2435
|
};
|
|
2436
2436
|
|
|
@@ -2891,14 +2891,14 @@ var Changes = class {
|
|
|
2891
2891
|
waiters = [];
|
|
2892
2892
|
wait(signal) {
|
|
2893
2893
|
if (signal?.aborted) return Promise.reject(new KernelError("EINTR"));
|
|
2894
|
-
return new Promise((
|
|
2894
|
+
return new Promise((resolve2, reject) => {
|
|
2895
2895
|
const onAbort = () => {
|
|
2896
2896
|
this.waiters = this.waiters.filter((w) => w !== waiter);
|
|
2897
2897
|
reject(new KernelError("EINTR"));
|
|
2898
2898
|
};
|
|
2899
2899
|
const waiter = () => {
|
|
2900
2900
|
signal?.removeEventListener("abort", onAbort);
|
|
2901
|
-
|
|
2901
|
+
resolve2();
|
|
2902
2902
|
};
|
|
2903
2903
|
this.waiters.push(waiter);
|
|
2904
2904
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -2907,7 +2907,7 @@ var Changes = class {
|
|
|
2907
2907
|
wake() {
|
|
2908
2908
|
const waiters = this.waiters;
|
|
2909
2909
|
this.waiters = [];
|
|
2910
|
-
for (const
|
|
2910
|
+
for (const resolve2 of waiters) resolve2();
|
|
2911
2911
|
}
|
|
2912
2912
|
};
|
|
2913
2913
|
function link(a, b) {
|
|
@@ -3075,7 +3075,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
3075
3075
|
});
|
|
3076
3076
|
const { host, port } = addr;
|
|
3077
3077
|
const dialled = new Promise(
|
|
3078
|
-
(
|
|
3078
|
+
(resolve2) => resolve2(route.uplink.dial({ network: "tcp", host, port, signal: abort.signal }))
|
|
3079
3079
|
);
|
|
3080
3080
|
dialled.then(
|
|
3081
3081
|
(conn) => abort.signal.aborted && conn.close(),
|
|
@@ -3425,8 +3425,8 @@ var MessageQueue = class {
|
|
|
3425
3425
|
this.overflow = overflow;
|
|
3426
3426
|
this.limit = limit;
|
|
3427
3427
|
this.taken = taken;
|
|
3428
|
-
this.closed = new Promise((
|
|
3429
|
-
this.settle =
|
|
3428
|
+
this.closed = new Promise((resolve2) => {
|
|
3429
|
+
this.settle = resolve2;
|
|
3430
3430
|
});
|
|
3431
3431
|
}
|
|
3432
3432
|
push(message3) {
|
|
@@ -3465,8 +3465,8 @@ var MessageQueue = class {
|
|
|
3465
3465
|
continue;
|
|
3466
3466
|
}
|
|
3467
3467
|
if (this.ended) return;
|
|
3468
|
-
await new Promise((
|
|
3469
|
-
this.waiter =
|
|
3468
|
+
await new Promise((resolve2) => {
|
|
3469
|
+
this.waiter = resolve2;
|
|
3470
3470
|
});
|
|
3471
3471
|
}
|
|
3472
3472
|
}
|
|
@@ -3557,8 +3557,8 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
3557
3557
|
const relay = async (nid, socket) => {
|
|
3558
3558
|
let ending;
|
|
3559
3559
|
let late;
|
|
3560
|
-
const unanswered = new Promise((
|
|
3561
|
-
late = () =>
|
|
3560
|
+
const unanswered = new Promise((resolve2) => {
|
|
3561
|
+
late = () => resolve2("late");
|
|
3562
3562
|
});
|
|
3563
3563
|
const flow = {
|
|
3564
3564
|
inflight: 0,
|
|
@@ -3586,8 +3586,8 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
3586
3586
|
}
|
|
3587
3587
|
flow.inflight += payloadSize(data);
|
|
3588
3588
|
while (flow.inflight > INBOUND_LIMIT && !flow.closing) {
|
|
3589
|
-
await new Promise((
|
|
3590
|
-
flow.wake =
|
|
3589
|
+
await new Promise((resolve2) => {
|
|
3590
|
+
flow.wake = resolve2;
|
|
3591
3591
|
});
|
|
3592
3592
|
}
|
|
3593
3593
|
}
|
|
@@ -3606,7 +3606,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
3606
3606
|
if (!socket) return;
|
|
3607
3607
|
socket.send(call.data);
|
|
3608
3608
|
while (socket.buffered > SEND_BUFFER && sockets.has(call.nid)) {
|
|
3609
|
-
await new Promise((
|
|
3609
|
+
await new Promise((resolve2) => setTimeout(resolve2, 10));
|
|
3610
3610
|
}
|
|
3611
3611
|
peer.postMessage({ net: "ws-acked", nid: call.nid, n: payloadSize(call.data) });
|
|
3612
3612
|
};
|
|
@@ -5113,10 +5113,10 @@ var Budget = class {
|
|
|
5113
5113
|
async acquire(n, signal) {
|
|
5114
5114
|
while (this.free < n) {
|
|
5115
5115
|
signal.throwIfAborted();
|
|
5116
|
-
await new Promise((
|
|
5116
|
+
await new Promise((resolve2) => {
|
|
5117
5117
|
const done4 = () => {
|
|
5118
5118
|
signal.removeEventListener("abort", done4);
|
|
5119
|
-
|
|
5119
|
+
resolve2();
|
|
5120
5120
|
};
|
|
5121
5121
|
this.waiters.push(done4);
|
|
5122
5122
|
signal.addEventListener("abort", done4, { once: true });
|
|
@@ -5258,14 +5258,14 @@ async function watchHangup(conn, abort, until) {
|
|
|
5258
5258
|
}
|
|
5259
5259
|
}
|
|
5260
5260
|
function untilAborted(response, signal) {
|
|
5261
|
-
return new Promise((
|
|
5261
|
+
return new Promise((resolve2, reject) => {
|
|
5262
5262
|
const onAbort = () => {
|
|
5263
5263
|
reject(signal.reason ?? new KernelError("EINTR"));
|
|
5264
5264
|
response.then((late) => late.cancel()).catch(() => void 0);
|
|
5265
5265
|
};
|
|
5266
5266
|
if (signal.aborted) return onAbort();
|
|
5267
5267
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5268
|
-
response.then(
|
|
5268
|
+
response.then(resolve2, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
5269
5269
|
});
|
|
5270
5270
|
}
|
|
5271
5271
|
function plainResponse(status, message3) {
|
|
@@ -5298,8 +5298,8 @@ function wireCode(code) {
|
|
|
5298
5298
|
return sendableCode(code) ? code : 1011;
|
|
5299
5299
|
}
|
|
5300
5300
|
function quietly(ms) {
|
|
5301
|
-
return new Promise((
|
|
5302
|
-
AbortSignal.timeout(ms).addEventListener("abort", () =>
|
|
5301
|
+
return new Promise((resolve2) => {
|
|
5302
|
+
AbortSignal.timeout(ms).addEventListener("abort", () => resolve2(), { once: true });
|
|
5303
5303
|
});
|
|
5304
5304
|
}
|
|
5305
5305
|
var RealmProxy = class {
|
|
@@ -5397,7 +5397,7 @@ var RealmProxy = class {
|
|
|
5397
5397
|
return false;
|
|
5398
5398
|
}
|
|
5399
5399
|
const url = ctx.origin ? tunnelRequestUrl(req, ctx.origin) : requestUrl(req);
|
|
5400
|
-
const
|
|
5400
|
+
const keep2 = keepsAlive(req);
|
|
5401
5401
|
const framing = requestFraming(req.headers);
|
|
5402
5402
|
const reserve = framing.kind === "length" ? framing.length : framing.kind === "chunked" ? this.cap() : 0;
|
|
5403
5403
|
if (reserve > this.cap()) throw new HttpError(413, `request body over ${this.cap()} bytes`);
|
|
@@ -5420,7 +5420,7 @@ var RealmProxy = class {
|
|
|
5420
5420
|
} finally {
|
|
5421
5421
|
this.bodies.release(reserve);
|
|
5422
5422
|
}
|
|
5423
|
-
return await this.relay(conn, req.method, req.minor, response,
|
|
5423
|
+
return await this.relay(conn, req.method, req.minor, response, keep2);
|
|
5424
5424
|
} finally {
|
|
5425
5425
|
this.stop.signal.removeEventListener("abort", stopExchange);
|
|
5426
5426
|
abort.abort();
|
|
@@ -5468,8 +5468,8 @@ var RealmProxy = class {
|
|
|
5468
5468
|
bodiless: bodiless2
|
|
5469
5469
|
});
|
|
5470
5470
|
const chunked = !bodiless2 && minor >= 1;
|
|
5471
|
-
const
|
|
5472
|
-
headers.push(["Connection",
|
|
5471
|
+
const keep2 = keepAlive && (bodiless2 || chunked);
|
|
5472
|
+
headers.push(["Connection", keep2 ? "keep-alive" : "close"]);
|
|
5473
5473
|
if (chunked) headers.push(["Transfer-Encoding", "chunked"]);
|
|
5474
5474
|
const signal = this.stop.signal;
|
|
5475
5475
|
await conn.write(
|
|
@@ -5478,7 +5478,7 @@ var RealmProxy = class {
|
|
|
5478
5478
|
);
|
|
5479
5479
|
if (bodiless2) {
|
|
5480
5480
|
await response.cancel();
|
|
5481
|
-
return
|
|
5481
|
+
return keep2;
|
|
5482
5482
|
}
|
|
5483
5483
|
try {
|
|
5484
5484
|
for await (const piece of response.body) {
|
|
@@ -5489,7 +5489,7 @@ var RealmProxy = class {
|
|
|
5489
5489
|
return false;
|
|
5490
5490
|
}
|
|
5491
5491
|
if (chunked) await conn.write(LAST_CHUNK, signal);
|
|
5492
|
-
return
|
|
5492
|
+
return keep2;
|
|
5493
5493
|
}
|
|
5494
5494
|
async connect(conn, incoming, req, idle) {
|
|
5495
5495
|
const target = tunnelTarget(req);
|
|
@@ -5712,10 +5712,10 @@ function header(der, at) {
|
|
|
5712
5712
|
let len = der[at + 1];
|
|
5713
5713
|
let start2 = at + 2;
|
|
5714
5714
|
if (len & 128) {
|
|
5715
|
-
const
|
|
5715
|
+
const count2 = len & 127;
|
|
5716
5716
|
len = 0;
|
|
5717
|
-
for (let i = 0; i <
|
|
5718
|
-
start2 +=
|
|
5717
|
+
for (let i = 0; i < count2; i++) len = len * 256 + der[start2 + i];
|
|
5718
|
+
start2 += count2;
|
|
5719
5719
|
}
|
|
5720
5720
|
if (start2 + len > der.length) throw new Error("truncated DER");
|
|
5721
5721
|
return [tag, start2, start2 + len];
|
|
@@ -5833,18 +5833,18 @@ var LEAF_LIFETIME = 7 * DAY;
|
|
|
5833
5833
|
var ECDSA = { name: "ECDSA", namedCurve: "P-256" };
|
|
5834
5834
|
var SIGN = { name: "ECDSA", hash: "SHA-256" };
|
|
5835
5835
|
function request(req) {
|
|
5836
|
-
return new Promise((
|
|
5837
|
-
req.onsuccess = () =>
|
|
5836
|
+
return new Promise((resolve2, reject) => {
|
|
5837
|
+
req.onsuccess = () => resolve2(req.result);
|
|
5838
5838
|
req.onerror = () => reject(req.error);
|
|
5839
5839
|
});
|
|
5840
5840
|
}
|
|
5841
5841
|
function indexedDbCaStore(dbName = "slicc-realm-ca") {
|
|
5842
5842
|
let db;
|
|
5843
5843
|
const open = () => {
|
|
5844
|
-
db ??= new Promise((
|
|
5844
|
+
db ??= new Promise((resolve2, reject) => {
|
|
5845
5845
|
const req = indexedDB.open(dbName, 1);
|
|
5846
5846
|
req.onupgradeneeded = () => req.result.createObjectStore("ca");
|
|
5847
|
-
req.onsuccess = () =>
|
|
5847
|
+
req.onsuccess = () => resolve2(req.result);
|
|
5848
5848
|
req.onerror = () => reject(req.error);
|
|
5849
5849
|
});
|
|
5850
5850
|
db.catch(() => {
|
|
@@ -5868,8 +5868,8 @@ function indexedDbCaStore(dbName = "slicc-realm-ca") {
|
|
|
5868
5868
|
if (kept === record) store.put(record, owner);
|
|
5869
5869
|
else stored = kept;
|
|
5870
5870
|
};
|
|
5871
|
-
await new Promise((
|
|
5872
|
-
tx.oncomplete = () =>
|
|
5871
|
+
await new Promise((resolve2, reject) => {
|
|
5872
|
+
tx.oncomplete = () => resolve2();
|
|
5873
5873
|
tx.onerror = () => reject(tx.error);
|
|
5874
5874
|
});
|
|
5875
5875
|
return stored;
|
|
@@ -6398,8 +6398,8 @@ var RemoteTransport = class {
|
|
|
6398
6398
|
}
|
|
6399
6399
|
ask(call) {
|
|
6400
6400
|
if (this.failure) return Promise.reject(this.failure);
|
|
6401
|
-
return new Promise((
|
|
6402
|
-
this.waiting.set(call.nid, { resolve, reject });
|
|
6401
|
+
return new Promise((resolve2, reject) => {
|
|
6402
|
+
this.waiting.set(call.nid, { resolve: resolve2, reject });
|
|
6403
6403
|
this.port.postMessage(call);
|
|
6404
6404
|
});
|
|
6405
6405
|
}
|
|
@@ -6804,7 +6804,7 @@ var CdpFacade = class {
|
|
|
6804
6804
|
const conn = await this.host(runtime);
|
|
6805
6805
|
try {
|
|
6806
6806
|
const reply = await new Promise(
|
|
6807
|
-
(
|
|
6807
|
+
(resolve2, reject) => {
|
|
6808
6808
|
const timer = setTimeout(
|
|
6809
6809
|
() => reject(new HttpError(504, "the CDP host did not answer Target.getTargets")),
|
|
6810
6810
|
this.options.listTimeout ?? LIST_TIMEOUT
|
|
@@ -6817,7 +6817,7 @@ var CdpFacade = class {
|
|
|
6817
6817
|
const parsed2 = JSON.parse(message3);
|
|
6818
6818
|
if (parsed2.id !== 1) return;
|
|
6819
6819
|
clearTimeout(timer);
|
|
6820
|
-
|
|
6820
|
+
resolve2(parsed2);
|
|
6821
6821
|
};
|
|
6822
6822
|
conn.send(JSON.stringify({ id: 1, method: "Target.getTargets" }));
|
|
6823
6823
|
}
|
|
@@ -6877,9 +6877,9 @@ var Relay = class {
|
|
|
6877
6877
|
}
|
|
6878
6878
|
async start(head) {
|
|
6879
6879
|
await this.send(head);
|
|
6880
|
-
const hostGone = new Promise((
|
|
6880
|
+
const hostGone = new Promise((resolve2) => {
|
|
6881
6881
|
this.host.onclose = (reason) => {
|
|
6882
|
-
void this.end(reason ? CLOSE.error : CLOSE.normal, reason ?? "").then(() =>
|
|
6882
|
+
void this.end(reason ? CLOSE.error : CLOSE.normal, reason ?? "").then(() => resolve2());
|
|
6883
6883
|
};
|
|
6884
6884
|
});
|
|
6885
6885
|
this.host.onmessage = (message3) => {
|
|
@@ -6893,8 +6893,8 @@ var Relay = class {
|
|
|
6893
6893
|
await Promise.race([pumping, hostGone]);
|
|
6894
6894
|
await this.writes;
|
|
6895
6895
|
let timer;
|
|
6896
|
-
const waited = new Promise((
|
|
6897
|
-
timer = setTimeout(
|
|
6896
|
+
const waited = new Promise((resolve2) => {
|
|
6897
|
+
timer = setTimeout(resolve2, this.closeWaitMs);
|
|
6898
6898
|
});
|
|
6899
6899
|
await Promise.race([pumping, waited]);
|
|
6900
6900
|
clearTimeout(timer);
|
|
@@ -7544,16 +7544,16 @@ var FreshModules = class {
|
|
|
7544
7544
|
if (head) await decide(path, head);
|
|
7545
7545
|
};
|
|
7546
7546
|
}
|
|
7547
|
-
const
|
|
7547
|
+
const bound2 = /* @__PURE__ */ new WeakMap();
|
|
7548
7548
|
return new Proxy(fs, {
|
|
7549
7549
|
get(target, key, receiver) {
|
|
7550
7550
|
if (Object.hasOwn(overrides, key)) return overrides[key];
|
|
7551
7551
|
const value = Reflect.get(target, key, receiver);
|
|
7552
7552
|
if (typeof value !== "function") return value;
|
|
7553
|
-
let method =
|
|
7553
|
+
let method = bound2.get(value);
|
|
7554
7554
|
if (method === void 0) {
|
|
7555
7555
|
method = value.bind(target);
|
|
7556
|
-
|
|
7556
|
+
bound2.set(value, method);
|
|
7557
7557
|
}
|
|
7558
7558
|
return method;
|
|
7559
7559
|
}
|
|
@@ -7621,12 +7621,12 @@ var PathGate = class {
|
|
|
7621
7621
|
tails = /* @__PURE__ */ new Map();
|
|
7622
7622
|
async acquire(path) {
|
|
7623
7623
|
const prev = this.tails.get(path) ?? Promise.resolve();
|
|
7624
|
-
const { promise, resolve } = Promise.withResolvers();
|
|
7624
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
7625
7625
|
const tail = prev.then(() => promise);
|
|
7626
7626
|
this.tails.set(path, tail);
|
|
7627
7627
|
await prev;
|
|
7628
7628
|
return () => {
|
|
7629
|
-
|
|
7629
|
+
resolve2();
|
|
7630
7630
|
if (this.tails.get(path) === tail) this.tails.delete(path);
|
|
7631
7631
|
};
|
|
7632
7632
|
}
|
|
@@ -8104,7 +8104,7 @@ var ChildTable = class {
|
|
|
8104
8104
|
}
|
|
8105
8105
|
async nextChange(candidates, flags2, interrupt) {
|
|
8106
8106
|
let wake;
|
|
8107
|
-
const stateChange = new Promise((
|
|
8107
|
+
const stateChange = new Promise((resolve2) => wake = resolve2);
|
|
8108
8108
|
const watching = flags2.untraced || flags2.continued;
|
|
8109
8109
|
if (watching && wake) this.stateChanged.push(wake);
|
|
8110
8110
|
try {
|
|
@@ -8151,6 +8151,65 @@ var ChildTable = class {
|
|
|
8151
8151
|
}
|
|
8152
8152
|
};
|
|
8153
8153
|
|
|
8154
|
+
// src/kernel/exec-ticket.ts
|
|
8155
|
+
var TICKET_ENV = "SLICC_SEALED_TICKET";
|
|
8156
|
+
var TICKET_TTL_MS = 3e4;
|
|
8157
|
+
var MAX_TICKETS = 256;
|
|
8158
|
+
var TICKET = /^[0-9a-f]{32}$/;
|
|
8159
|
+
async function argvDigest(argv) {
|
|
8160
|
+
const bytes = new TextEncoder().encode(JSON.stringify(argv));
|
|
8161
|
+
const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
|
|
8162
|
+
return [...hash].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
8163
|
+
}
|
|
8164
|
+
function isStrings(value) {
|
|
8165
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
8166
|
+
}
|
|
8167
|
+
function stringRecord(value) {
|
|
8168
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
8169
|
+
const entries = Object.entries(value);
|
|
8170
|
+
return entries.every(([, v]) => typeof v === "string") ? Object.fromEntries(entries) : void 0;
|
|
8171
|
+
}
|
|
8172
|
+
var TicketBook = class {
|
|
8173
|
+
booked = /* @__PURE__ */ new Map();
|
|
8174
|
+
now;
|
|
8175
|
+
normalise = async (path) => path;
|
|
8176
|
+
constructor(now = Date.now) {
|
|
8177
|
+
this.now = now;
|
|
8178
|
+
}
|
|
8179
|
+
get size() {
|
|
8180
|
+
return this.booked.size;
|
|
8181
|
+
}
|
|
8182
|
+
async record(req, reply, pid) {
|
|
8183
|
+
const { ticket, error } = reply;
|
|
8184
|
+
if (error !== void 0 || typeof ticket !== "string" || !TICKET.test(ticket)) return;
|
|
8185
|
+
const { path, argv, cwd } = req;
|
|
8186
|
+
const entry = {
|
|
8187
|
+
pid,
|
|
8188
|
+
path: await this.normalise(path),
|
|
8189
|
+
requested: path,
|
|
8190
|
+
requestedCwd: cwd,
|
|
8191
|
+
argv: await argvDigest(argv),
|
|
8192
|
+
cwd: await this.normalise(cwd),
|
|
8193
|
+
at: this.now()
|
|
8194
|
+
};
|
|
8195
|
+
this.prune();
|
|
8196
|
+
while (this.booked.size >= MAX_TICKETS)
|
|
8197
|
+
this.booked.delete(this.booked.keys().next().value);
|
|
8198
|
+
this.booked.set(ticket, entry);
|
|
8199
|
+
}
|
|
8200
|
+
take(ticket) {
|
|
8201
|
+
const booked = this.booked.get(ticket);
|
|
8202
|
+
this.booked.delete(ticket);
|
|
8203
|
+
return booked && this.now() - booked.at < TICKET_TTL_MS ? booked : void 0;
|
|
8204
|
+
}
|
|
8205
|
+
prune() {
|
|
8206
|
+
const now = this.now();
|
|
8207
|
+
for (const [ticket, booked] of this.booked) {
|
|
8208
|
+
if (now - booked.at >= TICKET_TTL_MS) this.booked.delete(ticket);
|
|
8209
|
+
}
|
|
8210
|
+
}
|
|
8211
|
+
};
|
|
8212
|
+
|
|
8154
8213
|
// src/mount/protocol.ts
|
|
8155
8214
|
var DRIVER_PROTOCOL = [1, 2];
|
|
8156
8215
|
function driverVersionError(theirs) {
|
|
@@ -8221,7 +8280,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
8221
8280
|
call(call, transfer = []) {
|
|
8222
8281
|
if (this.failure) return Promise.reject(this.failure);
|
|
8223
8282
|
const id2 = ++this.nextId;
|
|
8224
|
-
return new Promise((
|
|
8283
|
+
return new Promise((resolve2, reject) => {
|
|
8225
8284
|
const timer = unref(
|
|
8226
8285
|
setTimeout(() => {
|
|
8227
8286
|
this.waiting.delete(id2);
|
|
@@ -8234,7 +8293,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
8234
8293
|
this.onFail?.(error);
|
|
8235
8294
|
}, this.timeoutMs)
|
|
8236
8295
|
);
|
|
8237
|
-
this.waiting.set(id2, { resolve, reject, timer });
|
|
8296
|
+
this.waiting.set(id2, { resolve: resolve2, reject, timer });
|
|
8238
8297
|
this.port.postMessage({ ...call, id: id2 }, transfer);
|
|
8239
8298
|
});
|
|
8240
8299
|
}
|
|
@@ -8377,8 +8436,8 @@ var HeldPaths = class extends Map {
|
|
|
8377
8436
|
this.keptHandles.delete(handle);
|
|
8378
8437
|
if (kept) this.letGo(kept);
|
|
8379
8438
|
}
|
|
8380
|
-
const
|
|
8381
|
-
if (
|
|
8439
|
+
const count2 = (this.opens.get(key) ?? 0) + (on ? 1 : -1);
|
|
8440
|
+
if (count2 > 0) this.opens.set(key, count2);
|
|
8382
8441
|
else {
|
|
8383
8442
|
this.opens.delete(key);
|
|
8384
8443
|
for (const id2 of this.handlesAt(key)) this.handles.delete(id2);
|
|
@@ -8392,8 +8451,8 @@ var HeldPaths = class extends Map {
|
|
|
8392
8451
|
return this.lastHandle;
|
|
8393
8452
|
}
|
|
8394
8453
|
holdWrite(path, on) {
|
|
8395
|
-
const
|
|
8396
|
-
if (
|
|
8454
|
+
const count2 = (this.get(path) ?? 0) + (on ? 1 : -1);
|
|
8455
|
+
if (count2 > 0) this.set(path, count2);
|
|
8397
8456
|
else {
|
|
8398
8457
|
this.delete(path);
|
|
8399
8458
|
this.revoked.delete(path);
|
|
@@ -8415,18 +8474,18 @@ var HeldPaths = class extends Map {
|
|
|
8415
8474
|
for (const path of this.keys()) if (within5(path, prefix)) this.revoked.add(path);
|
|
8416
8475
|
}
|
|
8417
8476
|
renamed(from, to) {
|
|
8418
|
-
for (const [path,
|
|
8477
|
+
for (const [path, count2] of [...this]) {
|
|
8419
8478
|
if (!within5(path, from)) continue;
|
|
8420
8479
|
const moved2 = to + path.slice(from.length);
|
|
8421
8480
|
this.delete(path);
|
|
8422
|
-
this.set(moved2, (this.get(moved2) ?? 0) +
|
|
8481
|
+
this.set(moved2, (this.get(moved2) ?? 0) + count2);
|
|
8423
8482
|
if (this.revoked.delete(path)) this.revoked.add(moved2);
|
|
8424
8483
|
}
|
|
8425
|
-
for (const [path,
|
|
8484
|
+
for (const [path, count2] of [...this.opens]) {
|
|
8426
8485
|
if (!within5(path, from)) continue;
|
|
8427
8486
|
const moved2 = to + path.slice(from.length);
|
|
8428
8487
|
this.opens.delete(path);
|
|
8429
|
-
this.opens.set(moved2, (this.opens.get(moved2) ?? 0) +
|
|
8488
|
+
this.opens.set(moved2, (this.opens.get(moved2) ?? 0) + count2);
|
|
8430
8489
|
}
|
|
8431
8490
|
for (const [id2, key] of this.handles) {
|
|
8432
8491
|
if (within5(key, from)) this.handles.set(id2, to + key.slice(from.length));
|
|
@@ -10720,7 +10779,7 @@ var AsyncOps = class {
|
|
|
10720
10779
|
this.wake();
|
|
10721
10780
|
}
|
|
10722
10781
|
sleep(timeoutMs, signal) {
|
|
10723
|
-
return new Promise((
|
|
10782
|
+
return new Promise((resolve2, reject) => {
|
|
10724
10783
|
let timer;
|
|
10725
10784
|
const cleanup = () => {
|
|
10726
10785
|
clearTimeout(timer);
|
|
@@ -10729,7 +10788,7 @@ var AsyncOps = class {
|
|
|
10729
10788
|
};
|
|
10730
10789
|
const wake = () => {
|
|
10731
10790
|
cleanup();
|
|
10732
|
-
|
|
10791
|
+
resolve2(true);
|
|
10733
10792
|
};
|
|
10734
10793
|
const abort = () => {
|
|
10735
10794
|
cleanup();
|
|
@@ -10740,7 +10799,7 @@ var AsyncOps = class {
|
|
|
10740
10799
|
if (timeoutMs !== void 0) {
|
|
10741
10800
|
timer = setTimeout(() => {
|
|
10742
10801
|
cleanup();
|
|
10743
|
-
|
|
10802
|
+
resolve2(false);
|
|
10744
10803
|
}, timeoutMs);
|
|
10745
10804
|
}
|
|
10746
10805
|
});
|
|
@@ -11162,7 +11221,7 @@ var Resolver = class {
|
|
|
11162
11221
|
};
|
|
11163
11222
|
function waitFor(lookup, signal) {
|
|
11164
11223
|
lookup.waiters++;
|
|
11165
|
-
return new Promise((
|
|
11224
|
+
return new Promise((resolve2, reject) => {
|
|
11166
11225
|
const abort = () => {
|
|
11167
11226
|
if (--lookup.waiters === 0) lookup.abort.abort(new KernelError("EINTR"));
|
|
11168
11227
|
reject(new KernelError("EINTR"));
|
|
@@ -11172,7 +11231,7 @@ function waitFor(lookup, signal) {
|
|
|
11172
11231
|
if (signal?.aborted) return;
|
|
11173
11232
|
lookup.waiters--;
|
|
11174
11233
|
signal?.removeEventListener("abort", abort);
|
|
11175
|
-
|
|
11234
|
+
resolve2(value);
|
|
11176
11235
|
});
|
|
11177
11236
|
});
|
|
11178
11237
|
}
|
|
@@ -11353,8 +11412,8 @@ var KernelTty = class {
|
|
|
11353
11412
|
}
|
|
11354
11413
|
rubOut(n) {
|
|
11355
11414
|
const dropped2 = this.line.splice(this.line.length - n, n);
|
|
11356
|
-
const
|
|
11357
|
-
const cells =
|
|
11415
|
+
const utf83 = (this.termios.c_iflag & IUTF8) !== 0;
|
|
11416
|
+
const cells = utf83 ? dropped2.filter((b) => !isContinuation(b)).length : dropped2.length;
|
|
11358
11417
|
if (cells > 0 && this.termios.c_lflag & ECHO) {
|
|
11359
11418
|
this.output(encoder3.encode("\b \b".repeat(cells)), false);
|
|
11360
11419
|
}
|
|
@@ -11424,14 +11483,14 @@ var KernelTty = class {
|
|
|
11424
11483
|
}
|
|
11425
11484
|
changed(signal) {
|
|
11426
11485
|
if (signal?.aborted) return Promise.reject(new KernelError("EINTR"));
|
|
11427
|
-
return new Promise((
|
|
11486
|
+
return new Promise((resolve2, reject) => {
|
|
11428
11487
|
const onAbort = () => {
|
|
11429
11488
|
this.waiters = this.waiters.filter((w) => w !== waiter);
|
|
11430
11489
|
reject(new KernelError("EINTR"));
|
|
11431
11490
|
};
|
|
11432
11491
|
const waiter = () => {
|
|
11433
11492
|
signal?.removeEventListener("abort", onAbort);
|
|
11434
|
-
|
|
11493
|
+
resolve2();
|
|
11435
11494
|
};
|
|
11436
11495
|
this.waiters.push(waiter);
|
|
11437
11496
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -11440,7 +11499,7 @@ var KernelTty = class {
|
|
|
11440
11499
|
wake() {
|
|
11441
11500
|
const waiters = this.waiters;
|
|
11442
11501
|
this.waiters = [];
|
|
11443
|
-
for (const
|
|
11502
|
+
for (const resolve2 of waiters) resolve2();
|
|
11444
11503
|
}
|
|
11445
11504
|
};
|
|
11446
11505
|
|
|
@@ -11539,14 +11598,14 @@ var PtyPair = class {
|
|
|
11539
11598
|
}
|
|
11540
11599
|
changed(signal) {
|
|
11541
11600
|
if (signal?.aborted) return Promise.reject(new KernelError("EINTR"));
|
|
11542
|
-
return new Promise((
|
|
11601
|
+
return new Promise((resolve2, reject) => {
|
|
11543
11602
|
const onAbort = () => {
|
|
11544
11603
|
this.waiters = this.waiters.filter((w) => w !== waiter);
|
|
11545
11604
|
reject(new KernelError("EINTR"));
|
|
11546
11605
|
};
|
|
11547
11606
|
const waiter = () => {
|
|
11548
11607
|
signal?.removeEventListener("abort", onAbort);
|
|
11549
|
-
|
|
11608
|
+
resolve2();
|
|
11550
11609
|
};
|
|
11551
11610
|
this.waiters.push(waiter);
|
|
11552
11611
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -11555,7 +11614,7 @@ var PtyPair = class {
|
|
|
11555
11614
|
wake() {
|
|
11556
11615
|
const waiters = this.waiters;
|
|
11557
11616
|
this.waiters = [];
|
|
11558
|
-
for (const
|
|
11617
|
+
for (const resolve2 of waiters) resolve2();
|
|
11559
11618
|
}
|
|
11560
11619
|
};
|
|
11561
11620
|
var PtyTable = class {
|
|
@@ -11620,7 +11679,8 @@ function ptySyscall(req, ctx) {
|
|
|
11620
11679
|
if (!ctx.ptys) throw new KernelError("ENOENT");
|
|
11621
11680
|
const pair = ctx.ptys.get(req.n);
|
|
11622
11681
|
ttyOpenable(ctx.guard, pair.slave);
|
|
11623
|
-
const
|
|
11682
|
+
const slave = pair.openSlave();
|
|
11683
|
+
const fd = ctx.fds.install(ctx.ttyFilter?.(slave) ?? slave, 3);
|
|
11624
11684
|
if (!req.noctty) ctx.jobs?.acquireTerminal(ctx.pid, pair.slave);
|
|
11625
11685
|
return json4(fd);
|
|
11626
11686
|
}
|
|
@@ -11693,8 +11753,8 @@ async function runChild(req, deps) {
|
|
|
11693
11753
|
};
|
|
11694
11754
|
const controls = [];
|
|
11695
11755
|
const capture = () => {
|
|
11696
|
-
const { promise, resolve } = Promise.withResolvers();
|
|
11697
|
-
const control = { shut: false, ended:
|
|
11756
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
11757
|
+
const control = { shut: false, ended: resolve2, eof: promise };
|
|
11698
11758
|
controls.push(control);
|
|
11699
11759
|
return { capture: true, max, overflow: () => stop("ENOBUFS"), control };
|
|
11700
11760
|
};
|
|
@@ -11787,7 +11847,7 @@ async function waitReady(fds, read, write, deadline, interrupted2) {
|
|
|
11787
11847
|
return file.changed === void 0 ? [] : [file.changed(round.signal).catch(() => void 0)];
|
|
11788
11848
|
});
|
|
11789
11849
|
let timer;
|
|
11790
|
-
const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [new Promise((
|
|
11850
|
+
const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [new Promise((resolve2) => timer = setTimeout(resolve2, deadline - Date.now()))];
|
|
11791
11851
|
try {
|
|
11792
11852
|
await Promise.race([...changes, ...expiry, interrupted2]);
|
|
11793
11853
|
} finally {
|
|
@@ -11871,10 +11931,10 @@ async function socketSyscall(req, proc) {
|
|
|
11871
11931
|
}
|
|
11872
11932
|
}
|
|
11873
11933
|
function interruptible2(dialing, signal) {
|
|
11874
|
-
return new Promise((
|
|
11934
|
+
return new Promise((resolve2, reject) => {
|
|
11875
11935
|
const abort = () => reject(new KernelError("EINTR"));
|
|
11876
11936
|
signal.addEventListener("abort", abort, { once: true });
|
|
11877
|
-
dialing.then(
|
|
11937
|
+
dialing.then(resolve2, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
11878
11938
|
});
|
|
11879
11939
|
}
|
|
11880
11940
|
function unnamed(domain) {
|
|
@@ -12721,7 +12781,7 @@ var WasmProcess = class {
|
|
|
12721
12781
|
if (this.stopped) return "stop";
|
|
12722
12782
|
this.stopped = sig;
|
|
12723
12783
|
this.stops++;
|
|
12724
|
-
this.resumed = new Promise((
|
|
12784
|
+
this.resumed = new Promise((resolve2) => this.wake = resolve2);
|
|
12725
12785
|
const blocked = this.interrupt;
|
|
12726
12786
|
this.interrupt = new AbortController();
|
|
12727
12787
|
blocked.abort();
|
|
@@ -12786,7 +12846,9 @@ var WasmProcess = class {
|
|
|
12786
12846
|
const { ptys, jobs } = this.options;
|
|
12787
12847
|
const owner = this.options.owners ? this.ttyOwner() : void 0;
|
|
12788
12848
|
const guard2 = this.guarded();
|
|
12789
|
-
|
|
12849
|
+
const { ttyFilter } = this.options;
|
|
12850
|
+
const ctx = { pid: this.pid, fds: this.fds, ptys, jobs, guard: guard2, owner, ttyFilter };
|
|
12851
|
+
return ptySyscall(req, ctx);
|
|
12790
12852
|
}
|
|
12791
12853
|
return await this.procSyscall(req, cancelled);
|
|
12792
12854
|
} catch (e) {
|
|
@@ -12961,7 +13023,8 @@ var WasmProcess = class {
|
|
|
12961
13023
|
const tty = name2 === void 0 ? this.controllingTerminal() : this.options.jobs?.terminalNamed(name2);
|
|
12962
13024
|
if (!tty) throw new KernelError("ENXIO");
|
|
12963
13025
|
if (name2 !== void 0) ttyOpenable(this.guarded(), tty);
|
|
12964
|
-
|
|
13026
|
+
const file = tty.file();
|
|
13027
|
+
return this.fds.install(this.options.ttyFilter?.(file) ?? file, 3);
|
|
12965
13028
|
}
|
|
12966
13029
|
openSealed() {
|
|
12967
13030
|
const broker = this.options.sealed;
|
|
@@ -13001,15 +13064,8 @@ var WasmProcess = class {
|
|
|
13001
13064
|
async sealedCaller() {
|
|
13002
13065
|
const shown = await this.options.identity?.();
|
|
13003
13066
|
const broker = this.options.sealed;
|
|
13004
|
-
const
|
|
13005
|
-
return
|
|
13006
|
-
pid: shown?.pid ?? this.pid,
|
|
13007
|
-
ppid: shown?.ppid ?? 0,
|
|
13008
|
-
uid: this.cred.euid,
|
|
13009
|
-
gid: this.cred.egid,
|
|
13010
|
-
...tag !== void 0 ? { tag } : {},
|
|
13011
|
-
users: broker.users
|
|
13012
|
-
};
|
|
13067
|
+
const ids = { pid: shown?.pid ?? this.pid, ppid: shown?.ppid ?? 0 };
|
|
13068
|
+
return broker.stamp(ids, this.cred, broker.tagOf(this.pid));
|
|
13013
13069
|
}
|
|
13014
13070
|
guarded() {
|
|
13015
13071
|
const { guard: guard2 } = this.options;
|
|
@@ -13517,13 +13573,13 @@ var WasmProcess = class {
|
|
|
13517
13573
|
while (this.dlLock.depth > 0 && this.dlLock.owner !== owner) {
|
|
13518
13574
|
if (this.dying) throw new KernelError("EINTR");
|
|
13519
13575
|
const interrupt = this.interrupt.signal;
|
|
13520
|
-
const gone = await new Promise((
|
|
13576
|
+
const gone = await new Promise((resolve2) => {
|
|
13521
13577
|
const waiter = {
|
|
13522
13578
|
owner,
|
|
13523
13579
|
wake: (ended) => {
|
|
13524
13580
|
this.dlLock.waiters.delete(waiter);
|
|
13525
13581
|
interrupt.removeEventListener("abort", recheck);
|
|
13526
|
-
|
|
13582
|
+
resolve2(ended);
|
|
13527
13583
|
}
|
|
13528
13584
|
};
|
|
13529
13585
|
const recheck = () => waiter.wake(false);
|
|
@@ -13779,6 +13835,7 @@ function processOptions(opts, header3, hooks, created3) {
|
|
|
13779
13835
|
...inherited(opts),
|
|
13780
13836
|
...opts.owners ? { owners: true } : {},
|
|
13781
13837
|
...opts.sealed ? { sealed: opts.sealed } : {},
|
|
13838
|
+
...opts.ttyFilter ? { ttyFilter: opts.ttyFilter } : {},
|
|
13782
13839
|
...opts.clipboard ? { clipboard: opts.clipboard, ...clipboardName(opts) } : {},
|
|
13783
13840
|
...opts.readonlyAt ? { readonlyAt: opts.readonlyAt } : {},
|
|
13784
13841
|
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
@@ -14273,6 +14330,523 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
14273
14330
|
};
|
|
14274
14331
|
}
|
|
14275
14332
|
|
|
14333
|
+
// node_modules/@ai-ecoverse/slicc-scrub/dist/index.js
|
|
14334
|
+
var FRAGMENT = 16;
|
|
14335
|
+
var MIN_VALUE = 8;
|
|
14336
|
+
var MIN_BASE64 = 8;
|
|
14337
|
+
var encoder4 = new TextEncoder();
|
|
14338
|
+
var STD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
14339
|
+
function utf82(text) {
|
|
14340
|
+
return encoder4.encode(text);
|
|
14341
|
+
}
|
|
14342
|
+
function base642(bytes, padded = true) {
|
|
14343
|
+
let out = "";
|
|
14344
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
14345
|
+
const a = bytes[i];
|
|
14346
|
+
const b = i + 1 < bytes.length ? bytes[i + 1] : 0;
|
|
14347
|
+
const c = i + 2 < bytes.length ? bytes[i + 2] : 0;
|
|
14348
|
+
const triple = a << 16 | b << 8 | c;
|
|
14349
|
+
const left = bytes.length - i;
|
|
14350
|
+
out += STD[triple >> 18 & 63] + STD[triple >> 12 & 63];
|
|
14351
|
+
out += left > 1 ? STD[triple >> 6 & 63] : padded ? "=" : "";
|
|
14352
|
+
out += left > 2 ? STD[triple & 63] : padded ? "=" : "";
|
|
14353
|
+
}
|
|
14354
|
+
return out;
|
|
14355
|
+
}
|
|
14356
|
+
function urlSafe(text) {
|
|
14357
|
+
return text.replace(/\+/g, "-").replace(/\//g, "_");
|
|
14358
|
+
}
|
|
14359
|
+
function hex2(bytes) {
|
|
14360
|
+
let out = "";
|
|
14361
|
+
for (const byte of bytes) out += byte.toString(16).padStart(2, "0");
|
|
14362
|
+
return out;
|
|
14363
|
+
}
|
|
14364
|
+
function embedded(bytes, offset) {
|
|
14365
|
+
const shifted = new Uint8Array(offset + bytes.length);
|
|
14366
|
+
shifted.set(bytes, offset);
|
|
14367
|
+
const encoded = base642(shifted);
|
|
14368
|
+
const first = Math.ceil(8 * offset / 6);
|
|
14369
|
+
const last = Math.floor(8 * (offset + bytes.length) / 6);
|
|
14370
|
+
return encoded.slice(first, last);
|
|
14371
|
+
}
|
|
14372
|
+
function unicode(value, upper) {
|
|
14373
|
+
let out = "";
|
|
14374
|
+
for (let i = 0; i < value.length; i++) {
|
|
14375
|
+
const unit = value.charCodeAt(i);
|
|
14376
|
+
if (unit === 34) out += '\\"';
|
|
14377
|
+
else if (unit === 92) out += "\\\\";
|
|
14378
|
+
else if (unit < 32 || unit > 126) {
|
|
14379
|
+
const code = unit.toString(16).padStart(4, "0");
|
|
14380
|
+
out += `\\u${upper ? code.toUpperCase() : code}`;
|
|
14381
|
+
} else out += value[i];
|
|
14382
|
+
}
|
|
14383
|
+
return out;
|
|
14384
|
+
}
|
|
14385
|
+
function percent(value) {
|
|
14386
|
+
let component;
|
|
14387
|
+
try {
|
|
14388
|
+
component = encodeURIComponent(value);
|
|
14389
|
+
} catch {
|
|
14390
|
+
return [];
|
|
14391
|
+
}
|
|
14392
|
+
const lower = component.replace(/%[0-9A-F]{2}/g, (escape) => escape.toLowerCase());
|
|
14393
|
+
const plus = component.replace(/%20/g, "+");
|
|
14394
|
+
let form = "";
|
|
14395
|
+
for (const byte of utf82(value)) {
|
|
14396
|
+
const char = String.fromCharCode(byte);
|
|
14397
|
+
if (/[A-Za-z0-9*\-._]/.test(char)) form += char;
|
|
14398
|
+
else if (byte === 32) form += "+";
|
|
14399
|
+
else form += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
|
|
14400
|
+
}
|
|
14401
|
+
return [component, lower, plus, form];
|
|
14402
|
+
}
|
|
14403
|
+
function html(value, apostrophe) {
|
|
14404
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, apostrophe);
|
|
14405
|
+
}
|
|
14406
|
+
function encodings(bytes) {
|
|
14407
|
+
const standard = [base642(bytes), base642(bytes, false)];
|
|
14408
|
+
for (const offset of [0, 1, 2]) {
|
|
14409
|
+
const run2 = embedded(bytes, offset);
|
|
14410
|
+
if (run2.length >= MIN_BASE64) standard.push(run2);
|
|
14411
|
+
}
|
|
14412
|
+
return [...standard, ...standard.map(urlSafe)];
|
|
14413
|
+
}
|
|
14414
|
+
function shapes(value) {
|
|
14415
|
+
const raw = utf82(value);
|
|
14416
|
+
const seen = /* @__PURE__ */ new Set([value]);
|
|
14417
|
+
const out = [];
|
|
14418
|
+
if (raw.length < FRAGMENT) out.push({ bytes: raw, form: "raw" });
|
|
14419
|
+
for (let offset = 0; raw.length >= FRAGMENT && offset + FRAGMENT <= raw.length; offset++) {
|
|
14420
|
+
out.push({ bytes: raw.subarray(offset, offset + FRAGMENT), form: "fragment", offset });
|
|
14421
|
+
}
|
|
14422
|
+
const add = (text, form) => {
|
|
14423
|
+
if (seen.has(text)) return;
|
|
14424
|
+
seen.add(text);
|
|
14425
|
+
out.push({ bytes: utf82(text), form });
|
|
14426
|
+
};
|
|
14427
|
+
const json5 = JSON.stringify(value).slice(1, -1);
|
|
14428
|
+
for (const text of [
|
|
14429
|
+
json5,
|
|
14430
|
+
json5.replace(/\//g, "\\/"),
|
|
14431
|
+
unicode(value, false),
|
|
14432
|
+
unicode(value, true)
|
|
14433
|
+
]) {
|
|
14434
|
+
add(text, "json");
|
|
14435
|
+
}
|
|
14436
|
+
for (const text of percent(value)) add(text, "percent");
|
|
14437
|
+
for (const text of [html(value, "'"), html(value, "'")]) add(text, "html");
|
|
14438
|
+
for (const text of encodings(raw)) add(text, "base64");
|
|
14439
|
+
add(hex2(raw), "hex");
|
|
14440
|
+
add(hex2(raw).toUpperCase(), "hex");
|
|
14441
|
+
return out;
|
|
14442
|
+
}
|
|
14443
|
+
function wrappable(form) {
|
|
14444
|
+
return form === "base64" || form === "hex";
|
|
14445
|
+
}
|
|
14446
|
+
var Automaton = class {
|
|
14447
|
+
edges = /* @__PURE__ */ new Map();
|
|
14448
|
+
fail = [0];
|
|
14449
|
+
depth = [0];
|
|
14450
|
+
children = [0];
|
|
14451
|
+
out = [[]];
|
|
14452
|
+
dict = [-1];
|
|
14453
|
+
lengths = [];
|
|
14454
|
+
add(bytes) {
|
|
14455
|
+
let node = 0;
|
|
14456
|
+
for (const byte of bytes) {
|
|
14457
|
+
const key = node * 256 + byte;
|
|
14458
|
+
let next2 = this.edges.get(key);
|
|
14459
|
+
if (next2 === void 0) {
|
|
14460
|
+
next2 = this.depth.length;
|
|
14461
|
+
this.edges.set(key, next2);
|
|
14462
|
+
this.fail.push(0);
|
|
14463
|
+
this.depth.push(this.depth[node] + 1);
|
|
14464
|
+
this.children.push(0);
|
|
14465
|
+
this.children[node] += 1;
|
|
14466
|
+
this.out.push([]);
|
|
14467
|
+
this.dict.push(-1);
|
|
14468
|
+
}
|
|
14469
|
+
node = next2;
|
|
14470
|
+
}
|
|
14471
|
+
const id2 = this.lengths.length;
|
|
14472
|
+
this.lengths.push(bytes.length);
|
|
14473
|
+
this.out[node].push(id2);
|
|
14474
|
+
return id2;
|
|
14475
|
+
}
|
|
14476
|
+
build() {
|
|
14477
|
+
const queue = [];
|
|
14478
|
+
const byNode = /* @__PURE__ */ new Map();
|
|
14479
|
+
for (const [key, child] of this.edges) {
|
|
14480
|
+
const parent = Math.floor(key / 256);
|
|
14481
|
+
const list = byNode.get(parent) ?? [];
|
|
14482
|
+
list.push([key % 256, child]);
|
|
14483
|
+
byNode.set(parent, list);
|
|
14484
|
+
}
|
|
14485
|
+
for (const [, child] of byNode.get(0) ?? []) queue.push(child);
|
|
14486
|
+
for (let head = 0; head < queue.length; head++) {
|
|
14487
|
+
const node = queue[head];
|
|
14488
|
+
const fallback = this.fail[node];
|
|
14489
|
+
this.dict[node] = this.out[fallback].length > 0 ? fallback : this.dict[fallback];
|
|
14490
|
+
for (const [byte, child] of byNode.get(node) ?? []) {
|
|
14491
|
+
let state = fallback;
|
|
14492
|
+
let target = this.edges.get(state * 256 + byte);
|
|
14493
|
+
while (target === void 0 && state > 0) {
|
|
14494
|
+
state = this.fail[state];
|
|
14495
|
+
target = this.edges.get(state * 256 + byte);
|
|
14496
|
+
}
|
|
14497
|
+
this.fail[child] = target ?? 0;
|
|
14498
|
+
queue.push(child);
|
|
14499
|
+
}
|
|
14500
|
+
}
|
|
14501
|
+
}
|
|
14502
|
+
step(state, byte) {
|
|
14503
|
+
let current = state;
|
|
14504
|
+
for (; ; ) {
|
|
14505
|
+
const next2 = this.edges.get(current * 256 + byte);
|
|
14506
|
+
if (next2 !== void 0) return next2;
|
|
14507
|
+
if (current === 0) return 0;
|
|
14508
|
+
current = this.fail[current];
|
|
14509
|
+
}
|
|
14510
|
+
}
|
|
14511
|
+
matches(state, visit) {
|
|
14512
|
+
for (let node = state; node > 0; node = this.dict[node]) {
|
|
14513
|
+
for (const id2 of this.out[node]) visit(id2);
|
|
14514
|
+
}
|
|
14515
|
+
}
|
|
14516
|
+
partials(state, length2, visit) {
|
|
14517
|
+
for (let node = state; node > 0; node = this.fail[node]) {
|
|
14518
|
+
if (this.children[node] > 0) visit(length2 - this.depth[node]);
|
|
14519
|
+
}
|
|
14520
|
+
}
|
|
14521
|
+
};
|
|
14522
|
+
var RANK = {
|
|
14523
|
+
raw: 0,
|
|
14524
|
+
fragment: 1,
|
|
14525
|
+
json: 2,
|
|
14526
|
+
percent: 3,
|
|
14527
|
+
html: 4,
|
|
14528
|
+
base64: 5,
|
|
14529
|
+
hex: 6,
|
|
14530
|
+
wrapped: 7
|
|
14531
|
+
};
|
|
14532
|
+
var CR2 = 13;
|
|
14533
|
+
var LF2 = 10;
|
|
14534
|
+
var EMPTY2 = new Uint8Array(0);
|
|
14535
|
+
function register(automaton, sources, ids, bytes, source) {
|
|
14536
|
+
const key = Array.from(bytes).join(",");
|
|
14537
|
+
let id2 = ids.get(key);
|
|
14538
|
+
if (id2 === void 0) {
|
|
14539
|
+
id2 = automaton.add(bytes);
|
|
14540
|
+
ids.set(key, id2);
|
|
14541
|
+
sources[id2] = [];
|
|
14542
|
+
}
|
|
14543
|
+
sources[id2].push(source);
|
|
14544
|
+
}
|
|
14545
|
+
function prepare(secrets) {
|
|
14546
|
+
const main = new Automaton();
|
|
14547
|
+
const wrap = new Automaton();
|
|
14548
|
+
const sources = [];
|
|
14549
|
+
const wrapSources = [];
|
|
14550
|
+
const ids = /* @__PURE__ */ new Map();
|
|
14551
|
+
const wrapIds = /* @__PURE__ */ new Map();
|
|
14552
|
+
const values = secrets.map((secret) => utf82(secret.value));
|
|
14553
|
+
secrets.forEach((secret, index) => {
|
|
14554
|
+
if (typeof secret.value !== "string" || values[index].length < MIN_VALUE) {
|
|
14555
|
+
throw new RangeError(`the value of ${secret.name} is shorter than ${MIN_VALUE} bytes`);
|
|
14556
|
+
}
|
|
14557
|
+
for (const shape of shapes(secret.value)) {
|
|
14558
|
+
const source = { secret: index, form: shape.form, offset: shape.offset };
|
|
14559
|
+
register(main, sources, ids, shape.bytes, source);
|
|
14560
|
+
if (wrappable(shape.form)) register(wrap, wrapSources, wrapIds, shape.bytes, source);
|
|
14561
|
+
}
|
|
14562
|
+
});
|
|
14563
|
+
main.build();
|
|
14564
|
+
wrap.build();
|
|
14565
|
+
const replacements = secrets.map((secret) => [
|
|
14566
|
+
utf82(secret.placeholder),
|
|
14567
|
+
utf82(`[redacted:${secret.name}]`)
|
|
14568
|
+
]);
|
|
14569
|
+
return { secrets, values, main, wrap, sources, wrapSources, replacements };
|
|
14570
|
+
}
|
|
14571
|
+
function better(a, b) {
|
|
14572
|
+
if (!b) return true;
|
|
14573
|
+
if (a.end !== b.end) return a.end > b.end;
|
|
14574
|
+
if (a.rank !== b.rank) return a.rank < b.rank;
|
|
14575
|
+
return a.secret < b.secret;
|
|
14576
|
+
}
|
|
14577
|
+
function resolve(c, input, start2, end, source) {
|
|
14578
|
+
if (source.form !== "fragment") {
|
|
14579
|
+
return {
|
|
14580
|
+
start: start2,
|
|
14581
|
+
end,
|
|
14582
|
+
secret: source.secret,
|
|
14583
|
+
form: source.form,
|
|
14584
|
+
rank: RANK[source.form],
|
|
14585
|
+
growing: false
|
|
14586
|
+
};
|
|
14587
|
+
}
|
|
14588
|
+
const value = c.values[source.secret];
|
|
14589
|
+
let stop = end;
|
|
14590
|
+
let at = source.offset + FRAGMENT;
|
|
14591
|
+
while (stop < input.length && at < value.length && input[stop] === value[at]) {
|
|
14592
|
+
stop++;
|
|
14593
|
+
at++;
|
|
14594
|
+
}
|
|
14595
|
+
const form = source.offset === 0 && at === value.length ? "raw" : "fragment";
|
|
14596
|
+
const growing = stop === input.length && at < value.length;
|
|
14597
|
+
return { start: start2, end: stop, secret: source.secret, form, rank: RANK[form], growing };
|
|
14598
|
+
}
|
|
14599
|
+
function keep(best, candidate) {
|
|
14600
|
+
if (better(candidate, best.get(candidate.start))) best.set(candidate.start, candidate);
|
|
14601
|
+
}
|
|
14602
|
+
function scanMain(c, input, best, partials) {
|
|
14603
|
+
let state = 0;
|
|
14604
|
+
for (let i = 0; i < input.length; i++) {
|
|
14605
|
+
state = c.main.step(state, input[i]);
|
|
14606
|
+
c.main.matches(state, (id2) => {
|
|
14607
|
+
const start2 = i + 1 - c.main.lengths[id2];
|
|
14608
|
+
for (const source of c.sources[id2]) {
|
|
14609
|
+
const candidate = resolve(c, input, start2, i + 1, source);
|
|
14610
|
+
if (candidate.growing) partials.push(candidate.start);
|
|
14611
|
+
keep(best, candidate);
|
|
14612
|
+
}
|
|
14613
|
+
});
|
|
14614
|
+
}
|
|
14615
|
+
c.main.partials(state, input.length, (start2) => partials.push(start2));
|
|
14616
|
+
}
|
|
14617
|
+
function scanWrapped(c, input, best, partials) {
|
|
14618
|
+
const map = [];
|
|
14619
|
+
for (let i = 0; i < input.length; i++) if (input[i] !== CR2 && input[i] !== LF2) map.push(i);
|
|
14620
|
+
if (map.length === input.length) return;
|
|
14621
|
+
let state = 0;
|
|
14622
|
+
for (let v = 0; v < map.length; v++) {
|
|
14623
|
+
state = c.wrap.step(state, input[map[v]]);
|
|
14624
|
+
c.wrap.matches(state, (id2) => {
|
|
14625
|
+
const first = v + 1 - c.wrap.lengths[id2];
|
|
14626
|
+
const start2 = map[first];
|
|
14627
|
+
const end = map[v] + 1;
|
|
14628
|
+
const wrapped = end - start2 !== c.wrap.lengths[id2];
|
|
14629
|
+
for (const source of c.wrapSources[id2]) {
|
|
14630
|
+
const form = wrapped ? "wrapped" : source.form;
|
|
14631
|
+
keep(best, { start: start2, end, secret: source.secret, form, rank: RANK[form], growing: false });
|
|
14632
|
+
}
|
|
14633
|
+
});
|
|
14634
|
+
}
|
|
14635
|
+
c.wrap.partials(state, map.length, (start2) => partials.push(map[start2]));
|
|
14636
|
+
}
|
|
14637
|
+
function count(c, hits, candidate) {
|
|
14638
|
+
const name2 = c.secrets[candidate.secret].name;
|
|
14639
|
+
const key = `${name2}\0${candidate.form}`;
|
|
14640
|
+
const hit = hits.get(key) ?? { name: name2, form: candidate.form, count: 0 };
|
|
14641
|
+
hit.count += 1;
|
|
14642
|
+
hits.set(key, hit);
|
|
14643
|
+
}
|
|
14644
|
+
function concat5(parts2) {
|
|
14645
|
+
let length2 = 0;
|
|
14646
|
+
for (const part of parts2) length2 += part.length;
|
|
14647
|
+
const out = new Uint8Array(length2);
|
|
14648
|
+
let at = 0;
|
|
14649
|
+
for (const part of parts2) {
|
|
14650
|
+
out.set(part, at);
|
|
14651
|
+
at += part.length;
|
|
14652
|
+
}
|
|
14653
|
+
return out;
|
|
14654
|
+
}
|
|
14655
|
+
function pass(c, input, final) {
|
|
14656
|
+
const best = /* @__PURE__ */ new Map();
|
|
14657
|
+
const partials = [];
|
|
14658
|
+
scanMain(c, input, best, partials);
|
|
14659
|
+
scanWrapped(c, input, best, partials);
|
|
14660
|
+
const holds = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
|
|
14661
|
+
const starts = [...best.keys()].sort((a, b) => a - b);
|
|
14662
|
+
const parts2 = [];
|
|
14663
|
+
const hits = /* @__PURE__ */ new Map();
|
|
14664
|
+
let pos = 0;
|
|
14665
|
+
let cut = input.length;
|
|
14666
|
+
let s = 0;
|
|
14667
|
+
let h = 0;
|
|
14668
|
+
for (; ; ) {
|
|
14669
|
+
while (s < starts.length && starts[s] < pos) s++;
|
|
14670
|
+
while (h < holds.length && holds[h] < pos) h++;
|
|
14671
|
+
const hold = h < holds.length ? holds[h] : Infinity;
|
|
14672
|
+
const next2 = s < starts.length ? starts[s] : Infinity;
|
|
14673
|
+
if (hold <= next2) {
|
|
14674
|
+
cut = Math.min(hold, input.length);
|
|
14675
|
+
break;
|
|
14676
|
+
}
|
|
14677
|
+
const candidate = best.get(next2);
|
|
14678
|
+
parts2.push(
|
|
14679
|
+
input.subarray(pos, next2),
|
|
14680
|
+
c.replacements[candidate.secret][candidate.form === "raw" ? 0 : 1]
|
|
14681
|
+
);
|
|
14682
|
+
count(c, hits, candidate);
|
|
14683
|
+
pos = candidate.end;
|
|
14684
|
+
}
|
|
14685
|
+
parts2.push(input.subarray(pos, cut));
|
|
14686
|
+
return { output: concat5(parts2), cut, hits };
|
|
14687
|
+
}
|
|
14688
|
+
function merge(into, from) {
|
|
14689
|
+
for (const [key, hit] of from) {
|
|
14690
|
+
const known = into.get(key);
|
|
14691
|
+
if (known) known.count += hit.count;
|
|
14692
|
+
else into.set(key, { ...hit });
|
|
14693
|
+
}
|
|
14694
|
+
}
|
|
14695
|
+
function compile(secrets, options = {}) {
|
|
14696
|
+
const c = prepare(secrets.map((secret) => ({ ...secret })));
|
|
14697
|
+
const decoder4 = new TextDecoder();
|
|
14698
|
+
const idleMs = options.idleMs ?? 250;
|
|
14699
|
+
const scrubBytes = (input) => {
|
|
14700
|
+
if (c.secrets.length === 0) return { bytes: input.slice(), hits: [] };
|
|
14701
|
+
const result = pass(c, input, true);
|
|
14702
|
+
return { bytes: result.output, hits: [...result.hits.values()] };
|
|
14703
|
+
};
|
|
14704
|
+
return {
|
|
14705
|
+
version: options.version ?? 0,
|
|
14706
|
+
idleMs,
|
|
14707
|
+
size: c.main.lengths.length,
|
|
14708
|
+
bytes: scrubBytes,
|
|
14709
|
+
text(input) {
|
|
14710
|
+
const { bytes, hits } = scrubBytes(utf82(input));
|
|
14711
|
+
return { text: decoder4.decode(bytes), hits };
|
|
14712
|
+
},
|
|
14713
|
+
stream() {
|
|
14714
|
+
let pending = EMPTY2;
|
|
14715
|
+
const hits = /* @__PURE__ */ new Map();
|
|
14716
|
+
const run2 = (final) => {
|
|
14717
|
+
if (c.secrets.length === 0 || pending.length === 0) {
|
|
14718
|
+
const out = pending;
|
|
14719
|
+
pending = EMPTY2;
|
|
14720
|
+
return out;
|
|
14721
|
+
}
|
|
14722
|
+
const result = pass(c, pending, final);
|
|
14723
|
+
merge(hits, result.hits);
|
|
14724
|
+
pending = pending.slice(result.cut);
|
|
14725
|
+
return result.output;
|
|
14726
|
+
};
|
|
14727
|
+
return {
|
|
14728
|
+
push(chunk2) {
|
|
14729
|
+
pending = concat5([pending, chunk2]);
|
|
14730
|
+
return run2(false);
|
|
14731
|
+
},
|
|
14732
|
+
idle() {
|
|
14733
|
+
return pending.length < FRAGMENT ? run2(true) : EMPTY2;
|
|
14734
|
+
},
|
|
14735
|
+
end() {
|
|
14736
|
+
return run2(true);
|
|
14737
|
+
},
|
|
14738
|
+
get hits() {
|
|
14739
|
+
return [...hits.values()];
|
|
14740
|
+
}
|
|
14741
|
+
};
|
|
14742
|
+
}
|
|
14743
|
+
};
|
|
14744
|
+
}
|
|
14745
|
+
|
|
14746
|
+
// src/kernel/scrub-file.ts
|
|
14747
|
+
var SCRUB_IDLE_MS = 50;
|
|
14748
|
+
var encoder5 = new TextEncoder();
|
|
14749
|
+
function scrubberOf(secrets) {
|
|
14750
|
+
const usable = secrets.filter((s) => encoder5.encode(s.value).length >= MIN_VALUE);
|
|
14751
|
+
return usable.length > 0 ? compile(usable, { idleMs: SCRUB_IDLE_MS }) : void 0;
|
|
14752
|
+
}
|
|
14753
|
+
async function writeAll2(file, bytes, signal) {
|
|
14754
|
+
const write = file.write;
|
|
14755
|
+
for (let at = 0; at < bytes.length; ) {
|
|
14756
|
+
at += await write.call(file, bytes.subarray(at), at === 0 ? signal : void 0);
|
|
14757
|
+
}
|
|
14758
|
+
}
|
|
14759
|
+
function bound(file, key) {
|
|
14760
|
+
const method = file[key];
|
|
14761
|
+
return typeof method === "function" ? { [key]: method.bind(file) } : {};
|
|
14762
|
+
}
|
|
14763
|
+
function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
14764
|
+
const file = inner.file;
|
|
14765
|
+
const stream = scrubber.stream();
|
|
14766
|
+
let queue = Promise.resolve();
|
|
14767
|
+
let timer;
|
|
14768
|
+
let failed3;
|
|
14769
|
+
const raise = () => {
|
|
14770
|
+
if (failed3 === void 0) return;
|
|
14771
|
+
const err = failed3;
|
|
14772
|
+
failed3 = void 0;
|
|
14773
|
+
throw err;
|
|
14774
|
+
};
|
|
14775
|
+
const enqueue = (bytes, signal) => {
|
|
14776
|
+
const next2 = queue.then(() => bytes.length > 0 ? writeAll2(file, bytes, signal) : void 0);
|
|
14777
|
+
queue = next2.catch(() => void 0);
|
|
14778
|
+
return next2;
|
|
14779
|
+
};
|
|
14780
|
+
const release = () => {
|
|
14781
|
+
timer = void 0;
|
|
14782
|
+
enqueue(stream.idle()).catch((err) => {
|
|
14783
|
+
failed3 = err;
|
|
14784
|
+
});
|
|
14785
|
+
};
|
|
14786
|
+
return new OpenFile({
|
|
14787
|
+
...bound(file, "read"),
|
|
14788
|
+
...bound(file, "peek"),
|
|
14789
|
+
...bound(file, "poll"),
|
|
14790
|
+
...bound(file, "changed"),
|
|
14791
|
+
...bound(file, "stat"),
|
|
14792
|
+
...file.tty ? { tty: file.tty } : {},
|
|
14793
|
+
...file.clipboard ? { clipboard: file.clipboard } : {},
|
|
14794
|
+
...file.write ? {
|
|
14795
|
+
write: async (bytes, signal) => {
|
|
14796
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
14797
|
+
raise();
|
|
14798
|
+
await enqueue(stream.push(bytes), signal);
|
|
14799
|
+
timer = setTimeout(release, idleMs);
|
|
14800
|
+
return bytes.length;
|
|
14801
|
+
}
|
|
14802
|
+
} : {},
|
|
14803
|
+
flush: async () => {
|
|
14804
|
+
await queue;
|
|
14805
|
+
raise();
|
|
14806
|
+
await file.flush?.();
|
|
14807
|
+
},
|
|
14808
|
+
close: async () => {
|
|
14809
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
14810
|
+
let failure2;
|
|
14811
|
+
try {
|
|
14812
|
+
await enqueue(stream.end());
|
|
14813
|
+
raise();
|
|
14814
|
+
} catch (err) {
|
|
14815
|
+
failure2 = { err };
|
|
14816
|
+
}
|
|
14817
|
+
await inner.release();
|
|
14818
|
+
if (failure2) throw failure2.err;
|
|
14819
|
+
}
|
|
14820
|
+
});
|
|
14821
|
+
}
|
|
14822
|
+
function scrubbedAll(file, scrubbers) {
|
|
14823
|
+
return scrubbers.reduce((inner, scrubber) => scrubbed(inner, scrubber), file);
|
|
14824
|
+
}
|
|
14825
|
+
function stdioFiles(fds) {
|
|
14826
|
+
const files = /* @__PURE__ */ new Set();
|
|
14827
|
+
for (const fd of [1, 2]) {
|
|
14828
|
+
try {
|
|
14829
|
+
files.add(fds.get(fd));
|
|
14830
|
+
} catch {
|
|
14831
|
+
}
|
|
14832
|
+
}
|
|
14833
|
+
return files;
|
|
14834
|
+
}
|
|
14835
|
+
function scrubStdio(fds, scrubber) {
|
|
14836
|
+
const wrapped = /* @__PURE__ */ new Map();
|
|
14837
|
+
const stdio = stdioFiles(fds);
|
|
14838
|
+
for (const fd of fds.numbers()) {
|
|
14839
|
+
const original = fds.get(fd);
|
|
14840
|
+
if (!stdio.has(original) && !original.file.tty) continue;
|
|
14841
|
+
const known = wrapped.get(original);
|
|
14842
|
+
const flags2 = fds.statusFlags(fd);
|
|
14843
|
+
const wrapper = known ? known.retain() : scrubbed(original.retain(), scrubber);
|
|
14844
|
+
wrapped.set(original, wrapper);
|
|
14845
|
+
fds.installAt(fd, wrapper);
|
|
14846
|
+
if (flags2 !== void 0) fds.setStatusFlags(fd, flags2);
|
|
14847
|
+
}
|
|
14848
|
+
}
|
|
14849
|
+
|
|
14276
14850
|
// src/kernel/sealed.ts
|
|
14277
14851
|
var SEALED_MAX_BYTES = 64 * 1024;
|
|
14278
14852
|
var SEALED_TIMEOUT_MS = 1e4;
|
|
@@ -14286,7 +14860,7 @@ var SEALED_OPS = /* @__PURE__ */ new Set([
|
|
|
14286
14860
|
"cancel",
|
|
14287
14861
|
"materialize"
|
|
14288
14862
|
]);
|
|
14289
|
-
var
|
|
14863
|
+
var encoder6 = new TextEncoder();
|
|
14290
14864
|
var decoder3 = new TextDecoder("utf-8", { fatal: true });
|
|
14291
14865
|
function parseSealed(bytes) {
|
|
14292
14866
|
try {
|
|
@@ -14302,11 +14876,16 @@ function parseSealed(bytes) {
|
|
|
14302
14876
|
const req = parsed2;
|
|
14303
14877
|
if (req.v !== 1 || typeof req.op !== "string" || !SEALED_OPS.has(req.op))
|
|
14304
14878
|
throw new KernelError("EINVAL");
|
|
14879
|
+
if (req.op === "materialize" && !materializable(req)) throw new KernelError("EINVAL");
|
|
14305
14880
|
return req;
|
|
14306
14881
|
} finally {
|
|
14307
14882
|
bytes.fill(0);
|
|
14308
14883
|
}
|
|
14309
14884
|
}
|
|
14885
|
+
function materializable(req) {
|
|
14886
|
+
if (req.shellGrants !== true && !isStrings(req.names)) return false;
|
|
14887
|
+
return isStrings(req.argv) && typeof req.path === "string" && typeof req.cwd === "string";
|
|
14888
|
+
}
|
|
14310
14889
|
function errorReply(code, message3) {
|
|
14311
14890
|
return { v: 1, error: { code, message: message3 } };
|
|
14312
14891
|
}
|
|
@@ -14350,12 +14929,14 @@ var SealedChannel = class {
|
|
|
14350
14929
|
const timer = setTimeout(() => control.abort("timeout"), this.broker.timeoutMs);
|
|
14351
14930
|
const req = { ...fields, v: 1, op: fields.op, caller };
|
|
14352
14931
|
const flight = { control, done: Promise.resolve() };
|
|
14353
|
-
flight.done = this.answer(req, control.signal).then((reply) => {
|
|
14932
|
+
flight.done = this.answer(req, control.signal).then(async (reply) => {
|
|
14354
14933
|
clearTimeout(timer);
|
|
14355
14934
|
gone.removeEventListener("abort", withdraw);
|
|
14935
|
+
if (reply && req.op === "materialize")
|
|
14936
|
+
await this.broker.tickets.record(req, reply, caller.pid);
|
|
14356
14937
|
if (this.inflight !== flight) return;
|
|
14357
14938
|
this.inflight = void 0;
|
|
14358
|
-
if (reply) this.reply =
|
|
14939
|
+
if (reply) this.reply = encoder6.encode(serialized(reply));
|
|
14359
14940
|
});
|
|
14360
14941
|
this.inflight = flight;
|
|
14361
14942
|
return length2;
|
|
@@ -14363,8 +14944,8 @@ var SealedChannel = class {
|
|
|
14363
14944
|
async answer(req, signal) {
|
|
14364
14945
|
const hook = this.broker.hook;
|
|
14365
14946
|
if (!hook) return errorReply("ENOTCONN", "no vault is connected");
|
|
14366
|
-
const stopped = new Promise((
|
|
14367
|
-
signal.addEventListener("abort", () =>
|
|
14947
|
+
const stopped = new Promise((resolve2) => {
|
|
14948
|
+
signal.addEventListener("abort", () => resolve2(void 0), { once: true });
|
|
14368
14949
|
});
|
|
14369
14950
|
if (signal.aborted) return void 0;
|
|
14370
14951
|
const asked = Promise.resolve().then(() => hook(req, { signal })).then(
|
|
@@ -14419,17 +15000,60 @@ var SealedChannel = class {
|
|
|
14419
15000
|
this.reply = void 0;
|
|
14420
15001
|
}
|
|
14421
15002
|
};
|
|
15003
|
+
function swapOf(reply) {
|
|
15004
|
+
if (!isRecord(reply) || reply.error !== void 0) return void 0;
|
|
15005
|
+
const values = stringRecord(reply.values);
|
|
15006
|
+
const placeholders = stringRecord(reply.placeholders);
|
|
15007
|
+
return values && placeholders ? { values, placeholders } : void 0;
|
|
15008
|
+
}
|
|
14422
15009
|
var SealedBroker = class {
|
|
14423
15010
|
hook;
|
|
14424
15011
|
users;
|
|
14425
15012
|
timeoutMs;
|
|
14426
15013
|
tagOf;
|
|
15014
|
+
tickets = new TicketBook();
|
|
15015
|
+
userOf = async () => void 0;
|
|
14427
15016
|
constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
|
|
14428
15017
|
this.hook = hook;
|
|
14429
15018
|
this.users = users;
|
|
14430
15019
|
this.timeoutMs = timeoutMs;
|
|
14431
15020
|
this.tagOf = tagOf;
|
|
14432
15021
|
}
|
|
15022
|
+
async stamp(ids, cred, tag) {
|
|
15023
|
+
const user = await this.userOf(cred.euid).catch(() => void 0);
|
|
15024
|
+
return {
|
|
15025
|
+
pid: ids.pid,
|
|
15026
|
+
ppid: ids.ppid,
|
|
15027
|
+
uid: cred.euid,
|
|
15028
|
+
gid: cred.egid,
|
|
15029
|
+
...user !== void 0 ? { user } : {},
|
|
15030
|
+
groups: [...cred.groups],
|
|
15031
|
+
users: this.users,
|
|
15032
|
+
...tag !== void 0 ? { tag } : {}
|
|
15033
|
+
};
|
|
15034
|
+
}
|
|
15035
|
+
async consume(fields) {
|
|
15036
|
+
const { hook } = this;
|
|
15037
|
+
if (!hook) return void 0;
|
|
15038
|
+
const control = new AbortController();
|
|
15039
|
+
const timer = setTimeout(() => control.abort("timeout"), this.timeoutMs);
|
|
15040
|
+
const stopped = new Promise((resolve2) => {
|
|
15041
|
+
control.signal.addEventListener("abort", () => resolve2(void 0), { once: true });
|
|
15042
|
+
});
|
|
15043
|
+
const req = {
|
|
15044
|
+
...fields,
|
|
15045
|
+
v: 1,
|
|
15046
|
+
op: "materializeConsume",
|
|
15047
|
+
caller: fields.stamp
|
|
15048
|
+
};
|
|
15049
|
+
try {
|
|
15050
|
+
const asked = Promise.resolve().then(() => hook(req, { signal: control.signal })).then(swapOf, () => void 0);
|
|
15051
|
+
return await Promise.race([asked, stopped]);
|
|
15052
|
+
} finally {
|
|
15053
|
+
clearTimeout(timer);
|
|
15054
|
+
control.abort("done");
|
|
15055
|
+
}
|
|
15056
|
+
}
|
|
14433
15057
|
open() {
|
|
14434
15058
|
const channel = new SealedChannel(this);
|
|
14435
15059
|
return new OpenFile({
|
|
@@ -14928,11 +15552,11 @@ function codeOf3(err) {
|
|
|
14928
15552
|
}
|
|
14929
15553
|
function wait(ms, signal) {
|
|
14930
15554
|
if (signal.aborted) return Promise.resolve();
|
|
14931
|
-
return new Promise((
|
|
15555
|
+
return new Promise((resolve2) => {
|
|
14932
15556
|
const done4 = () => {
|
|
14933
15557
|
clearTimeout(timer);
|
|
14934
15558
|
signal.removeEventListener("abort", done4);
|
|
14935
|
-
|
|
15559
|
+
resolve2();
|
|
14936
15560
|
};
|
|
14937
15561
|
const timer = setTimeout(done4, ms);
|
|
14938
15562
|
signal.addEventListener("abort", done4, { once: true });
|
|
@@ -15259,11 +15883,11 @@ async function resize(h, path, size) {
|
|
|
15259
15883
|
}
|
|
15260
15884
|
}
|
|
15261
15885
|
function sleep(ms, signal) {
|
|
15262
|
-
return new Promise((
|
|
15886
|
+
return new Promise((resolve2) => {
|
|
15263
15887
|
const done4 = () => {
|
|
15264
15888
|
clearTimeout(timer);
|
|
15265
15889
|
signal.removeEventListener("abort", done4);
|
|
15266
|
-
|
|
15890
|
+
resolve2();
|
|
15267
15891
|
};
|
|
15268
15892
|
const timer = setTimeout(done4, ms);
|
|
15269
15893
|
signal.addEventListener("abort", done4);
|
|
@@ -15346,7 +15970,7 @@ var PORT_DEAD_MS = 1e4;
|
|
|
15346
15970
|
var PORT_LINGER_MS = 1e3;
|
|
15347
15971
|
function timed(transport, ms) {
|
|
15348
15972
|
const inflight = /* @__PURE__ */ new Set();
|
|
15349
|
-
const guard2 = (name2, run2, late, expire) => new Promise((
|
|
15973
|
+
const guard2 = (name2, run2, late, expire) => new Promise((resolve2, reject) => {
|
|
15350
15974
|
let expired = false;
|
|
15351
15975
|
const running = run2();
|
|
15352
15976
|
inflight.add(running);
|
|
@@ -15363,7 +15987,7 @@ function timed(transport, ms) {
|
|
|
15363
15987
|
(value) => {
|
|
15364
15988
|
clearTimeout(timer);
|
|
15365
15989
|
if (expired) late?.(value);
|
|
15366
|
-
|
|
15990
|
+
resolve2(value);
|
|
15367
15991
|
},
|
|
15368
15992
|
(err) => {
|
|
15369
15993
|
clearTimeout(timer);
|
|
@@ -15498,7 +16122,7 @@ var PortTransport = class {
|
|
|
15498
16122
|
ask(message3, bytes = 0, transfer = []) {
|
|
15499
16123
|
const id2 = ++this.next;
|
|
15500
16124
|
if (this.dead) return Promise.reject(fsError2("ENOTCONN", this.dead));
|
|
15501
|
-
return new Promise((
|
|
16125
|
+
return new Promise((resolve2, reject) => {
|
|
15502
16126
|
const timer = setTimeout(
|
|
15503
16127
|
() => {
|
|
15504
16128
|
this.waiting.delete(id2);
|
|
@@ -15512,7 +16136,7 @@ var PortTransport = class {
|
|
|
15512
16136
|
clearTimeout(timer);
|
|
15513
16137
|
this.waiting.delete(id2);
|
|
15514
16138
|
if (reply.error) reject(fsError2(reply.error.code ?? "EIO", reply.error.message ?? ""));
|
|
15515
|
-
else
|
|
16139
|
+
else resolve2(reply);
|
|
15516
16140
|
});
|
|
15517
16141
|
try {
|
|
15518
16142
|
this.port.postMessage({ id: id2, ...message3 }, transfer);
|
|
@@ -15541,7 +16165,7 @@ var PortTransport = class {
|
|
|
15541
16165
|
this.fail("the folder's watch ended");
|
|
15542
16166
|
return Promise.resolve();
|
|
15543
16167
|
}
|
|
15544
|
-
return new Promise((
|
|
16168
|
+
return new Promise((resolve2, reject) => {
|
|
15545
16169
|
const finish = () => {
|
|
15546
16170
|
this.waiting.delete(id2);
|
|
15547
16171
|
signal.removeEventListener("abort", stop);
|
|
@@ -15552,7 +16176,7 @@ var PortTransport = class {
|
|
|
15552
16176
|
this.port.postMessage({ id: id2, op: "unwatch" });
|
|
15553
16177
|
} catch {
|
|
15554
16178
|
}
|
|
15555
|
-
|
|
16179
|
+
resolve2();
|
|
15556
16180
|
};
|
|
15557
16181
|
this.watchBeat();
|
|
15558
16182
|
this.waiting.set(id2, (reply) => {
|
|
@@ -15560,7 +16184,7 @@ var PortTransport = class {
|
|
|
15560
16184
|
if (reply.event) return onEvent(reply.event);
|
|
15561
16185
|
finish();
|
|
15562
16186
|
if (reply.error) reject(fsError2(reply.error.code ?? "ENOTCONN", reply.error.message ?? ""));
|
|
15563
|
-
else
|
|
16187
|
+
else resolve2();
|
|
15564
16188
|
});
|
|
15565
16189
|
signal.addEventListener("abort", stop, { once: true });
|
|
15566
16190
|
try {
|
|
@@ -15673,10 +16297,10 @@ var ChunkedBytes = class {
|
|
|
15673
16297
|
}
|
|
15674
16298
|
truncate(size) {
|
|
15675
16299
|
if (size < this.size) {
|
|
15676
|
-
const
|
|
15677
|
-
this.chunks.length = Math.min(this.chunks.length,
|
|
15678
|
-
const tail = this.chunks[
|
|
15679
|
-
const from = size - (
|
|
16300
|
+
const keep2 = Math.ceil(size / CHUNK3);
|
|
16301
|
+
this.chunks.length = Math.min(this.chunks.length, keep2);
|
|
16302
|
+
const tail = this.chunks[keep2 - 1];
|
|
16303
|
+
const from = size - (keep2 - 1) * CHUNK3;
|
|
15680
16304
|
if (tail && from < tail.length) tail.fill(0, from);
|
|
15681
16305
|
}
|
|
15682
16306
|
this.size = size;
|
|
@@ -15921,8 +16545,8 @@ function importedMemory(bytes) {
|
|
|
15921
16545
|
at = end;
|
|
15922
16546
|
continue;
|
|
15923
16547
|
}
|
|
15924
|
-
const
|
|
15925
|
-
for (let i = 0; i <
|
|
16548
|
+
const count2 = u32();
|
|
16549
|
+
for (let i = 0; i < count2; i++) {
|
|
15926
16550
|
const module = name2();
|
|
15927
16551
|
const field3 = name2();
|
|
15928
16552
|
const kind = bytes[at++];
|
|
@@ -16351,7 +16975,7 @@ ${lines2}
|
|
|
16351
16975
|
const withdraw = () => control.abort("withdrawn");
|
|
16352
16976
|
requester.addEventListener("abort", withdraw, { once: true });
|
|
16353
16977
|
const aborted2 = new Promise(
|
|
16354
|
-
(
|
|
16978
|
+
(resolve2) => control.signal.addEventListener("abort", () => resolve2("aborted"), { once: true })
|
|
16355
16979
|
);
|
|
16356
16980
|
try {
|
|
16357
16981
|
const answered2 = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
|
|
@@ -16477,7 +17101,7 @@ var LAYOUT = [
|
|
|
16477
17101
|
];
|
|
16478
17102
|
var LOAD_SAMPLE_MS = 5e3;
|
|
16479
17103
|
var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
|
|
16480
|
-
var
|
|
17104
|
+
var encoder7 = new TextEncoder();
|
|
16481
17105
|
var USERS_MODES = ["off", "report", "enforce"];
|
|
16482
17106
|
function usersMode(mode = "off") {
|
|
16483
17107
|
if (USERS_MODES.includes(mode)) return mode;
|
|
@@ -16508,6 +17132,30 @@ function shebang(head) {
|
|
|
16508
17132
|
if (head[0] !== 35 || head[1] !== 33) return void 0;
|
|
16509
17133
|
return new TextDecoder().decode(head.subarray(0, SHEBANG_MAX)).slice(2).split("\n")[0].trim().split(/[ \t]+/);
|
|
16510
17134
|
}
|
|
17135
|
+
async function rootOnly(fs, path) {
|
|
17136
|
+
const names = chain(path);
|
|
17137
|
+
for (const [i, at] of names.entries()) {
|
|
17138
|
+
const st = await fs.lstat(at).catch(() => void 0);
|
|
17139
|
+
const kind = i === names.length - 1 ? st?.isFile : st?.isDirectory;
|
|
17140
|
+
if (!kind || st?.uid !== 0 || (st.mode & 18) !== 0) return false;
|
|
17141
|
+
}
|
|
17142
|
+
return true;
|
|
17143
|
+
}
|
|
17144
|
+
function plainEnv(words2) {
|
|
17145
|
+
const next2 = words2[1];
|
|
17146
|
+
if (baseName(words2[0] ?? "") !== "env" || next2 === void 0) return false;
|
|
17147
|
+
return next2 === "-S" || !next2.startsWith("-") && !next2.includes("=");
|
|
17148
|
+
}
|
|
17149
|
+
function shebangCommand(words2) {
|
|
17150
|
+
if (!plainEnv(words2)) {
|
|
17151
|
+
const arg2 = words2.slice(1).join(" ");
|
|
17152
|
+
return { interp: words2[0], args: arg2 ? [arg2] : [] };
|
|
17153
|
+
}
|
|
17154
|
+
const split2 = words2[1] === "-S";
|
|
17155
|
+
const [interp, ...rest2] = words2.slice(split2 ? 2 : 1);
|
|
17156
|
+
const arg = rest2.join(" ");
|
|
17157
|
+
return { interp, args: split2 ? rest2 : arg ? [arg] : [] };
|
|
17158
|
+
}
|
|
16511
17159
|
function interpreter(head) {
|
|
16512
17160
|
const words2 = shebang(head);
|
|
16513
17161
|
if (!words2) return "node";
|
|
@@ -16561,7 +17209,7 @@ function childHandle(handle) {
|
|
|
16561
17209
|
onState: (listener) => handle.onState(listener)
|
|
16562
17210
|
};
|
|
16563
17211
|
}
|
|
16564
|
-
function
|
|
17212
|
+
function concat6(chunks) {
|
|
16565
17213
|
const out = new Uint8Array(chunks.reduce((n, chunk2) => n + chunk2.length, 0));
|
|
16566
17214
|
let offset = 0;
|
|
16567
17215
|
for (const chunk2 of chunks) {
|
|
@@ -16647,6 +17295,7 @@ var Launcher = class {
|
|
|
16647
17295
|
usersMode;
|
|
16648
17296
|
dac;
|
|
16649
17297
|
sealed;
|
|
17298
|
+
scrubs = /* @__PURE__ */ new Map();
|
|
16650
17299
|
clipboard;
|
|
16651
17300
|
rootFs;
|
|
16652
17301
|
fileWatches;
|
|
@@ -16670,6 +17319,8 @@ var Launcher = class {
|
|
|
16670
17319
|
void 0,
|
|
16671
17320
|
(pid) => this.tagOf(pid)
|
|
16672
17321
|
);
|
|
17322
|
+
this.sealed.tickets.normalise = (path) => physicalPathAsync(this.base, path);
|
|
17323
|
+
this.sealed.userOf = async (uid) => (await this.users.lookup(uid))?.name;
|
|
16673
17324
|
if (this.owners) options.fs.trackOwners?.();
|
|
16674
17325
|
this.mounts = new MountTable({
|
|
16675
17326
|
open: (type, spec) => this.driver(type, spec),
|
|
@@ -16918,13 +17569,12 @@ var Launcher = class {
|
|
|
16918
17569
|
const binfmt = isWasm(head) ? void 0 : binfmtOf(await this.interpreters(scope), script);
|
|
16919
17570
|
const words2 = shebang(head) ?? (binfmt ? [binfmt] : void 0);
|
|
16920
17571
|
if (!words2) return void 0;
|
|
16921
|
-
|
|
16922
|
-
const [
|
|
16923
|
-
|
|
16924
|
-
const
|
|
16925
|
-
const found = interp ? await this.resolve(interp, interp, cwd, scope) : void 0;
|
|
17572
|
+
const { interp, args } = shebangCommand(words2);
|
|
17573
|
+
const passed = [...args, command ? script : file, ...argv.slice(1)];
|
|
17574
|
+
if (!interp) return void 0;
|
|
17575
|
+
const found = await this.resolve(interp, interp, cwd, scope);
|
|
16926
17576
|
if (!found) {
|
|
16927
|
-
if (
|
|
17577
|
+
if (depth >= MAX_INTERPRETERS || !await this.scriptCommand(interp, cwd, scope)) {
|
|
16928
17578
|
return void 0;
|
|
16929
17579
|
}
|
|
16930
17580
|
const inner = await this.interpreted(interp, [interp, ...passed], cwd, scope, depth + 1);
|
|
@@ -16964,6 +17614,99 @@ var Launcher = class {
|
|
|
16964
17614
|
await need(g, "exec", this.fs.resolvePath(req.cwd, file), want);
|
|
16965
17615
|
}
|
|
16966
17616
|
}
|
|
17617
|
+
async checkedPlan(req, { ppid, cred, scope }, fds) {
|
|
17618
|
+
const planned = await this.plan(req.file, req.argv, req.cwd, scope, req.argv0);
|
|
17619
|
+
try {
|
|
17620
|
+
await this.mayExec(cred, { ...req, pid: ppid }, planned);
|
|
17621
|
+
} catch (err) {
|
|
17622
|
+
await fds.closeAll();
|
|
17623
|
+
throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
|
|
17624
|
+
}
|
|
17625
|
+
if (planned) return planned;
|
|
17626
|
+
await fds.closeAll();
|
|
17627
|
+
throw new SpawnError(await this.unrunnable(req.file, req.cwd, scope));
|
|
17628
|
+
}
|
|
17629
|
+
async ticketFile(req, fds) {
|
|
17630
|
+
if (req.file.startsWith("/")) return physicalPathAsync(this.base, req.file);
|
|
17631
|
+
await fds.closeAll();
|
|
17632
|
+
throw new SpawnError("EACCES");
|
|
17633
|
+
}
|
|
17634
|
+
takeTicket(req) {
|
|
17635
|
+
if (!(TICKET_ENV in req.env)) return void 0;
|
|
17636
|
+
return this.sealed.tickets.take(req.env[TICKET_ENV] ?? "") ?? null;
|
|
17637
|
+
}
|
|
17638
|
+
async redeemed(req, who, planned, fds) {
|
|
17639
|
+
if (who.booked === void 0) return { env: req.env };
|
|
17640
|
+
try {
|
|
17641
|
+
const redeemed = await this.redeem(req, who, planned);
|
|
17642
|
+
if (redeemed.scrub) scrubStdio(fds, redeemed.scrub);
|
|
17643
|
+
return redeemed;
|
|
17644
|
+
} catch {
|
|
17645
|
+
await fds.closeAll();
|
|
17646
|
+
throw new SpawnError("EACCES");
|
|
17647
|
+
}
|
|
17648
|
+
}
|
|
17649
|
+
async redeem(req, { ppid, cred, scope, booked }, planned) {
|
|
17650
|
+
const { [TICKET_ENV]: ticket = "", ...env } = req.env;
|
|
17651
|
+
const caller = this.jobs.shown(ppid);
|
|
17652
|
+
const named = typeof req.argv0 === "string" && !planned.script && !planned.target.fixed;
|
|
17653
|
+
const argv = named ? [req.argv0, ...req.argv.slice(1)] : req.argv;
|
|
17654
|
+
const exact = booked?.pid === caller && req.file === booked.path && await physicalPathAsync(this.base, req.cwd) === booked.cwd && await argvDigest(argv) === booked.argv;
|
|
17655
|
+
if (!exact) throw new SpawnError("EACCES");
|
|
17656
|
+
const { requested: path, requestedCwd: cwd, path: resolved2 } = booked;
|
|
17657
|
+
const pid = this.nextPid++;
|
|
17658
|
+
const ids = { pid: req.exec ? caller : pid, ppid: caller };
|
|
17659
|
+
const stamp = await this.sealed.stamp(ids, cred, this.tagOf(ppid));
|
|
17660
|
+
const interpreters = await this.interpreterChain(planned, booked.cwd, scope);
|
|
17661
|
+
const trusted = this.usersMode === "enforce" && await this.trustedFiles(planned, req.file, booked.cwd, scope);
|
|
17662
|
+
const swap = await this.sealed.consume({
|
|
17663
|
+
ticket,
|
|
17664
|
+
stamp,
|
|
17665
|
+
path,
|
|
17666
|
+
resolved: resolved2,
|
|
17667
|
+
argv,
|
|
17668
|
+
cwd,
|
|
17669
|
+
interpreters,
|
|
17670
|
+
trusted
|
|
17671
|
+
});
|
|
17672
|
+
if (!swap) throw new SpawnError("EACCES");
|
|
17673
|
+
const secrets = [];
|
|
17674
|
+
for (const [name2, placeholder] of Object.entries(swap.placeholders)) {
|
|
17675
|
+
const value = swap.values[name2];
|
|
17676
|
+
if (value === void 0 || env[name2] !== placeholder) continue;
|
|
17677
|
+
env[name2] = value;
|
|
17678
|
+
secrets.push({ name: name2, value, placeholder });
|
|
17679
|
+
}
|
|
17680
|
+
const scrub = scrubberOf(secrets);
|
|
17681
|
+
return { env, pid, cwd: booked.cwd, ...scrub ? { scrub } : {} };
|
|
17682
|
+
}
|
|
17683
|
+
async interpreterChain(planned, cwd, scope) {
|
|
17684
|
+
const out = [];
|
|
17685
|
+
for (const entry of planned.via ?? []) {
|
|
17686
|
+
if (entry.includes("/")) {
|
|
17687
|
+
out.push(await physicalPathAsync(this.base, this.fs.resolvePath(cwd, entry)));
|
|
17688
|
+
continue;
|
|
17689
|
+
}
|
|
17690
|
+
const script = (await this.scriptCommand(entry, cwd, scope))?.script;
|
|
17691
|
+
out.push(
|
|
17692
|
+
await physicalPathAsync(this.base, script ?? await this.commandFile(entry, cwd, scope))
|
|
17693
|
+
);
|
|
17694
|
+
}
|
|
17695
|
+
return out;
|
|
17696
|
+
}
|
|
17697
|
+
async commandFile(name2, cwd, scope) {
|
|
17698
|
+
const scoped = await this.resolve(name2, name2, cwd, scope);
|
|
17699
|
+
const system = scope === "" ? scoped : await this.resolve(name2, name2, cwd, "");
|
|
17700
|
+
if (!scoped || system?.glue === scoped.glue) return `/usr/bin/${name2}`;
|
|
17701
|
+
return scoped.glue;
|
|
17702
|
+
}
|
|
17703
|
+
async trustedFiles(planned, file, cwd, scope) {
|
|
17704
|
+
const files = await this.backingOf(planned, file, cwd, scope);
|
|
17705
|
+
for (const at of files) {
|
|
17706
|
+
if (!await rootOnly(this.base, await physicalPathAsync(this.base, at))) return false;
|
|
17707
|
+
}
|
|
17708
|
+
return true;
|
|
17709
|
+
}
|
|
16967
17710
|
async grantedCwd(caller, cwd) {
|
|
16968
17711
|
const real = await physicalPathAsync(this.base, cwd).catch(() => void 0);
|
|
16969
17712
|
return real === cwd && await this.sudoer.reachable(caller, cwd);
|
|
@@ -16982,13 +17725,15 @@ var Launcher = class {
|
|
|
16982
17725
|
}
|
|
16983
17726
|
async backing(file, cwd) {
|
|
16984
17727
|
const planned = await this.plan(file, [file], cwd, "");
|
|
16985
|
-
|
|
17728
|
+
return planned && this.backingOf(planned, file, cwd, "");
|
|
17729
|
+
}
|
|
17730
|
+
async backingOf(planned, file, cwd, scope) {
|
|
16986
17731
|
const { glue, wasm, imports } = planned.target;
|
|
16987
17732
|
const files = [glue, wasm, ...imports ? [imports] : []];
|
|
16988
17733
|
const scripts = [];
|
|
16989
17734
|
for (const name2 of [file, ...planned.via ?? []]) {
|
|
16990
17735
|
if (name2.includes("/") && !COMMAND2.test(name2)) scripts.push(this.fs.resolvePath(cwd, name2));
|
|
16991
|
-
const script = (await this.scriptCommand(name2, cwd,
|
|
17736
|
+
const script = (await this.scriptCommand(name2, cwd, scope))?.script;
|
|
16992
17737
|
if (script) scripts.push(script);
|
|
16993
17738
|
}
|
|
16994
17739
|
files.push(...scripts, ...await this.binfmtManifests(scripts));
|
|
@@ -17117,6 +17862,7 @@ var Launcher = class {
|
|
|
17117
17862
|
const seen = { ...req.env, HOSTNAME: this.hostname, cwd };
|
|
17118
17863
|
const env = { ...expandDefaults(target.env, seen), ...req.env };
|
|
17119
17864
|
for (const key of target.unset ?? []) delete env[key];
|
|
17865
|
+
delete env[TICKET_ENV];
|
|
17120
17866
|
env.HOSTNAME = this.hostname;
|
|
17121
17867
|
let program;
|
|
17122
17868
|
try {
|
|
@@ -17132,16 +17878,23 @@ var Launcher = class {
|
|
|
17132
17878
|
groupSession(pgid) {
|
|
17133
17879
|
return this.jobs.sessionOf(pgid);
|
|
17134
17880
|
}
|
|
17881
|
+
treeScrubs(pid, req) {
|
|
17882
|
+
const inherited2 = req.ppid !== void 0 ? this.scrubs.get(req.ppid) : void 0;
|
|
17883
|
+
const scrubs = req.scrub ? [...inherited2 ?? [], req.scrub] : inherited2;
|
|
17884
|
+
if (scrubs) this.scrubs.set(pid, scrubs);
|
|
17885
|
+
return scrubs;
|
|
17886
|
+
}
|
|
17135
17887
|
start(req) {
|
|
17136
17888
|
this.sampling();
|
|
17137
17889
|
if (req.pgid !== void 0 && this.jobs.sessionOf(req.pgid) === void 0) {
|
|
17138
17890
|
throw new SpawnError("ESRCH");
|
|
17139
17891
|
}
|
|
17140
|
-
const pid = this.nextPid++;
|
|
17892
|
+
const pid = req.pid ?? this.nextPid++;
|
|
17893
|
+
const scrubs = this.treeScrubs(pid, req);
|
|
17141
17894
|
const stack = this.stackFor(req.tag);
|
|
17142
17895
|
const terminal = req.fds.stdioTerminal();
|
|
17143
17896
|
const decided = req.decided ?? Promise.resolve(true);
|
|
17144
|
-
const
|
|
17897
|
+
const count2 = (byParent) => {
|
|
17145
17898
|
this.identities.asked++;
|
|
17146
17899
|
if (!byParent) this.identities.timedOut++;
|
|
17147
17900
|
};
|
|
@@ -17149,7 +17902,7 @@ var Launcher = class {
|
|
|
17149
17902
|
const handle = spawnWasmProcess({
|
|
17150
17903
|
pid,
|
|
17151
17904
|
identity: async () => {
|
|
17152
|
-
await (asked ??= decided.then(
|
|
17905
|
+
await (asked ??= decided.then(count2));
|
|
17153
17906
|
return this.identityOf(pid);
|
|
17154
17907
|
},
|
|
17155
17908
|
onSyscall: (call) => {
|
|
@@ -17163,6 +17916,7 @@ var Launcher = class {
|
|
|
17163
17916
|
...this.owners && req.program.abi === "wasi" ? { fresh: (path, umask) => this.freshModules.add(path, umask, pid) } : {},
|
|
17164
17917
|
...this.owners ? { owners: true } : {},
|
|
17165
17918
|
sealed: this.sealed,
|
|
17919
|
+
...scrubs ? { ttyFilter: (file) => scrubbedAll(file, scrubs) } : {},
|
|
17166
17920
|
clipboard: this.clipboard,
|
|
17167
17921
|
...this.dac ? { dac: this.dac } : {},
|
|
17168
17922
|
program: req.program,
|
|
@@ -17229,6 +17983,7 @@ var Launcher = class {
|
|
|
17229
17983
|
if (spent) addTimes(this.imageTimes, this.jobs.shown(pid), spent);
|
|
17230
17984
|
this.stopped.delete(pid);
|
|
17231
17985
|
this.processes.delete(pid);
|
|
17986
|
+
this.scrubs.delete(pid);
|
|
17232
17987
|
if (this.processes.size === 0) {
|
|
17233
17988
|
clearInterval(this.sampler);
|
|
17234
17989
|
this.sampler = void 0;
|
|
@@ -17400,6 +18155,7 @@ var Launcher = class {
|
|
|
17400
18155
|
}
|
|
17401
18156
|
spawner(ppid, report) {
|
|
17402
18157
|
return async (req, fds, grant) => {
|
|
18158
|
+
const booked = this.takeTicket(req);
|
|
17403
18159
|
if (grant && !await this.grantedCwd(grant.caller, req.cwd)) {
|
|
17404
18160
|
await fds.closeAll();
|
|
17405
18161
|
throw new SpawnError("EACCES");
|
|
@@ -17411,23 +18167,20 @@ var Launcher = class {
|
|
|
17411
18167
|
}
|
|
17412
18168
|
const cred = grant ? grant.cred : this.credOf(ppid);
|
|
17413
18169
|
const scope = grant ? "" : await this.scopeOf(cred.euid);
|
|
17414
|
-
const
|
|
17415
|
-
|
|
17416
|
-
|
|
17417
|
-
|
|
17418
|
-
|
|
17419
|
-
|
|
17420
|
-
|
|
17421
|
-
|
|
17422
|
-
await fds.closeAll();
|
|
17423
|
-
throw new SpawnError(await this.unrunnable(req.file, req.cwd, scope));
|
|
17424
|
-
}
|
|
18170
|
+
const file = booked === void 0 ? req.file : await this.ticketFile(req, fds);
|
|
18171
|
+
const planned = await this.checkedPlan({ ...req, file }, { ppid, cred, scope }, fds);
|
|
18172
|
+
const redeemed = await this.redeemed(
|
|
18173
|
+
{ ...req, file },
|
|
18174
|
+
{ ppid, cred, scope, booked },
|
|
18175
|
+
planned,
|
|
18176
|
+
fds
|
|
18177
|
+
);
|
|
17425
18178
|
const exec = req.exec ? { exec: true } : {};
|
|
17426
18179
|
const deciding = req.exec ? void 0 : this.undecided(ppid);
|
|
17427
18180
|
const handle = await this.launch(planned, {
|
|
17428
18181
|
...deciding ? { decided: deciding.promise } : {},
|
|
17429
|
-
env: req.env,
|
|
17430
18182
|
cwd: req.cwd,
|
|
18183
|
+
...redeemed,
|
|
17431
18184
|
fds,
|
|
17432
18185
|
report,
|
|
17433
18186
|
ppid,
|
|
@@ -17480,11 +18233,11 @@ var Launcher = class {
|
|
|
17480
18233
|
if (!waiting) return;
|
|
17481
18234
|
this.deciding.delete(ppid);
|
|
17482
18235
|
setTimeout(() => {
|
|
17483
|
-
for (const
|
|
18236
|
+
for (const resolve2 of waiting) resolve2(true);
|
|
17484
18237
|
}, 0);
|
|
17485
18238
|
}
|
|
17486
18239
|
forker(ppid, parent) {
|
|
17487
|
-
const { exec: _exec, pgid: _pgid, group: _group, ...image } = parent;
|
|
18240
|
+
const { exec: _exec, pgid: _pgid, group: _group, pid: _pid, scrub: _scrub, ...image } = parent;
|
|
17488
18241
|
return async (state, fds) => childHandle(
|
|
17489
18242
|
this.start({
|
|
17490
18243
|
...image,
|
|
@@ -17861,7 +18614,14 @@ var Launcher = class {
|
|
|
17861
18614
|
);
|
|
17862
18615
|
}
|
|
17863
18616
|
environment(cwd, extra, account) {
|
|
17864
|
-
|
|
18617
|
+
const env = {
|
|
18618
|
+
...this.env,
|
|
18619
|
+
...userEnv(account, this.pnpmHome),
|
|
18620
|
+
PWD: cwd,
|
|
18621
|
+
...extra
|
|
18622
|
+
};
|
|
18623
|
+
delete env[TICKET_ENV];
|
|
18624
|
+
return env;
|
|
17865
18625
|
}
|
|
17866
18626
|
async account(user) {
|
|
17867
18627
|
if (typeof user === "object") return user;
|
|
@@ -17957,7 +18717,7 @@ var Launcher = class {
|
|
|
17957
18717
|
},
|
|
17958
18718
|
account
|
|
17959
18719
|
);
|
|
17960
|
-
const report = (message3) => options.onData(
|
|
18720
|
+
const report = (message3) => options.onData(encoder7.encode(`${message3}\r
|
|
17961
18721
|
`));
|
|
17962
18722
|
const handle = await this.launch(planned, {
|
|
17963
18723
|
env,
|
|
@@ -17988,18 +18748,18 @@ var Launcher = class {
|
|
|
17988
18748
|
const env = this.environment(cwd, options.env, account);
|
|
17989
18749
|
const out = [];
|
|
17990
18750
|
const err = [];
|
|
17991
|
-
const
|
|
18751
|
+
const keep2 = options.collect !== false;
|
|
17992
18752
|
const collect = (chunks, tee) => (bytes) => {
|
|
17993
|
-
if (
|
|
18753
|
+
if (keep2) chunks.push(bytes);
|
|
17994
18754
|
tee?.(bytes);
|
|
17995
18755
|
};
|
|
17996
18756
|
const stdout = collect(out, options.onStdout);
|
|
17997
18757
|
const stderr = collect(err, options.onStderr);
|
|
17998
|
-
const report = (message3) => stderr(
|
|
18758
|
+
const report = (message3) => stderr(encoder7.encode(`${message3}
|
|
17999
18759
|
`));
|
|
18000
18760
|
if (!planned) {
|
|
18001
18761
|
report(`${file}: command not found`);
|
|
18002
|
-
return { status: NOT_FOUND, stdout:
|
|
18762
|
+
return { status: NOT_FOUND, stdout: concat6(out), stderr: concat6(err) };
|
|
18003
18763
|
}
|
|
18004
18764
|
const fds = new FdTable();
|
|
18005
18765
|
fds.installAt(0, options.stdin ? bytesSource(options.stdin) : deviceFile("null"));
|
|
@@ -18017,7 +18777,7 @@ var Launcher = class {
|
|
|
18017
18777
|
options.onStarted?.(handle.pid);
|
|
18018
18778
|
const status = await handle.exited;
|
|
18019
18779
|
const signal = handle.termsig();
|
|
18020
|
-
return { status, ...signal ? { signal } : {}, stdout:
|
|
18780
|
+
return { status, ...signal ? { signal } : {}, stdout: concat6(out), stderr: concat6(err) };
|
|
18021
18781
|
}
|
|
18022
18782
|
};
|
|
18023
18783
|
|
|
@@ -18118,14 +18878,14 @@ function dial(l, req) {
|
|
|
18118
18878
|
function sudoApprovals(port) {
|
|
18119
18879
|
const waiting = /* @__PURE__ */ new Map();
|
|
18120
18880
|
return {
|
|
18121
|
-
ask: (req, { signal }) => new Promise((
|
|
18122
|
-
waiting.set(req.id,
|
|
18881
|
+
ask: (req, { signal }) => new Promise((resolve2) => {
|
|
18882
|
+
waiting.set(req.id, resolve2);
|
|
18123
18883
|
signal.addEventListener(
|
|
18124
18884
|
"abort",
|
|
18125
18885
|
() => {
|
|
18126
18886
|
waiting.delete(req.id);
|
|
18127
18887
|
port.postMessage({ sudoAbort: { id: req.id, reason: String(signal.reason) } });
|
|
18128
|
-
|
|
18888
|
+
resolve2("deny");
|
|
18129
18889
|
},
|
|
18130
18890
|
{ once: true }
|
|
18131
18891
|
);
|
|
@@ -18209,9 +18969,9 @@ function hostProtect(init, lookup) {
|
|
|
18209
18969
|
function policyAsker(port) {
|
|
18210
18970
|
const policies = /* @__PURE__ */ new Map();
|
|
18211
18971
|
let nextPolicy = 0;
|
|
18212
|
-
const askPolicy = (req) => new Promise((
|
|
18972
|
+
const askPolicy = (req) => new Promise((resolve2) => {
|
|
18213
18973
|
const id2 = ++nextPolicy;
|
|
18214
|
-
policies.set(id2,
|
|
18974
|
+
policies.set(id2, resolve2);
|
|
18215
18975
|
port.postMessage({ mountPolicy: { id: id2, req } });
|
|
18216
18976
|
});
|
|
18217
18977
|
return {
|
|
@@ -18239,10 +18999,10 @@ function serveKernel(port, deps) {
|
|
|
18239
18999
|
const locks = deps.locks === null ? void 0 : deps.locks ?? locksOf();
|
|
18240
19000
|
let holding;
|
|
18241
19001
|
function holdLock(locks2) {
|
|
18242
|
-
holding ??= new Promise((
|
|
19002
|
+
holding ??= new Promise((resolve2) => {
|
|
18243
19003
|
const name2 = `slicc-kernel:${crypto.randomUUID()}`;
|
|
18244
19004
|
void locks2.request(name2, () => {
|
|
18245
|
-
|
|
19005
|
+
resolve2(name2);
|
|
18246
19006
|
return new Promise(() => {
|
|
18247
19007
|
});
|
|
18248
19008
|
});
|