@ai-ecoverse/slicc-kernel 1.170.2 → 1.170.4
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 +12 -4
- package/dist/kernel-worker.js +163 -43
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.cjs +3 -3
- package/dist/node-process-worker.cjs.map +2 -2
- package/dist/node-process-worker.js +3 -3
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +163 -43
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +3 -3
- package/dist/process-worker.js.map +2 -2
- package/dist/types/commands.d.ts +2 -1
- package/dist/types/kernel/net/http-syscalls.d.ts +1 -0
- package/dist/types/kernel/net/placeholder-floor.d.ts +8 -0
- package/dist/types/launcher.d.ts +2 -0
- package/dist/types/realm/sync-fs-wire.d.ts +1 -1
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -3695,7 +3695,7 @@ function satisfies(version, range2) {
|
|
|
3695
3695
|
}
|
|
3696
3696
|
|
|
3697
3697
|
// src/version.ts
|
|
3698
|
-
var KERNEL_VERSION = true ? "1.170.
|
|
3698
|
+
var KERNEL_VERSION = true ? "1.170.4" : "0.0.0-dev";
|
|
3699
3699
|
var OS_RELEASE = "6.0.0-slicc";
|
|
3700
3700
|
function procVersion() {
|
|
3701
3701
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -3964,9 +3964,19 @@ function replacesOf(manifest) {
|
|
|
3964
3964
|
if (!Array.isArray(replaces)) return [];
|
|
3965
3965
|
return replaces.every((name2) => typeof name2 === "string" && PACKAGE_NAME.test(name2)) ? replaces : [];
|
|
3966
3966
|
}
|
|
3967
|
-
async function
|
|
3967
|
+
async function directInstalls(fs, root) {
|
|
3968
|
+
try {
|
|
3969
|
+
const project = root.slice(0, root.lastIndexOf("/"));
|
|
3970
|
+
const { dependencies } = JSON.parse(await fs.readFile(`${project}/package.json`));
|
|
3971
|
+
return new Set(Object.keys(dependencies ?? {}));
|
|
3972
|
+
} catch {
|
|
3973
|
+
return void 0;
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
async function tierPackages(fs, physical, roots, bins, kernel, global) {
|
|
3968
3977
|
const out = [];
|
|
3969
3978
|
for (const root of roots) {
|
|
3979
|
+
const direct = global.has(root) ? await directInstalls(fs, root) : void 0;
|
|
3970
3980
|
for (const pkg of await packages(fs, root)) {
|
|
3971
3981
|
let manifest;
|
|
3972
3982
|
try {
|
|
@@ -3978,12 +3988,15 @@ async function tierPackages(fs, physical, roots, bins, kernel) {
|
|
|
3978
3988
|
const named = new Set(own.map((command) => command.name));
|
|
3979
3989
|
const extra = bins ? await binCommandsOf(physical, pkg, manifest, named) : [];
|
|
3980
3990
|
const refused3 = engineRefusal(manifest, kernel);
|
|
3981
|
-
const
|
|
3991
|
+
const name2 = pkg.slice(root.length + 1);
|
|
3992
|
+
const dependency = direct?.has(name2) === false;
|
|
3993
|
+
const marks = { ...refused3 ? { refused: refused3 } : {}, ...dependency ? { dependency } : {} };
|
|
3982
3994
|
out.push({
|
|
3983
|
-
name:
|
|
3995
|
+
name: name2,
|
|
3984
3996
|
pkg,
|
|
3985
3997
|
replaces: replacesOf(manifest),
|
|
3986
|
-
commands:
|
|
3998
|
+
commands: [...own, ...extra].map((command) => ({ ...command, ...marks })),
|
|
3999
|
+
dependency
|
|
3987
4000
|
});
|
|
3988
4001
|
}
|
|
3989
4002
|
}
|
|
@@ -4009,19 +4022,25 @@ function winners(tier) {
|
|
|
4009
4022
|
}
|
|
4010
4023
|
return out;
|
|
4011
4024
|
}
|
|
4012
|
-
async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY, kernel = KERNEL_VERSION, refused3) {
|
|
4025
|
+
async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY, kernel = KERNEL_VERSION, refused3, global = /* @__PURE__ */ new Set()) {
|
|
4013
4026
|
const found = /* @__PURE__ */ new Map();
|
|
4014
4027
|
const physical = physicalResolver(fs);
|
|
4015
4028
|
const tiers = (typeof modules === "string" ? [modules] : modules).map(
|
|
4016
4029
|
(tier) => typeof tier === "string" ? [tier] : tier
|
|
4017
4030
|
);
|
|
4018
|
-
|
|
4019
|
-
const tier = await tierPackages(fs, physical, roots, index >= binsFrom, kernel);
|
|
4020
|
-
if (refused3) refused3.push(...tier.flatMap((entry) => entry.commands.filter((c) => c.refused)));
|
|
4031
|
+
const take = async (tier) => {
|
|
4021
4032
|
for (const [name2, { pkg, command }] of winners(tier)) {
|
|
4022
4033
|
if (!found.has(name2)) found.set(name2, await withPackagePaths(fs, pkg, command));
|
|
4023
4034
|
}
|
|
4035
|
+
};
|
|
4036
|
+
const dependencies = [];
|
|
4037
|
+
for (const [index, roots] of tiers.entries()) {
|
|
4038
|
+
const tier = await tierPackages(fs, physical, roots, index >= binsFrom, kernel, global);
|
|
4039
|
+
if (refused3) refused3.push(...tier.flatMap((entry) => entry.commands.filter((c) => c.refused)));
|
|
4040
|
+
await take(tier.filter((entry) => !entry.dependency));
|
|
4041
|
+
dependencies.push(tier.filter((entry) => entry.dependency));
|
|
4024
4042
|
}
|
|
4043
|
+
for (const tier of dependencies) await take(tier);
|
|
4025
4044
|
if (!found.has("sh") && found.has("bash")) {
|
|
4026
4045
|
found.set("sh", { ...found.get("bash"), name: "sh", argv0: "sh" });
|
|
4027
4046
|
}
|
|
@@ -5583,6 +5602,78 @@ var CronService = class {
|
|
|
5583
5602
|
}
|
|
5584
5603
|
};
|
|
5585
5604
|
|
|
5605
|
+
// src/kernel/net/placeholder-floor.ts
|
|
5606
|
+
var PLACEHOLDER = /fnox_proxy_[0-9a-f]{24}/;
|
|
5607
|
+
var ESCAPE = /%([0-9a-f]{2})/gi;
|
|
5608
|
+
var BASIC = /\bbasic\b(.*)/is;
|
|
5609
|
+
var PERCENT_LAYERS = 8;
|
|
5610
|
+
var BASE64_GROUP = 4;
|
|
5611
|
+
var PLACEHOLDER_REFUSED = "refused: this request has a sealed placeholder in its URL, a header or a Basic credential, and nothing fills it, so it was not sent";
|
|
5612
|
+
var PlaceholderRefused = class extends Error {
|
|
5613
|
+
status = 403;
|
|
5614
|
+
code = "EACCES";
|
|
5615
|
+
constructor() {
|
|
5616
|
+
super(PLACEHOLDER_REFUSED);
|
|
5617
|
+
}
|
|
5618
|
+
};
|
|
5619
|
+
function carries(text) {
|
|
5620
|
+
let layer = text;
|
|
5621
|
+
for (let i = 0; i < PERCENT_LAYERS; i++) {
|
|
5622
|
+
if (PLACEHOLDER.test(layer)) return true;
|
|
5623
|
+
const next3 = layer.replace(
|
|
5624
|
+
ESCAPE,
|
|
5625
|
+
(_, hex4) => String.fromCharCode(Number.parseInt(hex4, 16))
|
|
5626
|
+
);
|
|
5627
|
+
if (next3 === layer) return false;
|
|
5628
|
+
layer = next3;
|
|
5629
|
+
}
|
|
5630
|
+
return PLACEHOLDER.test(layer);
|
|
5631
|
+
}
|
|
5632
|
+
function basicCarries(value2) {
|
|
5633
|
+
const credential = BASIC.exec(value2)?.[1];
|
|
5634
|
+
if (credential === void 0) return false;
|
|
5635
|
+
const letters = credential.replace(/[^A-Za-z0-9+/_-]/g, "").replaceAll("-", "+").replaceAll("_", "/");
|
|
5636
|
+
for (let shift = 0; shift < BASE64_GROUP; shift++) {
|
|
5637
|
+
const part = letters.slice(shift);
|
|
5638
|
+
const whole = part.length % BASE64_GROUP === 1 ? part.slice(0, -1) : part;
|
|
5639
|
+
if (carries(atob(whole))) return true;
|
|
5640
|
+
}
|
|
5641
|
+
return false;
|
|
5642
|
+
}
|
|
5643
|
+
function headersCarry(headers) {
|
|
5644
|
+
return headers.some(
|
|
5645
|
+
([name2, value2]) => carries(name2.toLowerCase()) || carries(value2) || basicCarries(value2)
|
|
5646
|
+
);
|
|
5647
|
+
}
|
|
5648
|
+
function urlCarries(url) {
|
|
5649
|
+
return carries(url) || URL.canParse(url) && carries(new URL(url).href);
|
|
5650
|
+
}
|
|
5651
|
+
function refuse(request) {
|
|
5652
|
+
if (urlCarries(request.url) || headersCarry(request.headers)) throw new PlaceholderRefused();
|
|
5653
|
+
}
|
|
5654
|
+
function refuseSocket(request) {
|
|
5655
|
+
refuse(request);
|
|
5656
|
+
if (request.protocols.some(carries)) throw new PlaceholderRefused();
|
|
5657
|
+
}
|
|
5658
|
+
function placeholderFloor(inner) {
|
|
5659
|
+
const open = inner.websocket?.bind(inner);
|
|
5660
|
+
return {
|
|
5661
|
+
get traits() {
|
|
5662
|
+
return inner.traits;
|
|
5663
|
+
},
|
|
5664
|
+
...open ? {
|
|
5665
|
+
websocket: async (request) => {
|
|
5666
|
+
refuseSocket(request);
|
|
5667
|
+
return open(request);
|
|
5668
|
+
}
|
|
5669
|
+
} : {},
|
|
5670
|
+
async fetch(request, owner) {
|
|
5671
|
+
refuse(request);
|
|
5672
|
+
return inner.fetch(request, owner);
|
|
5673
|
+
}
|
|
5674
|
+
};
|
|
5675
|
+
}
|
|
5676
|
+
|
|
5586
5677
|
// src/kernel/net/ws-queue.ts
|
|
5587
5678
|
var INBOUND_LIMIT = 16 * 1024 * 1024;
|
|
5588
5679
|
var MESSAGE_LIMIT = 64 * 1024 * 1024;
|
|
@@ -6157,7 +6248,8 @@ var RealmProxy = class {
|
|
|
6157
6248
|
});
|
|
6158
6249
|
} catch (e) {
|
|
6159
6250
|
waiting.abort();
|
|
6160
|
-
|
|
6251
|
+
const status = e instanceof PlaceholderRefused ? e.status : 502;
|
|
6252
|
+
throw new HttpError(status, e instanceof Error ? e.message : String(e));
|
|
6161
6253
|
}
|
|
6162
6254
|
ctx.idle.ms = Number.POSITIVE_INFINITY;
|
|
6163
6255
|
try {
|
|
@@ -6371,7 +6463,7 @@ async function relay(socket, conn) {
|
|
|
6371
6463
|
// src/fs/attest.ts
|
|
6372
6464
|
var ATTEST_MAX = 1024 * 1024;
|
|
6373
6465
|
var UNOWNED = 1e3;
|
|
6374
|
-
function
|
|
6466
|
+
function refuse2(code, path, why) {
|
|
6375
6467
|
throw Object.assign(new Error(`attest ${path}: ${why}`), { code });
|
|
6376
6468
|
}
|
|
6377
6469
|
function chainOf(path) {
|
|
@@ -6413,11 +6505,11 @@ async function trustedParents(fs, path, o) {
|
|
|
6413
6505
|
const parents = [];
|
|
6414
6506
|
for (const dir of chainOf(path).slice(0, -1)) {
|
|
6415
6507
|
const st = await fs.lstat(dir);
|
|
6416
|
-
if (st.isSymbolicLink)
|
|
6417
|
-
if (!st.isDirectory)
|
|
6508
|
+
if (st.isSymbolicLink) refuse2("EACCES", path, `${dir} is a symlink`);
|
|
6509
|
+
if (!st.isDirectory) refuse2("ENOTDIR", path, `${dir} is not a directory`);
|
|
6418
6510
|
const perm = owned(dir, st);
|
|
6419
6511
|
if (o.users !== "off" && (perm.uid !== 0 || (perm.mode & 18) !== 0)) {
|
|
6420
|
-
|
|
6512
|
+
refuse2("EACCES", path, `${dir} is not root-owned or is writable by group or others`);
|
|
6421
6513
|
}
|
|
6422
6514
|
parents.push(perm);
|
|
6423
6515
|
}
|
|
@@ -6425,27 +6517,27 @@ async function trustedParents(fs, path, o) {
|
|
|
6425
6517
|
}
|
|
6426
6518
|
async function attest(fs, asked, o) {
|
|
6427
6519
|
if (typeof asked !== "string" || !asked.startsWith("/")) {
|
|
6428
|
-
|
|
6520
|
+
refuse2("EINVAL", String(asked), "not an absolute path");
|
|
6429
6521
|
}
|
|
6430
6522
|
const path = normalizePath(asked);
|
|
6431
6523
|
const mount = o.mounts.find((target) => {
|
|
6432
6524
|
const at = normalizePath(target);
|
|
6433
6525
|
return at === "/" || under(path, at);
|
|
6434
6526
|
});
|
|
6435
|
-
if (mount !== void 0)
|
|
6527
|
+
if (mount !== void 0) refuse2("EACCES", path, `under the mount ${mount}`);
|
|
6436
6528
|
const parents = await trustedParents(fs, path, o);
|
|
6437
6529
|
for (let tries = 0; ; tries++) {
|
|
6438
6530
|
const before = await fs.lstat(path);
|
|
6439
|
-
if (before.isSymbolicLink)
|
|
6531
|
+
if (before.isSymbolicLink) refuse2("EACCES", path, "is a symlink");
|
|
6440
6532
|
if (!before.isFile)
|
|
6441
|
-
|
|
6442
|
-
if (before.size > ATTEST_MAX)
|
|
6533
|
+
refuse2(before.isDirectory ? "EISDIR" : "EINVAL", path, "is not a regular file");
|
|
6534
|
+
if (before.size > ATTEST_MAX) refuse2("EFBIG", path, `is over ${ATTEST_MAX} bytes`);
|
|
6443
6535
|
const bytes = (await fs.readFileBuffer(path)).slice();
|
|
6444
6536
|
const after = await fs.lstat(path);
|
|
6445
6537
|
if (unchanged(before, after, bytes)) {
|
|
6446
6538
|
return attested(path, after, bytes, await sha256(bytes), o, parents);
|
|
6447
6539
|
}
|
|
6448
|
-
if (tries >= 1)
|
|
6540
|
+
if (tries >= 1) refuse2("EAGAIN", path, "changed while it was read");
|
|
6449
6541
|
}
|
|
6450
6542
|
}
|
|
6451
6543
|
var WATCH_DEBOUNCE_MS = 50;
|
|
@@ -11683,7 +11775,7 @@ function encodeSabResult(result) {
|
|
|
11683
11775
|
message: result.message,
|
|
11684
11776
|
...result.direct ? { direct: true } : {},
|
|
11685
11777
|
...result.dev !== void 0 ? { dev: result.dev } : {},
|
|
11686
|
-
...result.detail
|
|
11778
|
+
...result.detail ? { detail: result.detail } : {}
|
|
11687
11779
|
})
|
|
11688
11780
|
)
|
|
11689
11781
|
};
|
|
@@ -15097,23 +15189,29 @@ var HttpHandles = class {
|
|
|
15097
15189
|
return response.redirected ? { ...head, json: { ...head.json, redirected: true } } : head;
|
|
15098
15190
|
} catch (e) {
|
|
15099
15191
|
entry.upload?.cancel();
|
|
15100
|
-
|
|
15101
|
-
|
|
15102
|
-
const status = e.status;
|
|
15103
|
-
if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
|
|
15104
|
-
const code = codeOf2(e);
|
|
15105
|
-
const errno3 = text === NO_TRANSPORT ? "ENETUNREACH" : code !== "EIO" ? code : "ECONNREFUSED";
|
|
15106
|
-
const failed3 = e.detail === "transport";
|
|
15107
|
-
return { ok: false, errno: errno3, message: text, ...failed3 ? { detail: "transport" } : {} };
|
|
15108
|
-
}
|
|
15109
|
-
entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
|
|
15110
|
-
return this.headOf(handle, req.url, {
|
|
15111
|
-
status,
|
|
15112
|
-
statusText: "",
|
|
15113
|
-
headers: [["content-type", "text/plain; charset=utf-8"]]
|
|
15114
|
-
});
|
|
15192
|
+
if (port !== void 0) return { ok: false, errno: codeOf2(e), message: message2(e) };
|
|
15193
|
+
return this.failure(handle, req, e, entry);
|
|
15115
15194
|
}
|
|
15116
15195
|
}
|
|
15196
|
+
failure(handle, req, e, entry) {
|
|
15197
|
+
const text = message2(e);
|
|
15198
|
+
if (e instanceof PlaceholderRefused) {
|
|
15199
|
+
return { ok: false, errno: e.code, message: text, detail: "placeholder" };
|
|
15200
|
+
}
|
|
15201
|
+
const status = e.status;
|
|
15202
|
+
if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
|
|
15203
|
+
const code = codeOf2(e);
|
|
15204
|
+
const errno3 = text === NO_TRANSPORT ? "ENETUNREACH" : code !== "EIO" ? code : "ECONNREFUSED";
|
|
15205
|
+
const failed3 = e.detail === "transport";
|
|
15206
|
+
return { ok: false, errno: errno3, message: text, ...failed3 ? { detail: "transport" } : {} };
|
|
15207
|
+
}
|
|
15208
|
+
entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
|
|
15209
|
+
return this.headOf(handle, req.url, {
|
|
15210
|
+
status,
|
|
15211
|
+
statusText: "",
|
|
15212
|
+
headers: [["content-type", "text/plain; charset=utf-8"]]
|
|
15213
|
+
});
|
|
15214
|
+
}
|
|
15117
15215
|
headOf(handle, url, response) {
|
|
15118
15216
|
const { status, statusText, headers } = response;
|
|
15119
15217
|
return { ok: true, kind: "json", json: { handle, status, statusText, url, headers } };
|
|
@@ -18211,7 +18309,7 @@ var HEAD_MAX = 16 * 1024;
|
|
|
18211
18309
|
var ANY_PLACEHOLDER = /fnox_proxy_[0-9a-f]{24}/g;
|
|
18212
18310
|
var REQUEST_LINE2 = /^([!#$%&'*+.^_`|~0-9A-Za-z-]+) ([\x21-\x7e]+) HTTP\/1\.[01]$/;
|
|
18213
18311
|
var HEADER_LINE = /^([!#$%&'*+.^_`|~0-9A-Za-z-]+):[ \t]*(.*?)[ \t]*$/;
|
|
18214
|
-
var
|
|
18312
|
+
var BASIC2 = /^(Basic[ \t]+)([A-Za-z0-9+/]+={0,2})$/i;
|
|
18215
18313
|
var encoder8 = new TextEncoder();
|
|
18216
18314
|
function binary(text) {
|
|
18217
18315
|
let out = "";
|
|
@@ -18227,7 +18325,7 @@ function sniffHttp1(start2) {
|
|
|
18227
18325
|
return "no";
|
|
18228
18326
|
}
|
|
18229
18327
|
function basicOf(value2) {
|
|
18230
|
-
const m =
|
|
18328
|
+
const m = BASIC2.exec(value2);
|
|
18231
18329
|
if (!m) return void 0;
|
|
18232
18330
|
try {
|
|
18233
18331
|
return { scheme: m[1], decoded: atob(m[2]) };
|
|
@@ -25235,7 +25333,8 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
25235
25333
|
return { ...inner.traits, manualRedirects: true };
|
|
25236
25334
|
},
|
|
25237
25335
|
...inner.websocket ? { websocket: inner.websocket.bind(inner) } : {},
|
|
25238
|
-
async fetch(request,
|
|
25336
|
+
async fetch(request, caller) {
|
|
25337
|
+
const owner = caller ?? KERNEL;
|
|
25239
25338
|
const key = keyOf3(owner, request.method, request.url);
|
|
25240
25339
|
const waiting = held.get(key);
|
|
25241
25340
|
if (waiting && waiting.fingerprint === fingerprint(request.headers)) {
|
|
@@ -25244,7 +25343,7 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
25244
25343
|
return replay(waiting);
|
|
25245
25344
|
}
|
|
25246
25345
|
if (waiting) drop(key);
|
|
25247
|
-
const response = await inner.fetch(request);
|
|
25346
|
+
const response = await inner.fetch(request, caller);
|
|
25248
25347
|
if (!response.redirects?.length) return response;
|
|
25249
25348
|
return replay({
|
|
25250
25349
|
owner,
|
|
@@ -30971,7 +31070,7 @@ var Launcher = class {
|
|
|
30971
31070
|
...options.env
|
|
30972
31071
|
};
|
|
30973
31072
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
30974
|
-
this.transport = replayingHops(options.transport ?? missingTransport());
|
|
31073
|
+
this.transport = placeholderFloor(replayingHops(options.transport ?? missingTransport()));
|
|
30975
31074
|
this.announcedTraits = JSON.stringify(this.transport.traits);
|
|
30976
31075
|
this.uplink = options.uplink;
|
|
30977
31076
|
this.routes = new Routes(options.uplink?.traits.ipv6 === true);
|
|
@@ -31132,7 +31231,8 @@ var Launcher = class {
|
|
|
31132
31231
|
tiers,
|
|
31133
31232
|
tiers.length - appended2.length,
|
|
31134
31233
|
void 0,
|
|
31135
|
-
refused3
|
|
31234
|
+
refused3,
|
|
31235
|
+
await this.globalRoots(scope)
|
|
31136
31236
|
);
|
|
31137
31237
|
this.refusedOf.set(commands, refused3.map(refusing));
|
|
31138
31238
|
return commands;
|
|
@@ -31157,11 +31257,31 @@ var Launcher = class {
|
|
|
31157
31257
|
ownCommands(scope) {
|
|
31158
31258
|
let found = this.ownCatalogs.get(scope);
|
|
31159
31259
|
if (!found) {
|
|
31160
|
-
found =
|
|
31260
|
+
found = this.ownCatalog(scope);
|
|
31161
31261
|
this.ownCatalogs.set(scope, found);
|
|
31162
31262
|
}
|
|
31163
31263
|
return found;
|
|
31164
31264
|
}
|
|
31265
|
+
async ownCatalog(scope) {
|
|
31266
|
+
const roots = await pnpmGlobalRoots(this.base, scope);
|
|
31267
|
+
const own = await scanCommands(
|
|
31268
|
+
this.scanned,
|
|
31269
|
+
roots,
|
|
31270
|
+
void 0,
|
|
31271
|
+
void 0,
|
|
31272
|
+
void 0,
|
|
31273
|
+
new Set(roots)
|
|
31274
|
+
);
|
|
31275
|
+
const system = await this.commands();
|
|
31276
|
+
return new Set(
|
|
31277
|
+
[...own.values()].filter((command) => !command.dependency || !system.has(command.name)).map((command) => command.name)
|
|
31278
|
+
);
|
|
31279
|
+
}
|
|
31280
|
+
async globalRoots(scope) {
|
|
31281
|
+
const homes = scope ? [scope, this.pnpmHome] : [this.pnpmHome];
|
|
31282
|
+
const roots = await Promise.all(homes.map((home) => pnpmGlobalRoots(this.base, home)));
|
|
31283
|
+
return new Set(roots.flat());
|
|
31284
|
+
}
|
|
31165
31285
|
interpreters(scope = "") {
|
|
31166
31286
|
let found = this.binfmts.get(scope);
|
|
31167
31287
|
if (!found) {
|