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
package/README.md
CHANGED
|
@@ -20,21 +20,9 @@
|
|
|
20
20
|
- [Web shell (browser)](#web-shell-browser)
|
|
21
21
|
- [Programmatic API](#programmatic-api)
|
|
22
22
|
- [How It Works](#how-it-works)
|
|
23
|
-
- [API Reference](#api-reference)
|
|
24
|
-
- [`VirtualSshServer`](#virtualsshserver)
|
|
25
|
-
- [`VirtualSftpServer`](#virtualsftpserver)
|
|
26
|
-
- [`VirtualShell`](#virtualshell)
|
|
27
|
-
- [`VirtualFileSystem`](#virtualfilesystem)
|
|
28
|
-
- [Mount API](#mount-api)
|
|
29
|
-
- [`VirtualUserManager`](#virtualusermanager)
|
|
30
|
-
- [`VirtualPackageManager`](#virtualpackagemanager)
|
|
31
|
-
- [Snapshot Diff Tooling](#snapshot-diff-tooling)
|
|
32
|
-
- [`HoneyPot`](#honeypot)
|
|
33
|
-
- [`SshClient`](#sshclient-programmatic-api)
|
|
34
|
-
- [Key Types](#key-types)
|
|
35
|
-
- [Command Helpers](#command-helpers)
|
|
23
|
+
- [API Reference](#api-reference)
|
|
36
24
|
- [Examples](#examples)
|
|
37
|
-
- [Built-in Commands (
|
|
25
|
+
- [Built-in Commands (106)](#built-in-commands-106)
|
|
38
26
|
- [Shell Scripting](#shell-scripting)
|
|
39
27
|
- [Linux Rootfs & VFS PATH Resolution](#linux-rootfs--vfs-path-resolution)
|
|
40
28
|
- [Configuration](#configuration)
|
|
@@ -56,8 +44,8 @@
|
|
|
56
44
|
| Mode | Entry point | Use case |
|
|
57
45
|
|------|-------------|----------|
|
|
58
46
|
| **SSH/SFTP server** | `VirtualSshServer` / `VirtualSftpServer` | Honeypots, remote testing, training environments |
|
|
59
|
-
| **Web shell** | `builds/fortune-nyx-v1.5.
|
|
60
|
-
| **Standalone CLI** | `builds/fortune-nyx-v1.5.
|
|
47
|
+
| **Web shell** | `builds/fortune-nyx-v1.5.5-web.min.js` (ESM) | Embedded terminals, interactive tutorials, browser demos |
|
|
48
|
+
| **Standalone CLI** | `builds/fortune-nyx-v1.5.5-directbash-k6.1.0.mjs` (single file) | Local shell, one-liner demos, no install required |
|
|
61
49
|
<!-- /BUILD:mode-table -->
|
|
62
50
|
|
|
63
51
|
All three modes share the same core: a pure in-memory VFS, a real shell interpreter, a virtual package manager, and a typed programmatic API.
|
|
@@ -78,17 +66,17 @@ npm install typescript-virtual-container
|
|
|
78
66
|
<!-- BUILD:curl-start -->
|
|
79
67
|
#### Interactivea local shell — persists VFS in .vfs/ in the current directory
|
|
80
68
|
```bash
|
|
81
|
-
curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.
|
|
69
|
+
curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.5-directbash-k6.1.0.mjs -o fortune-nyx-v1.5.5-directbash-k6.1.0.mjs && node fortune-nyx-v1.5.5-directbash-k6.1.0.mjs
|
|
82
70
|
```
|
|
83
71
|
|
|
84
72
|
#### SSH server (connect with any SSH client on port 2222)
|
|
85
73
|
```bash
|
|
86
|
-
curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.
|
|
74
|
+
curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.5-ssh.cjs -o fortune-nyx-v1.5.5-ssh.cjs && node fortune-nyx-v1.5.5-ssh.cjs
|
|
87
75
|
```
|
|
88
76
|
|
|
89
77
|
#### SSH server without SFTP (lighter build)
|
|
90
78
|
```bash
|
|
91
|
-
curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.
|
|
79
|
+
curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.5-ssh-nosftp.js -o fortune-nyx-v1.5.5-ssh-nosftp.js && node fortune-nyx-v1.5.5-ssh-nosftp.js
|
|
92
80
|
```
|
|
93
81
|
<!-- /BUILD:curl-start -->
|
|
94
82
|
|
|
@@ -96,13 +84,13 @@ curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-cont
|
|
|
96
84
|
> The standalone builds are intended for quick demos and testing. For production use, it's recommended to install the package and import the relevant classes directly in your codebase for better performance, stability, and security.
|
|
97
85
|
|
|
98
86
|
<!-- BUILD:selfStandalone-options -->
|
|
99
|
-
**`fortune-nyx-v1.5.
|
|
87
|
+
**`fortune-nyx-v1.5.5-directbash-k6.1.0.mjs` options:**
|
|
100
88
|
|
|
101
89
|
```bash
|
|
102
|
-
node fortune-nyx-v1.5.
|
|
103
|
-
node fortune-nyx-v1.5.
|
|
104
|
-
node fortune-nyx-v1.5.
|
|
105
|
-
SSH_MIMIC_HOSTNAME=my-box node fortune-nyx-v1.5.
|
|
90
|
+
node fortune-nyx-v1.5.5-directbash-k6.1.0.mjs # boot as root
|
|
91
|
+
node fortune-nyx-v1.5.5-directbash-k6.1.0.mjs --user alice # boot as alice (prompts for password if set)
|
|
92
|
+
node fortune-nyx-v1.5.5-directbash-k6.1.0.mjs --user=alice # same, inline form
|
|
93
|
+
SSH_MIMIC_HOSTNAME=my-box node fortune-nyx-v1.5.5-directbash-k6.1.0.mjs # custom hostname
|
|
106
94
|
```
|
|
107
95
|
<!-- /BUILD:selfStandalone-options -->
|
|
108
96
|
|
|
@@ -129,7 +117,7 @@ Two browser bundles are available:
|
|
|
129
117
|
<!-- BUILD:web-table -->
|
|
130
118
|
| Bundle | Format | Entry point | Use case |
|
|
131
119
|
|--------|--------|-------------|----------|
|
|
132
|
-
| `builds/fortune-nyx-v1.5.
|
|
120
|
+
| `builds/fortune-nyx-v1.5.5-web.min.js` | ESM | `createWebShell()` | Embedded terminals, modern bundlers |
|
|
133
121
|
<!-- /BUILD:web-table -->
|
|
134
122
|
|
|
135
123
|
Both bundles persist the VFS in **IndexedDB** — state survives page reloads.
|
|
@@ -141,11 +129,11 @@ bun run build-all # rebuild everything
|
|
|
141
129
|
```
|
|
142
130
|
|
|
143
131
|
<!-- BUILD:web-options -->
|
|
144
|
-
**`fortune-nyx-v1.5.
|
|
132
|
+
**`fortune-nyx-v1.5.5-web.min.js`** — lightweight shell with IndexedDB VFS:
|
|
145
133
|
|
|
146
134
|
```html
|
|
147
135
|
<script type="module">
|
|
148
|
-
import { createWebShell } from "./builds/fortune-nyx-v1.5.
|
|
136
|
+
import { createWebShell } from "./builds/fortune-nyx-v1.5.5-web.min.js";
|
|
149
137
|
|
|
150
138
|
const shell = createWebShell("web-vm", {
|
|
151
139
|
vfs: { databaseName: "virtual-env-js", storeName: "vfs" },
|
|
@@ -157,11 +145,11 @@ bun run build-all # rebuild everything
|
|
|
157
145
|
</script>
|
|
158
146
|
```
|
|
159
147
|
|
|
160
|
-
**`fortune-nyx-v1.5.
|
|
148
|
+
**`fortune-nyx-v1.5.5-web.min.js`** — mirrors the `VirtualShell` programmatic API:
|
|
161
149
|
|
|
162
150
|
```html
|
|
163
151
|
<script type="module">
|
|
164
|
-
import { createVirtualShellShim } from "./builds/fortune-nyx-v1.5.
|
|
152
|
+
import { createVirtualShellShim } from "./builds/fortune-nyx-v1.5.5-web.min.js";
|
|
165
153
|
|
|
166
154
|
const shell = createVirtualShellShim("web-vm");
|
|
167
155
|
await shell.ensureInitialized();
|
|
@@ -242,502 +230,6 @@ console.log(r.stdout);
|
|
|
242
230
|
<!-- https://itsrealfortune.fr/typescript-virtual-container/ -->
|
|
243
231
|
API reference for all core classes and utilities. Designed for quick lookup while developing with the library. More extensive documentation, examples, and guides are available in <a href="https://itsrealfortune.fr/typescript-virtual-container/">the documentation</a>.
|
|
244
232
|
|
|
245
|
-
### `VirtualSshServer`
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
new VirtualSshServer({
|
|
249
|
-
port: number;
|
|
250
|
-
hostname?: string; // default: "typescript-vm"
|
|
251
|
-
shell?: VirtualShell; // share state with SFTP server
|
|
252
|
-
maxAuthAttempts?: number; // default: 5
|
|
253
|
-
lockoutDurationMs?: number; // default: 60_000
|
|
254
|
-
})
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
If `shell` is omitted, the server creates `new VirtualShell(hostname)` internally.
|
|
258
|
-
|
|
259
|
-
**Methods**
|
|
260
|
-
|
|
261
|
-
| Method | Description |
|
|
262
|
-
|--------|-------------|
|
|
263
|
-
| `start(): Promise<number>` | Initialize VFS, users, start listening. Returns bound port. |
|
|
264
|
-
| `stop(): void` | Gracefully close server and all active connections. |
|
|
265
|
-
| `clearLockout(ip): void` | Manually lift a rate-limit lockout for an IP. |
|
|
266
|
-
| `getVfs(): VirtualFileSystem \| null` | Access VFS instance (null before start). |
|
|
267
|
-
| `getUsers(): VirtualUserManager \| null` | Access user manager (null before start). |
|
|
268
|
-
| `getHostname(): string` | Returns configured hostname. |
|
|
269
|
-
|
|
270
|
-
**Events**
|
|
271
|
-
|
|
272
|
-
| Event | Data | Description |
|
|
273
|
-
|-------|------|-------------|
|
|
274
|
-
| `start` | `{ port }` | Server started |
|
|
275
|
-
| `stop` | — | Server stopped |
|
|
276
|
-
| `auth:success` | `{ username, remoteAddress, method? }` | Authenticated |
|
|
277
|
-
| `auth:failure` | `{ username, remoteAddress, reason?, method? }` | Auth failed |
|
|
278
|
-
| `auth:lockout` | `{ ip, until: Date }` | IP locked out |
|
|
279
|
-
| `client:connect` | — | New SSH client connected |
|
|
280
|
-
| `client:disconnect` | `{ user }` | SSH client disconnected |
|
|
281
|
-
|
|
282
|
-
---
|
|
283
|
-
|
|
284
|
-
### `VirtualSftpServer`
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
new VirtualSftpServer({
|
|
288
|
-
port: number;
|
|
289
|
-
hostname?: string;
|
|
290
|
-
shell?: VirtualShell; // share state with SSH server (recommended)
|
|
291
|
-
vfs?: VirtualFileSystem; // explicit if no shell
|
|
292
|
-
users?: VirtualUserManager; // explicit if no shell
|
|
293
|
-
})
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
Supports `password` and `keyboard-interactive` auth. Confines all operations to `/home/<user>`. Unsupported operations return `OP_UNSUPPORTED`.
|
|
297
|
-
|
|
298
|
-
**Methods:** `start(): Promise<number>`, `stop(): void`
|
|
299
|
-
|
|
300
|
-
**Events:** `start`, `stop`, `auth:success { username, remoteAddress }`, `auth:failure { username, remoteAddress }`, `client:connect`, `client:disconnect { user }`
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
### `VirtualShell`
|
|
305
|
-
|
|
306
|
-
Coordinates the VFS, user manager, package manager, and command runtime.
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
new VirtualShell(
|
|
310
|
-
hostname: string,
|
|
311
|
-
properties?: ShellProperties, // kernel, os, arch — surfaced by uname/neofetch
|
|
312
|
-
vfsOptions?: VfsOptions, // { mode: "memory"|"fs", snapshotPath?: string }
|
|
313
|
-
)
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
interface ShellProperties {
|
|
318
|
-
kernel: string; // e.g. "1.0.0+itsrealfortune+1-amd64"
|
|
319
|
-
os: string; // e.g. "Fortune GNU/Linux x64"
|
|
320
|
-
arch: string; // e.g. "x86_64"
|
|
321
|
-
}
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
**Methods**
|
|
325
|
-
|
|
326
|
-
| Method | Description |
|
|
327
|
-
|--------|-------------|
|
|
328
|
-
| `ensureInitialized(): Promise<void>` | Await before using programmatically. |
|
|
329
|
-
| `addCommand(name, params, callback)` | Register a custom shell command. |
|
|
330
|
-
| `executeCommand(rawInput, authUser, cwd)` | Run a raw command string. |
|
|
331
|
-
| `startInteractiveSession(stream, authUser, sessionId, remoteAddress, terminalSize)` | Attach a PTY session. |
|
|
332
|
-
| `writeFileAsUser(authUser, path, content)` | Write with quota enforcement. |
|
|
333
|
-
| `refreshProcFs(): void` | Refresh all `/proc/*` files (uptime, meminfo, cpuinfo, per-pid). |
|
|
334
|
-
| `refreshProcSessions(): void` | Lightweight refresh of `/proc/<pid>` and `/proc/self` only. |
|
|
335
|
-
| `mount(vPath, hostPath, options?): void` | Mount a host directory into the VFS. See [Mount API](#mount-api). |
|
|
336
|
-
| `unmount(vPath): void` | Remove a host directory mount. |
|
|
337
|
-
| `getMounts()` | List all active mounts as `{ vPath, hostPath, readOnly }[]`. |
|
|
338
|
-
| `syncPasswd(): void` | Sync `/etc/passwd`, `/etc/group`, `/etc/shadow` from user manager. |
|
|
339
|
-
| `getVfs(): VirtualFileSystem \| null` | Access VFS instance. |
|
|
340
|
-
| `getUsers(): VirtualUserManager \| null` | Access user manager. |
|
|
341
|
-
| `getHostname(): string` | Returns configured hostname. |
|
|
342
|
-
|
|
343
|
-
**Public fields**
|
|
344
|
-
|
|
345
|
-
| Field | Type | Description |
|
|
346
|
-
|-------|------|-------------|
|
|
347
|
-
| `vfs` | `VirtualFileSystem` | Backing virtual filesystem. |
|
|
348
|
-
| `users` | `VirtualUserManager` | Virtual user database. |
|
|
349
|
-
| `packageManager` | `VirtualPackageManager` | APT/dpkg package manager. |
|
|
350
|
-
| `hostname` | `string` | Hostname shown in prompt and SSH ident. |
|
|
351
|
-
| `properties` | `ShellProperties` | Distro identity strings. |
|
|
352
|
-
| `startTime` | `number` | Unix ms timestamp of shell creation. |
|
|
353
|
-
|
|
354
|
-
**Events:** `initialized`, `command { command, user, cwd }`, `session:start { user, sessionId, remoteAddress }`
|
|
355
|
-
|
|
356
|
-
**Custom command example:**
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
shell.addCommand("greet", ["[name]"], ({ args, authUser }) => {
|
|
360
|
-
const name = args[0] ?? authUser;
|
|
361
|
-
return { stdout: `Hello, ${name}!\n`, exitCode: 0 };
|
|
362
|
-
});
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
### `VirtualFileSystem`
|
|
368
|
-
|
|
369
|
-
Pure in-memory virtual filesystem. No host filesystem access at runtime.
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
// Memory mode (default) — ephemeral
|
|
373
|
-
new VirtualFileSystem()
|
|
374
|
-
|
|
375
|
-
// FS mode — persists to binary .vfsb file
|
|
376
|
-
new VirtualFileSystem({ mode: "fs", snapshotPath: "./data" })
|
|
377
|
-
await vfs.restoreMirror(); // load from disk (no-op if no file yet)
|
|
378
|
-
await vfs.flushMirror(); // save to disk
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
**Methods**
|
|
382
|
-
|
|
383
|
-
| Method | Description |
|
|
384
|
-
|--------|-------------|
|
|
385
|
-
| `mkdir(path, mode?)` | Create directory and any missing parents. |
|
|
386
|
-
| `writeFile(path, content, options?)` | Write file. `options.compress` gzips; `options.mode` sets POSIX mode bits. |
|
|
387
|
-
| `readFile(path): string` | Read as UTF-8. Transparently decompresses gzip. |
|
|
388
|
-
| `readFileRaw(path): Buffer` | Read as Buffer. |
|
|
389
|
-
| `exists(path): boolean` | Test existence. |
|
|
390
|
-
| `stat(path): VfsNodeStats` | Returns metadata. |
|
|
391
|
-
| `list(path?): string[]` | List direct children (sorted). |
|
|
392
|
-
| `tree(path?): string` | Render ASCII directory tree. |
|
|
393
|
-
| `move(from, to)` | Move or rename. |
|
|
394
|
-
| `remove(path, options?)` | Delete. `options.recursive` required for non-empty dirs. |
|
|
395
|
-
| `chmod(path, mode)` | Update POSIX mode bits. |
|
|
396
|
-
| `compressFile(path)` / `decompressFile(path)` | Gzip-compress / gunzip in place. |
|
|
397
|
-
| `symlink(target, linkPath)` | Create symbolic link. |
|
|
398
|
-
| `isSymlink(path): boolean` | Test if path is a symlink. |
|
|
399
|
-
| `resolveSymlink(path, maxDepth?): string` | Resolve symlink chain (default max 8 hops). |
|
|
400
|
-
| `getUsageBytes(path?): number` | Total stored bytes under a path. |
|
|
401
|
-
| `toSnapshot(): VfsSnapshot` | Export tree as JSON-serialisable snapshot. |
|
|
402
|
-
| `importSnapshot(snapshot)` | Replace current state from a snapshot. |
|
|
403
|
-
| `restoreMirror(): Promise<void>` | Load from disk (`"fs"` mode) / no-op otherwise. |
|
|
404
|
-
| `flushMirror(): Promise<void>` | Save to disk (`"fs"` mode) / emit event otherwise. |
|
|
405
|
-
| `VirtualFileSystem.fromSnapshot(snapshot)` | **Static.** Create memory-mode instance from snapshot. |
|
|
406
|
-
|
|
407
|
-
**Events:** `file:write { path, size }`, `file:read { path, size }`, `dir:create { path, mode }`, `node:remove { path }`, `symlink:create { link, target }`, `snapshot:import`, `snapshot:restore { path }`, `mirror:flush { path? }`
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
#### Mount API
|
|
411
|
-
|
|
412
|
-
Mount a host directory inside the VM — all standard VFS operations (`readFile`, `writeFile`, `exists`, `stat`, `list`) are transparently delegated to the host filesystem.
|
|
413
|
-
|
|
414
|
-
> **Node.js only.** In browser environments `mount()` is a silent no-op — the `vPath` remains an empty in-memory directory.
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
// Read-only mount (default) — shell commands can read host files
|
|
418
|
-
shell.mount("/workspace", "./my-project");
|
|
419
|
-
|
|
420
|
-
// Read-write mount — shell commands can also write back to the host
|
|
421
|
-
shell.mount("/data", "./data", { readOnly: false });
|
|
422
|
-
|
|
423
|
-
// Unmount — delegation removed, vPath stays as an empty VFS directory
|
|
424
|
-
shell.unmount("/workspace");
|
|
425
|
-
|
|
426
|
-
// Introspect
|
|
427
|
-
shell.getMounts();
|
|
428
|
-
// → [{ vPath: "/workspace", hostPath: "/abs/path/my-project", readOnly: true }]
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
Direct VFS usage:
|
|
432
|
-
|
|
433
|
-
```typescript
|
|
434
|
-
shell.vfs.mount("/workspace", "./my-project");
|
|
435
|
-
shell.vfs.unmount("/workspace");
|
|
436
|
-
shell.vfs.getMounts();
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
**Events:** `mount { vPath, hostPath, readOnly }`, `unmount { vPath }`
|
|
440
|
-
|
|
441
|
-
**Snapshot behaviour:** mounted files are **not** included in `toSnapshot()` — only the in-memory VFS tree is serialised. The mount configuration itself is also not persisted; restore it after each `fromSnapshot()` or `restoreMirror()`.
|
|
442
|
-
|
|
443
|
-
#### VFSB Binary Format
|
|
444
|
-
|
|
445
|
-
In `"fs"` mode, state is persisted as a compact binary file (`vfs-snapshot.vfsb`).
|
|
446
|
-
|
|
447
|
-
| Metric | JSON+base64 | VFSB binary |
|
|
448
|
-
|--------|-------------|-------------|
|
|
449
|
-
| File size (10 MB content) | ~13.7 MB | ~10.0 MB |
|
|
450
|
-
| Encode time | ~12 ms | ~0.04 ms |
|
|
451
|
-
| Decode time | ~18 ms | ~0.07 ms |
|
|
452
|
-
|
|
453
|
-
Wire format: 5-byte header (`VFS!` magic + version), followed by a recursive node tree with type, name, mode, timestamps, and raw content bytes (no base64). Legacy JSON snapshots are auto-detected and migrated on first `flushMirror()`.
|
|
454
|
-
|
|
455
|
-
Low-level API:
|
|
456
|
-
```typescript
|
|
457
|
-
import { encodeVfs, decodeVfs, isBinarySnapshot } from "typescript-virtual-container/src/VirtualFileSystem/binaryPack";
|
|
458
|
-
const buf = encodeVfs(vfs.root);
|
|
459
|
-
const root = decodeVfs(buf);
|
|
460
|
-
isBinarySnapshot(buf); // true — starts with "VFS!" magic
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
---
|
|
464
|
-
|
|
465
|
-
### `VirtualUserManager`
|
|
466
|
-
|
|
467
|
-
Manages users, password hashing (scrypt), sudo privileges, storage quotas, SSH public keys, and session tracking.
|
|
468
|
-
|
|
469
|
-
```typescript
|
|
470
|
-
new VirtualUserManager(
|
|
471
|
-
vfs: VirtualFileSystem,
|
|
472
|
-
autoSudoForNewUsers?: boolean, // default: true
|
|
473
|
-
)
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
Auth data is stored at `/etc/` inside the VFS.
|
|
477
|
-
|
|
478
|
-
**Methods**
|
|
479
|
-
|
|
480
|
-
| Method | Description |
|
|
481
|
-
|--------|-------------|
|
|
482
|
-
| `initialize(): Promise<void>` | Load users/sudoers, ensure root exists. |
|
|
483
|
-
| `verifyPassword(username, password): boolean` | Check plaintext password. |
|
|
484
|
-
| `hasPassword(username): boolean` | Returns `true` if a password is set. |
|
|
485
|
-
| `hashPassword(password): string` | Hash with scrypt (or SHA-256 with `SSH_MIMIC_FAST_PASSWORD_HASH=1`). |
|
|
486
|
-
| `getPasswordHash(username): string \| null` | Raw stored hash. |
|
|
487
|
-
| `addUser(username, password): Promise<void>` | Create user with home directory. |
|
|
488
|
-
| `deleteUser(username): Promise<void>` | Delete user. Throws on `root` or missing user. |
|
|
489
|
-
| `setPassword(username, password): Promise<void>` | Update password. |
|
|
490
|
-
| `isSudoer(username): boolean` | Returns `true` if user has sudo. |
|
|
491
|
-
| `addSudoer(username): Promise<void>` | Grant sudo. |
|
|
492
|
-
| `removeSudoer(username): Promise<void>` | Revoke sudo. Throws on `root`. |
|
|
493
|
-
| `setQuotaBytes(username, maxBytes): Promise<void>` | Set per-user write quota. |
|
|
494
|
-
| `clearQuota(username): Promise<void>` | Remove quota limit. |
|
|
495
|
-
| `getQuotaBytes(username): number \| null` | Quota in bytes, or `null` if unlimited. |
|
|
496
|
-
| `getUsageBytes(username): number` | Current usage under `/home/<user>`. |
|
|
497
|
-
| `assertWriteWithinQuota(username, path, content)` | Throws if write would exceed quota. |
|
|
498
|
-
| `listUsers(): string[]` | Sorted list of all usernames. |
|
|
499
|
-
| `addAuthorizedKey(username, algo, data)` | Register SSH public key. |
|
|
500
|
-
| `getAuthorizedKeys(username)` | List authorized keys. |
|
|
501
|
-
| `removeAuthorizedKeys(username)` | Revoke all authorized keys. |
|
|
502
|
-
| `registerSession(username, remoteAddress): VirtualActiveSession` | Allocate virtual TTY and register session. |
|
|
503
|
-
| `unregisterSession(sessionId): void` | Remove session on disconnect. Safe with `null`. |
|
|
504
|
-
| `updateSession(sessionId, username, remoteAddress): void` | Update after `su`/`sudo` identity change. |
|
|
505
|
-
| `listActiveSessions(): VirtualActiveSession[]` | All active sessions sorted by start time. |
|
|
506
|
-
|
|
507
|
-
**Events:** `initialized`, `user:add { username }`, `user:delete { username }`, `key:add { username, algo }`, `key:remove { username }`, `session:register { sessionId, username, remoteAddress }`, `session:unregister { sessionId, username }`
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
### `VirtualPackageManager`
|
|
512
|
-
|
|
513
|
-
Simulates APT/dpkg backed by a 25-package registry. Accessed via `shell.packageManager`.
|
|
514
|
-
|
|
515
|
-
**Methods**
|
|
516
|
-
|
|
517
|
-
| Method | Description |
|
|
518
|
-
|--------|-------------|
|
|
519
|
-
| `install(names, opts?)` | Install packages (resolves deps, writes files to VFS). Returns `{ output, exitCode }` |
|
|
520
|
-
| `remove(names, opts?)` | Remove. `opts.purge` also removes config files. |
|
|
521
|
-
| `search(term)` | Search by name or description. |
|
|
522
|
-
| `show(name)` | dpkg-style metadata block. |
|
|
523
|
-
| `listInstalled()` | All installed packages as `InstalledPackage[]`. |
|
|
524
|
-
| `listAvailable()` | All registry packages. |
|
|
525
|
-
| `isInstalled(name)` | Returns `true` if installed. |
|
|
526
|
-
| `installedCount()` | Count of installed packages. |
|
|
527
|
-
| `findInRegistry(name)` | Look up `PackageDefinition` by name. |
|
|
528
|
-
|
|
529
|
-
**Custom packages:**
|
|
530
|
-
|
|
531
|
-
```typescript
|
|
532
|
-
const customPkg = {
|
|
533
|
-
name: "myapp",
|
|
534
|
-
version: "1.0.0",
|
|
535
|
-
description: "My application",
|
|
536
|
-
files: [
|
|
537
|
-
{ path: "/usr/bin/myapp", content: "#!/bin/sh\necho myapp v1.0.0\n", mode: 0o755 },
|
|
538
|
-
{ path: "/etc/myapp/config.json", content: JSON.stringify({ port: 3000 }) },
|
|
539
|
-
],
|
|
540
|
-
onInstall: (vfs) => {
|
|
541
|
-
vfs.mkdir("/var/lib/myapp", 0o755);
|
|
542
|
-
vfs.mkdir("/var/log/myapp", 0o755);
|
|
543
|
-
},
|
|
544
|
-
};
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
---
|
|
548
|
-
|
|
549
|
-
### Snapshot Diff Tooling
|
|
550
|
-
|
|
551
|
-
```typescript
|
|
552
|
-
import { diffSnapshots, formatDiff, assertDiff } from "typescript-virtual-container";
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
**`diffSnapshots(before, after, options?): VfsDiff`**
|
|
556
|
-
|
|
557
|
-
```typescript
|
|
558
|
-
const before = shell.vfs.toSnapshot();
|
|
559
|
-
await client.exec("apt install vim && mkdir -p /app");
|
|
560
|
-
const after = shell.vfs.toSnapshot();
|
|
561
|
-
|
|
562
|
-
const diff = diffSnapshots(before, after, { ignore: ["/proc", "/var/log"] });
|
|
563
|
-
diff.clean; // false
|
|
564
|
-
diff.added; // [{ path: "/usr/bin/vim", type: "file" }, ...]
|
|
565
|
-
diff.modified; // [{ path: "/var/lib/dpkg/status", before: "...", after: "..." }]
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
**`formatDiff(diff, options?): string`** — human-readable output like `git diff --stat`. Options: `showContent: boolean`, `maxContentChars: number`.
|
|
569
|
-
|
|
570
|
-
**`assertDiff(diff, expected): void`** — throws on mismatch, designed for test suites:
|
|
571
|
-
|
|
572
|
-
```typescript
|
|
573
|
-
assertDiff(diff, { added: ["/app", "/usr/bin/vim"], modified: ["/var/lib/dpkg/status"] });
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
---
|
|
577
|
-
|
|
578
|
-
### `HoneyPot`
|
|
579
|
-
|
|
580
|
-
Comprehensive security auditing. Attaches to all core components to log activity and detect anomalies.
|
|
581
|
-
|
|
582
|
-
```typescript
|
|
583
|
-
new HoneyPot(maxLogSize?: number) // default: 10000
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
**Methods**
|
|
587
|
-
|
|
588
|
-
| Method | Description |
|
|
589
|
-
|--------|-------------|
|
|
590
|
-
| `attach(shell, vfs, users, ssh?, sftp?)` | Subscribe to all event sources. |
|
|
591
|
-
| `getAuditLog(type?, source?): AuditLogEntry[]` | Full log, optionally filtered. |
|
|
592
|
-
| `getStats(): Readonly<HoneyPotStats>` | Aggregated activity counters. |
|
|
593
|
-
| `getRecent(limit?): AuditLogEntry[]` | Most recent entries, reverse-chronological. |
|
|
594
|
-
| `detectAnomalies()` | Returns `{ type, severity, message }[]`. |
|
|
595
|
-
| `reset()` | Clear log and reset counters. |
|
|
596
|
-
| `exportJson(): string` | Serialise full log + stats to JSON. |
|
|
597
|
-
|
|
598
|
-
`detectAnomalies` detects: high auth failure rates, excessive failures, unusual command volume, unusual file write volume.
|
|
599
|
-
|
|
600
|
-
```typescript
|
|
601
|
-
const hp = new HoneyPot(50_000);
|
|
602
|
-
hp.attach(shell, shell.vfs, shell.users, ssh);
|
|
603
|
-
|
|
604
|
-
hp.getAuditLog("auth:failure").forEach(e =>
|
|
605
|
-
console.log(e.details.username, e.details.remoteAddress)
|
|
606
|
-
);
|
|
607
|
-
|
|
608
|
-
hp.detectAnomalies().forEach(a =>
|
|
609
|
-
console.log(`[${a.severity.toUpperCase()}] ${a.type}: ${a.message}`)
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
process.on("SIGINT", () => {
|
|
613
|
-
require("fs").writeFileSync("audit.json", hp.exportJson());
|
|
614
|
-
process.exit(0);
|
|
615
|
-
});
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
---
|
|
619
|
-
|
|
620
|
-
### `SshClient` (Programmatic API)
|
|
621
|
-
|
|
622
|
-
Execute shell commands against a `VirtualShell` without SSH overhead. Maintains working-directory state.
|
|
623
|
-
|
|
624
|
-
```typescript
|
|
625
|
-
new SshClient(shell: VirtualShell, username: string)
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
**Methods**
|
|
629
|
-
|
|
630
|
-
| Method | Description |
|
|
631
|
-
|--------|-------------|
|
|
632
|
-
| `exec(command): Promise<CommandResult>` | Run raw command string (supports `&&`, `\|`, etc.). |
|
|
633
|
-
| `ls(path?)` | List directory. |
|
|
634
|
-
| `pwd()` | Print current working directory. |
|
|
635
|
-
| `cd(path)` | Change directory. Updates internal cwd on success. |
|
|
636
|
-
| `cat(path)` | Read file via `cat` command. |
|
|
637
|
-
| `readFile(path)` | Read file directly from VFS. |
|
|
638
|
-
| `writeFile(path, content)` | Write file directly to VFS. |
|
|
639
|
-
| `mkdir(path, recursive?)` | Create directory. |
|
|
640
|
-
| `touch(path)` | Create empty file. |
|
|
641
|
-
| `rm(path, recursive?)` | Remove file or directory. |
|
|
642
|
-
| `tree(path?)` | Render ASCII directory tree. |
|
|
643
|
-
| `whoami()` / `hostname()` / `who()` | System info commands. |
|
|
644
|
-
| `getCwd(): string` | Returns current cwd (no I/O). |
|
|
645
|
-
| `getUsername(): string` | Returns authenticated username. |
|
|
646
|
-
|
|
647
|
-
---
|
|
648
|
-
|
|
649
|
-
### Key Types
|
|
650
|
-
|
|
651
|
-
```typescript
|
|
652
|
-
interface CommandResult {
|
|
653
|
-
stdout?: string;
|
|
654
|
-
stderr?: string;
|
|
655
|
-
exitCode?: number;
|
|
656
|
-
nextCwd?: string;
|
|
657
|
-
clearScreen?: boolean;
|
|
658
|
-
closeSession?: boolean;
|
|
659
|
-
switchUser?: string;
|
|
660
|
-
openEditor?: NanoEditorSession;
|
|
661
|
-
openHtop?: boolean;
|
|
662
|
-
sudoChallenge?: SudoChallenge;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
interface ShellEnv {
|
|
666
|
-
vars: Record<string, string>; // $VAR accessible in expansions
|
|
667
|
-
lastExitCode: number; // $?
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
interface ShellModule {
|
|
671
|
-
name: string;
|
|
672
|
-
params: string[];
|
|
673
|
-
aliases?: string[];
|
|
674
|
-
description?: string;
|
|
675
|
-
category?: string; // navigation|files|text|archive|system|package|network|shell|users|misc
|
|
676
|
-
run: (ctx: CommandContext) => CommandResult | Promise<CommandResult>;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
interface CommandContext {
|
|
680
|
-
authUser: string;
|
|
681
|
-
hostname: string;
|
|
682
|
-
activeSessions: VirtualActiveSession[];
|
|
683
|
-
rawInput: string;
|
|
684
|
-
mode: "shell" | "exec";
|
|
685
|
-
args: string[];
|
|
686
|
-
stdin?: string;
|
|
687
|
-
cwd: string;
|
|
688
|
-
shell: VirtualShell;
|
|
689
|
-
env: ShellEnv;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
interface VirtualActiveSession {
|
|
693
|
-
id: string;
|
|
694
|
-
username: string;
|
|
695
|
-
tty: string;
|
|
696
|
-
remoteAddress: string;
|
|
697
|
-
startedAt: string; // ISO-8601
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/** Returned by adduser, passwd, deluser — triggers interactive password prompt in the terminal. */
|
|
701
|
-
interface PasswordChallenge {
|
|
702
|
-
preamble?: string; // Lines printed before the first prompt
|
|
703
|
-
prompt: string; // e.g. "New password: "
|
|
704
|
-
confirmPrompt?: string; // Second prompt for confirmation
|
|
705
|
-
confirmText?: string; // Destructive confirmation prompt (y/N)
|
|
706
|
-
action: "adduser" | "passwd" | "deluser" | "su";
|
|
707
|
-
targetUsername: string;
|
|
708
|
-
newUsername?: string; // adduser only
|
|
709
|
-
}
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
---
|
|
713
|
-
|
|
714
|
-
### Command Helpers
|
|
715
|
-
|
|
716
|
-
```typescript
|
|
717
|
-
import { ifFlag, getFlag, getArg, parseArgs } from "typescript-virtual-container";
|
|
718
|
-
|
|
719
|
-
// ifFlag — true if any given flag appears in args
|
|
720
|
-
ifFlag(args, ["-r", "--recursive"]) // boolean
|
|
721
|
-
|
|
722
|
-
// getFlag — value, true if valueless, undefined if absent
|
|
723
|
-
getFlag(args, ["-o", "--output"])
|
|
724
|
-
// ["--output", "file.txt"] → "file.txt"
|
|
725
|
-
// ["--output=file.txt"] → "file.txt"
|
|
726
|
-
// ["--verbose"] → true
|
|
727
|
-
// [] → undefined
|
|
728
|
-
|
|
729
|
-
// getArg — positional at index N, skipping known flags
|
|
730
|
-
// args = ["-r", "src", "dest"]
|
|
731
|
-
getArg(args, 0, { flags: ["-r"] }) // "src"
|
|
732
|
-
getArg(args, 1, { flags: ["-r"] }) // "dest"
|
|
733
|
-
|
|
734
|
-
// parseArgs — structured parse
|
|
735
|
-
const { flags, flagsWithValues, positionals } = parseArgs(args, {
|
|
736
|
-
flags: ["-r", "--recursive"],
|
|
737
|
-
flagsWithValue: ["-o", "--output"],
|
|
738
|
-
});
|
|
739
|
-
```
|
|
740
|
-
|
|
741
233
|
</details>
|
|
742
234
|
|
|
743
235
|
---
|
|
@@ -983,9 +475,9 @@ echo "Welcome back, root!"
|
|
|
983
475
|
---
|
|
984
476
|
|
|
985
477
|
<details>
|
|
986
|
-
<summary><strong>Built-in Commands (
|
|
478
|
+
<summary><strong>Built-in Commands (106)</strong></summary>
|
|
987
479
|
|
|
988
|
-
Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage. Type `man <command>` for full manual pages — all
|
|
480
|
+
Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage. Type `man <command>` for full manual pages — all 106 commands are documented.
|
|
989
481
|
|
|
990
482
|
### Navigation
|
|
991
483
|
|
|
@@ -1029,6 +521,9 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
|
|
|
1029
521
|
| `tee [files]` | `-a` | Read stdin, write to stdout and files |
|
|
1030
522
|
| `tr <set1> [set2]` | `-d` | Translate or delete characters |
|
|
1031
523
|
| `uniq` | `-c` `-d` `-u` | Filter repeated lines |
|
|
524
|
+
| `basename <path> [suffix]` | `-a` `-s` | Strip directory and suffix from path |
|
|
525
|
+
| `dirname <path>` | | Strip last component from path |
|
|
526
|
+
| `file <path...>` | | Determine file type (magic bytes) |
|
|
1032
527
|
| `wc [files]` | `-l` `-w` `-c` | Word/line/byte count |
|
|
1033
528
|
| `xargs [cmd]` | | Build and execute commands from stdin |
|
|
1034
529
|
|
|
@@ -1051,7 +546,10 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
|
|
|
1051
546
|
| `hostname` | | Print hostname |
|
|
1052
547
|
| `htop` | | System monitor (mock) |
|
|
1053
548
|
| `id [user]` | | User identity (uid/gid/groups) |
|
|
549
|
+
| `dmesg` | `-n` | Print kernel ring buffer messages |
|
|
550
|
+
| `ip <object>` | `addr` `route` `link` `neigh` | Modern network interface/routing tool |
|
|
1054
551
|
| `kill [-9] <pid>` | | Send signal (mock) |
|
|
552
|
+
| `last [user]` | | Show login history |
|
|
1055
553
|
| `lsb_release` | `-a` `-i` `-d` `-r` `-c` | Distribution info |
|
|
1056
554
|
| `neofetch` | | System info (real package count and uptime) |
|
|
1057
555
|
| `node` | `--version` `-e` `-p` | Virtual JS runtime; **requires `apt install nodejs`** |
|
|
@@ -1063,6 +561,7 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
|
|
|
1063
561
|
| `sleep <seconds>` | | Delay execution |
|
|
1064
562
|
| `uname` | `-a` `-r` `-m` | System information |
|
|
1065
563
|
| `uptime` | `-p` `-s` | Running time |
|
|
564
|
+
| `w` | | Who is logged on and what they are doing |
|
|
1066
565
|
| `who` | | Active sessions |
|
|
1067
566
|
| `whoami` | | Current user |
|
|
1068
567
|
|
|
@@ -1097,12 +596,25 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
|
|
|
1097
596
|
| `source <file>` | | Execute file in current env; alias `.` |
|
|
1098
597
|
| `test <expr>` / `[ <expr> ]` | | POSIX conditional: `-f` `-d` `-e` `-z` `-n` `-x` `-s` `=` `!=` `-eq` `-lt` `-gt` `-le` `-ge` `!` `-a` `-o` |
|
|
1099
598
|
| `trap [action] [signal]` | | Signal handlers; supports `EXIT` |
|
|
599
|
+
| `stty` | `-a` `size` | Print/change terminal line settings |
|
|
600
|
+
| `tput <cap>` | `cols` `lines` `setaf` `bold` `sgr0` | Query terminfo / output terminal escape sequences |
|
|
1100
601
|
| `true` | | Return exit code 0 |
|
|
1101
602
|
| `type <command>` | | Describe command interpretation |
|
|
1102
603
|
| `unalias <name>` | `-a` | Remove aliases |
|
|
1103
604
|
| `unset <VAR>` | | Remove shell variable |
|
|
1104
605
|
| `which <command>` | | Locate command in `$PATH` |
|
|
1105
606
|
|
|
607
|
+
### Misc & Fun
|
|
608
|
+
|
|
609
|
+
| Command | Flags | Description |
|
|
610
|
+
|---------|-------|-------------|
|
|
611
|
+
| `cmatrix` | | Matrix-style falling characters |
|
|
612
|
+
| `cowsay [msg]` | | ASCII cow saying something |
|
|
613
|
+
| `cowthink [msg]` | | ASCII cow thinking |
|
|
614
|
+
| `fortune` | | Print a random adage |
|
|
615
|
+
| `sl` | | Steam locomotive (cure for mistyping `ls`) |
|
|
616
|
+
| `yes [string]` | | Repeatedly output string until killed |
|
|
617
|
+
|
|
1106
618
|
### Package Management
|
|
1107
619
|
|
|
1108
620
|
| Command | Flags | Description |
|
|
@@ -1123,7 +635,7 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
|
|
|
1123
635
|
| `su [user]` | | Switch user |
|
|
1124
636
|
| `sudo <cmd>` | `-i` | Run as root |
|
|
1125
637
|
|
|
1126
|
-
**ℹ️ All
|
|
638
|
+
**ℹ️ All 106 built-in commands include complete JSDoc documentation** with `@category` and `@params` tags. See [src/commands/](https://github.com/itsrealfortune/typescript-virtual-container/tree/main/src/commands) for source code and inline documentation.
|
|
1127
639
|
|
|
1128
640
|
Custom commands: `shell.addCommand(name, params, callback)`.
|
|
1129
641
|
|
|
@@ -1646,15 +1158,15 @@ Open:
|
|
|
1646
1158
|
- [x] Pure in-memory VFS · symlinks · binary snapshot format (VFSB, ~27% smaller than JSON+base64)
|
|
1647
1159
|
- [x] Linux rootfs on boot — `/etc`, `/proc`, `/sys`, `/dev`, `/usr`, `/var`
|
|
1648
1160
|
- [x] Virtual package manager — `apt`/`dpkg`, 25 packages, VFS file writes
|
|
1649
|
-
- [x]
|
|
1650
|
-
- [x] Real shell interpreter — `if`/`for`/`while`/`case`/functions, `$(cmd)`, `$((expr))`, `${#VAR}`, `{a,b,c}` brace expansion, `{1..N}` ranges, `2>/dev/null` stderr redirect, `2>&1`, `(( x++ ))`
|
|
1161
|
+
- [x] 106 built-in commands across 10 categories (added `w`, `ip`, `dmesg`, `last`, `basename`, `dirname`, `file`, `tput`, `stty`, `yes`, `fortune`, `cowsay`, `cowthink`, `cmatrix`, `sl`)
|
|
1162
|
+
- [x] Real shell interpreter — `if`/`for`/`while`/`case`/functions, `$(cmd)`, `$((expr))`, `${#VAR}`, `{a,b,c}` brace expansion, `{1..N}` ranges, `*.glob` expansion, `!!`/`!n` history expansion, `\` line continuation, `2>/dev/null` stderr redirect, `2>&1`, `(( x++ ))`
|
|
1651
1163
|
- [x] `curl`/`wget` as pure `fetch()` · VFS PATH resolution · `/sbin` root-only
|
|
1652
1164
|
- [x] `/proc/self` and `/proc/<pid>` per-session entries
|
|
1653
1165
|
- [x] Snapshot diff tooling — `diffSnapshots`, `formatDiff`, `assertDiff`
|
|
1654
1166
|
- [x] `node`/`python3`/`npm`/`npx` — package-gated virtual REPL stubs
|
|
1655
1167
|
<!-- BUILD:changelog -->
|
|
1656
|
-
- [x] Web shell bundles (`fortune-nyx-v1.5.
|
|
1657
|
-
- [x] Self-standalone CLI (`fortune-nyx-v1.5.
|
|
1168
|
+
- [x] Web shell bundles (`fortune-nyx-v1.5.5-web.min.js`) — fully browser-native with IndexedDB VFS
|
|
1169
|
+
- [x] Self-standalone CLI (`fortune-nyx-v1.5.5-directbash-k6.1.0.mjs`) — single-file interactive shell, per-user history, tab completion
|
|
1658
1170
|
<!-- /BUILD:changelog -->
|
|
1659
1171
|
- [x] 120+ `man` pages — all built-in commands documented via `man <cmd>`
|
|
1660
1172
|
- [x] Shared `tokenize.ts` — unified tokenizer for shell parser and runtime (eliminates duplication)
|