@ai-ecoverse/slicc-kernel 1.67.1 → 1.68.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 +10 -0
- package/dist/index.js +49 -2
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +266 -22
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +87 -21
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +222 -15
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +87 -21
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -866,6 +866,7 @@ function kernelFdKind(file) {
|
|
|
866
866
|
if (file.held) return "held";
|
|
867
867
|
if (file.heldMeta && "device" in file.heldMeta) return "device";
|
|
868
868
|
if (file.tty) return "tty";
|
|
869
|
+
if (file.sealed) return "sealed";
|
|
869
870
|
return file.seek ? "file" : "stream";
|
|
870
871
|
}
|
|
871
872
|
var FdTable = class _FdTable {
|
|
@@ -11182,6 +11183,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
11182
11183
|
"fd-open-tty",
|
|
11183
11184
|
"fd-tty-names",
|
|
11184
11185
|
"fd-tty-owner",
|
|
11186
|
+
"fd-open-sealed",
|
|
11185
11187
|
"tty-get",
|
|
11186
11188
|
"tty-set",
|
|
11187
11189
|
"tty-winsz",
|
|
@@ -11237,6 +11239,7 @@ var WasmProcess = class {
|
|
|
11237
11239
|
ignored = 0;
|
|
11238
11240
|
inherited = 0;
|
|
11239
11241
|
interrupt = new AbortController();
|
|
11242
|
+
gone = new AbortController();
|
|
11240
11243
|
dying = false;
|
|
11241
11244
|
umask = DEFAULT_UMASK;
|
|
11242
11245
|
cred;
|
|
@@ -11459,6 +11462,7 @@ var WasmProcess = class {
|
|
|
11459
11462
|
}
|
|
11460
11463
|
async write(fd, body, nonblock = false, cancelled) {
|
|
11461
11464
|
const file = this.fds.get(fd).file;
|
|
11465
|
+
if (file.sealed) return file.sealed.send(body, await this.sealedCaller(), this.gone.signal);
|
|
11462
11466
|
if (!file.write) throw new KernelError("EBADF");
|
|
11463
11467
|
if (!pollFile(file).writable) {
|
|
11464
11468
|
if (nonblock) throw new KernelError("EAGAIN");
|
|
@@ -11540,6 +11544,24 @@ var WasmProcess = class {
|
|
|
11540
11544
|
if (name2 !== void 0) ttyOpenable(this.guarded(), tty);
|
|
11541
11545
|
return this.fds.install(tty.file(), 3);
|
|
11542
11546
|
}
|
|
11547
|
+
openSealed() {
|
|
11548
|
+
const broker = this.options.sealed;
|
|
11549
|
+
if (!broker) throw new KernelError("ENOENT");
|
|
11550
|
+
return this.fds.install(broker.open(), 3);
|
|
11551
|
+
}
|
|
11552
|
+
async sealedCaller() {
|
|
11553
|
+
const shown = await this.options.identity?.();
|
|
11554
|
+
const broker = this.options.sealed;
|
|
11555
|
+
const tag = broker.tagOf(this.pid);
|
|
11556
|
+
return {
|
|
11557
|
+
pid: shown?.pid ?? this.pid,
|
|
11558
|
+
ppid: shown?.ppid ?? 0,
|
|
11559
|
+
uid: this.cred.euid,
|
|
11560
|
+
gid: this.cred.egid,
|
|
11561
|
+
...tag !== void 0 ? { tag } : {},
|
|
11562
|
+
users: broker.users
|
|
11563
|
+
};
|
|
11564
|
+
}
|
|
11543
11565
|
guarded() {
|
|
11544
11566
|
const { guard: guard2 } = this.options;
|
|
11545
11567
|
return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
@@ -11660,6 +11682,8 @@ var WasmProcess = class {
|
|
|
11660
11682
|
return { ok: true, kind: "json", json: this.openTty(req.name) };
|
|
11661
11683
|
case "fd-tty-names":
|
|
11662
11684
|
return { ok: true, kind: "json", json: this.options.jobs?.terminalNames() ?? [] };
|
|
11685
|
+
case "fd-open-sealed":
|
|
11686
|
+
return { ok: true, kind: "json", json: this.openSealed() };
|
|
11663
11687
|
case "fd-tty-owner":
|
|
11664
11688
|
return { ok: true, kind: "json", json: this.terminalByName(req.name).owner ?? null };
|
|
11665
11689
|
case "fd-select": {
|
|
@@ -12095,6 +12119,7 @@ var WasmProcess = class {
|
|
|
12095
12119
|
async exit() {
|
|
12096
12120
|
if (this.exited) return;
|
|
12097
12121
|
this.exited = true;
|
|
12122
|
+
this.gone.abort();
|
|
12098
12123
|
this.die();
|
|
12099
12124
|
this.clearAlarm();
|
|
12100
12125
|
this.interrupt.abort();
|
|
@@ -12282,6 +12307,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
12282
12307
|
return {
|
|
12283
12308
|
...inherited(opts),
|
|
12284
12309
|
...opts.owners ? { owners: true } : {},
|
|
12310
|
+
...opts.sealed ? { sealed: opts.sealed } : {},
|
|
12285
12311
|
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
12286
12312
|
...opts.identity ? { identity: opts.identity } : {},
|
|
12287
12313
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
@@ -12764,6 +12790,178 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
12764
12790
|
};
|
|
12765
12791
|
}
|
|
12766
12792
|
|
|
12793
|
+
// src/kernel/sealed.ts
|
|
12794
|
+
var SEALED_MAX_BYTES = 64 * 1024;
|
|
12795
|
+
var SEALED_TIMEOUT_MS = 1e4;
|
|
12796
|
+
var SEALED_OPS = /* @__PURE__ */ new Set([
|
|
12797
|
+
"seal",
|
|
12798
|
+
"placeholder",
|
|
12799
|
+
"list",
|
|
12800
|
+
"test",
|
|
12801
|
+
"request",
|
|
12802
|
+
"status",
|
|
12803
|
+
"cancel",
|
|
12804
|
+
"materialize"
|
|
12805
|
+
]);
|
|
12806
|
+
var encoder3 = new TextEncoder();
|
|
12807
|
+
var decoder2 = new TextDecoder("utf-8", { fatal: true });
|
|
12808
|
+
function parseSealed(bytes) {
|
|
12809
|
+
try {
|
|
12810
|
+
if (bytes.length > SEALED_MAX_BYTES) throw new KernelError("EMSGSIZE");
|
|
12811
|
+
let parsed2;
|
|
12812
|
+
try {
|
|
12813
|
+
parsed2 = JSON.parse(decoder2.decode(bytes));
|
|
12814
|
+
} catch {
|
|
12815
|
+
throw new KernelError("EINVAL");
|
|
12816
|
+
}
|
|
12817
|
+
if (typeof parsed2 !== "object" || parsed2 === null || Array.isArray(parsed2))
|
|
12818
|
+
throw new KernelError("EINVAL");
|
|
12819
|
+
const req = parsed2;
|
|
12820
|
+
if (req.v !== 1 || typeof req.op !== "string" || !SEALED_OPS.has(req.op))
|
|
12821
|
+
throw new KernelError("EINVAL");
|
|
12822
|
+
return req;
|
|
12823
|
+
} finally {
|
|
12824
|
+
bytes.fill(0);
|
|
12825
|
+
}
|
|
12826
|
+
}
|
|
12827
|
+
function errorReply(code, message3) {
|
|
12828
|
+
return { v: 1, error: { code, message: message3 } };
|
|
12829
|
+
}
|
|
12830
|
+
function isRecord(value) {
|
|
12831
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12832
|
+
}
|
|
12833
|
+
function serialized(reply) {
|
|
12834
|
+
let plain;
|
|
12835
|
+
try {
|
|
12836
|
+
const text = JSON.stringify(reply);
|
|
12837
|
+
plain = text === void 0 ? void 0 : JSON.parse(text);
|
|
12838
|
+
} catch (err) {
|
|
12839
|
+
return JSON.stringify(errorReply("EIO", lineOf(err)));
|
|
12840
|
+
}
|
|
12841
|
+
if (!isRecord(plain)) return JSON.stringify(errorReply("EIO", "the vault gave no reply"));
|
|
12842
|
+
const { v: _, ...rest2 } = plain;
|
|
12843
|
+
return JSON.stringify({ v: 1, ...rest2 });
|
|
12844
|
+
}
|
|
12845
|
+
function lineOf(err) {
|
|
12846
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
12847
|
+
return (text.split("\n")[0] ?? "").slice(0, 200);
|
|
12848
|
+
}
|
|
12849
|
+
var SealedChannel = class {
|
|
12850
|
+
reply;
|
|
12851
|
+
offset = 0;
|
|
12852
|
+
inflight;
|
|
12853
|
+
broker;
|
|
12854
|
+
constructor(broker) {
|
|
12855
|
+
this.broker = broker;
|
|
12856
|
+
}
|
|
12857
|
+
send(bytes, caller, gone) {
|
|
12858
|
+
const length2 = bytes.length;
|
|
12859
|
+
const fields = parseSealed(bytes);
|
|
12860
|
+
this.reply = void 0;
|
|
12861
|
+
this.offset = 0;
|
|
12862
|
+
this.inflight?.control.abort("replaced");
|
|
12863
|
+
const control = new AbortController();
|
|
12864
|
+
const withdraw = () => control.abort("withdrawn");
|
|
12865
|
+
if (gone.aborted) withdraw();
|
|
12866
|
+
else gone.addEventListener("abort", withdraw, { once: true });
|
|
12867
|
+
const timer = setTimeout(() => control.abort("timeout"), this.broker.timeoutMs);
|
|
12868
|
+
const req = { ...fields, v: 1, op: fields.op, caller };
|
|
12869
|
+
const flight = { control, done: Promise.resolve() };
|
|
12870
|
+
flight.done = this.answer(req, control.signal).then((reply) => {
|
|
12871
|
+
clearTimeout(timer);
|
|
12872
|
+
gone.removeEventListener("abort", withdraw);
|
|
12873
|
+
if (this.inflight !== flight) return;
|
|
12874
|
+
this.inflight = void 0;
|
|
12875
|
+
if (reply) this.reply = encoder3.encode(serialized(reply));
|
|
12876
|
+
});
|
|
12877
|
+
this.inflight = flight;
|
|
12878
|
+
return length2;
|
|
12879
|
+
}
|
|
12880
|
+
async answer(req, signal) {
|
|
12881
|
+
const hook = this.broker.hook;
|
|
12882
|
+
if (!hook) return errorReply("ENOTCONN", "no vault is connected");
|
|
12883
|
+
const stopped = new Promise((resolve) => {
|
|
12884
|
+
signal.addEventListener("abort", () => resolve(void 0), { once: true });
|
|
12885
|
+
});
|
|
12886
|
+
if (signal.aborted) return void 0;
|
|
12887
|
+
const asked = Promise.resolve().then(() => hook(req, { signal })).then(
|
|
12888
|
+
(reply2) => isRecord(reply2) ? reply2 : errorReply("EIO", "the vault gave no reply"),
|
|
12889
|
+
(err) => errorReply("EIO", lineOf(err))
|
|
12890
|
+
);
|
|
12891
|
+
const reply = await Promise.race([asked, stopped]);
|
|
12892
|
+
if (!signal.aborted) return reply;
|
|
12893
|
+
return signal.reason === "timeout" ? errorReply("ETIMEDOUT", "the vault did not answer within 10 s") : void 0;
|
|
12894
|
+
}
|
|
12895
|
+
async read(max, signal) {
|
|
12896
|
+
for (; ; ) {
|
|
12897
|
+
if (this.reply) {
|
|
12898
|
+
const out = this.reply.slice(this.offset, this.offset + max);
|
|
12899
|
+
this.offset += out.length;
|
|
12900
|
+
if (this.offset >= this.reply.length) {
|
|
12901
|
+
this.reply = void 0;
|
|
12902
|
+
this.offset = 0;
|
|
12903
|
+
}
|
|
12904
|
+
return out;
|
|
12905
|
+
}
|
|
12906
|
+
const flight = this.inflight;
|
|
12907
|
+
if (!flight) return new Uint8Array(0);
|
|
12908
|
+
await this.until(flight, signal);
|
|
12909
|
+
}
|
|
12910
|
+
}
|
|
12911
|
+
async until(flight, signal) {
|
|
12912
|
+
if (!signal) return flight.done;
|
|
12913
|
+
if (signal.aborted) throw new KernelError("EINTR");
|
|
12914
|
+
let stop = () => {
|
|
12915
|
+
};
|
|
12916
|
+
const interrupted2 = new Promise((_, reject) => {
|
|
12917
|
+
stop = () => reject(new KernelError("EINTR"));
|
|
12918
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
12919
|
+
});
|
|
12920
|
+
try {
|
|
12921
|
+
await Promise.race([flight.done, interrupted2]);
|
|
12922
|
+
} finally {
|
|
12923
|
+
signal.removeEventListener("abort", stop);
|
|
12924
|
+
}
|
|
12925
|
+
}
|
|
12926
|
+
poll() {
|
|
12927
|
+
return { readable: this.reply !== void 0 || !this.inflight, writable: true, hangup: false };
|
|
12928
|
+
}
|
|
12929
|
+
async changed(signal) {
|
|
12930
|
+
const flight = this.inflight;
|
|
12931
|
+
if (flight) await this.until(flight, signal);
|
|
12932
|
+
}
|
|
12933
|
+
close() {
|
|
12934
|
+
this.inflight?.control.abort("withdrawn");
|
|
12935
|
+
this.inflight = void 0;
|
|
12936
|
+
this.reply = void 0;
|
|
12937
|
+
}
|
|
12938
|
+
};
|
|
12939
|
+
var SealedBroker = class {
|
|
12940
|
+
hook;
|
|
12941
|
+
users;
|
|
12942
|
+
timeoutMs;
|
|
12943
|
+
tagOf;
|
|
12944
|
+
constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
|
|
12945
|
+
this.hook = hook;
|
|
12946
|
+
this.users = users;
|
|
12947
|
+
this.timeoutMs = timeoutMs;
|
|
12948
|
+
this.tagOf = tagOf;
|
|
12949
|
+
}
|
|
12950
|
+
open() {
|
|
12951
|
+
const channel = new SealedChannel(this);
|
|
12952
|
+
return new OpenFile({
|
|
12953
|
+
read: (max, signal) => channel.read(max, signal),
|
|
12954
|
+
write: async () => {
|
|
12955
|
+
throw new KernelError("EINVAL");
|
|
12956
|
+
},
|
|
12957
|
+
poll: () => channel.poll(),
|
|
12958
|
+
changed: (signal) => channel.changed(signal),
|
|
12959
|
+
close: () => channel.close(),
|
|
12960
|
+
sealed: channel
|
|
12961
|
+
});
|
|
12962
|
+
}
|
|
12963
|
+
};
|
|
12964
|
+
|
|
12767
12965
|
// src/kernel/settling.ts
|
|
12768
12966
|
var SETUP_OPS = /* @__PURE__ */ new Set([
|
|
12769
12967
|
"proc-list",
|
|
@@ -13411,13 +13609,13 @@ var HostfsClient = class {
|
|
|
13411
13609
|
const response = await this.send("/api/hostfs/watch", { method: "POST", signal });
|
|
13412
13610
|
onOpen();
|
|
13413
13611
|
const reader = response.body.getReader();
|
|
13414
|
-
const
|
|
13612
|
+
const decoder3 = new TextDecoder();
|
|
13415
13613
|
let buffered = "";
|
|
13416
13614
|
try {
|
|
13417
13615
|
for (; ; ) {
|
|
13418
13616
|
const { done: done4, value } = await reader.read();
|
|
13419
13617
|
if (done4) return;
|
|
13420
|
-
buffered +=
|
|
13618
|
+
buffered += decoder3.decode(value, { stream: true });
|
|
13421
13619
|
let end = buffered.indexOf("\n");
|
|
13422
13620
|
while (end >= 0) {
|
|
13423
13621
|
const line = buffered.slice(0, end).trim();
|
|
@@ -14898,7 +15096,7 @@ var LAYOUT = [
|
|
|
14898
15096
|
];
|
|
14899
15097
|
var LOAD_SAMPLE_MS = 5e3;
|
|
14900
15098
|
var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
|
|
14901
|
-
var
|
|
15099
|
+
var encoder4 = new TextEncoder();
|
|
14902
15100
|
var USERS_MODES = ["off", "report", "enforce"];
|
|
14903
15101
|
function usersMode(mode = "off") {
|
|
14904
15102
|
if (USERS_MODES.includes(mode)) return mode;
|
|
@@ -15048,12 +15246,19 @@ var Launcher = class {
|
|
|
15048
15246
|
fstab = Promise.resolve([]);
|
|
15049
15247
|
usersMode;
|
|
15050
15248
|
dac;
|
|
15249
|
+
sealed;
|
|
15051
15250
|
nextPid = 1e3;
|
|
15052
15251
|
boot = Date.now();
|
|
15053
15252
|
terminals = 0;
|
|
15054
15253
|
constructor(options) {
|
|
15055
15254
|
this.usersMode = usersMode(options.users);
|
|
15056
15255
|
this.dac = this.usersMode === "off" ? void 0 : new Dac(this.usersMode, options.onDenial);
|
|
15256
|
+
this.sealed = new SealedBroker(
|
|
15257
|
+
options.sealed,
|
|
15258
|
+
this.usersMode,
|
|
15259
|
+
void 0,
|
|
15260
|
+
(pid) => this.tagOf(pid)
|
|
15261
|
+
);
|
|
15057
15262
|
if (this.owners) options.fs.trackOwners?.();
|
|
15058
15263
|
this.mounts = new MountTable({
|
|
15059
15264
|
open: (type, spec) => this.driver(type, spec),
|
|
@@ -15453,6 +15658,7 @@ var Launcher = class {
|
|
|
15453
15658
|
...req.umask !== void 0 ? { umask: req.umask } : {},
|
|
15454
15659
|
cred: req.cred,
|
|
15455
15660
|
...this.owners ? { owners: true } : {},
|
|
15661
|
+
sealed: this.sealed,
|
|
15456
15662
|
...this.dac ? { dac: this.dac } : {},
|
|
15457
15663
|
program: req.program,
|
|
15458
15664
|
argv0: req.argv0,
|
|
@@ -16091,7 +16297,7 @@ var Launcher = class {
|
|
|
16091
16297
|
},
|
|
16092
16298
|
account
|
|
16093
16299
|
);
|
|
16094
|
-
const report = (message3) => options.onData(
|
|
16300
|
+
const report = (message3) => options.onData(encoder4.encode(`${message3}\r
|
|
16095
16301
|
`));
|
|
16096
16302
|
const handle = await this.launch(planned, {
|
|
16097
16303
|
env,
|
|
@@ -16128,7 +16334,7 @@ var Launcher = class {
|
|
|
16128
16334
|
};
|
|
16129
16335
|
const stdout = collect(out, options.onStdout);
|
|
16130
16336
|
const stderr = collect(err, options.onStderr);
|
|
16131
|
-
const report = (message3) => stderr(
|
|
16337
|
+
const report = (message3) => stderr(encoder4.encode(`${message3}
|
|
16132
16338
|
`));
|
|
16133
16339
|
if (!planned) {
|
|
16134
16340
|
report(`${file}: command not found`);
|
|
@@ -16665,7 +16871,7 @@ function dialStream(port, onClose) {
|
|
|
16665
16871
|
|
|
16666
16872
|
// src/client/loopback-fetch.ts
|
|
16667
16873
|
var OWN_HEADERS = /* @__PURE__ */ new Set(["host", "connection", "content-length", "transfer-encoding"]);
|
|
16668
|
-
var
|
|
16874
|
+
var encoder5 = new TextEncoder();
|
|
16669
16875
|
var latin12 = new TextDecoder("latin1");
|
|
16670
16876
|
var ByteSource = class {
|
|
16671
16877
|
buffered = new Uint8Array(0);
|
|
@@ -16683,7 +16889,7 @@ var ByteSource = class {
|
|
|
16683
16889
|
return true;
|
|
16684
16890
|
}
|
|
16685
16891
|
async until(marker) {
|
|
16686
|
-
const needle =
|
|
16892
|
+
const needle = encoder5.encode(marker);
|
|
16687
16893
|
for (; ; ) {
|
|
16688
16894
|
const at = indexOf(this.buffered, needle);
|
|
16689
16895
|
if (at >= 0) return this.take(at + needle.length);
|
|
@@ -16791,7 +16997,7 @@ async function requestBytes(request) {
|
|
|
16791
16997
|
});
|
|
16792
16998
|
if (body) lines2.push(`Content-Length: ${body.length}`);
|
|
16793
16999
|
lines2.push("Connection: close", "", "");
|
|
16794
|
-
const head =
|
|
17000
|
+
const head = encoder5.encode(lines2.join("\r\n"));
|
|
16795
17001
|
const out = new Uint8Array(head.length + (body?.length ?? 0));
|
|
16796
17002
|
out.set(head);
|
|
16797
17003
|
if (body) out.set(body, head.length);
|
|
@@ -16845,8 +17051,8 @@ var KernelCallError = class extends Error {
|
|
|
16845
17051
|
this.code = code;
|
|
16846
17052
|
}
|
|
16847
17053
|
};
|
|
16848
|
-
var
|
|
16849
|
-
var bytesOf2 = (data) => typeof data === "string" ?
|
|
17054
|
+
var encoder6 = new TextEncoder();
|
|
17055
|
+
var bytesOf2 = (data) => typeof data === "string" ? encoder6.encode(data) : data;
|
|
16850
17056
|
var UNAVAILABLE = {
|
|
16851
17057
|
manualRedirects: false,
|
|
16852
17058
|
encodedBodies: false,
|
|
@@ -17264,8 +17470,8 @@ function nodeWorker(file, live, closed) {
|
|
|
17264
17470
|
}
|
|
17265
17471
|
function textOf(on) {
|
|
17266
17472
|
if (!on) return void 0;
|
|
17267
|
-
const
|
|
17268
|
-
return (bytes) => on(
|
|
17473
|
+
const decoder3 = new TextDecoder();
|
|
17474
|
+
return (bytes) => on(decoder3.decode(bytes, { stream: true }));
|
|
17269
17475
|
}
|
|
17270
17476
|
async function createNodeKernel(options = {}) {
|
|
17271
17477
|
const root = options.root ?? memoryRoot();
|
|
@@ -17298,6 +17504,7 @@ async function createNodeKernel(options = {}) {
|
|
|
17298
17504
|
...options.hostname !== void 0 ? { hostname: options.hostname } : {},
|
|
17299
17505
|
...options.users !== void 0 ? { users: options.users } : {},
|
|
17300
17506
|
...options.onDenial ? { onDenial: options.onDenial } : {},
|
|
17507
|
+
...options.sealed ? { sealed: options.sealed } : {},
|
|
17301
17508
|
...options.approve ? { approve: options.approve } : {}
|
|
17302
17509
|
});
|
|
17303
17510
|
await launcher.prepare();
|
|
@@ -17306,7 +17513,7 @@ async function createNodeKernel(options = {}) {
|
|
|
17306
17513
|
pending.add(reject);
|
|
17307
17514
|
work().then(resolve, reject).finally(() => pending.delete(reject));
|
|
17308
17515
|
});
|
|
17309
|
-
const
|
|
17516
|
+
const decoder3 = new TextDecoder();
|
|
17310
17517
|
return {
|
|
17311
17518
|
root,
|
|
17312
17519
|
async run(argv, opts = {}) {
|
|
@@ -17323,8 +17530,8 @@ async function createNodeKernel(options = {}) {
|
|
|
17323
17530
|
);
|
|
17324
17531
|
return {
|
|
17325
17532
|
status: result.status,
|
|
17326
|
-
stdout:
|
|
17327
|
-
stderr:
|
|
17533
|
+
stdout: decoder3.decode(result.stdout),
|
|
17534
|
+
stderr: decoder3.decode(result.stderr)
|
|
17328
17535
|
};
|
|
17329
17536
|
},
|
|
17330
17537
|
async openTerminal(argv, opts = {}) {
|