@ecmaos/kernel 0.6.4 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.vite/manifest.json +12 -12
- package/dist/{install-DIY-HQ9n.js → install-vHqmAl7t.js} +2 -2
- package/dist/{install-DIY-HQ9n.js.map → install-vHqmAl7t.js.map} +1 -1
- package/dist/{kernel-DtEbpoeV.js → kernel-DZB_DlxI.js} +1071 -175
- package/dist/kernel-DZB_DlxI.js.map +1 -0
- package/dist/kernel.js +1 -1
- package/dist/{topbar.min-BK1fdCNA.js → topbar.min-BAV19NIs.js} +2 -2
- package/dist/{topbar.min-BK1fdCNA.js.map → topbar.min-BAV19NIs.js.map} +1 -1
- package/dist/ui.js +1 -1
- package/dist/{uninstall-BOyXf2bF.js → uninstall-Ds11Scu8.js} +2 -2
- package/dist/{uninstall-BOyXf2bF.js.map → uninstall-Ds11Scu8.js.map} +1 -1
- package/package.json +6 -5
- package/dist/kernel-DtEbpoeV.js.map +0 -1
|
@@ -25369,39 +25369,101 @@ const _Auth = class _Auth {
|
|
|
25369
25369
|
// Create a new credential
|
|
25370
25370
|
create: /* @__PURE__ */ __name(async (options) => {
|
|
25371
25371
|
try {
|
|
25372
|
-
|
|
25372
|
+
if (!this.passkey.isSupported()) {
|
|
25373
|
+
throw new Error("WebAuthn is not supported in this browser");
|
|
25374
|
+
}
|
|
25375
|
+
if (!window.isSecureContext) {
|
|
25376
|
+
throw new Error("WebAuthn requires a secure context (HTTPS or localhost)");
|
|
25377
|
+
}
|
|
25378
|
+
const credential = await navigator.credentials.create({ publicKey: options });
|
|
25379
|
+
if (!credential || !(credential instanceof PublicKeyCredential)) {
|
|
25380
|
+
throw new Error("Failed to create credential");
|
|
25381
|
+
}
|
|
25382
|
+
return credential;
|
|
25373
25383
|
} catch (error) {
|
|
25374
|
-
|
|
25375
|
-
|
|
25384
|
+
if (error instanceof Error) {
|
|
25385
|
+
if (error.name === "NotAllowedError") {
|
|
25386
|
+
throw new Error("User cancelled or denied the operation");
|
|
25387
|
+
} else if (error.name === "InvalidStateError") {
|
|
25388
|
+
throw new Error("Credential already exists or operation is invalid");
|
|
25389
|
+
} else if (error.name === "NotSupportedError") {
|
|
25390
|
+
throw new Error("The operation is not supported");
|
|
25391
|
+
} else if (error.name === "SecurityError") {
|
|
25392
|
+
throw new Error("Security error: operation not allowed");
|
|
25393
|
+
}
|
|
25394
|
+
throw error;
|
|
25395
|
+
}
|
|
25396
|
+
throw new Error(`Error creating credential: ${String(error)}`);
|
|
25376
25397
|
}
|
|
25377
25398
|
}, "create"),
|
|
25378
25399
|
// Get an existing credential
|
|
25379
25400
|
get: /* @__PURE__ */ __name(async (options) => {
|
|
25380
25401
|
try {
|
|
25381
|
-
|
|
25402
|
+
if (!this.passkey.isSupported()) {
|
|
25403
|
+
throw new Error("WebAuthn is not supported in this browser");
|
|
25404
|
+
}
|
|
25405
|
+
if (!window.isSecureContext) {
|
|
25406
|
+
throw new Error("WebAuthn requires a secure context (HTTPS or localhost)");
|
|
25407
|
+
}
|
|
25408
|
+
const credential = await navigator.credentials.get({ publicKey: options });
|
|
25409
|
+
if (!credential || !(credential instanceof PublicKeyCredential)) {
|
|
25410
|
+
return null;
|
|
25411
|
+
}
|
|
25412
|
+
return credential;
|
|
25382
25413
|
} catch (error) {
|
|
25383
|
-
|
|
25384
|
-
|
|
25414
|
+
if (error instanceof Error) {
|
|
25415
|
+
if (error.name === "NotAllowedError") {
|
|
25416
|
+
throw new Error("User cancelled or denied the operation");
|
|
25417
|
+
} else if (error.name === "InvalidStateError") {
|
|
25418
|
+
throw new Error("No matching credential found");
|
|
25419
|
+
} else if (error.name === "NotSupportedError") {
|
|
25420
|
+
throw new Error("The operation is not supported");
|
|
25421
|
+
} else if (error.name === "SecurityError") {
|
|
25422
|
+
throw new Error("Security error: operation not allowed");
|
|
25423
|
+
}
|
|
25424
|
+
throw error;
|
|
25425
|
+
}
|
|
25426
|
+
throw new Error(`Error getting credential: ${String(error)}`);
|
|
25385
25427
|
}
|
|
25386
25428
|
}, "get"),
|
|
25387
25429
|
// Check if WebAuthn is supported in the current browser
|
|
25388
25430
|
isSupported: /* @__PURE__ */ __name(() => {
|
|
25389
|
-
return !!window.PublicKeyCredential;
|
|
25431
|
+
return !!window.PublicKeyCredential && !!navigator.credentials;
|
|
25390
25432
|
}, "isSupported"),
|
|
25391
|
-
//
|
|
25392
|
-
|
|
25393
|
-
|
|
25394
|
-
|
|
25395
|
-
|
|
25396
|
-
|
|
25397
|
-
|
|
25398
|
-
|
|
25399
|
-
|
|
25400
|
-
|
|
25401
|
-
|
|
25402
|
-
|
|
25403
|
-
|
|
25404
|
-
|
|
25433
|
+
// Verify a passkey signature
|
|
25434
|
+
verify: /* @__PURE__ */ __name(async (credential, challenge, publicKey) => {
|
|
25435
|
+
try {
|
|
25436
|
+
const response = credential.response;
|
|
25437
|
+
const signature = response.signature;
|
|
25438
|
+
const clientDataJSON = response.clientDataJSON;
|
|
25439
|
+
const authenticatorData = response.authenticatorData;
|
|
25440
|
+
const clientData = JSON.parse(new TextDecoder().decode(clientDataJSON));
|
|
25441
|
+
const receivedChallenge = Uint8Array.from(atob(clientData.challenge), (c) => c.charCodeAt(0));
|
|
25442
|
+
const expectedChallenge = challenge;
|
|
25443
|
+
if (receivedChallenge.length !== expectedChallenge.length) {
|
|
25444
|
+
return false;
|
|
25445
|
+
}
|
|
25446
|
+
for (let i = 0; i < expectedChallenge.length; i++) {
|
|
25447
|
+
if (receivedChallenge[i] !== expectedChallenge[i]) {
|
|
25448
|
+
return false;
|
|
25449
|
+
}
|
|
25450
|
+
}
|
|
25451
|
+
const clientDataHash = await crypto.subtle.digest("SHA-256", clientDataJSON);
|
|
25452
|
+
const signedData = new Uint8Array(authenticatorData.byteLength + clientDataHash.byteLength);
|
|
25453
|
+
signedData.set(new Uint8Array(authenticatorData), 0);
|
|
25454
|
+
signedData.set(new Uint8Array(clientDataHash), authenticatorData.byteLength);
|
|
25455
|
+
const isValid2 = await crypto.subtle.verify(
|
|
25456
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
25457
|
+
publicKey,
|
|
25458
|
+
signature,
|
|
25459
|
+
signedData
|
|
25460
|
+
);
|
|
25461
|
+
return isValid2;
|
|
25462
|
+
} catch (error) {
|
|
25463
|
+
console.error("Error verifying passkey:", error);
|
|
25464
|
+
return false;
|
|
25465
|
+
}
|
|
25466
|
+
}, "verify")
|
|
25405
25467
|
});
|
|
25406
25468
|
__publicField(this, "password", {
|
|
25407
25469
|
create: /* @__PURE__ */ __name(async (options) => {
|
|
@@ -28559,7 +28621,7 @@ const _Dom = class _Dom {
|
|
|
28559
28621
|
}
|
|
28560
28622
|
async topbar(show) {
|
|
28561
28623
|
if (!this._topbar) return;
|
|
28562
|
-
const { default: topbar } = await import("./topbar.min-
|
|
28624
|
+
const { default: topbar } = await import("./topbar.min-BAV19NIs.js").then((n) => n.t);
|
|
28563
28625
|
this._topbarShow = show ?? !this._topbarShow;
|
|
28564
28626
|
if (this._topbarShow) topbar.show();
|
|
28565
28627
|
else topbar.hide();
|
|
@@ -59629,7 +59691,7 @@ const _TerminalCommand = class _TerminalCommand {
|
|
|
59629
59691
|
};
|
|
59630
59692
|
__name(_TerminalCommand, "TerminalCommand");
|
|
59631
59693
|
let TerminalCommand = _TerminalCommand;
|
|
59632
|
-
function createCommand$
|
|
59694
|
+
function createCommand$l(kernel, shell, terminal) {
|
|
59633
59695
|
return new TerminalCommand({
|
|
59634
59696
|
command: "cat",
|
|
59635
59697
|
description: "Concatenate files and print on the standard output",
|
|
@@ -59644,6 +59706,8 @@ function createCommand$h(kernel, shell, terminal) {
|
|
|
59644
59706
|
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
59645
59707
|
if (!process2) return 1;
|
|
59646
59708
|
const writer = process2.stdout.getWriter();
|
|
59709
|
+
const isTTY = process2.stdoutIsTTY ?? false;
|
|
59710
|
+
let lastByte;
|
|
59647
59711
|
try {
|
|
59648
59712
|
if (!argv.path || !argv.path[0]) {
|
|
59649
59713
|
const reader = process2.stdin.getReader();
|
|
@@ -59651,11 +59715,17 @@ function createCommand$h(kernel, shell, terminal) {
|
|
|
59651
59715
|
while (true) {
|
|
59652
59716
|
const { done, value } = await reader.read();
|
|
59653
59717
|
if (done) break;
|
|
59718
|
+
if (value.length > 0) {
|
|
59719
|
+
lastByte = value[value.length - 1];
|
|
59720
|
+
}
|
|
59654
59721
|
await writer.write(value);
|
|
59655
59722
|
}
|
|
59656
59723
|
} finally {
|
|
59657
59724
|
reader.releaseLock();
|
|
59658
59725
|
}
|
|
59726
|
+
if (isTTY && lastByte !== void 0 && lastByte !== 10) {
|
|
59727
|
+
await writer.write(new Uint8Array([10]));
|
|
59728
|
+
}
|
|
59659
59729
|
return 0;
|
|
59660
59730
|
}
|
|
59661
59731
|
const files = argv.path || [];
|
|
@@ -59678,7 +59748,11 @@ function createCommand$h(kernel, shell, terminal) {
|
|
|
59678
59748
|
const data = new Uint8Array(chunkSize);
|
|
59679
59749
|
const readSize = Math.min(chunkSize, stat2.size - bytesRead);
|
|
59680
59750
|
await handle.read(data, 0, readSize, bytesRead);
|
|
59681
|
-
|
|
59751
|
+
const chunk = data.subarray(0, readSize);
|
|
59752
|
+
if (chunk.length > 0) {
|
|
59753
|
+
lastByte = chunk[chunk.length - 1];
|
|
59754
|
+
}
|
|
59755
|
+
await writer.write(chunk);
|
|
59682
59756
|
bytesRead += readSize;
|
|
59683
59757
|
}
|
|
59684
59758
|
} else {
|
|
@@ -59695,7 +59769,11 @@ function createCommand$h(kernel, shell, terminal) {
|
|
|
59695
59769
|
if (bytesRead > 0) {
|
|
59696
59770
|
const bytesToWrite = maxBytes ? Math.min(bytesRead, maxBytes - totalBytesRead) : bytesRead;
|
|
59697
59771
|
if (bytesToWrite > 0) {
|
|
59698
|
-
|
|
59772
|
+
const chunk = data.subarray(0, bytesToWrite);
|
|
59773
|
+
if (chunk.length > 0) {
|
|
59774
|
+
lastByte = chunk[chunk.length - 1];
|
|
59775
|
+
}
|
|
59776
|
+
await writer.write(chunk);
|
|
59699
59777
|
totalBytesRead += bytesToWrite;
|
|
59700
59778
|
}
|
|
59701
59779
|
}
|
|
@@ -59705,16 +59783,18 @@ function createCommand$h(kernel, shell, terminal) {
|
|
|
59705
59783
|
kernel.terminal.events.off(TerminalEvents.INTERRUPT, interruptHandler);
|
|
59706
59784
|
}
|
|
59707
59785
|
}
|
|
59786
|
+
if (isTTY && lastByte !== void 0 && lastByte !== 10) {
|
|
59787
|
+
await writer.write(new Uint8Array([10]));
|
|
59788
|
+
}
|
|
59708
59789
|
return 0;
|
|
59709
59790
|
} finally {
|
|
59710
59791
|
writer.releaseLock();
|
|
59711
|
-
await writeStdout(process2, terminal, "\n");
|
|
59712
59792
|
}
|
|
59713
59793
|
}, "run")
|
|
59714
59794
|
});
|
|
59715
59795
|
}
|
|
59716
|
-
__name(createCommand$
|
|
59717
|
-
function createCommand$
|
|
59796
|
+
__name(createCommand$l, "createCommand$l");
|
|
59797
|
+
function createCommand$k(kernel, shell, terminal) {
|
|
59718
59798
|
return new TerminalCommand({
|
|
59719
59799
|
command: "cd",
|
|
59720
59800
|
description: "Change the shell working directory",
|
|
@@ -59735,8 +59815,8 @@ function createCommand$g(kernel, shell, terminal) {
|
|
|
59735
59815
|
}, "run")
|
|
59736
59816
|
});
|
|
59737
59817
|
}
|
|
59738
|
-
__name(createCommand$
|
|
59739
|
-
function createCommand$
|
|
59818
|
+
__name(createCommand$k, "createCommand$k");
|
|
59819
|
+
function createCommand$j(kernel, shell, terminal) {
|
|
59740
59820
|
return new TerminalCommand({
|
|
59741
59821
|
command: "chmod",
|
|
59742
59822
|
description: "Change file mode bits",
|
|
@@ -59762,8 +59842,8 @@ function createCommand$f(kernel, shell, terminal) {
|
|
|
59762
59842
|
}, "run")
|
|
59763
59843
|
});
|
|
59764
59844
|
}
|
|
59765
|
-
__name(createCommand$
|
|
59766
|
-
function createCommand$
|
|
59845
|
+
__name(createCommand$j, "createCommand$j");
|
|
59846
|
+
function createCommand$i(kernel, shell, terminal) {
|
|
59767
59847
|
return new TerminalCommand({
|
|
59768
59848
|
command: "cp",
|
|
59769
59849
|
description: "Copy files",
|
|
@@ -59785,8 +59865,8 @@ function createCommand$e(kernel, shell, terminal) {
|
|
|
59785
59865
|
}, "run")
|
|
59786
59866
|
});
|
|
59787
59867
|
}
|
|
59788
|
-
__name(createCommand$
|
|
59789
|
-
function createCommand$
|
|
59868
|
+
__name(createCommand$i, "createCommand$i");
|
|
59869
|
+
function createCommand$h(kernel, shell, terminal) {
|
|
59790
59870
|
return new TerminalCommand({
|
|
59791
59871
|
command: "echo",
|
|
59792
59872
|
description: "Print arguments to the standard output",
|
|
@@ -59795,11 +59875,14 @@ function createCommand$d(kernel, shell, terminal) {
|
|
|
59795
59875
|
terminal,
|
|
59796
59876
|
options: [
|
|
59797
59877
|
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
59878
|
+
{ name: "n", type: Boolean, alias: "n", description: "Do not output the trailing newline" },
|
|
59798
59879
|
{ name: "text", type: String, typeLabel: "{underline text}", defaultOption: true, multiple: true, description: "The text to print" }
|
|
59799
59880
|
],
|
|
59800
59881
|
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
59882
|
+
const noNewline = argv.n || false;
|
|
59801
59883
|
const text = (argv.text || []).join(" ");
|
|
59802
|
-
const
|
|
59884
|
+
const output2 = noNewline ? text : text + "\n";
|
|
59885
|
+
const data = new TextEncoder().encode(output2);
|
|
59803
59886
|
if (process2) {
|
|
59804
59887
|
const writer = process2.stdout.getWriter();
|
|
59805
59888
|
try {
|
|
@@ -59808,14 +59891,298 @@ function createCommand$d(kernel, shell, terminal) {
|
|
|
59808
59891
|
writer.releaseLock();
|
|
59809
59892
|
}
|
|
59810
59893
|
} else {
|
|
59811
|
-
terminal.write(
|
|
59894
|
+
terminal.write(output2);
|
|
59812
59895
|
}
|
|
59813
59896
|
return 0;
|
|
59814
59897
|
}, "run")
|
|
59815
59898
|
});
|
|
59816
59899
|
}
|
|
59817
|
-
__name(createCommand$
|
|
59818
|
-
function createCommand$
|
|
59900
|
+
__name(createCommand$h, "createCommand$h");
|
|
59901
|
+
function createCommand$g(kernel, shell, terminal) {
|
|
59902
|
+
return new TerminalCommand({
|
|
59903
|
+
command: "grep",
|
|
59904
|
+
description: "Search for patterns in files or standard input",
|
|
59905
|
+
kernel,
|
|
59906
|
+
shell,
|
|
59907
|
+
terminal,
|
|
59908
|
+
options: [
|
|
59909
|
+
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
59910
|
+
{ name: "ignore-case", type: Boolean, alias: "i", description: "Ignore case distinctions" },
|
|
59911
|
+
{ name: "line-number", type: Boolean, alias: "n", description: "Print line number with output lines" },
|
|
59912
|
+
{ name: "args", type: String, defaultOption: true, multiple: true, description: "Pattern and file(s) to search" }
|
|
59913
|
+
],
|
|
59914
|
+
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
59915
|
+
if (!process2) return 1;
|
|
59916
|
+
const args = argv.args || [];
|
|
59917
|
+
if (args.length === 0 || !args[0]) {
|
|
59918
|
+
await writelnStderr(process2, terminal, "grep: pattern is required");
|
|
59919
|
+
return 1;
|
|
59920
|
+
}
|
|
59921
|
+
const pattern2 = args[0];
|
|
59922
|
+
const files = args.slice(1);
|
|
59923
|
+
const ignoreCase = argv["ignore-case"] || false;
|
|
59924
|
+
const showLineNumbers = argv["line-number"] || false;
|
|
59925
|
+
const flags = ignoreCase ? "i" : "";
|
|
59926
|
+
let regex;
|
|
59927
|
+
try {
|
|
59928
|
+
regex = new RegExp(pattern2, flags);
|
|
59929
|
+
} catch (error) {
|
|
59930
|
+
await writelnStderr(process2, terminal, `grep: invalid pattern: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
59931
|
+
return 1;
|
|
59932
|
+
}
|
|
59933
|
+
const writer = process2.stdout.getWriter();
|
|
59934
|
+
let exitCode = 0;
|
|
59935
|
+
try {
|
|
59936
|
+
if (files.length === 0) {
|
|
59937
|
+
if (!process2.stdin) {
|
|
59938
|
+
await writelnStderr(process2, terminal, "grep: No input provided");
|
|
59939
|
+
return 1;
|
|
59940
|
+
}
|
|
59941
|
+
const reader = process2.stdin.getReader();
|
|
59942
|
+
let currentLineNumber = 1;
|
|
59943
|
+
let buffer2 = "";
|
|
59944
|
+
try {
|
|
59945
|
+
while (true) {
|
|
59946
|
+
const { done, value } = await reader.read();
|
|
59947
|
+
if (done) break;
|
|
59948
|
+
const chunk = new TextDecoder().decode(value, { stream: true });
|
|
59949
|
+
buffer2 += chunk;
|
|
59950
|
+
const lines = buffer2.split("\n");
|
|
59951
|
+
buffer2 = lines.pop() || "";
|
|
59952
|
+
for (const line3 of lines) {
|
|
59953
|
+
if (regex.test(line3)) {
|
|
59954
|
+
const output2 = showLineNumbers ? `${currentLineNumber}:${line3}
|
|
59955
|
+
` : `${line3}
|
|
59956
|
+
`;
|
|
59957
|
+
await writer.write(new TextEncoder().encode(output2));
|
|
59958
|
+
}
|
|
59959
|
+
currentLineNumber++;
|
|
59960
|
+
}
|
|
59961
|
+
}
|
|
59962
|
+
if (buffer2 && regex.test(buffer2)) {
|
|
59963
|
+
const output2 = showLineNumbers ? `${currentLineNumber}:${buffer2}
|
|
59964
|
+
` : `${buffer2}
|
|
59965
|
+
`;
|
|
59966
|
+
await writer.write(new TextEncoder().encode(output2));
|
|
59967
|
+
}
|
|
59968
|
+
} finally {
|
|
59969
|
+
reader.releaseLock();
|
|
59970
|
+
}
|
|
59971
|
+
} else {
|
|
59972
|
+
for (const file of files) {
|
|
59973
|
+
const fullPath = path$1.resolve(shell.cwd, file);
|
|
59974
|
+
let interrupted = false;
|
|
59975
|
+
const interruptHandler = /* @__PURE__ */ __name(() => {
|
|
59976
|
+
interrupted = true;
|
|
59977
|
+
}, "interruptHandler");
|
|
59978
|
+
kernel.terminal.events.on(TerminalEvents.INTERRUPT, interruptHandler);
|
|
59979
|
+
try {
|
|
59980
|
+
if (fullPath.startsWith("/dev")) {
|
|
59981
|
+
await writelnStderr(process2, terminal, `grep: ${file}: cannot search device files`);
|
|
59982
|
+
exitCode = 1;
|
|
59983
|
+
continue;
|
|
59984
|
+
}
|
|
59985
|
+
const handle = await shell.context.fs.promises.open(fullPath, "r");
|
|
59986
|
+
const stat2 = await shell.context.fs.promises.stat(fullPath);
|
|
59987
|
+
let bytesRead = 0;
|
|
59988
|
+
const chunkSize = 1024;
|
|
59989
|
+
let buffer2 = "";
|
|
59990
|
+
let currentLineNumber = 1;
|
|
59991
|
+
while (bytesRead < stat2.size) {
|
|
59992
|
+
if (interrupted) break;
|
|
59993
|
+
const data = new Uint8Array(chunkSize);
|
|
59994
|
+
const readSize = Math.min(chunkSize, stat2.size - bytesRead);
|
|
59995
|
+
await handle.read(data, 0, readSize, bytesRead);
|
|
59996
|
+
const chunk = data.subarray(0, readSize);
|
|
59997
|
+
const text = new TextDecoder().decode(chunk, { stream: true });
|
|
59998
|
+
buffer2 += text;
|
|
59999
|
+
const lines = buffer2.split("\n");
|
|
60000
|
+
buffer2 = lines.pop() || "";
|
|
60001
|
+
for (const line3 of lines) {
|
|
60002
|
+
if (regex.test(line3)) {
|
|
60003
|
+
const prefix = files.length > 1 ? `${file}:` : "";
|
|
60004
|
+
const lineNumPrefix = showLineNumbers ? `${currentLineNumber}:` : "";
|
|
60005
|
+
const output2 = `${prefix}${lineNumPrefix}${line3}
|
|
60006
|
+
`;
|
|
60007
|
+
await writer.write(new TextEncoder().encode(output2));
|
|
60008
|
+
}
|
|
60009
|
+
currentLineNumber++;
|
|
60010
|
+
}
|
|
60011
|
+
bytesRead += readSize;
|
|
60012
|
+
}
|
|
60013
|
+
if (buffer2 && regex.test(buffer2)) {
|
|
60014
|
+
const prefix = files.length > 1 ? `${file}:` : "";
|
|
60015
|
+
const lineNumPrefix = showLineNumbers ? `${currentLineNumber}:` : "";
|
|
60016
|
+
const output2 = `${prefix}${lineNumPrefix}${buffer2}
|
|
60017
|
+
`;
|
|
60018
|
+
await writer.write(new TextEncoder().encode(output2));
|
|
60019
|
+
}
|
|
60020
|
+
} catch (error) {
|
|
60021
|
+
await writelnStderr(process2, terminal, `grep: ${file}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
60022
|
+
exitCode = 1;
|
|
60023
|
+
} finally {
|
|
60024
|
+
kernel.terminal.events.off(TerminalEvents.INTERRUPT, interruptHandler);
|
|
60025
|
+
}
|
|
60026
|
+
}
|
|
60027
|
+
}
|
|
60028
|
+
return exitCode;
|
|
60029
|
+
} finally {
|
|
60030
|
+
writer.releaseLock();
|
|
60031
|
+
}
|
|
60032
|
+
}, "run")
|
|
60033
|
+
});
|
|
60034
|
+
}
|
|
60035
|
+
__name(createCommand$g, "createCommand$g");
|
|
60036
|
+
function createCommand$f(kernel, shell, terminal) {
|
|
60037
|
+
return new TerminalCommand({
|
|
60038
|
+
command: "head",
|
|
60039
|
+
description: "Print the first lines of files",
|
|
60040
|
+
kernel,
|
|
60041
|
+
shell,
|
|
60042
|
+
terminal,
|
|
60043
|
+
options: [
|
|
60044
|
+
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
60045
|
+
{ name: "lines", type: Number, alias: "n", description: "Print the first NUM lines instead of the first 10" },
|
|
60046
|
+
{ name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, multiple: true, description: "The path(s) to the file(s) to read" }
|
|
60047
|
+
],
|
|
60048
|
+
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
60049
|
+
if (!process2) return 1;
|
|
60050
|
+
const writer = process2.stdout.getWriter();
|
|
60051
|
+
const numLines = argv.lines ?? 10;
|
|
60052
|
+
try {
|
|
60053
|
+
if (!argv.path || !argv.path[0]) {
|
|
60054
|
+
if (!process2.stdin) {
|
|
60055
|
+
return 0;
|
|
60056
|
+
}
|
|
60057
|
+
const reader = process2.stdin.getReader();
|
|
60058
|
+
const decoder2 = new TextDecoder();
|
|
60059
|
+
const lines = [];
|
|
60060
|
+
let buffer2 = "";
|
|
60061
|
+
try {
|
|
60062
|
+
while (true) {
|
|
60063
|
+
let readResult;
|
|
60064
|
+
try {
|
|
60065
|
+
readResult = await reader.read();
|
|
60066
|
+
} catch (error) {
|
|
60067
|
+
if (error instanceof Error) {
|
|
60068
|
+
throw error;
|
|
60069
|
+
}
|
|
60070
|
+
break;
|
|
60071
|
+
}
|
|
60072
|
+
const { done, value } = readResult;
|
|
60073
|
+
if (done) {
|
|
60074
|
+
buffer2 += decoder2.decode();
|
|
60075
|
+
break;
|
|
60076
|
+
}
|
|
60077
|
+
if (value) {
|
|
60078
|
+
buffer2 += decoder2.decode(value, { stream: true });
|
|
60079
|
+
const newLines = buffer2.split("\n");
|
|
60080
|
+
buffer2 = newLines.pop() || "";
|
|
60081
|
+
lines.push(...newLines);
|
|
60082
|
+
if (lines.length >= numLines) break;
|
|
60083
|
+
}
|
|
60084
|
+
}
|
|
60085
|
+
if (buffer2 && lines.length < numLines) {
|
|
60086
|
+
lines.push(buffer2);
|
|
60087
|
+
}
|
|
60088
|
+
} finally {
|
|
60089
|
+
try {
|
|
60090
|
+
reader.releaseLock();
|
|
60091
|
+
} catch {
|
|
60092
|
+
}
|
|
60093
|
+
}
|
|
60094
|
+
const output2 = lines.slice(0, numLines).join("\n");
|
|
60095
|
+
if (output2) {
|
|
60096
|
+
await writer.write(new TextEncoder().encode(output2 + "\n"));
|
|
60097
|
+
}
|
|
60098
|
+
return 0;
|
|
60099
|
+
}
|
|
60100
|
+
const files = argv.path || [];
|
|
60101
|
+
const isMultipleFiles = files.length > 1;
|
|
60102
|
+
for (let i = 0; i < files.length; i++) {
|
|
60103
|
+
const file = files[i];
|
|
60104
|
+
if (!file) continue;
|
|
60105
|
+
const fullPath = path$1.resolve(shell.cwd, file);
|
|
60106
|
+
if (isMultipleFiles) {
|
|
60107
|
+
const header = i > 0 ? "\n" : "";
|
|
60108
|
+
await writer.write(new TextEncoder().encode(`${header}==> ${file} <==
|
|
60109
|
+
`));
|
|
60110
|
+
}
|
|
60111
|
+
let interrupted = false;
|
|
60112
|
+
const interruptHandler = /* @__PURE__ */ __name(() => {
|
|
60113
|
+
interrupted = true;
|
|
60114
|
+
}, "interruptHandler");
|
|
60115
|
+
kernel.terminal.events.on(TerminalEvents.INTERRUPT, interruptHandler);
|
|
60116
|
+
try {
|
|
60117
|
+
if (!fullPath.startsWith("/dev")) {
|
|
60118
|
+
const handle = await shell.context.fs.promises.open(fullPath, "r");
|
|
60119
|
+
const stat2 = await shell.context.fs.promises.stat(fullPath);
|
|
60120
|
+
const decoder2 = new TextDecoder();
|
|
60121
|
+
const lines = [];
|
|
60122
|
+
let buffer2 = "";
|
|
60123
|
+
let bytesRead = 0;
|
|
60124
|
+
const chunkSize = 1024;
|
|
60125
|
+
while (bytesRead < stat2.size && lines.length < numLines) {
|
|
60126
|
+
if (interrupted) break;
|
|
60127
|
+
const data = new Uint8Array(chunkSize);
|
|
60128
|
+
const readSize = Math.min(chunkSize, stat2.size - bytesRead);
|
|
60129
|
+
await handle.read(data, 0, readSize, bytesRead);
|
|
60130
|
+
const chunk = data.subarray(0, readSize);
|
|
60131
|
+
buffer2 += decoder2.decode(chunk, { stream: true });
|
|
60132
|
+
const newLines = buffer2.split("\n");
|
|
60133
|
+
buffer2 = newLines.pop() || "";
|
|
60134
|
+
lines.push(...newLines);
|
|
60135
|
+
bytesRead += readSize;
|
|
60136
|
+
if (lines.length >= numLines) break;
|
|
60137
|
+
}
|
|
60138
|
+
if (buffer2 && lines.length < numLines) {
|
|
60139
|
+
lines.push(buffer2);
|
|
60140
|
+
}
|
|
60141
|
+
const output2 = lines.slice(0, numLines).join("\n");
|
|
60142
|
+
if (output2) {
|
|
60143
|
+
await writer.write(new TextEncoder().encode(output2 + "\n"));
|
|
60144
|
+
}
|
|
60145
|
+
} else {
|
|
60146
|
+
const device = await shell.context.fs.promises.open(fullPath);
|
|
60147
|
+
const decoder2 = new TextDecoder();
|
|
60148
|
+
const lines = [];
|
|
60149
|
+
let buffer2 = "";
|
|
60150
|
+
const chunkSize = 1024;
|
|
60151
|
+
const data = new Uint8Array(chunkSize);
|
|
60152
|
+
let bytesRead = 0;
|
|
60153
|
+
do {
|
|
60154
|
+
if (interrupted) break;
|
|
60155
|
+
const result = await device.read(data);
|
|
60156
|
+
bytesRead = result.bytesRead;
|
|
60157
|
+
if (bytesRead > 0) {
|
|
60158
|
+
buffer2 += decoder2.decode(data.subarray(0, bytesRead), { stream: true });
|
|
60159
|
+
const newLines = buffer2.split("\n");
|
|
60160
|
+
buffer2 = newLines.pop() || "";
|
|
60161
|
+
lines.push(...newLines);
|
|
60162
|
+
if (lines.length >= numLines) break;
|
|
60163
|
+
}
|
|
60164
|
+
} while (bytesRead > 0 && lines.length < numLines);
|
|
60165
|
+
if (buffer2 && lines.length < numLines) {
|
|
60166
|
+
lines.push(buffer2);
|
|
60167
|
+
}
|
|
60168
|
+
const output2 = lines.slice(0, numLines).join("\n");
|
|
60169
|
+
if (output2) {
|
|
60170
|
+
await writer.write(new TextEncoder().encode(output2 + "\n"));
|
|
60171
|
+
}
|
|
60172
|
+
}
|
|
60173
|
+
} finally {
|
|
60174
|
+
kernel.terminal.events.off(TerminalEvents.INTERRUPT, interruptHandler);
|
|
60175
|
+
}
|
|
60176
|
+
}
|
|
60177
|
+
return 0;
|
|
60178
|
+
} finally {
|
|
60179
|
+
writer.releaseLock();
|
|
60180
|
+
}
|
|
60181
|
+
}, "run")
|
|
60182
|
+
});
|
|
60183
|
+
}
|
|
60184
|
+
__name(createCommand$f, "createCommand$f");
|
|
60185
|
+
function createCommand$e(kernel, shell, terminal) {
|
|
59819
60186
|
return new TerminalCommand({
|
|
59820
60187
|
command: "ln",
|
|
59821
60188
|
description: "Create links between files",
|
|
@@ -59907,7 +60274,7 @@ function createCommand$c(kernel, shell, terminal) {
|
|
|
59907
60274
|
}, "run")
|
|
59908
60275
|
});
|
|
59909
60276
|
}
|
|
59910
|
-
__name(createCommand$
|
|
60277
|
+
__name(createCommand$e, "createCommand$e");
|
|
59911
60278
|
var humanFormat$2 = { exports: {} };
|
|
59912
60279
|
var humanFormat$1 = humanFormat$2.exports;
|
|
59913
60280
|
var hasRequiredHumanFormat;
|
|
@@ -60188,7 +60555,7 @@ function requireHumanFormat() {
|
|
|
60188
60555
|
__name(requireHumanFormat, "requireHumanFormat");
|
|
60189
60556
|
var humanFormatExports = requireHumanFormat();
|
|
60190
60557
|
const humanFormat = /* @__PURE__ */ getDefaultExportFromCjs(humanFormatExports);
|
|
60191
|
-
function createCommand$
|
|
60558
|
+
function createCommand$d(kernel, shell, terminal) {
|
|
60192
60559
|
return new TerminalCommand({
|
|
60193
60560
|
command: "ls",
|
|
60194
60561
|
description: "List directory contents",
|
|
@@ -60324,8 +60691,10 @@ function createCommand$b(kernel, shell, terminal) {
|
|
|
60324
60691
|
const linkInfo = getLinkInfo(file.linkTarget, file.linkStats, file.stats);
|
|
60325
60692
|
if (linkInfo) return linkInfo;
|
|
60326
60693
|
if (descriptions.has(path$1.resolve(fullPath, file.name))) return descriptions.get(path$1.resolve(fullPath, file.name));
|
|
60327
|
-
|
|
60328
|
-
|
|
60694
|
+
if (file.name.includes(".")) {
|
|
60695
|
+
const ext = file.name.split(".").pop();
|
|
60696
|
+
if (ext && descriptions.has("." + ext)) return descriptions.get("." + ext);
|
|
60697
|
+
}
|
|
60329
60698
|
if (!file.stats) return "";
|
|
60330
60699
|
if (file.stats.isBlockDevice() || file.stats.isCharacterDevice()) ;
|
|
60331
60700
|
return "";
|
|
@@ -60353,8 +60722,8 @@ function createCommand$b(kernel, shell, terminal) {
|
|
|
60353
60722
|
}, "run")
|
|
60354
60723
|
});
|
|
60355
60724
|
}
|
|
60356
|
-
__name(createCommand$
|
|
60357
|
-
function createCommand$
|
|
60725
|
+
__name(createCommand$d, "createCommand$d");
|
|
60726
|
+
function createCommand$c(kernel, shell, terminal) {
|
|
60358
60727
|
return new TerminalCommand({
|
|
60359
60728
|
command: "mkdir",
|
|
60360
60729
|
description: "Create a directory",
|
|
@@ -60373,8 +60742,8 @@ function createCommand$a(kernel, shell, terminal) {
|
|
|
60373
60742
|
}, "run")
|
|
60374
60743
|
});
|
|
60375
60744
|
}
|
|
60376
|
-
__name(createCommand$
|
|
60377
|
-
function createCommand$
|
|
60745
|
+
__name(createCommand$c, "createCommand$c");
|
|
60746
|
+
function createCommand$b(kernel, shell, terminal) {
|
|
60378
60747
|
return new TerminalCommand({
|
|
60379
60748
|
command: "mv",
|
|
60380
60749
|
description: "Move or rename files",
|
|
@@ -60413,8 +60782,8 @@ function createCommand$9(kernel, shell, terminal) {
|
|
|
60413
60782
|
}, "run")
|
|
60414
60783
|
});
|
|
60415
60784
|
}
|
|
60416
|
-
__name(createCommand$
|
|
60417
|
-
function createCommand$
|
|
60785
|
+
__name(createCommand$b, "createCommand$b");
|
|
60786
|
+
function createCommand$a(kernel, shell, terminal) {
|
|
60418
60787
|
return new TerminalCommand({
|
|
60419
60788
|
command: "pwd",
|
|
60420
60789
|
description: "Print the shell working directory",
|
|
@@ -60430,8 +60799,8 @@ function createCommand$8(kernel, shell, terminal) {
|
|
|
60430
60799
|
}, "run")
|
|
60431
60800
|
});
|
|
60432
60801
|
}
|
|
60433
|
-
__name(createCommand$
|
|
60434
|
-
function createCommand$
|
|
60802
|
+
__name(createCommand$a, "createCommand$a");
|
|
60803
|
+
function createCommand$9(kernel, shell, terminal) {
|
|
60435
60804
|
return new TerminalCommand({
|
|
60436
60805
|
command: "rm",
|
|
60437
60806
|
description: "Remove files or directories",
|
|
@@ -60451,8 +60820,8 @@ function createCommand$7(kernel, shell, terminal) {
|
|
|
60451
60820
|
}, "run")
|
|
60452
60821
|
});
|
|
60453
60822
|
}
|
|
60454
|
-
__name(createCommand$
|
|
60455
|
-
function createCommand$
|
|
60823
|
+
__name(createCommand$9, "createCommand$9");
|
|
60824
|
+
function createCommand$8(kernel, shell, terminal) {
|
|
60456
60825
|
return new TerminalCommand({
|
|
60457
60826
|
command: "rmdir",
|
|
60458
60827
|
description: "Remove a directory",
|
|
@@ -60471,7 +60840,7 @@ function createCommand$6(kernel, shell, terminal) {
|
|
|
60471
60840
|
}, "run")
|
|
60472
60841
|
});
|
|
60473
60842
|
}
|
|
60474
|
-
__name(createCommand$
|
|
60843
|
+
__name(createCommand$8, "createCommand$8");
|
|
60475
60844
|
const MAX_32_BITS = 4294967295;
|
|
60476
60845
|
const MAX_16_BITS = 65535;
|
|
60477
60846
|
const MAX_8_BITS = 255;
|
|
@@ -65266,7 +65635,7 @@ const table = {
|
|
|
65266
65635
|
return mimeTypes;
|
|
65267
65636
|
})();
|
|
65268
65637
|
t(configure);
|
|
65269
|
-
function createCommand$
|
|
65638
|
+
function createCommand$7(kernel, shell, terminal) {
|
|
65270
65639
|
return new TerminalCommand({
|
|
65271
65640
|
command: "stat",
|
|
65272
65641
|
description: "Display information about a file or directory",
|
|
@@ -65296,8 +65665,8 @@ function createCommand$5(kernel, shell, terminal) {
|
|
|
65296
65665
|
}, "run")
|
|
65297
65666
|
});
|
|
65298
65667
|
}
|
|
65299
|
-
__name(createCommand$
|
|
65300
|
-
function createCommand$
|
|
65668
|
+
__name(createCommand$7, "createCommand$7");
|
|
65669
|
+
function createCommand$6(kernel, shell, terminal) {
|
|
65301
65670
|
return new TerminalCommand({
|
|
65302
65671
|
command: "touch",
|
|
65303
65672
|
description: "Create an empty file",
|
|
@@ -65316,37 +65685,84 @@ function createCommand$4(kernel, shell, terminal) {
|
|
|
65316
65685
|
}, "run")
|
|
65317
65686
|
});
|
|
65318
65687
|
}
|
|
65319
|
-
__name(createCommand$
|
|
65320
|
-
function createCommand$
|
|
65688
|
+
__name(createCommand$6, "createCommand$6");
|
|
65689
|
+
function createCommand$5(kernel, shell, terminal) {
|
|
65321
65690
|
return new TerminalCommand({
|
|
65322
65691
|
command: "hex",
|
|
65323
|
-
description: "Display file contents in hexadecimal format",
|
|
65692
|
+
description: "Display file contents or stdin in hexadecimal format",
|
|
65324
65693
|
kernel,
|
|
65325
65694
|
shell,
|
|
65326
65695
|
terminal,
|
|
65327
65696
|
options: [
|
|
65328
65697
|
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
65329
|
-
{ name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, description: "The path to the file to display" }
|
|
65698
|
+
{ name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, description: "The path to the file to display (if omitted, reads from stdin)" }
|
|
65330
65699
|
],
|
|
65331
65700
|
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
65701
|
+
if (!process2) return 1;
|
|
65332
65702
|
const filePath = argv.path;
|
|
65333
|
-
|
|
65334
|
-
await writelnStderr(process2, terminal, "Usage: hex <file>");
|
|
65335
|
-
return 1;
|
|
65336
|
-
}
|
|
65337
|
-
const fullPath = path$1.resolve(shell.cwd, filePath);
|
|
65703
|
+
let data;
|
|
65338
65704
|
try {
|
|
65339
|
-
|
|
65340
|
-
|
|
65341
|
-
|
|
65342
|
-
|
|
65343
|
-
|
|
65344
|
-
|
|
65345
|
-
|
|
65346
|
-
|
|
65347
|
-
|
|
65705
|
+
if (!filePath) {
|
|
65706
|
+
if (!process2.stdin) {
|
|
65707
|
+
await writelnStderr(process2, terminal, "Usage: hex <file>");
|
|
65708
|
+
await writelnStderr(process2, terminal, " or: <command> | hex");
|
|
65709
|
+
return 1;
|
|
65710
|
+
}
|
|
65711
|
+
if (process2.stdinIsTTY) {
|
|
65712
|
+
await writelnStderr(process2, terminal, "Usage: hex <file>");
|
|
65713
|
+
await writelnStderr(process2, terminal, " or: <command> | hex");
|
|
65714
|
+
return 1;
|
|
65715
|
+
}
|
|
65716
|
+
const reader = process2.stdin.getReader();
|
|
65717
|
+
const chunks = [];
|
|
65718
|
+
try {
|
|
65719
|
+
const first = await reader.read();
|
|
65720
|
+
if (first.done && !first.value) {
|
|
65721
|
+
await writelnStderr(process2, terminal, "Usage: hex <file>");
|
|
65722
|
+
await writelnStderr(process2, terminal, " or: <command> | hex");
|
|
65723
|
+
return 1;
|
|
65724
|
+
}
|
|
65725
|
+
if (first.value) {
|
|
65726
|
+
chunks.push(first.value);
|
|
65727
|
+
}
|
|
65728
|
+
if (!first.done) {
|
|
65729
|
+
while (true) {
|
|
65730
|
+
const { done, value } = await reader.read();
|
|
65731
|
+
if (done) break;
|
|
65732
|
+
if (value) {
|
|
65733
|
+
chunks.push(value);
|
|
65734
|
+
}
|
|
65735
|
+
}
|
|
65736
|
+
}
|
|
65737
|
+
} finally {
|
|
65738
|
+
reader.releaseLock();
|
|
65739
|
+
}
|
|
65740
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
65741
|
+
if (totalLength === 0) {
|
|
65742
|
+
await writelnStderr(process2, terminal, "Usage: hex <file>");
|
|
65743
|
+
await writelnStderr(process2, terminal, " or: <command> | hex");
|
|
65744
|
+
return 1;
|
|
65745
|
+
}
|
|
65746
|
+
data = new Uint8Array(totalLength);
|
|
65747
|
+
let offset = 0;
|
|
65748
|
+
for (const chunk of chunks) {
|
|
65749
|
+
data.set(chunk, offset);
|
|
65750
|
+
offset += chunk.length;
|
|
65751
|
+
}
|
|
65752
|
+
} else {
|
|
65753
|
+
const fullPath = path$1.resolve(shell.cwd, filePath);
|
|
65754
|
+
const exists2 = await shell.context.fs.promises.exists(fullPath);
|
|
65755
|
+
if (!exists2) {
|
|
65756
|
+
await writelnStderr(process2, terminal, `hex: ${filePath}: No such file or directory`);
|
|
65757
|
+
return 1;
|
|
65758
|
+
}
|
|
65759
|
+
const stats = await shell.context.fs.promises.stat(fullPath);
|
|
65760
|
+
if (stats.isDirectory()) {
|
|
65761
|
+
await writelnStderr(process2, terminal, `hex: ${filePath}: Is a directory`);
|
|
65762
|
+
return 1;
|
|
65763
|
+
}
|
|
65764
|
+
data = await shell.context.fs.promises.readFile(fullPath);
|
|
65348
65765
|
}
|
|
65349
|
-
const data = await shell.context.fs.promises.readFile(fullPath);
|
|
65350
65766
|
const bytesPerLine = 16;
|
|
65351
65767
|
for (let offset = 0; offset < data.length; offset += bytesPerLine) {
|
|
65352
65768
|
const lineBytes = data.slice(offset, offset + bytesPerLine);
|
|
@@ -65383,13 +65799,14 @@ function createCommand$3(kernel, shell, terminal) {
|
|
|
65383
65799
|
}
|
|
65384
65800
|
return 0;
|
|
65385
65801
|
} catch (error) {
|
|
65386
|
-
|
|
65802
|
+
const errorPath = filePath || "stdin";
|
|
65803
|
+
await writelnStderr(process2, terminal, `hex: ${errorPath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
65387
65804
|
return 1;
|
|
65388
65805
|
}
|
|
65389
65806
|
}, "run")
|
|
65390
65807
|
});
|
|
65391
65808
|
}
|
|
65392
|
-
__name(createCommand$
|
|
65809
|
+
__name(createCommand$5, "createCommand$5");
|
|
65393
65810
|
const csi = "\x1B[";
|
|
65394
65811
|
const ansi = {};
|
|
65395
65812
|
ansi.style = {
|
|
@@ -65567,7 +65984,7 @@ ansi.erase = {
|
|
|
65567
65984
|
return csi + (n || 0) + "K";
|
|
65568
65985
|
}, "inLine")
|
|
65569
65986
|
};
|
|
65570
|
-
function createCommand$
|
|
65987
|
+
function createCommand$4(kernel, shell, terminal) {
|
|
65571
65988
|
return new TerminalCommand({
|
|
65572
65989
|
command: "less",
|
|
65573
65990
|
description: "View file contents interactively",
|
|
@@ -65730,7 +66147,182 @@ function createCommand$2(kernel, shell, terminal) {
|
|
|
65730
66147
|
}, "run")
|
|
65731
66148
|
});
|
|
65732
66149
|
}
|
|
65733
|
-
__name(createCommand$
|
|
66150
|
+
__name(createCommand$4, "createCommand$4");
|
|
66151
|
+
function createCommand$3(kernel, shell, terminal) {
|
|
66152
|
+
return new TerminalCommand({
|
|
66153
|
+
command: "passkey",
|
|
66154
|
+
description: "Manage passkey credentials for WebAuthn authentication",
|
|
66155
|
+
kernel,
|
|
66156
|
+
shell,
|
|
66157
|
+
terminal,
|
|
66158
|
+
options: [
|
|
66159
|
+
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
66160
|
+
{ name: "subcommand", type: String, defaultOption: true, description: "Subcommand: register, list, remove, remove-all" },
|
|
66161
|
+
{ name: "name", type: String, description: "Name/description for the passkey (used with register)" },
|
|
66162
|
+
{ name: "id", type: String, description: "Passkey ID to remove (used with remove)" }
|
|
66163
|
+
],
|
|
66164
|
+
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
66165
|
+
if (!process2) return 1;
|
|
66166
|
+
const currentUid = shell.credentials.uid;
|
|
66167
|
+
const user2 = kernel.users.get(currentUid);
|
|
66168
|
+
if (!user2) {
|
|
66169
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: Current user not found"));
|
|
66170
|
+
return 1;
|
|
66171
|
+
}
|
|
66172
|
+
const subcommand = argv.subcommand?.toLowerCase();
|
|
66173
|
+
if (!subcommand || subcommand === "help" || argv.help) {
|
|
66174
|
+
await writelnStdout(process2, terminal, "Usage: passkey <subcommand> [options]");
|
|
66175
|
+
await writelnStdout(process2, terminal, "");
|
|
66176
|
+
await writelnStdout(process2, terminal, "Subcommands:");
|
|
66177
|
+
await writelnStdout(process2, terminal, " register [--name <name>] Register a new passkey");
|
|
66178
|
+
await writelnStdout(process2, terminal, " list List all registered passkeys");
|
|
66179
|
+
await writelnStdout(process2, terminal, " remove --id <id> Remove a specific passkey");
|
|
66180
|
+
await writelnStdout(process2, terminal, " remove-all Remove all passkeys");
|
|
66181
|
+
return 0;
|
|
66182
|
+
}
|
|
66183
|
+
try {
|
|
66184
|
+
switch (subcommand) {
|
|
66185
|
+
case "register": {
|
|
66186
|
+
if (!kernel.auth.passkey.isSupported()) {
|
|
66187
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: WebAuthn is not supported in this browser"));
|
|
66188
|
+
return 1;
|
|
66189
|
+
}
|
|
66190
|
+
const name = argv.name || void 0;
|
|
66191
|
+
const username = user2.username;
|
|
66192
|
+
const userId = new TextEncoder().encode(username);
|
|
66193
|
+
const challenge = crypto.getRandomValues(new Uint8Array(32));
|
|
66194
|
+
const rpId = globalThis.location.hostname || "localhost";
|
|
66195
|
+
const createOptions = {
|
|
66196
|
+
challenge,
|
|
66197
|
+
rp: {
|
|
66198
|
+
name: kernel.name || "ecmaOS",
|
|
66199
|
+
id: rpId
|
|
66200
|
+
},
|
|
66201
|
+
user: {
|
|
66202
|
+
id: userId,
|
|
66203
|
+
name: username,
|
|
66204
|
+
displayName: username
|
|
66205
|
+
},
|
|
66206
|
+
pubKeyCredParams: [
|
|
66207
|
+
{ type: "public-key", alg: -7 },
|
|
66208
|
+
{ type: "public-key", alg: -257 }
|
|
66209
|
+
],
|
|
66210
|
+
authenticatorSelection: {
|
|
66211
|
+
userVerification: "preferred"
|
|
66212
|
+
},
|
|
66213
|
+
timeout: 6e4
|
|
66214
|
+
};
|
|
66215
|
+
await writelnStdout(process2, terminal, chalk$1.yellow("Please interact with your authenticator to register a passkey..."));
|
|
66216
|
+
const credential = await kernel.auth.passkey.create(createOptions);
|
|
66217
|
+
if (!credential || !(credential instanceof PublicKeyCredential)) {
|
|
66218
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: Failed to create passkey. Registration cancelled or failed."));
|
|
66219
|
+
return 1;
|
|
66220
|
+
}
|
|
66221
|
+
const publicKeyCredential = credential;
|
|
66222
|
+
const response = publicKeyCredential.response;
|
|
66223
|
+
const credentialId = btoa(String.fromCharCode(...new Uint8Array(publicKeyCredential.rawId)));
|
|
66224
|
+
let publicKeyArray;
|
|
66225
|
+
try {
|
|
66226
|
+
if (typeof response.getPublicKey === "function") {
|
|
66227
|
+
try {
|
|
66228
|
+
const publicKeyCrypto = response.getPublicKey();
|
|
66229
|
+
if (publicKeyCrypto && publicKeyCrypto instanceof CryptoKey) {
|
|
66230
|
+
const publicKeyJwk = await crypto.subtle.exportKey("jwk", publicKeyCrypto);
|
|
66231
|
+
publicKeyArray = new TextEncoder().encode(JSON.stringify(publicKeyJwk));
|
|
66232
|
+
} else {
|
|
66233
|
+
throw new Error("getPublicKey() did not return a valid CryptoKey");
|
|
66234
|
+
}
|
|
66235
|
+
} catch (exportError) {
|
|
66236
|
+
await writelnStderr(process2, terminal, chalk$1.yellow(`Warning: Could not extract public key via getPublicKey(): ${exportError instanceof Error ? exportError.message : String(exportError)}. Using attestationObject instead.`));
|
|
66237
|
+
const attestationObject = response.attestationObject;
|
|
66238
|
+
publicKeyArray = new Uint8Array(attestationObject);
|
|
66239
|
+
}
|
|
66240
|
+
} else {
|
|
66241
|
+
const attestationObject = response.attestationObject;
|
|
66242
|
+
publicKeyArray = new Uint8Array(attestationObject);
|
|
66243
|
+
}
|
|
66244
|
+
} catch (error) {
|
|
66245
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error processing credential data: ${error instanceof Error ? error.message : String(error)}`));
|
|
66246
|
+
return 1;
|
|
66247
|
+
}
|
|
66248
|
+
const passkey = {
|
|
66249
|
+
id: crypto.randomUUID(),
|
|
66250
|
+
credentialId,
|
|
66251
|
+
publicKey: publicKeyArray,
|
|
66252
|
+
createdAt: Date.now(),
|
|
66253
|
+
name
|
|
66254
|
+
};
|
|
66255
|
+
await kernel.users.addPasskey(currentUid, passkey);
|
|
66256
|
+
await writelnStdout(process2, terminal, chalk$1.green(`Passkey registered successfully${name ? `: ${name}` : ""}`));
|
|
66257
|
+
await writelnStdout(process2, terminal, `Passkey ID: ${passkey.id}`);
|
|
66258
|
+
return 0;
|
|
66259
|
+
}
|
|
66260
|
+
case "list": {
|
|
66261
|
+
const passkeys = await kernel.users.getPasskeys(currentUid);
|
|
66262
|
+
if (passkeys.length === 0) {
|
|
66263
|
+
await writelnStdout(process2, terminal, "No passkeys registered for this user.");
|
|
66264
|
+
return 0;
|
|
66265
|
+
}
|
|
66266
|
+
await writelnStdout(process2, terminal, `Registered passkeys (${passkeys.length}):`);
|
|
66267
|
+
await writelnStdout(process2, terminal, "");
|
|
66268
|
+
for (const pk of passkeys) {
|
|
66269
|
+
const createdDate = new Date(pk.createdAt).toLocaleString();
|
|
66270
|
+
const lastUsedDate = pk.lastUsed ? new Date(pk.lastUsed).toLocaleString() : "Never";
|
|
66271
|
+
await writelnStdout(process2, terminal, ` ID: ${pk.id}`);
|
|
66272
|
+
if (pk.name) {
|
|
66273
|
+
await writelnStdout(process2, terminal, ` Name: ${pk.name}`);
|
|
66274
|
+
}
|
|
66275
|
+
await writelnStdout(process2, terminal, ` Created: ${createdDate}`);
|
|
66276
|
+
await writelnStdout(process2, terminal, ` Last used: ${lastUsedDate}`);
|
|
66277
|
+
await writelnStdout(process2, terminal, "");
|
|
66278
|
+
}
|
|
66279
|
+
return 0;
|
|
66280
|
+
}
|
|
66281
|
+
case "remove": {
|
|
66282
|
+
const id = argv.id;
|
|
66283
|
+
if (!id) {
|
|
66284
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: --id is required for remove command"));
|
|
66285
|
+
await writelnStdout(process2, terminal, "Usage: passkey remove --id <id>");
|
|
66286
|
+
return 1;
|
|
66287
|
+
}
|
|
66288
|
+
const passkeys = await kernel.users.getPasskeys(currentUid);
|
|
66289
|
+
const passkey = passkeys.find((pk) => pk.id === id);
|
|
66290
|
+
if (!passkey) {
|
|
66291
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error: Passkey with ID ${id} not found`));
|
|
66292
|
+
return 1;
|
|
66293
|
+
}
|
|
66294
|
+
await kernel.users.removePasskey(currentUid, id);
|
|
66295
|
+
await writelnStdout(process2, terminal, chalk$1.green(`Passkey removed successfully${passkey.name ? `: ${passkey.name}` : ""}`));
|
|
66296
|
+
return 0;
|
|
66297
|
+
}
|
|
66298
|
+
case "remove-all": {
|
|
66299
|
+
const passkeys = await kernel.users.getPasskeys(currentUid);
|
|
66300
|
+
if (passkeys.length === 0) {
|
|
66301
|
+
await writelnStdout(process2, terminal, "No passkeys to remove.");
|
|
66302
|
+
return 0;
|
|
66303
|
+
}
|
|
66304
|
+
await kernel.users.savePasskeys(currentUid, []);
|
|
66305
|
+
const passkeysPath = `${user2.home}/.passkeys`;
|
|
66306
|
+
try {
|
|
66307
|
+
await kernel.filesystem.fs.unlink(passkeysPath);
|
|
66308
|
+
} catch {
|
|
66309
|
+
}
|
|
66310
|
+
await writelnStdout(process2, terminal, chalk$1.green(`Removed ${passkeys.length} passkey(s)`));
|
|
66311
|
+
return 0;
|
|
66312
|
+
}
|
|
66313
|
+
default:
|
|
66314
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error: Unknown subcommand: ${subcommand}`));
|
|
66315
|
+
await writelnStdout(process2, terminal, 'Run "passkey help" for usage information');
|
|
66316
|
+
return 1;
|
|
66317
|
+
}
|
|
66318
|
+
} catch (error) {
|
|
66319
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
66320
|
+
return 1;
|
|
66321
|
+
}
|
|
66322
|
+
}, "run")
|
|
66323
|
+
});
|
|
66324
|
+
}
|
|
66325
|
+
__name(createCommand$3, "createCommand$3");
|
|
65734
66326
|
function parseSedExpression(expr) {
|
|
65735
66327
|
expr = expr.trim();
|
|
65736
66328
|
const substituteMatch = expr.match(/^(\d+)?(,(\d+|\$))?s\/(.+?)\/(.*?)\/([gip]*\d*)$/);
|
|
@@ -65893,7 +66485,7 @@ function applySedCommand(line3, lineNum, totalLines, command) {
|
|
|
65893
66485
|
return { result: line3, shouldPrint: false };
|
|
65894
66486
|
}
|
|
65895
66487
|
__name(applySedCommand, "applySedCommand");
|
|
65896
|
-
function createCommand$
|
|
66488
|
+
function createCommand$2(kernel, shell, terminal) {
|
|
65897
66489
|
return new TerminalCommand({
|
|
65898
66490
|
command: "sed",
|
|
65899
66491
|
description: "Stream editor for filtering and transforming text",
|
|
@@ -66088,8 +66680,8 @@ function createCommand$1(kernel, shell, terminal) {
|
|
|
66088
66680
|
}, "run")
|
|
66089
66681
|
});
|
|
66090
66682
|
}
|
|
66091
|
-
__name(createCommand$
|
|
66092
|
-
function createCommand(kernel, shell, terminal) {
|
|
66683
|
+
__name(createCommand$2, "createCommand$2");
|
|
66684
|
+
function createCommand$1(kernel, shell, terminal) {
|
|
66093
66685
|
return new TerminalCommand({
|
|
66094
66686
|
command: "tee",
|
|
66095
66687
|
description: "Read from standard input and write to standard output and files",
|
|
@@ -66165,27 +66757,173 @@ function createCommand(kernel, shell, terminal) {
|
|
|
66165
66757
|
}, "run")
|
|
66166
66758
|
});
|
|
66167
66759
|
}
|
|
66760
|
+
__name(createCommand$1, "createCommand$1");
|
|
66761
|
+
function createCommand(kernel, shell, terminal) {
|
|
66762
|
+
return new TerminalCommand({
|
|
66763
|
+
command: "tail",
|
|
66764
|
+
description: "Print the last lines of files",
|
|
66765
|
+
kernel,
|
|
66766
|
+
shell,
|
|
66767
|
+
terminal,
|
|
66768
|
+
options: [
|
|
66769
|
+
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
66770
|
+
{ name: "lines", type: Number, alias: "n", description: "Print the last NUM lines instead of the last 10" },
|
|
66771
|
+
{ name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, multiple: true, description: "The path(s) to the file(s) to read" }
|
|
66772
|
+
],
|
|
66773
|
+
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
66774
|
+
if (!process2) return 1;
|
|
66775
|
+
const writer = process2.stdout.getWriter();
|
|
66776
|
+
const numLines = argv.lines ?? 10;
|
|
66777
|
+
try {
|
|
66778
|
+
if (!argv.path || !argv.path[0]) {
|
|
66779
|
+
if (!process2.stdin) {
|
|
66780
|
+
return 0;
|
|
66781
|
+
}
|
|
66782
|
+
const reader = process2.stdin.getReader();
|
|
66783
|
+
const decoder2 = new TextDecoder();
|
|
66784
|
+
const lines = [];
|
|
66785
|
+
let buffer2 = "";
|
|
66786
|
+
try {
|
|
66787
|
+
while (true) {
|
|
66788
|
+
let readResult;
|
|
66789
|
+
try {
|
|
66790
|
+
readResult = await reader.read();
|
|
66791
|
+
} catch (error) {
|
|
66792
|
+
if (error instanceof Error) {
|
|
66793
|
+
throw error;
|
|
66794
|
+
}
|
|
66795
|
+
break;
|
|
66796
|
+
}
|
|
66797
|
+
const { done, value } = readResult;
|
|
66798
|
+
if (done) {
|
|
66799
|
+
buffer2 += decoder2.decode();
|
|
66800
|
+
break;
|
|
66801
|
+
}
|
|
66802
|
+
if (value) {
|
|
66803
|
+
buffer2 += decoder2.decode(value, { stream: true });
|
|
66804
|
+
const newLines = buffer2.split("\n");
|
|
66805
|
+
buffer2 = newLines.pop() || "";
|
|
66806
|
+
lines.push(...newLines);
|
|
66807
|
+
}
|
|
66808
|
+
}
|
|
66809
|
+
if (buffer2) {
|
|
66810
|
+
lines.push(buffer2);
|
|
66811
|
+
}
|
|
66812
|
+
} finally {
|
|
66813
|
+
try {
|
|
66814
|
+
reader.releaseLock();
|
|
66815
|
+
} catch {
|
|
66816
|
+
}
|
|
66817
|
+
}
|
|
66818
|
+
const output2 = lines.slice(-numLines).join("\n");
|
|
66819
|
+
if (output2) {
|
|
66820
|
+
await writer.write(new TextEncoder().encode(output2 + "\n"));
|
|
66821
|
+
}
|
|
66822
|
+
return 0;
|
|
66823
|
+
}
|
|
66824
|
+
const files = argv.path || [];
|
|
66825
|
+
const isMultipleFiles = files.length > 1;
|
|
66826
|
+
for (let i = 0; i < files.length; i++) {
|
|
66827
|
+
const file = files[i];
|
|
66828
|
+
if (!file) continue;
|
|
66829
|
+
const fullPath = path$1.resolve(shell.cwd, file);
|
|
66830
|
+
if (isMultipleFiles) {
|
|
66831
|
+
const header = i > 0 ? "\n" : "";
|
|
66832
|
+
await writer.write(new TextEncoder().encode(`${header}==> ${file} <==
|
|
66833
|
+
`));
|
|
66834
|
+
}
|
|
66835
|
+
let interrupted = false;
|
|
66836
|
+
const interruptHandler = /* @__PURE__ */ __name(() => {
|
|
66837
|
+
interrupted = true;
|
|
66838
|
+
}, "interruptHandler");
|
|
66839
|
+
kernel.terminal.events.on(TerminalEvents.INTERRUPT, interruptHandler);
|
|
66840
|
+
try {
|
|
66841
|
+
if (!fullPath.startsWith("/dev")) {
|
|
66842
|
+
const handle = await shell.context.fs.promises.open(fullPath, "r");
|
|
66843
|
+
const stat2 = await shell.context.fs.promises.stat(fullPath);
|
|
66844
|
+
const decoder2 = new TextDecoder();
|
|
66845
|
+
let buffer2 = "";
|
|
66846
|
+
let bytesRead = 0;
|
|
66847
|
+
const chunkSize = 1024;
|
|
66848
|
+
while (bytesRead < stat2.size) {
|
|
66849
|
+
if (interrupted) break;
|
|
66850
|
+
const data = new Uint8Array(chunkSize);
|
|
66851
|
+
const readSize = Math.min(chunkSize, stat2.size - bytesRead);
|
|
66852
|
+
await handle.read(data, 0, readSize, bytesRead);
|
|
66853
|
+
const chunk = data.subarray(0, readSize);
|
|
66854
|
+
buffer2 += decoder2.decode(chunk, { stream: true });
|
|
66855
|
+
bytesRead += readSize;
|
|
66856
|
+
}
|
|
66857
|
+
const lines = buffer2.split("\n");
|
|
66858
|
+
if (lines[lines.length - 1] === "") {
|
|
66859
|
+
lines.pop();
|
|
66860
|
+
}
|
|
66861
|
+
const output2 = lines.slice(-numLines).join("\n");
|
|
66862
|
+
if (output2) {
|
|
66863
|
+
await writer.write(new TextEncoder().encode(output2 + "\n"));
|
|
66864
|
+
}
|
|
66865
|
+
} else {
|
|
66866
|
+
const device = await shell.context.fs.promises.open(fullPath);
|
|
66867
|
+
const decoder2 = new TextDecoder();
|
|
66868
|
+
const lines = [];
|
|
66869
|
+
let buffer2 = "";
|
|
66870
|
+
const chunkSize = 1024;
|
|
66871
|
+
const data = new Uint8Array(chunkSize);
|
|
66872
|
+
let bytesRead = 0;
|
|
66873
|
+
do {
|
|
66874
|
+
if (interrupted) break;
|
|
66875
|
+
const result = await device.read(data);
|
|
66876
|
+
bytesRead = result.bytesRead;
|
|
66877
|
+
if (bytesRead > 0) {
|
|
66878
|
+
buffer2 += decoder2.decode(data.subarray(0, bytesRead), { stream: true });
|
|
66879
|
+
}
|
|
66880
|
+
} while (bytesRead > 0);
|
|
66881
|
+
const allLines = buffer2.split("\n");
|
|
66882
|
+
if (allLines[allLines.length - 1] === "") {
|
|
66883
|
+
allLines.pop();
|
|
66884
|
+
}
|
|
66885
|
+
lines.push(...allLines);
|
|
66886
|
+
const output2 = lines.slice(-numLines).join("\n");
|
|
66887
|
+
if (output2) {
|
|
66888
|
+
await writer.write(new TextEncoder().encode(output2 + "\n"));
|
|
66889
|
+
}
|
|
66890
|
+
}
|
|
66891
|
+
} finally {
|
|
66892
|
+
kernel.terminal.events.off(TerminalEvents.INTERRUPT, interruptHandler);
|
|
66893
|
+
}
|
|
66894
|
+
}
|
|
66895
|
+
return 0;
|
|
66896
|
+
} finally {
|
|
66897
|
+
writer.releaseLock();
|
|
66898
|
+
}
|
|
66899
|
+
}, "run")
|
|
66900
|
+
});
|
|
66901
|
+
}
|
|
66168
66902
|
__name(createCommand, "createCommand");
|
|
66169
66903
|
function createAllCommands(kernel, shell, terminal) {
|
|
66170
66904
|
return {
|
|
66171
|
-
cat: createCommand$
|
|
66172
|
-
cd: createCommand$
|
|
66173
|
-
chmod: createCommand$
|
|
66174
|
-
cp: createCommand$
|
|
66175
|
-
echo: createCommand$
|
|
66176
|
-
|
|
66177
|
-
|
|
66178
|
-
|
|
66179
|
-
|
|
66180
|
-
|
|
66181
|
-
|
|
66182
|
-
|
|
66183
|
-
|
|
66184
|
-
|
|
66185
|
-
|
|
66186
|
-
|
|
66187
|
-
|
|
66188
|
-
|
|
66905
|
+
cat: createCommand$l(kernel, shell, terminal),
|
|
66906
|
+
cd: createCommand$k(kernel, shell, terminal),
|
|
66907
|
+
chmod: createCommand$j(kernel, shell, terminal),
|
|
66908
|
+
cp: createCommand$i(kernel, shell, terminal),
|
|
66909
|
+
echo: createCommand$h(kernel, shell, terminal),
|
|
66910
|
+
grep: createCommand$g(kernel, shell, terminal),
|
|
66911
|
+
head: createCommand$f(kernel, shell, terminal),
|
|
66912
|
+
ln: createCommand$e(kernel, shell, terminal),
|
|
66913
|
+
ls: createCommand$d(kernel, shell, terminal),
|
|
66914
|
+
mkdir: createCommand$c(kernel, shell, terminal),
|
|
66915
|
+
mv: createCommand$b(kernel, shell, terminal),
|
|
66916
|
+
pwd: createCommand$a(kernel, shell, terminal),
|
|
66917
|
+
rm: createCommand$9(kernel, shell, terminal),
|
|
66918
|
+
rmdir: createCommand$8(kernel, shell, terminal),
|
|
66919
|
+
stat: createCommand$7(kernel, shell, terminal),
|
|
66920
|
+
touch: createCommand$6(kernel, shell, terminal),
|
|
66921
|
+
hex: createCommand$5(kernel, shell, terminal),
|
|
66922
|
+
less: createCommand$4(kernel, shell, terminal),
|
|
66923
|
+
passkey: createCommand$3(kernel, shell, terminal),
|
|
66924
|
+
sed: createCommand$2(kernel, shell, terminal),
|
|
66925
|
+
tail: createCommand(kernel, shell, terminal),
|
|
66926
|
+
tee: createCommand$1(kernel, shell, terminal)
|
|
66189
66927
|
};
|
|
66190
66928
|
}
|
|
66191
66929
|
__name(createAllCommands, "createAllCommands");
|
|
@@ -66289,7 +67027,7 @@ const TerminalCommands = /* @__PURE__ */ __name((kernel, shell, terminal) => {
|
|
|
66289
67027
|
{ name: "reinstall", type: Boolean, description: "Reinstall the package if it is already installed" }
|
|
66290
67028
|
],
|
|
66291
67029
|
run: /* @__PURE__ */ __name(async (argv) => {
|
|
66292
|
-
const { default: install } = await import("./install-
|
|
67030
|
+
const { default: install } = await import("./install-vHqmAl7t.js");
|
|
66293
67031
|
return await install({ kernel, shell, terminal, args: [argv.package, argv.registry, argv.reinstall] });
|
|
66294
67032
|
}, "run")
|
|
66295
67033
|
}),
|
|
@@ -66304,7 +67042,7 @@ const TerminalCommands = /* @__PURE__ */ __name((kernel, shell, terminal) => {
|
|
|
66304
67042
|
{ name: "package", type: String, typeLabel: "{underline package}", defaultOption: true, description: "The package name and optional version (e.g. package@1.0.0). If no version is specified, all versions will be uninstalled." }
|
|
66305
67043
|
],
|
|
66306
67044
|
run: /* @__PURE__ */ __name(async (argv) => {
|
|
66307
|
-
const { default: uninstall } = await import("./uninstall-
|
|
67045
|
+
const { default: uninstall } = await import("./uninstall-Ds11Scu8.js");
|
|
66308
67046
|
return await uninstall({ kernel, shell, terminal, args: [argv.package] });
|
|
66309
67047
|
}, "run")
|
|
66310
67048
|
}),
|
|
@@ -66675,7 +67413,6 @@ const fetch$1 = /* @__PURE__ */ __name(async ({ shell, terminal, process: proces
|
|
|
66675
67413
|
} finally {
|
|
66676
67414
|
reader.releaseLock();
|
|
66677
67415
|
writer?.releaseLock();
|
|
66678
|
-
await writeStdout(process2, terminal, "\n");
|
|
66679
67416
|
}
|
|
66680
67417
|
return 0;
|
|
66681
67418
|
} catch (error) {
|
|
@@ -67545,11 +68282,14 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
|
|
|
67545
68282
|
async readline(prompt = "", hide = false, noListen = false) {
|
|
67546
68283
|
let input = "";
|
|
67547
68284
|
let cursor = 0;
|
|
67548
|
-
|
|
68285
|
+
const wasListening = this._keyListener !== void 0;
|
|
68286
|
+
this.unlisten();
|
|
67549
68287
|
this.write(prompt);
|
|
67550
68288
|
this.focus();
|
|
67551
68289
|
const result = await new Promise((resolve2) => {
|
|
67552
68290
|
const disposable = this.onKey(({ domEvent }) => {
|
|
68291
|
+
domEvent.preventDefault();
|
|
68292
|
+
domEvent.stopPropagation();
|
|
67553
68293
|
switch (domEvent.key) {
|
|
67554
68294
|
case "Enter":
|
|
67555
68295
|
disposable.dispose();
|
|
@@ -67557,18 +68297,24 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
|
|
|
67557
68297
|
resolve2(input);
|
|
67558
68298
|
break;
|
|
67559
68299
|
case "ArrowLeft":
|
|
67560
|
-
|
|
67561
|
-
|
|
68300
|
+
if (cursor > 0) {
|
|
68301
|
+
this.write(ansi$7.cursor.back());
|
|
68302
|
+
cursor--;
|
|
68303
|
+
}
|
|
67562
68304
|
break;
|
|
67563
68305
|
case "ArrowRight":
|
|
67564
|
-
|
|
67565
|
-
|
|
68306
|
+
if (cursor < input.length) {
|
|
68307
|
+
this.write(ansi$7.cursor.forward());
|
|
68308
|
+
cursor++;
|
|
68309
|
+
}
|
|
67566
68310
|
break;
|
|
67567
68311
|
case "Home":
|
|
67568
|
-
this.write(ansi$7.cursor.horizontalAbsolute(0));
|
|
68312
|
+
this.write(ansi$7.cursor.horizontalAbsolute(prompt.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length + 1));
|
|
68313
|
+
cursor = 0;
|
|
67569
68314
|
break;
|
|
67570
68315
|
case "End":
|
|
67571
|
-
this.write(ansi$7.cursor.horizontalAbsolute(input.length));
|
|
68316
|
+
this.write(ansi$7.cursor.horizontalAbsolute(prompt.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length + input.length + 1));
|
|
68317
|
+
cursor = input.length;
|
|
67572
68318
|
break;
|
|
67573
68319
|
case "Escape":
|
|
67574
68320
|
disposable.dispose();
|
|
@@ -67577,19 +68323,35 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
|
|
|
67577
68323
|
case "Backspace":
|
|
67578
68324
|
if (cursor > 0) {
|
|
67579
68325
|
input = input.slice(0, cursor - 1) + input.slice(cursor);
|
|
67580
|
-
|
|
68326
|
+
const promptLen = prompt.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length;
|
|
68327
|
+
this.write(ansi$7.cursor.horizontalAbsolute(promptLen + 1) + ansi$7.erase.inLine(0) + input);
|
|
68328
|
+
if (cursor < input.length + 1) {
|
|
68329
|
+
this.write(`\x1B[${input.length + 1 - cursor}D`);
|
|
68330
|
+
}
|
|
67581
68331
|
cursor--;
|
|
67582
68332
|
} else this.write("\x07");
|
|
67583
68333
|
break;
|
|
67584
68334
|
case "Delete":
|
|
67585
|
-
if (cursor < input.length)
|
|
68335
|
+
if (cursor < input.length) {
|
|
68336
|
+
input = input.slice(0, cursor) + input.slice(cursor + 1);
|
|
68337
|
+
this.write(ansi$7.erase.inLine(0) + input.slice(cursor));
|
|
68338
|
+
if (input.length - cursor > 0) {
|
|
68339
|
+
this.write(`\x1B[${input.length - cursor}D`);
|
|
68340
|
+
}
|
|
68341
|
+
}
|
|
67586
68342
|
break;
|
|
67587
68343
|
default:
|
|
67588
68344
|
if (domEvent.key.length === 1 && !domEvent.ctrlKey && !domEvent.metaKey && !domEvent.altKey) {
|
|
67589
68345
|
const charCode = domEvent.key.charCodeAt(0);
|
|
67590
68346
|
if (charCode >= 32 && charCode <= 126) {
|
|
67591
68347
|
input = input.slice(0, cursor) + domEvent.key + input.slice(cursor);
|
|
67592
|
-
if (!hide)
|
|
68348
|
+
if (!hide) {
|
|
68349
|
+
const promptLen = prompt.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length;
|
|
68350
|
+
this.write(ansi$7.cursor.horizontalAbsolute(promptLen + 1) + ansi$7.erase.inLine(0) + input);
|
|
68351
|
+
if (cursor < input.length - 1) {
|
|
68352
|
+
this.write(`\x1B[${input.length - cursor - 1}D`);
|
|
68353
|
+
}
|
|
68354
|
+
}
|
|
67593
68355
|
cursor++;
|
|
67594
68356
|
}
|
|
67595
68357
|
}
|
|
@@ -67598,7 +68360,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
|
|
|
67598
68360
|
if (cursor > input.length) cursor = input.length;
|
|
67599
68361
|
});
|
|
67600
68362
|
});
|
|
67601
|
-
if (!noListen) this.listen();
|
|
68363
|
+
if (wasListening && !noListen) this.listen();
|
|
67602
68364
|
return result;
|
|
67603
68365
|
}
|
|
67604
68366
|
spinner(spinner, prefix, suffix) {
|
|
@@ -67804,33 +68566,23 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
|
|
|
67804
68566
|
break;
|
|
67805
68567
|
case "Backspace":
|
|
67806
68568
|
if (this._cursorPosition > 0) {
|
|
67807
|
-
|
|
68569
|
+
const tail = this._cmd.slice(this._cursorPosition);
|
|
68570
|
+
this._cmd = this._cmd.slice(0, this._cursorPosition - 1) + tail;
|
|
67808
68571
|
this._cursorPosition--;
|
|
67809
|
-
this.write("\b");
|
|
67810
|
-
|
|
67811
|
-
|
|
68572
|
+
this.write("\b" + ansi$7.erase.inLine(0) + tail);
|
|
68573
|
+
if (tail.length > 0) {
|
|
68574
|
+
this.write(`\x1B[${tail.length}D`);
|
|
68575
|
+
}
|
|
67812
68576
|
} else this.write("\x07");
|
|
67813
68577
|
break;
|
|
67814
68578
|
case "Delete":
|
|
67815
68579
|
if (this._cursorPosition < this._cmd.length) {
|
|
67816
|
-
|
|
67817
|
-
this.
|
|
67818
|
-
|
|
67819
|
-
|
|
67820
|
-
|
|
67821
|
-
this.write("> " + parts[0] + chalk$2.gray("#" + parts.slice(1).join("#")));
|
|
67822
|
-
} else {
|
|
67823
|
-
this.write("> " + this._cmd);
|
|
67824
|
-
}
|
|
67825
|
-
} else {
|
|
67826
|
-
const parts = this._cmd.split("#");
|
|
67827
|
-
if (parts.length > 1) {
|
|
67828
|
-
this.write(this.prompt() + parts[0] + chalk$2.gray("#" + parts.slice(1).join("#")));
|
|
67829
|
-
} else {
|
|
67830
|
-
this.write(this.prompt() + this._cmd);
|
|
67831
|
-
}
|
|
68580
|
+
const tail = this._cmd.slice(this._cursorPosition + 1);
|
|
68581
|
+
this._cmd = this._cmd.slice(0, this._cursorPosition) + tail;
|
|
68582
|
+
this.write(ansi$7.erase.inLine(0) + tail);
|
|
68583
|
+
if (tail.length > 0) {
|
|
68584
|
+
this.write(`\x1B[${tail.length}D`);
|
|
67832
68585
|
}
|
|
67833
|
-
if (this._cursorPosition < this._cmd.length) this.write(`\x1B[${this._cmd.length - this._cursorPosition}D`);
|
|
67834
68586
|
}
|
|
67835
68587
|
break;
|
|
67836
68588
|
case "ArrowUp":
|
|
@@ -67933,25 +68685,18 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
|
|
|
67933
68685
|
default:
|
|
67934
68686
|
this._isTabCycling = false;
|
|
67935
68687
|
if (key.length === 1) {
|
|
68688
|
+
const wasAtEnd = this._cursorPosition === this._cmd.length;
|
|
67936
68689
|
this._cmd = this._cmd.slice(0, this._cursorPosition) + key + this._cmd.slice(this._cursorPosition);
|
|
67937
68690
|
this._cursorPosition++;
|
|
67938
|
-
|
|
67939
|
-
|
|
67940
|
-
const parts = this._cmd.split("#");
|
|
67941
|
-
if (parts.length > 1) {
|
|
67942
|
-
this.write("> " + parts[0] + chalk$2.gray("#" + parts.slice(1).join("#")));
|
|
67943
|
-
} else {
|
|
67944
|
-
this.write("> " + this._cmd);
|
|
67945
|
-
}
|
|
68691
|
+
if (wasAtEnd) {
|
|
68692
|
+
this.write(key);
|
|
67946
68693
|
} else {
|
|
67947
|
-
const
|
|
67948
|
-
|
|
67949
|
-
|
|
67950
|
-
|
|
67951
|
-
this.write(this.prompt() + this._cmd);
|
|
68694
|
+
const tail = this._cmd.slice(this._cursorPosition);
|
|
68695
|
+
this.write(key + tail);
|
|
68696
|
+
if (tail.length > 0) {
|
|
68697
|
+
this.write(`\x1B[${tail.length}D`);
|
|
67952
68698
|
}
|
|
67953
68699
|
}
|
|
67954
|
-
if (this._cursorPosition < this._cmd.length) this.write(`\x1B[${this._cmd.length - this._cursorPosition}D`);
|
|
67955
68700
|
}
|
|
67956
68701
|
}
|
|
67957
68702
|
}
|
|
@@ -70801,7 +71546,9 @@ const _Process = class _Process {
|
|
|
70801
71546
|
__publicField(this, "_status", "stopped");
|
|
70802
71547
|
__publicField(this, "_stderr");
|
|
70803
71548
|
__publicField(this, "_stdin");
|
|
71549
|
+
__publicField(this, "_stdinIsTTY");
|
|
70804
71550
|
__publicField(this, "_stdout");
|
|
71551
|
+
__publicField(this, "_stdoutIsTTY");
|
|
70805
71552
|
__publicField(this, "_terminal");
|
|
70806
71553
|
__publicField(this, "_uid");
|
|
70807
71554
|
__publicField(this, "_keepAlive", false);
|
|
@@ -70822,7 +71569,9 @@ const _Process = class _Process {
|
|
|
70822
71569
|
this._terminal = options.terminal || this.kernel.terminal;
|
|
70823
71570
|
this._uid = options.uid;
|
|
70824
71571
|
this._stdin = options.stdin || this.terminal.getInputStream();
|
|
71572
|
+
this._stdinIsTTY = options.stdinIsTTY ?? (options.stdin ? false : true);
|
|
70825
71573
|
this._stdout = options.stdout || this.terminal.stdout || new WritableStream();
|
|
71574
|
+
this._stdoutIsTTY = options.stdoutIsTTY ?? (options.stdout ? false : true);
|
|
70826
71575
|
this._stderr = options.stderr || this.terminal.stderr || new WritableStream();
|
|
70827
71576
|
this._fdtable = new FDTable(this._stdin, this._stdout, this._stderr);
|
|
70828
71577
|
this.kernel.processes.add(this);
|
|
@@ -70869,9 +71618,15 @@ const _Process = class _Process {
|
|
|
70869
71618
|
get stdin() {
|
|
70870
71619
|
return this._stdin;
|
|
70871
71620
|
}
|
|
71621
|
+
get stdinIsTTY() {
|
|
71622
|
+
return this._stdinIsTTY;
|
|
71623
|
+
}
|
|
70872
71624
|
get stdout() {
|
|
70873
71625
|
return this._stdout;
|
|
70874
71626
|
}
|
|
71627
|
+
get stdoutIsTTY() {
|
|
71628
|
+
return this._stdoutIsTTY;
|
|
71629
|
+
}
|
|
70875
71630
|
get terminal() {
|
|
70876
71631
|
return this._terminal;
|
|
70877
71632
|
}
|
|
@@ -70958,6 +71713,8 @@ const _Process = class _Process {
|
|
|
70958
71713
|
shell: this.shell,
|
|
70959
71714
|
terminal: this.terminal,
|
|
70960
71715
|
stdin: this._stdin,
|
|
71716
|
+
stdinIsTTY: this._stdinIsTTY,
|
|
71717
|
+
stdoutIsTTY: this._stdoutIsTTY,
|
|
70961
71718
|
stdout: this._stdout,
|
|
70962
71719
|
stderr: this._stderr,
|
|
70963
71720
|
uid: this.uid
|
|
@@ -71742,6 +72499,7 @@ const _Shell = class _Shell {
|
|
|
71742
72499
|
const isFirstCommand = i === 0;
|
|
71743
72500
|
const isLastCommand = i === commands.length - 1;
|
|
71744
72501
|
let inputStream;
|
|
72502
|
+
let stdinIsTTY = false;
|
|
71745
72503
|
if (isFirstCommand) {
|
|
71746
72504
|
const inputRedirect = redirections.find((r) => r.type === "<");
|
|
71747
72505
|
if (inputRedirect) {
|
|
@@ -71750,14 +72508,17 @@ const _Shell = class _Shell {
|
|
|
71750
72508
|
throw new Error(`File not found: ${sourcePath}`);
|
|
71751
72509
|
}
|
|
71752
72510
|
inputStream = this.createFileReadStream(sourcePath, env2, kernel);
|
|
72511
|
+
stdinIsTTY = false;
|
|
71753
72512
|
} else {
|
|
71754
72513
|
inputStream = this._terminal.getInputStream();
|
|
72514
|
+
stdinIsTTY = true;
|
|
71755
72515
|
}
|
|
71756
72516
|
} else {
|
|
71757
72517
|
if (!prevReadable) {
|
|
71758
72518
|
throw new Error("Pipeline error: missing previous stream");
|
|
71759
72519
|
}
|
|
71760
72520
|
inputStream = prevReadable;
|
|
72521
|
+
stdinIsTTY = false;
|
|
71761
72522
|
}
|
|
71762
72523
|
let outputStream;
|
|
71763
72524
|
let errorStream;
|
|
@@ -71827,17 +72588,20 @@ const _Shell = class _Shell {
|
|
|
71827
72588
|
errorStream = this.createTerminalErrorStream();
|
|
71828
72589
|
}
|
|
71829
72590
|
}
|
|
71830
|
-
|
|
72591
|
+
const stdoutIsTTY = !stdoutRedirect && isLastCommand;
|
|
72592
|
+
pipelineSetup.push({ finalCommand, args, inputStream, stdinIsTTY, outputStream, errorStream, stdoutIsTTY });
|
|
71831
72593
|
}
|
|
71832
72594
|
const commandPromises = pipelineSetup.map(
|
|
71833
|
-
({ finalCommand, args, inputStream, outputStream, errorStream }) => this._kernel.execute({
|
|
72595
|
+
({ finalCommand, args, inputStream, stdinIsTTY, outputStream, errorStream, stdoutIsTTY }) => this._kernel.execute({
|
|
71834
72596
|
command: finalCommand,
|
|
71835
72597
|
args,
|
|
71836
72598
|
kernel: this._kernel,
|
|
71837
72599
|
shell: this,
|
|
71838
72600
|
terminal: this._terminal,
|
|
71839
72601
|
stdin: inputStream,
|
|
72602
|
+
stdinIsTTY,
|
|
71840
72603
|
stdout: outputStream,
|
|
72604
|
+
stdoutIsTTY,
|
|
71841
72605
|
stderr: errorStream
|
|
71842
72606
|
})
|
|
71843
72607
|
);
|
|
@@ -72157,10 +72921,27 @@ const _Users = class _Users {
|
|
|
72157
72921
|
/**
|
|
72158
72922
|
* Login a user
|
|
72159
72923
|
*/
|
|
72160
|
-
async login(username, password) {
|
|
72924
|
+
async login(username, password, passkeyCredential) {
|
|
72161
72925
|
const user2 = Array.from(this._users.values()).find((u) => u.username === username);
|
|
72162
|
-
|
|
72163
|
-
if (
|
|
72926
|
+
if (!user2) throw new Error("Invalid username or password");
|
|
72927
|
+
if (passkeyCredential) {
|
|
72928
|
+
const passkeys = await this.getPasskeys(user2.uid);
|
|
72929
|
+
const credential = passkeyCredential;
|
|
72930
|
+
const credentialId = btoa(String.fromCharCode(...new Uint8Array(credential.rawId)));
|
|
72931
|
+
const matchingPasskey = passkeys.find((pk) => pk.credentialId === credentialId);
|
|
72932
|
+
if (!matchingPasskey) {
|
|
72933
|
+
throw new Error("Passkey not found for this user");
|
|
72934
|
+
}
|
|
72935
|
+
matchingPasskey.lastUsed = Date.now();
|
|
72936
|
+
await this.savePasskeys(user2.uid, passkeys);
|
|
72937
|
+
} else if (password) {
|
|
72938
|
+
const hashedPassword = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(password.trim()));
|
|
72939
|
+
if (user2.password !== Array.from(new Uint8Array(hashedPassword)).map((b) => b.toString(16).padStart(2, "0")).join("")) {
|
|
72940
|
+
throw new Error("Invalid username or password");
|
|
72941
|
+
}
|
|
72942
|
+
} else {
|
|
72943
|
+
throw new Error("Password or passkey required");
|
|
72944
|
+
}
|
|
72164
72945
|
const cred = createCredentials({
|
|
72165
72946
|
uid: user2.uid,
|
|
72166
72947
|
gid: user2.gid,
|
|
@@ -72204,6 +72985,77 @@ const _Users = class _Users {
|
|
|
72204
72985
|
throw new Error(`User with UID ${uid} not found`);
|
|
72205
72986
|
}
|
|
72206
72987
|
}
|
|
72988
|
+
/**
|
|
72989
|
+
* Get all passkeys for a user
|
|
72990
|
+
*/
|
|
72991
|
+
async getPasskeys(uid) {
|
|
72992
|
+
const user2 = this._users.get(uid);
|
|
72993
|
+
if (!user2) return [];
|
|
72994
|
+
const passkeysPath = `${user2.home}/.passkeys`;
|
|
72995
|
+
try {
|
|
72996
|
+
const exists2 = await this._options.kernel.filesystem.fs.exists(passkeysPath);
|
|
72997
|
+
if (!exists2) return [];
|
|
72998
|
+
const content = await this._options.kernel.filesystem.fs.readFile(passkeysPath, "utf-8");
|
|
72999
|
+
const parsed = JSON.parse(content);
|
|
73000
|
+
return parsed.map((pk) => {
|
|
73001
|
+
const publicKeyArray = JSON.parse(pk.publicKey);
|
|
73002
|
+
return {
|
|
73003
|
+
...pk,
|
|
73004
|
+
publicKey: new Uint8Array(publicKeyArray)
|
|
73005
|
+
};
|
|
73006
|
+
});
|
|
73007
|
+
} catch (error) {
|
|
73008
|
+
this._options.kernel.log.warn(`Failed to read passkeys for user ${uid}: ${error}`);
|
|
73009
|
+
return [];
|
|
73010
|
+
}
|
|
73011
|
+
}
|
|
73012
|
+
/**
|
|
73013
|
+
* Save passkeys for a user
|
|
73014
|
+
*/
|
|
73015
|
+
async savePasskeys(uid, passkeys) {
|
|
73016
|
+
const user2 = this._users.get(uid);
|
|
73017
|
+
if (!user2) throw new Error(`User with UID ${uid} not found`);
|
|
73018
|
+
const passkeysPath = `${user2.home}/.passkeys`;
|
|
73019
|
+
const serialized = passkeys.map((pk) => {
|
|
73020
|
+
const publicKeyArray = pk.publicKey instanceof ArrayBuffer ? Array.from(new Uint8Array(pk.publicKey)) : Array.from(pk.publicKey);
|
|
73021
|
+
return {
|
|
73022
|
+
...pk,
|
|
73023
|
+
publicKey: JSON.stringify(publicKeyArray)
|
|
73024
|
+
};
|
|
73025
|
+
});
|
|
73026
|
+
await this._options.kernel.filesystem.fs.writeFile(
|
|
73027
|
+
passkeysPath,
|
|
73028
|
+
JSON.stringify(serialized, null, 2),
|
|
73029
|
+
{ encoding: "utf-8", mode: 384 }
|
|
73030
|
+
);
|
|
73031
|
+
try {
|
|
73032
|
+
await this._options.kernel.filesystem.fs.chown(passkeysPath, uid, user2.gid);
|
|
73033
|
+
} catch {
|
|
73034
|
+
}
|
|
73035
|
+
}
|
|
73036
|
+
/**
|
|
73037
|
+
* Add a passkey to a user's collection
|
|
73038
|
+
*/
|
|
73039
|
+
async addPasskey(uid, passkey) {
|
|
73040
|
+
const existing = await this.getPasskeys(uid);
|
|
73041
|
+
existing.push(passkey);
|
|
73042
|
+
await this.savePasskeys(uid, existing);
|
|
73043
|
+
}
|
|
73044
|
+
/**
|
|
73045
|
+
* Remove a passkey by ID
|
|
73046
|
+
*/
|
|
73047
|
+
async removePasskey(uid, passkeyId) {
|
|
73048
|
+
const existing = await this.getPasskeys(uid);
|
|
73049
|
+
const filtered = existing.filter((pk) => pk.id !== passkeyId);
|
|
73050
|
+
await this.savePasskeys(uid, filtered);
|
|
73051
|
+
}
|
|
73052
|
+
/**
|
|
73053
|
+
* Check if a user has any registered passkeys
|
|
73054
|
+
*/
|
|
73055
|
+
async hasPasskeys(uid) {
|
|
73056
|
+
const passkeys = await this.getPasskeys(uid);
|
|
73057
|
+
return passkeys.length > 0;
|
|
73058
|
+
}
|
|
72207
73059
|
};
|
|
72208
73060
|
__name(_Users, "Users");
|
|
72209
73061
|
let Users = _Users;
|
|
@@ -73568,10 +74420,10 @@ const _Workers = class _Workers {
|
|
|
73568
74420
|
};
|
|
73569
74421
|
__name(_Workers, "Workers");
|
|
73570
74422
|
let Workers = _Workers;
|
|
73571
|
-
const __vite_import_meta_env__ = { "AUTHOR": { "name": "Jay Mathis", "email": "code@mathis.network", "url": "https://github.com/mathiscode" }, "BASE_URL": "/", "DESCRIPTION": "ecmaOS: Micro-kernel and framework for web technologies", "DEV": false, "HOMEPAGE": "https://ecmaos.sh", "KNOWN_ISSUES": ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"], "MODE": "production", "NAME": "@ecmaos/kernel", "PROD": true, "REPOSITORY": "https://github.com/ecmaos/ecmaos", "SSR": false, "TIPS": ["If it ever fails to boot, check your logs
|
|
74423
|
+
const __vite_import_meta_env__ = { "AUTHOR": { "name": "Jay Mathis", "email": "code@mathis.network", "url": "https://github.com/mathiscode" }, "BASE_URL": "/", "DESCRIPTION": "ecmaOS: Micro-kernel and framework for web technologies", "DEV": false, "HOMEPAGE": "https://ecmaos.sh", "KNOWN_ISSUES": ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"], "MODE": "production", "NAME": "@ecmaos/kernel", "PROD": true, "REPOSITORY": "https://github.com/ecmaos/ecmaos", "SSR": false, "TIPS": ["If it ever fails to boot, check your logs, try clearing all data, try incognito mode, or try another browser", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "You can register and login with a passkey: 'passkey register' and 'passkey list'", "Try 'fetch /xkcd-os.sixel'"], "VERSION": "0.6.6", "VITE_APP_SHOW_DEFAULT_LOGIN": "true", "VITE_AUTOLOGIN_PASSWORD": "root", "VITE_AUTOLOGIN_USERNAME": "root", "VITE_BOOT_DISABLE_ISSUES": "true", "VITE_BOOT_DISABLE_LOGO_CONSOLE": "false", "VITE_BOOT_DISABLE_LOGO_FIGLET": "false", "VITE_BOOT_DISABLE_TIPS": "false", "VITE_INITFS": "/initfs.tar.gz", "VITE_KERNEL_INTERVALS_PROC": "1000", "VITE_KERNEL_MODULES": "@ecmaos-modules/boilerplate@0.1.0", "VITE_METAL_SOCKET": "ws://localhost:30445/socket", "VITE_PORT": "30443", "VITE_RECOMMENDED_APPS": "@ecmaos-apps/code,@ecmaos-apps/edit,@ecmaos-apps/ai,@ecmaos-apps/webamp,@ecmaos-apps/news", "XTERM_VERSION": "5.5.0", "ZENFS_VERSION": "2.4.2" };
|
|
73572
74424
|
var define_import_meta_env_AUTHOR_default = { name: "Jay Mathis", email: "code@mathis.network", url: "https://github.com/mathiscode" };
|
|
73573
74425
|
var define_import_meta_env_KNOWN_ISSUES_default = ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"];
|
|
73574
|
-
var define_import_meta_env_TIPS_default = ["If it ever fails to boot, check your logs
|
|
74426
|
+
var define_import_meta_env_TIPS_default = ["If it ever fails to boot, check your logs, try clearing all data, try incognito mode, or try another browser", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "You can register and login with a passkey: 'passkey register' and 'passkey list'", "Try 'fetch /xkcd-os.sixel'"];
|
|
73575
74427
|
const DefaultKernelOptions = {
|
|
73576
74428
|
devices: DefaultDevices,
|
|
73577
74429
|
dom: DefaultDomOptions,
|
|
@@ -73613,7 +74465,7 @@ const _Kernel = class _Kernel {
|
|
|
73613
74465
|
/** Name of the kernel */
|
|
73614
74466
|
__publicField(this, "name", "@ecmaos/kernel");
|
|
73615
74467
|
/** Version string of the kernel */
|
|
73616
|
-
__publicField(this, "version", "0.6.
|
|
74468
|
+
__publicField(this, "version", "0.6.6");
|
|
73617
74469
|
/** Authentication and authorization service */
|
|
73618
74470
|
__publicField(this, "auth");
|
|
73619
74471
|
/** BIOS module providing low-level functionality */
|
|
@@ -73771,7 +74623,7 @@ const _Kernel = class _Kernel {
|
|
|
73771
74623
|
];
|
|
73772
74624
|
this.terminal.writeln(chalk$2.red.bold(`🐉 ${t2("kernel.experimental", "EXPERIMENTAL")} 🐉`));
|
|
73773
74625
|
this.terminal.writeln(
|
|
73774
|
-
`${this.terminal.createSpecialLink("https://ecmaos.sh", "@ecmaos/kernel")}@${"0.6.
|
|
74626
|
+
`${this.terminal.createSpecialLink("https://ecmaos.sh", "@ecmaos/kernel")}@${"0.6.6"}` + chalk$2.cyan(` [${dependencyLinks.map((link2) => link2.link).join(", ")}]`)
|
|
73775
74627
|
);
|
|
73776
74628
|
this.terminal.writeln(`${t2("kernel.madeBy", "Made with ❤️ by Jay Mathis")} ${this.terminal.createSpecialLink(
|
|
73777
74629
|
define_import_meta_env_AUTHOR_default?.url || "https://github.com/mathiscode",
|
|
@@ -73788,14 +74640,14 @@ const _Kernel = class _Kernel {
|
|
|
73788
74640
|
if (logoFiglet && true) {
|
|
73789
74641
|
console.log(`%c${logoFiglet}`, "color: green");
|
|
73790
74642
|
console.log(`%c${"https://github.com/ecmaos/ecmaos"}`, "color: blue; text-decoration: underline; font-size: 16px");
|
|
73791
|
-
this.log.info(`${"@ecmaos/kernel"} v${"0.6.
|
|
74643
|
+
this.log.info(`${"@ecmaos/kernel"} v${"0.6.6"}`);
|
|
73792
74644
|
}
|
|
73793
74645
|
if (Notification?.permission === "default") Notification.requestPermission();
|
|
73794
74646
|
if (Notification?.permission === "denied") this.log.warn(t2("kernel.permissionNotificationDenied", "Notification permission denied"));
|
|
73795
74647
|
this.intervals.set("title-blink", () => {
|
|
73796
74648
|
globalThis.document.title = globalThis.document.title.includes("_") ? "ecmaos# " : "ecmaos# _";
|
|
73797
74649
|
}, 600);
|
|
73798
|
-
this.toast.success(`${"@ecmaos/kernel"} v${"0.6.
|
|
74650
|
+
this.toast.success(`${"@ecmaos/kernel"} v${"0.6.6"}`);
|
|
73799
74651
|
}
|
|
73800
74652
|
await this.configure({ devices: this.options.devices || DefaultDevices, filesystem: Filesystem.options() });
|
|
73801
74653
|
const requiredPaths = [
|
|
@@ -73956,20 +74808,62 @@ const _Kernel = class _Kernel {
|
|
|
73956
74808
|
const icon = isSecure ? "🔒" : "🔓";
|
|
73957
74809
|
this.terminal.writeln(`${icon} ${protocolStr}//${hostname}${port}`);
|
|
73958
74810
|
const username = await this.terminal.readline(`👤 ${this.i18n.t("Username")}: `);
|
|
73959
|
-
const
|
|
73960
|
-
|
|
73961
|
-
|
|
73962
|
-
|
|
74811
|
+
const user22 = Array.from(this.users.all.values()).find((u) => u.username === username);
|
|
74812
|
+
let loginSuccess = false;
|
|
74813
|
+
let userCred = null;
|
|
74814
|
+
if (user22) {
|
|
74815
|
+
const passkeys = await this.users.getPasskeys(user22.uid);
|
|
74816
|
+
if (passkeys.length > 0 && this.auth.passkey.isSupported()) {
|
|
74817
|
+
try {
|
|
74818
|
+
const challenge = crypto.getRandomValues(new Uint8Array(32));
|
|
74819
|
+
const rpId = globalThis.location.hostname || "localhost";
|
|
74820
|
+
const allowCredentials = passkeys.map((pk) => {
|
|
74821
|
+
const credentialIdBytes = Uint8Array.from(atob(pk.credentialId), (c) => c.charCodeAt(0));
|
|
74822
|
+
return {
|
|
74823
|
+
id: credentialIdBytes.buffer,
|
|
74824
|
+
type: "public-key",
|
|
74825
|
+
transports: ["usb", "nfc", "ble", "internal"]
|
|
74826
|
+
};
|
|
74827
|
+
});
|
|
74828
|
+
const requestOptions = {
|
|
74829
|
+
challenge,
|
|
74830
|
+
allowCredentials,
|
|
74831
|
+
rpId,
|
|
74832
|
+
userVerification: "preferred",
|
|
74833
|
+
timeout: 6e4
|
|
74834
|
+
};
|
|
74835
|
+
this.terminal.writeln(chalk$2.yellow("🔐 Please use your passkey to authenticate..."));
|
|
74836
|
+
const credential = await this.auth.passkey.get(requestOptions);
|
|
74837
|
+
if (credential && credential instanceof PublicKeyCredential) {
|
|
74838
|
+
userCred = await this.users.login(username, void 0, credential);
|
|
74839
|
+
loginSuccess = true;
|
|
74840
|
+
} else {
|
|
74841
|
+
this.terminal.writeln(chalk$2.yellow("Passkey authentication cancelled or failed. Falling back to password..."));
|
|
74842
|
+
}
|
|
74843
|
+
} catch (err2) {
|
|
74844
|
+
this.terminal.writeln(chalk$2.yellow(`Passkey authentication error: ${err2.message}. Falling back to password...`));
|
|
74845
|
+
}
|
|
74846
|
+
}
|
|
74847
|
+
}
|
|
74848
|
+
if (!loginSuccess) {
|
|
74849
|
+
const password = await this.terminal.readline(`🔑 ${this.i18n.t("Password")}: `, true);
|
|
74850
|
+
userCred = await this.users.login(username, password);
|
|
74851
|
+
}
|
|
74852
|
+
if (!userCred) {
|
|
74853
|
+
throw new Error("Login failed");
|
|
74854
|
+
}
|
|
74855
|
+
this.shell.credentials = userCred.cred;
|
|
74856
|
+
this.shell.context = bindContext({ root: "/", pwd: "/", credentials: userCred.cred });
|
|
73963
74857
|
await this.shell.loadEnvFile();
|
|
73964
|
-
this.shell.env.set("UID",
|
|
73965
|
-
this.shell.env.set("GID",
|
|
73966
|
-
this.shell.env.set("SUID", cred.suid.toString());
|
|
73967
|
-
this.shell.env.set("SGID", cred.sgid.toString());
|
|
73968
|
-
this.shell.env.set("EUID", cred.euid.toString());
|
|
73969
|
-
this.shell.env.set("EGID", cred.egid.toString());
|
|
73970
|
-
this.shell.env.set("SHELL",
|
|
73971
|
-
this.shell.env.set("HOME",
|
|
73972
|
-
this.shell.env.set("USER",
|
|
74858
|
+
this.shell.env.set("UID", userCred.user.uid.toString());
|
|
74859
|
+
this.shell.env.set("GID", userCred.user.gid.toString());
|
|
74860
|
+
this.shell.env.set("SUID", userCred.cred.suid.toString());
|
|
74861
|
+
this.shell.env.set("SGID", userCred.cred.sgid.toString());
|
|
74862
|
+
this.shell.env.set("EUID", userCred.cred.euid.toString());
|
|
74863
|
+
this.shell.env.set("EGID", userCred.cred.egid.toString());
|
|
74864
|
+
this.shell.env.set("SHELL", userCred.user.shell || "ecmaos");
|
|
74865
|
+
this.shell.env.set("HOME", userCred.user.home || "/root");
|
|
74866
|
+
this.shell.env.set("USER", userCred.user.username);
|
|
73973
74867
|
process$1.env = Object.fromEntries(this.shell.env);
|
|
73974
74868
|
break;
|
|
73975
74869
|
} catch (err2) {
|
|
@@ -74222,7 +75116,9 @@ const _Kernel = class _Kernel {
|
|
|
74222
75116
|
terminal: options.terminal || this.terminal,
|
|
74223
75117
|
entry: /* @__PURE__ */ __name(async (params) => await command.run.call(params, params.pid, params.args), "entry"),
|
|
74224
75118
|
stdin: options.stdin,
|
|
75119
|
+
stdinIsTTY: options.stdinIsTTY,
|
|
74225
75120
|
stdout: options.stdout,
|
|
75121
|
+
stdoutIsTTY: options.stdoutIsTTY,
|
|
74226
75122
|
stderr: options.stderr
|
|
74227
75123
|
});
|
|
74228
75124
|
const exitCode = await process2.start();
|
|
@@ -74499,7 +75395,7 @@ const _Kernel = class _Kernel {
|
|
|
74499
75395
|
memory: "?",
|
|
74500
75396
|
platform: navigator.userAgentData?.platform || navigator?.platform || navigator.userAgent,
|
|
74501
75397
|
querystring: location.search,
|
|
74502
|
-
version: `${"@ecmaos/kernel"} ${"0.6.
|
|
75398
|
+
version: `${"@ecmaos/kernel"} ${"0.6.6"}`,
|
|
74503
75399
|
language: navigator.language,
|
|
74504
75400
|
host: location.host,
|
|
74505
75401
|
userAgent: navigator.userAgent,
|
|
@@ -74676,4 +75572,4 @@ export {
|
|
|
74676
75572
|
path$1 as p,
|
|
74677
75573
|
semver as s
|
|
74678
75574
|
};
|
|
74679
|
-
//# sourceMappingURL=kernel-
|
|
75575
|
+
//# sourceMappingURL=kernel-DZB_DlxI.js.map
|