typescript-virtual-container 1.6.1 → 1.6.3

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 CHANGED
@@ -13,7 +13,7 @@
13
13
  ## Table of Contents
14
14
 
15
15
  - [Three ways to run](#three-ways-to-run) · [Get Started](#get-started)
16
- - [How It Works](#how-it-works) · [Built-in Commands](#built-in-commands-149)
16
+ - [How It Works](#how-it-works) · [Built-in Commands](#built-in-commands-152)
17
17
  - [Shell Scripting](#shell-scripting) · [Linux Rootfs](#linux-rootfs--vfs-path-resolution)
18
18
  - [Configuration](#configuration) · [Troubleshooting](#troubleshooting)
19
19
  - [FAQ](#faq) · [Contributing](#contributing)
@@ -27,8 +27,8 @@
27
27
  | Mode | Entry point | Use case |
28
28
  |------|-------------|----------|
29
29
  | **SSH/SFTP server** | `VirtualSshServer` / `VirtualSftpServer` | Honeypots, remote testing, training environments |
30
- | **Web shell** | `builds/fortune-nyx-v1.6.1-web.min.js` (ESM) | Embedded terminals, interactive tutorials, browser demos |
31
- | **Standalone CLI** | `builds/fortune-nyx-v1.6.1-directbash-k6.1.0.mjs` (single file) | Local shell, one-liner demos, no install required |
30
+ | **Web shell** | `builds/fortune-nyx-v1.6.3-web.min.js` (ESM) | Embedded terminals, interactive tutorials, browser demos — run `startxfce4` for a full XFCE desktop |
31
+ | **Standalone CLI** | `builds/fortune-nyx-v1.6.3-directbash-k6.1.0.mjs` (single file) | Local shell, one-liner demos, no install required |
32
32
  <!-- /BUILD:mode-table -->
33
33
 
34
34
  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.
@@ -49,22 +49,22 @@ npm install typescript-virtual-container
49
49
  <!-- BUILD:curl-start -->
50
50
  #### Interactive local shell — persists VFS in .vfs/ in the current directory
51
51
  ```bash
52
- curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.6.1-directbash-k6.1.0.mjs -o fortune-nyx-v1.6.1-directbash-k6.1.0.mjs && node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs
52
+ curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.6.3-directbash-k6.1.0.mjs -o fortune-nyx-v1.6.3-directbash-k6.1.0.mjs && node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs
53
53
  ```
54
54
 
55
55
  #### SSH server with built-in SFTP subsystem (scp / sftp on port 2222)
56
56
  ```bash
57
- curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.6.1-ssh.cjs -o fortune-nyx-v1.6.1-ssh.cjs && node fortune-nyx-v1.6.1-ssh.cjs
57
+ curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.6.3-ssh.cjs -o fortune-nyx-v1.6.3-ssh.cjs && node fortune-nyx-v1.6.3-ssh.cjs
58
58
  ```
59
59
 
60
60
  #### Custom SSH port
61
61
  ```bash
62
- node fortune-nyx-v1.6.1-ssh.cjs --ssh-port=2022
62
+ node fortune-nyx-v1.6.3-ssh.cjs --ssh-port=2022
63
63
  ```
64
64
 
65
65
  #### SSH disabled (handler only, no server started)
66
66
  ```bash
67
- node fortune-nyx-v1.6.1-ssh.cjs --no-ssh
67
+ node fortune-nyx-v1.6.3-ssh.cjs --no-ssh
68
68
  ```
69
69
  <!-- /BUILD:curl-start -->
70
70
 
@@ -72,16 +72,16 @@ node fortune-nyx-v1.6.1-ssh.cjs --no-ssh
72
72
  > 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.
73
73
 
74
74
  <!-- BUILD:selfStandalone-options -->
75
- **`fortune-nyx-v1.6.1-directbash-k6.1.0.mjs` options:**
75
+ **`fortune-nyx-v1.6.3-directbash-k6.1.0.mjs` options:**
76
76
 
77
77
  ```bash
78
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs # boot as root
79
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs --user alice # boot as alice (prompts for password if set)
80
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs --user=alice # same, inline form
81
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs --hostname=my-box # custom hostname
82
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs --snapshot=/data/.vfs # custom VFS snapshot path
83
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs --help # show all options
84
- node fortune-nyx-v1.6.1-directbash-k6.1.0.mjs --version # print version
78
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs # boot as root
79
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs --user alice # boot as alice (prompts for password if set)
80
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs --user=alice # same, inline form
81
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs --hostname=my-box # custom hostname
82
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs --snapshot=/data/.vfs # custom VFS snapshot path
83
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs --help # show all options
84
+ node fortune-nyx-v1.6.3-directbash-k6.1.0.mjs --version # print version
85
85
  ```
86
86
  <!-- /BUILD:selfStandalone-options -->
87
87
 
@@ -108,7 +108,7 @@ Two browser bundles are available:
108
108
  <!-- BUILD:web-table -->
109
109
  | Bundle | Format | Entry point | Use case |
110
110
  |--------|--------|-------------|----------|
111
- | `builds/fortune-nyx-v1.6.1-web.min.js` | ESM | `createWebShell()` | Embedded terminals, modern bundlers |
111
+ | `builds/fortune-nyx-v1.6.3-web.min.js` | ESM | `createWebShell()` | Embedded terminals, modern bundlers |
112
112
  <!-- /BUILD:web-table -->
113
113
 
114
114
  Both bundles persist the VFS in **IndexedDB** — state survives page reloads.
@@ -120,11 +120,11 @@ bun run build-all # rebuild everything
120
120
  ```
121
121
 
122
122
  <!-- BUILD:web-options -->
123
- **`fortune-nyx-v1.6.1-web.min.js`** — lightweight shell with IndexedDB VFS:
123
+ **`fortune-nyx-v1.6.3-web.min.js`** — lightweight shell with IndexedDB VFS:
124
124
 
125
125
  ```html
126
126
  <script type="module">
127
- import { createWebShell } from "./builds/fortune-nyx-v1.6.1-web.min.js";
127
+ import { createWebShell } from "./builds/fortune-nyx-v1.6.3-web.min.js";
128
128
 
129
129
  const shell = createWebShell("web-vm", {
130
130
  vfs: { databaseName: "virtual-env-js", storeName: "vfs" },
@@ -136,11 +136,11 @@ bun run build-all # rebuild everything
136
136
  </script>
137
137
  ```
138
138
 
139
- **`fortune-nyx-v1.6.1-web.min.js`** — mirrors the `VirtualShell` programmatic API:
139
+ **`fortune-nyx-v1.6.3-web.min.js`** — mirrors the `VirtualShell` programmatic API:
140
140
 
141
141
  ```html
142
142
  <script type="module">
143
- import { createVirtualShellShim } from "./builds/fortune-nyx-v1.6.1-web.min.js";
143
+ import { createVirtualShellShim } from "./builds/fortune-nyx-v1.6.3-web.min.js";
144
144
 
145
145
  const shell = createVirtualShellShim("web-vm");
146
146
  await shell.ensureInitialized();
@@ -186,13 +186,13 @@ console.log(r.stdout);
186
186
  │ per-IP rate limiting / lockout home-dir confinement │
187
187
  └─────────────────────────┬────────────────────────────────────────────────┘
188
188
 
189
- ┌──────────▼──────────┐
190
- │ VirtualShell │
191
- │ script parser │ &&/||/; · if/for/while/case
192
- │ command executor │ per-session ShellEnv
193
- │ .bashrc loader │ /home/<user>/.bashrc
194
- │ session manager │
195
- └──┬──────────────┬───┘
189
+ ┌──────────▼──────────┐ ┌──────────────────────────┐
190
+ │ VirtualShell │────────▶ DesktopManager │
191
+ │ script parser │ XFCE panel · windows │
192
+ │ command executor │ Thunar · Mousepad │
193
+ │ .bashrc loader │ Trash · terminal windows│
194
+ │ session manager │ │ (browser only) │
195
+ └──┬──────────────┬───┘ └──────────────────────────┘
196
196
  │ │
197
197
  ┌────────────▼───┐ ┌─────▼───────────────┐
198
198
  │VirtualFileSystem│ │ VirtualUserManager │
@@ -211,7 +211,7 @@ console.log(r.stdout);
211
211
 
212
212
  **What it is:** a shell emulator and virtual Linux environment for developer workflows.
213
213
 
214
- **What it is not:** a kernel-level security boundary. `curl`/`wget` use the native `fetch()` API — no host binary spawned. `node`/`python3`/`npm` are virtual REPL stubs, not real runtimes. `execvp` is never called. Do not expose to the public internet without additional isolation.
214
+ **What it is not:** a fully isolated sandbox. The shell commands are contained — no host binary is ever spawned, `execvp` is never called, `node`/`python3`/`npm` are virtual stubs. But `curl`/`wget` use the real `fetch()` API (live network access), all instances share the same JS heap as the host application, and CPU/memory are not capped. Do not expose to untrusted input without additional infrastructure-level isolation.
215
215
 
216
216
  ---
217
217
 
@@ -440,9 +440,9 @@ const [r1, r2] = await Promise.all([
440
440
  ---
441
441
 
442
442
  <details>
443
- <summary><strong>Built-in Commands (149)</strong></summary>
443
+ <summary><strong>Built-in Commands (152)</strong></summary>
444
444
 
445
- Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage. Type `man <command>` for full manual pages — all 149 commands are documented.
445
+ Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage. Type `man <command>` for full manual pages — all commands are documented.
446
446
 
447
447
  ### Navigation
448
448
 
@@ -598,6 +598,16 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
598
598
  | `history [n]` | Command history |
599
599
  | `help` | Full list: type `help` in the shell |
600
600
 
601
+ ### Desktop (browser only)
602
+
603
+ | Command | Description |
604
+ |---------|-------------|
605
+ | `startxfce4` | Launch the XFCE desktop — blocks the shell until logout |
606
+ | `thunar [path]` | Open the file manager window |
607
+ | `mousepad [file]` | Open the text editor (`gedit` and `xed` are aliases) |
608
+
609
+ > Desktop commands are no-ops outside the browser environment.
610
+
601
611
  ### Fun
602
612
 
603
613
  | Command | Description |
@@ -613,7 +623,7 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
613
623
  | `pacman` | Pacman game (mock) |
614
624
  | `help` | Full list: type `help` in the shell |
615
625
 
616
- **ℹ️ All 149 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.
626
+ **ℹ️ All 152 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.
617
627
 
618
628
  Custom commands: `shell.addCommand(name, params, callback)`.
619
629
 
@@ -954,27 +964,46 @@ import type {
954
964
 
955
965
  ## FAQ
956
966
 
957
- **Is this a real container runtime?**
958
- No it emulates SSH sessions, users, and filesystem behavior in a virtual runtime. Ideal for testing, simulations, and automation where full OS isolation is not required.
967
+ **What exactly is this project?**
968
+ A self-contained Linux environment implemented entirely in TypeScript. It is not a mock, a stub, or a thin SSH wrapper — it is a full virtual container with its own filesystem (`VirtualFileSystem`), user and permission system (`VirtualUserManager`), shell interpreter, package manager, network layer, process table, and desktop environment. Each `VirtualShell` instance is an independent container that runs anywhere TypeScript runs: Node.js, Bun, or the browser.
969
+
970
+ **How is this different from a Docker container or a real VM?**
971
+ Docker and VMs enforce kernel-level isolation and run real binaries. This project runs entirely in the JavaScript runtime — no subprocess is ever spawned, no host binary is called. The trade-off is intentional: you get zero-dependency portability (including the browser), a fully inspectable and programmable environment, and no host OS requirements. It is not a security boundary.
972
+
973
+ **Is the environment fully isolated?**
974
+ No — and this is important to understand before exposing it to untrusted input:
975
+
976
+ - **Network is real.** `curl` and `wget` use the host's `fetch()` — requests reach the actual internet.
977
+ - **The JS heap is shared.** All `VirtualShell` instances run in the same JavaScript runtime as your application. There is no memory boundary between them or between the shell and the host.
978
+ - **No resource enforcement.** CPU usage and memory consumption are not capped by the container itself — a runaway loop consumes real host resources.
979
+ - **Filesystem isolation holds** in `"memory"` mode (the VFS never touches the host FS) and is limited to one `.vfsb` file in `"fs"` mode.
980
+
981
+ In short: the shell commands are sandboxed, the runtime is not.
959
982
 
960
983
  **Can I use this in production?**
961
- Yes for automation contexts (sandboxed command runners, test harnesses, training environments, honeypots). It is not a security boundary like a real container/VM.
984
+ Yes, for the right use cases: automated test harnesses, interactive tutorials, training environments, honeypots, and browser-based shell experiences. Do not expose it to arbitrary untrusted input without additional isolation at the infrastructure level — it is not a security boundary.
962
985
 
963
986
  **Does the VFS touch the host filesystem?**
964
- In `"memory"` mode: no. In `"fs"` mode: one binary file (`vfs-snapshot.vfsb`) inside `snapshotPath` only.
987
+ In `"memory"` mode: never. In `"fs"` mode: exactly one binary file (`vfs-snapshot.vfsb`) inside `snapshotPath`. In the browser: IndexedDB only.
965
988
 
966
- **Can I run multiple isolated shells?**
967
- Yes. Each `new VirtualShell(...)` is completely independent (separate VFS, users, env state).
989
+ **Can I run multiple isolated environments in parallel?**
990
+ Yes. Each `new VirtualShell(...)` is fully independent separate VFS, user database, environment state, and session manager. They share no global state.
968
991
 
969
992
  **Does the shell support `&&`, `||`, `;`, and `&`?**
970
- Yes — plus pipes, redirections, `if`/`for`/`while`/`case`, function definitions, and background jobs (`cmd &`).
993
+ Yes — plus pipes, redirections, `if`/`for`/`while`/`until`/`case`, function definitions, arrays, brace expansion, glob expansion, heredocs, `set -e`/`set -x`, and background jobs (`cmd &`).
971
994
 
972
995
  **Can I use this for honeypot deployments?**
973
- Yes — use `HoneyPot.attach()` to capture all activity, configure `maxAuthAttempts` to throttle scanners, export on shutdown.
996
+ Yes — `HoneyPot.attach()` captures every command, file write, auth attempt, and session event with timestamps. Configure `maxAuthAttempts` to throttle scanners. Export the audit log on shutdown.
974
997
 
975
998
  **Is SFTP fully supported?**
976
999
  Core operations are implemented. Extended attributes and symlinks return `OP_UNSUPPORTED`.
977
1000
 
1001
+ **Does the desktop work outside the browser?**
1002
+ No — `startxfce4`, `thunar`, and `mousepad` require a DOM. In Node.js/Bun they return an error immediately. The `DesktopManager` is only instantiated in the web shell example (`examples/app.ts`).
1003
+
1004
+ **What does the desktop simulate?**
1005
+ A single-user XFCE session: a panel with Applications menu and clock, draggable windows, a file manager (Thunar) with navigation, right-click context menu, rename, and trash, a text editor (Mousepad) with Ctrl+S save, and terminal windows each backed by a real interactive shell session against the same VFS.
1006
+
978
1007
  ---
979
1008
 
980
1009
  ## Contributing
@@ -993,8 +1022,9 @@ Core operations are implemented. Extended attributes and symlinks return `OP_UNS
993
1022
  - Passwords hashed with scrypt (N=32768, r=8, p=1) with random per-user salt.
994
1023
  - Root account always exists and cannot be deleted.
995
1024
  - Per-IP rate limiting prevents automated brute-force on the SSH server.
996
- - This project does **not** provide kernel-level or process-level isolation.
997
- - Do **not** expose to the public internet without understanding the risks.
1025
+ - This project does **not** provide kernel-level or process-level isolation. All `VirtualShell` instances share the same JS heap as the host application.
1026
+ - `curl` and `wget` issue real network requests via `fetch()` they are not sandboxed.
1027
+ - Do **not** expose to untrusted input without additional infrastructure-level isolation.
998
1028
 
999
1029
  Vulnerability reports: contact maintainers privately before public disclosure — see `SECURITY.md`.
1000
1030
 
@@ -1018,6 +1048,8 @@ MIT — see [LICENSE](./LICENSE).
1018
1048
  Open:
1019
1049
 
1020
1050
  - [ ] WebSocket-based remote shell client (experimental)
1051
+ - [ ] XFCE desktop: resize windows, multi-monitor layout
1052
+ - [ ] Thunar: drag-and-drop between folders
1021
1053
 
1022
1054
  <details>
1023
1055
  <summary>Completed</summary>
@@ -1033,9 +1065,10 @@ Open:
1033
1065
  - [x] Snapshot diff tooling — `diffSnapshots`, `formatDiff`, `assertDiff`
1034
1066
  - [x] `node`/`python3`/`npm`/`npx` — package-gated virtual REPL stubs
1035
1067
  <!-- BUILD:changelog -->
1036
- - [x] Web shell bundles (`fortune-nyx-v1.6.1-web.min.js`) — fully browser-native with IndexedDB VFS
1037
- - [x] Self-standalone CLI (`fortune-nyx-v1.6.1-directbash-k6.1.0.mjs`) — single-file interactive shell, per-user history, tab completion
1068
+ - [x] Web shell bundles (`fortune-nyx-v1.6.3-web.min.js`) — fully browser-native with IndexedDB VFS
1069
+ - [x] Self-standalone CLI (`fortune-nyx-v1.6.3-directbash-k6.1.0.mjs`) — single-file interactive shell, per-user history, tab completion
1038
1070
  <!-- /BUILD:changelog -->
1071
+ - [x] XFCE desktop simulation — `startxfce4` launches a full in-browser desktop with draggable windows, XFCE panel (Applications menu, clock, tray), Thunar file manager (navigate, right-click, trash, rename), Mousepad text editor (Ctrl+S, dirty indicator), terminal windows with live shell sessions, Font Awesome icons
1039
1072
  - [x] 127+ `man` pages — all built-in commands documented via `man <cmd>`
1040
1073
  - [x] Background job support — trailing `&` fires commands async; `:(){ :|:& };:` fork-bomb safely blocked by `MAX_CALL_DEPTH` guard; shell function names now accept any non-whitespace identifier (POSIX-compliant)
1041
1074
  - [x] Shared `tokenize.ts` — unified tokenizer for shell parser and runtime (eliminates duplication)