typescript-virtual-container 1.5.3 → 1.5.5
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 +44 -532
- package/dist/.tsbuildinfo +1 -0
- package/dist/SSHMimic/executor.js +23 -5
- package/dist/VirtualPackageManager/index.js +10 -0
- package/dist/VirtualShell/shell.js +158 -11
- package/dist/commands/basename.d.ts +13 -0
- package/dist/commands/basename.js +45 -0
- package/dist/commands/bc.d.ts +2 -0
- package/dist/commands/bc.js +28 -0
- package/dist/commands/file.d.ts +8 -0
- package/dist/commands/file.js +57 -0
- package/dist/commands/fun.d.ts +32 -0
- package/dist/commands/fun.js +172 -0
- package/dist/commands/ip.d.ts +7 -0
- package/dist/commands/ip.js +52 -0
- package/dist/commands/jobs.d.ts +4 -0
- package/dist/commands/jobs.js +27 -0
- package/dist/commands/last.d.ts +13 -0
- package/dist/commands/last.js +68 -0
- package/dist/commands/manuals-bundle.js +598 -6
- package/dist/commands/registry.js +30 -2
- package/dist/commands/runtime.js +24 -3
- package/dist/commands/set.js +20 -0
- package/dist/commands/sh.js +74 -1
- package/dist/commands/tput.d.ts +13 -0
- package/dist/commands/tput.js +76 -0
- package/dist/commands/w.d.ts +7 -0
- package/dist/commands/w.js +38 -0
- package/dist/utils/expand.d.ts +12 -0
- package/dist/utils/expand.js +87 -1
- package/package.json +9 -3
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -50
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -31
- package/.github/dependabot.yml +0 -27
- package/.github/pull_request_template.md +0 -21
- package/.github/workflows/create-pull-request.yml +0 -85
- package/.github/workflows/publish.yml +0 -25
- package/.github/workflows/test-battery.yml +0 -102
- package/.vscode/settings.json +0 -20
- package/CODE_OF_CONDUCT.md +0 -39
- package/CONTRIBUTING.md +0 -59
- package/HONEYPOT.md +0 -358
- package/SECURITY.md +0 -33
- package/benchmark-results.txt +0 -40
- package/benchmark-virtualshell.ts +0 -88
- package/biome.json +0 -37
- package/build.js +0 -22
- package/builds/fortune-nyx-v1.5.3-directbash-k6.1.0.mjs +0 -1764
- package/builds/fortune-nyx-v1.5.3-ssh-nosftp.js +0 -1764
- package/builds/fortune-nyx-v1.5.3-ssh.cjs +0 -1765
- package/builds/fortune-nyx-v1.5.3-web.min.js +0 -17036
- package/bun.lock +0 -244
- package/docs/.nojekyll +0 -1
- package/docs/app.js +0 -1751
- package/docs/assets/hierarchy.js +0 -1
- package/docs/assets/highlight.css +0 -162
- package/docs/assets/icons.js +0 -18
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -60
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1633
- package/docs/classes/HoneyPot.html +0 -31
- package/docs/classes/IdleManager.html +0 -162
- package/docs/classes/SshClient.html +0 -66
- package/docs/classes/VirtualFileSystem.html +0 -279
- package/docs/classes/VirtualPackageManager.html +0 -63
- package/docs/classes/VirtualSftpServer.html +0 -169
- package/docs/classes/VirtualShell.html +0 -285
- package/docs/classes/VirtualSshServer.html +0 -182
- package/docs/classes/VirtualUserManager.html +0 -276
- package/docs/demo.html +0 -82
- package/docs/functions/assertDiff.html +0 -6
- package/docs/functions/diffSnapshots.html +0 -7
- package/docs/functions/formatDiff.html +0 -6
- package/docs/functions/getArg.html +0 -13
- package/docs/functions/getFlag.html +0 -15
- package/docs/functions/ifFlag.html +0 -11
- package/docs/hierarchy.html +0 -1
- package/docs/index.html +0 -1869
- package/docs/interfaces/AuditLogEntry.html +0 -6
- package/docs/interfaces/CommandContext.html +0 -22
- package/docs/interfaces/CommandResult.html +0 -26
- package/docs/interfaces/ExecStream.html +0 -11
- package/docs/interfaces/HoneyPotStats.html +0 -16
- package/docs/interfaces/IdleManagerOptions.html +0 -7
- package/docs/interfaces/InstalledPackage.html +0 -20
- package/docs/interfaces/NanoEditorSession.html +0 -8
- package/docs/interfaces/PackageDefinition.html +0 -30
- package/docs/interfaces/PackageFile.html +0 -8
- package/docs/interfaces/PasswordChallenge.html +0 -16
- package/docs/interfaces/RemoveOptions.html +0 -4
- package/docs/interfaces/ShellEnv.html +0 -6
- package/docs/interfaces/ShellModule.html +0 -14
- package/docs/interfaces/ShellProperties.html +0 -14
- package/docs/interfaces/ShellStream.html +0 -11
- package/docs/interfaces/SudoChallenge.html +0 -24
- package/docs/interfaces/VfsBaseNode.html +0 -12
- package/docs/interfaces/VfsDiff.html +0 -10
- package/docs/interfaces/VfsDiffEntry.html +0 -6
- package/docs/interfaces/VfsDiffModified.html +0 -10
- package/docs/interfaces/VfsDirectoryNode.html +0 -15
- package/docs/interfaces/VfsFileNode.html +0 -17
- package/docs/interfaces/VfsOptions.html +0 -26
- package/docs/interfaces/VfsSnapshot.html +0 -3
- package/docs/interfaces/VfsSnapshotBaseNode.html +0 -8
- package/docs/interfaces/VfsSnapshotDirectoryNode.html +0 -10
- package/docs/interfaces/VfsSnapshotFileNode.html +0 -12
- package/docs/interfaces/VirtualActiveSession.html +0 -12
- package/docs/interfaces/VirtualSftpServerOptions.html +0 -7
- package/docs/interfaces/VirtualShellVfsLike.html +0 -15
- package/docs/interfaces/VirtualShellVfsOptions.html +0 -3
- package/docs/interfaces/WriteFileOptions.html +0 -6
- package/docs/media/LICENSE +0 -21
- package/docs/modules.html +0 -1
- package/docs/types/ArgParseOptions.html +0 -4
- package/docs/types/CommandMode.html +0 -2
- package/docs/types/CommandOutcome.html +0 -2
- package/docs/types/IdleState.html +0 -1
- package/docs/types/VfsNodeStats.html +0 -2
- package/docs/types/VfsNodeType.html +0 -2
- package/docs/types/VfsPersistenceMode.html +0 -5
- package/docs/types/VfsSnapshotNode.html +0 -2
- package/examples/README.md +0 -288
- package/examples/app.js +0 -1751
- package/examples/app.ts +0 -299
- package/examples/build.js +0 -27
- package/examples/demo.html +0 -33
- package/examples/honeypot-audit.ts +0 -180
- package/examples/honeypot-export.ts +0 -253
- package/examples/honeypot-quickstart.ts +0 -110
- package/examples/index.html +0 -82
- package/examples/server.js +0 -55
- package/polyfills/buffer.js +0 -117
- package/polyfills/node_child_process/index.js +0 -2
- package/polyfills/node_crypto/index.js +0 -167
- package/polyfills/node_events/index.js +0 -9
- package/polyfills/node_fs/index.js +0 -202
- package/polyfills/node_fs/promises.js +0 -4
- package/polyfills/node_os/index.js +0 -9
- package/polyfills/node_path/index.js +0 -28
- package/polyfills/node_vm/index.js +0 -7
- package/polyfills/node_zlib/index.js +0 -3
- package/polyfills/process.js +0 -14
- package/polyfills/ssh2/index.js +0 -75
- package/scripts/build-all.mjs +0 -226
- package/scripts/build-names.mjs +0 -43
- package/scripts/generate-manuals-bundle.mjs +0 -49
- package/scripts/postinstall.js +0 -42
- package/scripts/publish-package.sh +0 -70
- package/src/Honeypot/index.ts +0 -457
- package/src/SSHClient/index.ts +0 -270
- package/src/SSHMimic/exec.ts +0 -49
- package/src/SSHMimic/executor.ts +0 -251
- package/src/SSHMimic/hostKey.ts +0 -21
- package/src/SSHMimic/index.ts +0 -337
- package/src/SSHMimic/loginBanner.ts +0 -36
- package/src/SSHMimic/loginFormat.ts +0 -10
- package/src/SSHMimic/prompt.ts +0 -14
- package/src/SSHMimic/sftp.ts +0 -883
- package/src/VirtualFileSystem/binaryPack.ts +0 -258
- package/src/VirtualFileSystem/index.ts +0 -1193
- package/src/VirtualFileSystem/internalTypes.ts +0 -43
- package/src/VirtualFileSystem/journal.ts +0 -171
- package/src/VirtualFileSystem/path.ts +0 -74
- package/src/VirtualPackageManager/index.ts +0 -996
- package/src/VirtualShell/idleManager.ts +0 -137
- package/src/VirtualShell/index.ts +0 -475
- package/src/VirtualShell/shell.ts +0 -700
- package/src/VirtualShell/shellParser.ts +0 -285
- package/src/VirtualUserManager/index.ts +0 -758
- package/src/bun.d.ts +0 -1
- package/src/commands/adduser.ts +0 -103
- package/src/commands/alias.ts +0 -69
- package/src/commands/apt.ts +0 -233
- package/src/commands/awk.ts +0 -168
- package/src/commands/base64.ts +0 -29
- package/src/commands/cat.ts +0 -52
- package/src/commands/cd.ts +0 -25
- package/src/commands/chmod.ts +0 -85
- package/src/commands/clear.ts +0 -15
- package/src/commands/command-helpers.ts +0 -286
- package/src/commands/cp.ts +0 -83
- package/src/commands/curl.ts +0 -147
- package/src/commands/cut.ts +0 -36
- package/src/commands/date.ts +0 -30
- package/src/commands/declare.ts +0 -49
- package/src/commands/deluser.ts +0 -98
- package/src/commands/df.ts +0 -23
- package/src/commands/diff.ts +0 -43
- package/src/commands/dpkg.ts +0 -180
- package/src/commands/du.ts +0 -56
- package/src/commands/echo.ts +0 -58
- package/src/commands/env.ts +0 -23
- package/src/commands/exit.ts +0 -18
- package/src/commands/export.ts +0 -34
- package/src/commands/find.ts +0 -68
- package/src/commands/free.ts +0 -47
- package/src/commands/grep.ts +0 -116
- package/src/commands/groups.ts +0 -19
- package/src/commands/gzip.ts +0 -88
- package/src/commands/head.ts +0 -52
- package/src/commands/help.ts +0 -152
- package/src/commands/helpers.ts +0 -234
- package/src/commands/history.ts +0 -34
- package/src/commands/hostname.ts +0 -14
- package/src/commands/htop.ts +0 -20
- package/src/commands/id.ts +0 -19
- package/src/commands/index.ts +0 -9
- package/src/commands/kill.ts +0 -19
- package/src/commands/ln.ts +0 -71
- package/src/commands/ls.ts +0 -243
- package/src/commands/lsb-release.ts +0 -63
- package/src/commands/man.ts +0 -31
- package/src/commands/manuals/adduser.txt +0 -11
- package/src/commands/manuals/apt-cache.txt +0 -12
- package/src/commands/manuals/apt.txt +0 -20
- package/src/commands/manuals/awk.txt +0 -13
- package/src/commands/manuals/cat.txt +0 -14
- package/src/commands/manuals/cd.txt +0 -16
- package/src/commands/manuals/chmod.txt +0 -16
- package/src/commands/manuals/clear.txt +0 -10
- package/src/commands/manuals/cp.txt +0 -10
- package/src/commands/manuals/curl.txt +0 -20
- package/src/commands/manuals/date.txt +0 -14
- package/src/commands/manuals/declare.txt +0 -12
- package/src/commands/manuals/deluser.txt +0 -10
- package/src/commands/manuals/df.txt +0 -10
- package/src/commands/manuals/dpkg-query.txt +0 -11
- package/src/commands/manuals/dpkg.txt +0 -14
- package/src/commands/manuals/du.txt +0 -11
- package/src/commands/manuals/echo.txt +0 -11
- package/src/commands/manuals/false.txt +0 -10
- package/src/commands/manuals/find.txt +0 -11
- package/src/commands/manuals/free.txt +0 -12
- package/src/commands/manuals/grep.txt +0 -13
- package/src/commands/manuals/groups.txt +0 -10
- package/src/commands/manuals/gzip.txt +0 -11
- package/src/commands/manuals/head.txt +0 -10
- package/src/commands/manuals/help.txt +0 -11
- package/src/commands/manuals/history.txt +0 -11
- package/src/commands/manuals/hostname.txt +0 -10
- package/src/commands/manuals/id.txt +0 -10
- package/src/commands/manuals/kill.txt +0 -13
- package/src/commands/manuals/ls.txt +0 -20
- package/src/commands/manuals/lsb_release.txt +0 -14
- package/src/commands/manuals/mkdir.txt +0 -10
- package/src/commands/manuals/mv.txt +0 -10
- package/src/commands/manuals/nano.txt +0 -11
- package/src/commands/manuals/neofetch.txt +0 -10
- package/src/commands/manuals/node.txt +0 -13
- package/src/commands/manuals/npm.txt +0 -13
- package/src/commands/manuals/npx.txt +0 -13
- package/src/commands/manuals/passwd.txt +0 -11
- package/src/commands/manuals/ping.txt +0 -10
- package/src/commands/manuals/printf.txt +0 -11
- package/src/commands/manuals/ps.txt +0 -10
- package/src/commands/manuals/pwd.txt +0 -10
- package/src/commands/manuals/python3.txt +0 -13
- package/src/commands/manuals/readlink.txt +0 -10
- package/src/commands/manuals/return.txt +0 -10
- package/src/commands/manuals/rm.txt +0 -10
- package/src/commands/manuals/sed.txt +0 -11
- package/src/commands/manuals/set.txt +0 -11
- package/src/commands/manuals/shift.txt +0 -10
- package/src/commands/manuals/sleep.txt +0 -10
- package/src/commands/manuals/sort.txt +0 -12
- package/src/commands/manuals/source.txt +0 -11
- package/src/commands/manuals/ssh.txt +0 -11
- package/src/commands/manuals/stat.txt +0 -10
- package/src/commands/manuals/su.txt +0 -13
- package/src/commands/manuals/sudo.txt +0 -11
- package/src/commands/manuals/tail.txt +0 -10
- package/src/commands/manuals/tar.txt +0 -19
- package/src/commands/manuals/tee.txt +0 -10
- package/src/commands/manuals/test.txt +0 -11
- package/src/commands/manuals/touch.txt +0 -11
- package/src/commands/manuals/tr.txt +0 -10
- package/src/commands/manuals/trap.txt +0 -10
- package/src/commands/manuals/true.txt +0 -10
- package/src/commands/manuals/type.txt +0 -10
- package/src/commands/manuals/uname.txt +0 -12
- package/src/commands/manuals/uniq.txt +0 -12
- package/src/commands/manuals/unset.txt +0 -10
- package/src/commands/manuals/uptime.txt +0 -11
- package/src/commands/manuals/wc.txt +0 -12
- package/src/commands/manuals/wget.txt +0 -12
- package/src/commands/manuals/which.txt +0 -10
- package/src/commands/manuals/whoami.txt +0 -10
- package/src/commands/manuals/xargs.txt +0 -10
- package/src/commands/manuals-bundle.ts +0 -898
- package/src/commands/mkdir.ts +0 -31
- package/src/commands/mv.ts +0 -50
- package/src/commands/nano.ts +0 -38
- package/src/commands/neofetch.ts +0 -53
- package/src/commands/node.ts +0 -341
- package/src/commands/npm.ts +0 -132
- package/src/commands/passwd.ts +0 -50
- package/src/commands/ping.ts +0 -32
- package/src/commands/printf.ts +0 -129
- package/src/commands/ps.ts +0 -58
- package/src/commands/pwd.ts +0 -9
- package/src/commands/python.ts +0 -2229
- package/src/commands/read.ts +0 -46
- package/src/commands/registry.ts +0 -249
- package/src/commands/rm.ts +0 -42
- package/src/commands/runtime.ts +0 -421
- package/src/commands/sed.ts +0 -68
- package/src/commands/seq.ts +0 -43
- package/src/commands/set.ts +0 -29
- package/src/commands/sh.ts +0 -467
- package/src/commands/shift.ts +0 -63
- package/src/commands/sleep.ts +0 -20
- package/src/commands/sort.ts +0 -46
- package/src/commands/source.ts +0 -52
- package/src/commands/stat.ts +0 -61
- package/src/commands/su.ts +0 -72
- package/src/commands/sudo.ts +0 -76
- package/src/commands/tail.ts +0 -53
- package/src/commands/tar.ts +0 -102
- package/src/commands/tee.ts +0 -36
- package/src/commands/test.ts +0 -137
- package/src/commands/touch.ts +0 -28
- package/src/commands/tr.ts +0 -70
- package/src/commands/tree.ts +0 -20
- package/src/commands/true.ts +0 -27
- package/src/commands/type.ts +0 -48
- package/src/commands/uname.ts +0 -29
- package/src/commands/uniq.ts +0 -39
- package/src/commands/unset.ts +0 -17
- package/src/commands/uptime.ts +0 -54
- package/src/commands/wc.ts +0 -55
- package/src/commands/wget.ts +0 -148
- package/src/commands/which.ts +0 -37
- package/src/commands/who.ts +0 -25
- package/src/commands/whoami.ts +0 -14
- package/src/commands/xargs.ts +0 -31
- package/src/index.ts +0 -67
- package/src/modules/linuxRootfs.ts +0 -1961
- package/src/modules/neofetch.ts +0 -358
- package/src/modules/shellInteractive.ts +0 -57
- package/src/modules/shellRuntime.ts +0 -76
- package/src/self-standalone.ts +0 -542
- package/src/standalone-wo-sftp.ts +0 -38
- package/src/standalone.ts +0 -72
- package/src/types/commands.ts +0 -146
- package/src/types/pipeline.ts +0 -52
- package/src/types/streams.ts +0 -32
- package/src/types/tar-stream.d.ts +0 -38
- package/src/types/vfs.ts +0 -98
- package/src/utils/expand.ts +0 -491
- package/src/utils/perfLogger.ts +0 -72
- package/src/utils/tokenize.ts +0 -98
- package/src/utils/vfsDiff.ts +0 -275
- package/tests/command-helpers.test.ts +0 -116
- package/tests/commands-admin-net.test.ts +0 -441
- package/tests/commands-advanced.test.ts +0 -456
- package/tests/commands-core.test.ts +0 -562
- package/tests/commands-missing.test.ts +0 -570
- package/tests/commands-specific-units.test.ts +0 -327
- package/tests/commands-text-sys.test.ts +0 -445
- package/tests/expand.test.ts +0 -170
- package/tests/helpers.test.ts +0 -97
- package/tests/new-features.test.ts +0 -1036
- package/tests/parser-executor.test.ts +0 -37
- package/tests/sftp.test.ts +0 -323
- package/tests/ssh-exec.test.ts +0 -45
- package/tests/test-helper.ts +0 -79
- package/tests/users.test.ts +0 -86
- package/tsconfig.json +0 -49
- package/typedoc.json +0 -47
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolvePath } from "./helpers";
|
|
2
|
+
const MAGIC = [
|
|
3
|
+
[s => s.startsWith('\x7fELF'), "ELF 64-bit LSB executable, x86-64"],
|
|
4
|
+
[/^#!\/bin\/sh/, "POSIX shell script, ASCII text executable"],
|
|
5
|
+
[/^#!\/bin\/bash/, "Bourne-Again shell script, ASCII text executable"],
|
|
6
|
+
[/^#!\/usr\/bin\/env (node|bun)/, "Node.js script, ASCII text executable"],
|
|
7
|
+
[/^#!\/usr\/bin\/env python/, "Python script, ASCII text executable"],
|
|
8
|
+
[/^\x89PNG/, "PNG image data"],
|
|
9
|
+
[/^GIF8/, "GIF image data"],
|
|
10
|
+
[/^\xff\xd8\xff/, "JPEG image data"],
|
|
11
|
+
[/^PK\x03\x04/, "Zip archive data"],
|
|
12
|
+
[/^\x1f\x8b/, "gzip compressed data"],
|
|
13
|
+
[s => s.trimStart().startsWith('{') || s.trimStart().startsWith('['), "JSON data"],
|
|
14
|
+
[/^<\?xml/, "XML document, ASCII text"],
|
|
15
|
+
[/^<!DOCTYPE html/i, "HTML document, ASCII text"],
|
|
16
|
+
[/^[^\x00-\x08\x0e-\x1f\x7f-\x9f]*$/, "ASCII text"],
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Determine file type.
|
|
20
|
+
* @category files
|
|
21
|
+
* @params ["<file>..."]
|
|
22
|
+
*/
|
|
23
|
+
export const fileCommand = {
|
|
24
|
+
name: "file",
|
|
25
|
+
description: "Determine file type",
|
|
26
|
+
category: "files",
|
|
27
|
+
params: ["<file>..."],
|
|
28
|
+
run: ({ args, cwd, shell }) => {
|
|
29
|
+
if (!args.length)
|
|
30
|
+
return { stderr: "file: missing operand", exitCode: 1 };
|
|
31
|
+
const lines = [];
|
|
32
|
+
let exitCode = 0;
|
|
33
|
+
for (const arg of args) {
|
|
34
|
+
const p = resolvePath(cwd, arg);
|
|
35
|
+
if (!shell.vfs.exists(p)) {
|
|
36
|
+
lines.push(`${arg}: ERROR: No such file or directory`);
|
|
37
|
+
exitCode = 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const st = shell.vfs.stat(p);
|
|
41
|
+
if (st.type === "directory") {
|
|
42
|
+
lines.push(`${arg}: directory`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const content = shell.vfs.readFile(p);
|
|
46
|
+
let type = "data";
|
|
47
|
+
for (const [matcher, label] of MAGIC) {
|
|
48
|
+
if (typeof matcher === "function" ? matcher(content) : matcher.test(content)) {
|
|
49
|
+
type = label;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
lines.push(`${arg}: ${type}`);
|
|
54
|
+
}
|
|
55
|
+
return { stdout: lines.join("\n"), exitCode };
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ShellModule } from "../types/commands";
|
|
2
|
+
/**
|
|
3
|
+
* Output a string repeatedly until killed.
|
|
4
|
+
* @category misc
|
|
5
|
+
* @params ["[string]"]
|
|
6
|
+
*/
|
|
7
|
+
export declare const yesCommand: ShellModule;
|
|
8
|
+
/**
|
|
9
|
+
* Print a random, hopefully interesting adage.
|
|
10
|
+
* @category misc
|
|
11
|
+
* @params [""]
|
|
12
|
+
*/
|
|
13
|
+
export declare const fortuneCommand: ShellModule;
|
|
14
|
+
/**
|
|
15
|
+
* Generate an ASCII picture of a cow with a message.
|
|
16
|
+
* @category misc
|
|
17
|
+
* @params ["[message]"]
|
|
18
|
+
*/
|
|
19
|
+
export declare const cowsayCommand: ShellModule;
|
|
20
|
+
export declare const cowthinkCommand: ShellModule;
|
|
21
|
+
/**
|
|
22
|
+
* Show falling characters in the terminal like the Matrix movie.
|
|
23
|
+
* @category misc
|
|
24
|
+
* @params [""]
|
|
25
|
+
*/
|
|
26
|
+
export declare const cmatrixCommand: ShellModule;
|
|
27
|
+
/**
|
|
28
|
+
* You have SL.
|
|
29
|
+
* @category misc
|
|
30
|
+
* @params [""]
|
|
31
|
+
*/
|
|
32
|
+
export declare const slCommand: ShellModule;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// ── yes ───────────────────────────────────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* Output a string repeatedly until killed.
|
|
4
|
+
* @category misc
|
|
5
|
+
* @params ["[string]"]
|
|
6
|
+
*/
|
|
7
|
+
export const yesCommand = {
|
|
8
|
+
name: "yes",
|
|
9
|
+
description: "Output a string repeatedly until killed",
|
|
10
|
+
category: "misc",
|
|
11
|
+
params: ["[string]"],
|
|
12
|
+
run: ({ args }) => {
|
|
13
|
+
const word = args.length ? args.join(" ") : "y";
|
|
14
|
+
// Output 200 lines (simulate before Ctrl+C which isn't supported in virtual shell)
|
|
15
|
+
return { stdout: Array(200).fill(word).join("\n"), exitCode: 0 };
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
// ── fortune ──────────────────────────────────────────────────────────────────
|
|
19
|
+
const FORTUNES = [
|
|
20
|
+
"The best way to predict the future is to invent it. — Alan Kay",
|
|
21
|
+
"Any sufficiently advanced technology is indistinguishable from magic. — Arthur C. Clarke",
|
|
22
|
+
"Talk is cheap. Show me the code. — Linus Torvalds",
|
|
23
|
+
"Programs must be written for people to read, and only incidentally for machines to execute. — Harold Abelson",
|
|
24
|
+
"Debugging is twice as hard as writing the code in the first place. — Brian W. Kernighan",
|
|
25
|
+
"The most powerful tool we have as developers is automation. — Scott Hanselman",
|
|
26
|
+
"First, solve the problem. Then, write the code. — John Johnson",
|
|
27
|
+
"Make it work, make it right, make it fast. — Kent Beck",
|
|
28
|
+
"The function of good software is to make the complex appear simple. — Grady Booch",
|
|
29
|
+
"Premature optimization is the root of all evil. — Donald Knuth",
|
|
30
|
+
"There are only two hard things in Computer Science: cache invalidation and naming things. — Phil Karlton",
|
|
31
|
+
"The best code is no code at all. — Jeff Atwood",
|
|
32
|
+
"Linux is only free if your time has no value. — Jamie Zawinski",
|
|
33
|
+
"Software is like sex: it's better when it's free. — Linus Torvalds",
|
|
34
|
+
"Real programmers don't comment their code. If it was hard to write, it should be hard to understand.",
|
|
35
|
+
"It's not a bug — it's an undocumented feature.",
|
|
36
|
+
"The cloud is just someone else's computer.",
|
|
37
|
+
"There's no place like 127.0.0.1",
|
|
38
|
+
"sudo make me a sandwich.",
|
|
39
|
+
"To understand recursion, you must first understand recursion.",
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Print a random, hopefully interesting adage.
|
|
43
|
+
* @category misc
|
|
44
|
+
* @params [""]
|
|
45
|
+
*/
|
|
46
|
+
export const fortuneCommand = {
|
|
47
|
+
name: "fortune",
|
|
48
|
+
description: "Print a random adage",
|
|
49
|
+
category: "misc",
|
|
50
|
+
params: [],
|
|
51
|
+
run: () => {
|
|
52
|
+
const idx = Math.floor(Math.random() * FORTUNES.length);
|
|
53
|
+
return { stdout: FORTUNES[idx], exitCode: 0 };
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
// ── cowsay ───────────────────────────────────────────────────────────────────
|
|
57
|
+
function cowsay(message, dead = false) {
|
|
58
|
+
const lines = message.split("\n");
|
|
59
|
+
const maxLen = Math.max(...lines.map(l => l.length));
|
|
60
|
+
const _border = "-".repeat(maxLen + 2);
|
|
61
|
+
const body = lines.length === 1
|
|
62
|
+
? `< ${lines[0]} >`
|
|
63
|
+
: lines.map((l, i) => {
|
|
64
|
+
const pad = " ".repeat(maxLen - l.length);
|
|
65
|
+
if (i === 0)
|
|
66
|
+
return `/ ${l}${pad} \\`;
|
|
67
|
+
if (i === lines.length - 1)
|
|
68
|
+
return `\\ ${l}${pad} /`;
|
|
69
|
+
return `| ${l}${pad} |`;
|
|
70
|
+
}).join("\n");
|
|
71
|
+
const eyes = dead ? "xx" : "oo";
|
|
72
|
+
return [
|
|
73
|
+
` ${"_".repeat(maxLen + 2)}`,
|
|
74
|
+
`( ${body} )`,
|
|
75
|
+
` ${"‾".repeat(maxLen + 2)}`,
|
|
76
|
+
` \\ ^__^`,
|
|
77
|
+
` \\ (${eyes})\\_______`,
|
|
78
|
+
` (__)\\ )\\/\\`,
|
|
79
|
+
` ||----w |`,
|
|
80
|
+
` || ||`,
|
|
81
|
+
].join("\n");
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Generate an ASCII picture of a cow with a message.
|
|
85
|
+
* @category misc
|
|
86
|
+
* @params ["[message]"]
|
|
87
|
+
*/
|
|
88
|
+
export const cowsayCommand = {
|
|
89
|
+
name: "cowsay",
|
|
90
|
+
description: "Generate ASCII cow with message",
|
|
91
|
+
category: "misc",
|
|
92
|
+
params: ["[message]"],
|
|
93
|
+
run: ({ args, stdin }) => {
|
|
94
|
+
const msg = args.length ? args.join(" ") : (stdin?.trim() ?? "Moo.");
|
|
95
|
+
return { stdout: cowsay(msg), exitCode: 0 };
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
export const cowthinkCommand = {
|
|
99
|
+
name: "cowthink",
|
|
100
|
+
description: "Generate ASCII cow thinking",
|
|
101
|
+
category: "misc",
|
|
102
|
+
params: ["[message]"],
|
|
103
|
+
run: ({ args, stdin }) => {
|
|
104
|
+
const msg = args.length ? args.join(" ") : (stdin?.trim() ?? "Hmm...");
|
|
105
|
+
return { stdout: cowsay(msg).replace(/\\\s*\^__\^/, "o ^__^").replace(/\\\s*\(oo\)/, "o (oo)"), exitCode: 0 };
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
// ── cmatrix ──────────────────────────────────────────────────────────────────
|
|
109
|
+
/**
|
|
110
|
+
* Show falling characters in the terminal like the Matrix movie.
|
|
111
|
+
* @category misc
|
|
112
|
+
* @params [""]
|
|
113
|
+
*/
|
|
114
|
+
export const cmatrixCommand = {
|
|
115
|
+
name: "cmatrix",
|
|
116
|
+
description: "Show falling characters like the Matrix",
|
|
117
|
+
category: "misc",
|
|
118
|
+
params: [],
|
|
119
|
+
run: () => {
|
|
120
|
+
const cols = 80;
|
|
121
|
+
const rows = 24;
|
|
122
|
+
const chars = "ハミヒーウシナモニサワツオリアホテマケメエカキムユラセネスタヌヘ01234567890ABCDEF";
|
|
123
|
+
const green = "\x1b[32m";
|
|
124
|
+
const bright = "\x1b[1;32m";
|
|
125
|
+
const reset = "\x1b[0m";
|
|
126
|
+
const lines = [];
|
|
127
|
+
for (let r = 0; r < rows; r++) {
|
|
128
|
+
let line = "";
|
|
129
|
+
for (let c = 0; c < cols; c++) {
|
|
130
|
+
const ch = chars[Math.floor(Math.random() * chars.length)];
|
|
131
|
+
if (Math.random() < 0.05)
|
|
132
|
+
line += bright + ch + reset;
|
|
133
|
+
else if (Math.random() < 0.7)
|
|
134
|
+
line += green + ch + reset;
|
|
135
|
+
else
|
|
136
|
+
line += " ";
|
|
137
|
+
}
|
|
138
|
+
lines.push(line);
|
|
139
|
+
}
|
|
140
|
+
return { stdout: `\x1b[2J\x1b[H${lines.join("\n")}\n${reset}[cmatrix: press Ctrl+C to exit]`, exitCode: 0 };
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
// ── sl (Steam Locomotive) ─────────────────────────────────────────────────────
|
|
144
|
+
const TRAIN = [
|
|
145
|
+
" ==== ________ ___________ ",
|
|
146
|
+
" _D _| |_______/ \\__I_I_____===__|_________| ",
|
|
147
|
+
" |(_)--- | H\\________/ | | =|___ ___| ___",
|
|
148
|
+
" / | | H | | | | ||_| |_|| _| |_",
|
|
149
|
+
" | | | H |__--------------------| [___] | =| |",
|
|
150
|
+
" | ________|___H__/__|_____/[][]~\\_______| | -| __ |",
|
|
151
|
+
" |/ | |-----------I_____I [][] [] D |=======|____|__| |_|_|",
|
|
152
|
+
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__| |___|o |",
|
|
153
|
+
" |/-=|___|= || || || |_____/~\\___/ |___| |_|",
|
|
154
|
+
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ |",
|
|
155
|
+
];
|
|
156
|
+
/**
|
|
157
|
+
* You have SL.
|
|
158
|
+
* @category misc
|
|
159
|
+
* @params [""]
|
|
160
|
+
*/
|
|
161
|
+
export const slCommand = {
|
|
162
|
+
name: "sl",
|
|
163
|
+
description: "Steam Locomotive — you have sl",
|
|
164
|
+
category: "misc",
|
|
165
|
+
params: [],
|
|
166
|
+
run: () => {
|
|
167
|
+
return {
|
|
168
|
+
stdout: `\n\n${TRAIN.join("\n")}\n\n choo choo! 🚂\n`,
|
|
169
|
+
exitCode: 0,
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const ADDR_OUTPUT = `1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
|
2
|
+
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
|
3
|
+
inet 127.0.0.1/8 scope host lo
|
|
4
|
+
valid_lft forever preferred_lft forever
|
|
5
|
+
inet6 ::1/128 scope host
|
|
6
|
+
valid_lft forever preferred_lft forever
|
|
7
|
+
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
|
|
8
|
+
link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
|
|
9
|
+
inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0
|
|
10
|
+
valid_lft forever preferred_lft forever
|
|
11
|
+
inet6 fe80::42:aff:fe00:2/64 scope link
|
|
12
|
+
valid_lft forever preferred_lft forever`;
|
|
13
|
+
const ROUTE_OUTPUT = `default via 10.0.0.1 dev eth0
|
|
14
|
+
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.2`;
|
|
15
|
+
const LINK_OUTPUT = `1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
|
|
16
|
+
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
|
17
|
+
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
|
|
18
|
+
link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff`;
|
|
19
|
+
/**
|
|
20
|
+
* Show/manipulate routing, network devices, interfaces and tunnels.
|
|
21
|
+
* @category network
|
|
22
|
+
* @params ["<object> <command>"]
|
|
23
|
+
*/
|
|
24
|
+
export const ipCommand = {
|
|
25
|
+
name: "ip",
|
|
26
|
+
description: "Show/manipulate routing, network devices, interfaces",
|
|
27
|
+
category: "network",
|
|
28
|
+
params: ["<object> <command>"],
|
|
29
|
+
run: ({ args }) => {
|
|
30
|
+
const obj = args[0]?.toLowerCase();
|
|
31
|
+
const cmd = args[1]?.toLowerCase() ?? "show";
|
|
32
|
+
if (!obj) {
|
|
33
|
+
return { stderr: "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\nOBJECT := { link | addr | route | neigh }", exitCode: 1 };
|
|
34
|
+
}
|
|
35
|
+
if (obj === "addr" || obj === "address" || obj === "a") {
|
|
36
|
+
return { stdout: ADDR_OUTPUT, exitCode: 0 };
|
|
37
|
+
}
|
|
38
|
+
if (obj === "route" || obj === "r" || obj === "ro") {
|
|
39
|
+
return { stdout: ROUTE_OUTPUT, exitCode: 0 };
|
|
40
|
+
}
|
|
41
|
+
if (obj === "link" || obj === "l") {
|
|
42
|
+
return { stdout: LINK_OUTPUT, exitCode: 0 };
|
|
43
|
+
}
|
|
44
|
+
if (obj === "neigh" || obj === "n") {
|
|
45
|
+
return { stdout: "10.0.0.1 dev eth0 lladdr 02:42:0a:00:00:01 REACHABLE", exitCode: 0 };
|
|
46
|
+
}
|
|
47
|
+
if (["set", "add", "del", "flush", "change", "replace"].includes(cmd)) {
|
|
48
|
+
return { exitCode: 0 }; // silently succeed mutations
|
|
49
|
+
}
|
|
50
|
+
return { stderr: `ip: Object "${obj}" is unknown, try "ip help".`, exitCode: 1 };
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const jobsCommand = {
|
|
2
|
+
name: "jobs",
|
|
3
|
+
description: "List active jobs",
|
|
4
|
+
category: "shell",
|
|
5
|
+
params: [],
|
|
6
|
+
run: () => ({ stdout: "", exitCode: 0 }),
|
|
7
|
+
};
|
|
8
|
+
export const bgCommand = {
|
|
9
|
+
name: "bg",
|
|
10
|
+
description: "Resume a suspended job in the background",
|
|
11
|
+
category: "shell",
|
|
12
|
+
params: ["[%jobspec]"],
|
|
13
|
+
run: ({ args }) => ({
|
|
14
|
+
stderr: `bg: ${args[0] ?? "%1"}: no such job`,
|
|
15
|
+
exitCode: 1,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
export const fgCommand = {
|
|
19
|
+
name: "fg",
|
|
20
|
+
description: "Resume a suspended job in the foreground",
|
|
21
|
+
category: "shell",
|
|
22
|
+
params: ["[%jobspec]"],
|
|
23
|
+
run: ({ args }) => ({
|
|
24
|
+
stderr: `fg: ${args[0] ?? "%1"}: no such job`,
|
|
25
|
+
exitCode: 1,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShellModule } from "../types/commands";
|
|
2
|
+
/**
|
|
3
|
+
* Show listing of last logged in users.
|
|
4
|
+
* @category system
|
|
5
|
+
* @params ["[username]"]
|
|
6
|
+
*/
|
|
7
|
+
export declare const lastCommand: ShellModule;
|
|
8
|
+
/**
|
|
9
|
+
* Show system log messages.
|
|
10
|
+
* @category system
|
|
11
|
+
* @params ["[-n n]"]
|
|
12
|
+
*/
|
|
13
|
+
export declare const dmesgCommand: ShellModule;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { userHome } from "./runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Show listing of last logged in users.
|
|
4
|
+
* @category system
|
|
5
|
+
* @params ["[username]"]
|
|
6
|
+
*/
|
|
7
|
+
export const lastCommand = {
|
|
8
|
+
name: "last",
|
|
9
|
+
description: "Show listing of last logged in users",
|
|
10
|
+
category: "system",
|
|
11
|
+
params: ["[username]"],
|
|
12
|
+
run: ({ args, shell, authUser }) => {
|
|
13
|
+
const target = args[0] ?? authUser;
|
|
14
|
+
const logPath = `${userHome(target)}/.lastlog`;
|
|
15
|
+
const lines = [];
|
|
16
|
+
if (shell.vfs.exists(logPath)) {
|
|
17
|
+
try {
|
|
18
|
+
const log = JSON.parse(shell.vfs.readFile(logPath));
|
|
19
|
+
const d = new Date(log.at);
|
|
20
|
+
const ds = `${d.toDateString().slice(0, 3)} ${d.toLocaleString("en-US", {
|
|
21
|
+
month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false,
|
|
22
|
+
}).replace(",", "")}`;
|
|
23
|
+
lines.push(`${target.padEnd(10)} pts/0 ${(log.from ?? "browser").padEnd(16)} ${ds} still logged in`);
|
|
24
|
+
}
|
|
25
|
+
catch { }
|
|
26
|
+
}
|
|
27
|
+
lines.push("");
|
|
28
|
+
lines.push(`wtmp begins ${new Date().toDateString()}`);
|
|
29
|
+
return { stdout: lines.join("\n"), exitCode: 0 };
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Show system log messages.
|
|
34
|
+
* @category system
|
|
35
|
+
* @params ["[-n n]"]
|
|
36
|
+
*/
|
|
37
|
+
export const dmesgCommand = {
|
|
38
|
+
name: "dmesg",
|
|
39
|
+
description: "Print or control the kernel ring buffer",
|
|
40
|
+
category: "system",
|
|
41
|
+
params: ["[-n n]"],
|
|
42
|
+
run: ({ args }) => {
|
|
43
|
+
const n = args.includes("-n") ? parseInt(args[args.indexOf("-n") + 1] ?? "20", 10) : 20;
|
|
44
|
+
const msgs = [
|
|
45
|
+
"[ 0.000000] Booting Linux on physical CPU 0x0",
|
|
46
|
+
"[ 0.000000] Linux version 6.1.0-fortune (gcc version 12.2.0)",
|
|
47
|
+
"[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.1.0 root=/dev/sda1 ro quiet",
|
|
48
|
+
"[ 0.000000] BIOS-provided physical RAM map:",
|
|
49
|
+
"[ 0.000000] ACPI: IRQ0 used by override.",
|
|
50
|
+
"[ 0.125000] PCI: Using configuration type 1 for base access",
|
|
51
|
+
"[ 0.250000] clocksource: tsc-early: mask: 0xffffffffffffffff",
|
|
52
|
+
"[ 0.375000] CPU: Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz",
|
|
53
|
+
"[ 0.500000] Calibrating delay loop... 5800.00 BogoMIPS",
|
|
54
|
+
"[ 1.000000] NET: Registered PF_INET protocol family",
|
|
55
|
+
"[ 1.125000] virtio_net virtio0 eth0: renamed from eth0",
|
|
56
|
+
"[ 1.250000] EXT4-fs (sda1): mounted filesystem with ordered data mode",
|
|
57
|
+
"[ 1.375000] systemd[1]: systemd 252 running in system mode",
|
|
58
|
+
"[ 1.500000] systemd[1]: Reached target basic.system",
|
|
59
|
+
"[ 2.000000] audit: type=1403 audit(0.0:2): policy loaded",
|
|
60
|
+
"[ 2.125000] NET: Registered PF_PACKET protocol family",
|
|
61
|
+
"[ 2.250000] 8021q: 802.1Q VLAN Support v1.8",
|
|
62
|
+
"[ 2.375000] bridge: filtering via arp/ip/ip6tables is no longer available",
|
|
63
|
+
"[ 2.500000] Bluetooth: Core ver 2.22",
|
|
64
|
+
"[ 3.000000] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0",
|
|
65
|
+
].slice(0, n);
|
|
66
|
+
return { stdout: msgs.join("\n"), exitCode: 0 };
|
|
67
|
+
},
|
|
68
|
+
};
|