typescript-virtual-container 1.5.5 → 1.5.7

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.
Files changed (64) hide show
  1. package/README.md +117 -35
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/SSHMimic/index.d.ts +5 -1
  4. package/dist/SSHMimic/index.js +27 -3
  5. package/dist/SSHMimic/scp.d.ts +34 -0
  6. package/dist/SSHMimic/scp.js +285 -0
  7. package/dist/SSHMimic/sftp.d.ts +53 -3
  8. package/dist/SSHMimic/sftp.js +9 -3
  9. package/dist/VirtualFileSystem/binaryPack.d.ts +7 -0
  10. package/dist/VirtualFileSystem/binaryPack.js +37 -1
  11. package/dist/VirtualFileSystem/index.d.ts +7 -0
  12. package/dist/VirtualFileSystem/index.js +67 -27
  13. package/dist/VirtualFileSystem/internalTypes.d.ts +2 -0
  14. package/dist/VirtualFileSystem/path.d.ts +5 -0
  15. package/dist/VirtualFileSystem/path.js +24 -11
  16. package/dist/VirtualPackageManager/index.d.ts +4 -2
  17. package/dist/VirtualPackageManager/index.js +24 -4
  18. package/dist/VirtualShell/index.d.ts +4 -0
  19. package/dist/VirtualShell/index.js +1 -7
  20. package/dist/VirtualShell/shell.js +40 -10
  21. package/dist/VirtualShell/shellParser.js +1 -22
  22. package/dist/commands/awk.d.ts +6 -11
  23. package/dist/commands/awk.js +462 -109
  24. package/dist/commands/bzip2.d.ts +11 -0
  25. package/dist/commands/bzip2.js +91 -0
  26. package/dist/commands/exit.js +1 -1
  27. package/dist/commands/find.d.ts +2 -2
  28. package/dist/commands/find.js +209 -37
  29. package/dist/commands/helpers.d.ts +0 -20
  30. package/dist/commands/helpers.js +0 -97
  31. package/dist/commands/lsof.d.ts +6 -0
  32. package/dist/commands/lsof.js +30 -0
  33. package/dist/commands/perl.d.ts +6 -0
  34. package/dist/commands/perl.js +76 -0
  35. package/dist/commands/python.js +5 -2
  36. package/dist/commands/registry.js +19 -1
  37. package/dist/commands/runtime.js +65 -87
  38. package/dist/commands/sed.d.ts +2 -2
  39. package/dist/commands/sed.js +216 -34
  40. package/dist/commands/sh.js +42 -0
  41. package/dist/commands/strace.d.ts +6 -0
  42. package/dist/commands/strace.js +26 -0
  43. package/dist/commands/tar.d.ts +2 -1
  44. package/dist/commands/tar.js +138 -52
  45. package/dist/commands/test.js +2 -2
  46. package/dist/commands/zip.d.ts +11 -0
  47. package/dist/commands/zip.js +232 -0
  48. package/dist/modules/linuxRootfs.js +1 -4
  49. package/dist/modules/neofetch.js +2 -2
  50. package/dist/types/commands.d.ts +4 -0
  51. package/dist/utils/argv.d.ts +6 -0
  52. package/dist/utils/argv.js +32 -0
  53. package/dist/utils/expand.d.ts +5 -2
  54. package/dist/utils/expand.js +112 -45
  55. package/dist/utils/glob.d.ts +6 -0
  56. package/dist/utils/glob.js +34 -0
  57. package/dist/utils/tokenize.js +13 -13
  58. package/package.json +9 -7
  59. package/dist/self-standalone.d.ts +0 -1
  60. package/dist/self-standalone.js +0 -444
  61. package/dist/standalone-wo-sftp.d.ts +0 -1
  62. package/dist/standalone-wo-sftp.js +0 -30
  63. package/dist/standalone.d.ts +0 -1
  64. package/dist/standalone.js +0 -61
package/README.md CHANGED
@@ -22,7 +22,7 @@
22
22
  - [How It Works](#how-it-works)
23
23
  - [API Reference](#api-reference)
24
24
  - [Examples](#examples)
25
- - [Built-in Commands (106)](#built-in-commands-106)
25
+ - [Built-in Commands (118)](#built-in-commands-118)
26
26
  - [Shell Scripting](#shell-scripting)
27
27
  - [Linux Rootfs & VFS PATH Resolution](#linux-rootfs--vfs-path-resolution)
28
28
  - [Configuration](#configuration)
@@ -44,8 +44,8 @@
44
44
  | Mode | Entry point | Use case |
45
45
  |------|-------------|----------|
46
46
  | **SSH/SFTP server** | `VirtualSshServer` / `VirtualSftpServer` | Honeypots, remote testing, training environments |
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 |
47
+ | **Web shell** | `builds/fortune-nyx-v1.5.7-web.min.js` (ESM) | Embedded terminals, interactive tutorials, browser demos |
48
+ | **Standalone CLI** | `builds/fortune-nyx-v1.5.7-directbash-k6.1.0.mjs` (single file) | Local shell, one-liner demos, no install required |
49
49
  <!-- /BUILD:mode-table -->
50
50
 
51
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.
@@ -64,19 +64,24 @@ npm install typescript-virtual-container
64
64
  ### Try instantly (zero install)
65
65
 
66
66
  <!-- BUILD:curl-start -->
67
- #### Interactivea local shell — persists VFS in .vfs/ in the current directory
67
+ #### Interactive local shell — persists VFS in .vfs/ in the current directory
68
68
  ```bash
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
69
+ curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.7-directbash-k6.1.0.mjs -o fortune-nyx-v1.5.7-directbash-k6.1.0.mjs && node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs
70
70
  ```
71
71
 
72
- #### SSH server (connect with any SSH client on port 2222)
72
+ #### SSH server with built-in SFTP subsystem (scp / sftp on port 2222)
73
73
  ```bash
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
74
+ curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-container/refs/heads/main/builds/fortune-nyx-v1.5.7-ssh.cjs -o fortune-nyx-v1.5.7-ssh.cjs && node fortune-nyx-v1.5.7-ssh.cjs
75
75
  ```
76
76
 
77
- #### SSH server without SFTP (lighter build)
77
+ #### Custom SSH port
78
78
  ```bash
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
79
+ node fortune-nyx-v1.5.7-ssh.cjs --ssh-port=2022
80
+ ```
81
+
82
+ #### SSH disabled (handler only, no server started)
83
+ ```bash
84
+ node fortune-nyx-v1.5.7-ssh.cjs --no-ssh
80
85
  ```
81
86
  <!-- /BUILD:curl-start -->
82
87
 
@@ -84,13 +89,16 @@ curl -s https://raw.githubusercontent.com/itsrealfortune/typescript-virtual-cont
84
89
  > 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.
85
90
 
86
91
  <!-- BUILD:selfStandalone-options -->
87
- **`fortune-nyx-v1.5.5-directbash-k6.1.0.mjs` options:**
92
+ **`fortune-nyx-v1.5.7-directbash-k6.1.0.mjs` options:**
88
93
 
89
94
  ```bash
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
95
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs # boot as root
96
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs --user alice # boot as alice (prompts for password if set)
97
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs --user=alice # same, inline form
98
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs --hostname=my-box # custom hostname
99
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs --snapshot=/data/.vfs # custom VFS snapshot path
100
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs --help # show all options
101
+ node fortune-nyx-v1.5.7-directbash-k6.1.0.mjs --version # print version
94
102
  ```
95
103
  <!-- /BUILD:selfStandalone-options -->
96
104
 
@@ -117,7 +125,7 @@ Two browser bundles are available:
117
125
  <!-- BUILD:web-table -->
118
126
  | Bundle | Format | Entry point | Use case |
119
127
  |--------|--------|-------------|----------|
120
- | `builds/fortune-nyx-v1.5.5-web.min.js` | ESM | `createWebShell()` | Embedded terminals, modern bundlers |
128
+ | `builds/fortune-nyx-v1.5.7-web.min.js` | ESM | `createWebShell()` | Embedded terminals, modern bundlers |
121
129
  <!-- /BUILD:web-table -->
122
130
 
123
131
  Both bundles persist the VFS in **IndexedDB** — state survives page reloads.
@@ -129,11 +137,11 @@ bun run build-all # rebuild everything
129
137
  ```
130
138
 
131
139
  <!-- BUILD:web-options -->
132
- **`fortune-nyx-v1.5.5-web.min.js`** — lightweight shell with IndexedDB VFS:
140
+ **`fortune-nyx-v1.5.7-web.min.js`** — lightweight shell with IndexedDB VFS:
133
141
 
134
142
  ```html
135
143
  <script type="module">
136
- import { createWebShell } from "./builds/fortune-nyx-v1.5.5-web.min.js";
144
+ import { createWebShell } from "./builds/fortune-nyx-v1.5.7-web.min.js";
137
145
 
138
146
  const shell = createWebShell("web-vm", {
139
147
  vfs: { databaseName: "virtual-env-js", storeName: "vfs" },
@@ -145,11 +153,11 @@ bun run build-all # rebuild everything
145
153
  </script>
146
154
  ```
147
155
 
148
- **`fortune-nyx-v1.5.5-web.min.js`** — mirrors the `VirtualShell` programmatic API:
156
+ **`fortune-nyx-v1.5.7-web.min.js`** — mirrors the `VirtualShell` programmatic API:
149
157
 
150
158
  ```html
151
159
  <script type="module">
152
- import { createVirtualShellShim } from "./builds/fortune-nyx-v1.5.5-web.min.js";
160
+ import { createVirtualShellShim } from "./builds/fortune-nyx-v1.5.7-web.min.js";
153
161
 
154
162
  const shell = createVirtualShellShim("web-vm");
155
163
  await shell.ensureInitialized();
@@ -475,9 +483,9 @@ echo "Welcome back, root!"
475
483
  ---
476
484
 
477
485
  <details>
478
- <summary><strong>Built-in Commands (106)</strong></summary>
486
+ <summary><strong>Built-in Commands (118)</strong></summary>
479
487
 
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.
488
+ Type `help` in the shell for a grouped, colorized listing. Type `help <command>` for detailed usage. Type `man <command>` for full manual pages — all 118 commands are documented.
481
489
 
482
490
  ### Navigation
483
491
 
@@ -495,7 +503,7 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
495
503
  | `cat <path...>` | `-n` `-b` | Concatenate and print; `-n` numbers lines, `-b` numbers non-blank |
496
504
  | `chmod <mode> <file>` | | Octal (`755`) or symbolic (`+x`, `u+x`, `go-w`, `a=rx`) |
497
505
  | `cp <src> <dest>` | `-r` | Copy file or directory |
498
- | `find [path]` | `-name` `-type` | Search for files |
506
+ | `find [path]` | `-name` `-iname` `-type` `-maxdepth` `-mindepth` `-exec` `-not` `-o` `-a` `-empty` `-size` | Search for files |
499
507
  | `ln <target> <link>` | `-s` | Hard or symbolic link |
500
508
  | `readlink <path>` | `-f` | Print resolved path of symbolic link |
501
509
  | `mkdir <path>` | `-p` | Create directory |
@@ -509,13 +517,13 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
509
517
 
510
518
  | Command | Flags | Description |
511
519
  |---------|-------|-------------|
512
- | `awk [-F <sep>] '<prog>'` | | Pattern scanning |
520
+ | `awk [-F <sep>] '<prog>'` | `-v var=val` | Pattern scanning — NR/NF, `BEGIN`/`END`, field assign, `gsub`/`sub`/`substr`/`split`/`length`, `printf` |
513
521
  | `base64` | `-d` | Encode/decode base64 |
514
522
  | `cut` | `-d` `-f` | Remove sections from lines |
515
523
  | `diff <f1> <f2>` | | Compare files line by line |
516
524
  | `grep <pattern> [files]` | `-i` `-v` `-n` `-r` | Search file content |
517
525
  | `head [files]` | `-n <N>` | First N lines |
518
- | `sed -e 's/pat/rep/[g]'` | `-i` | Stream editor |
526
+ | `sed -e 's/pat/rep/[g]'` | `-n` `-i` `-e` | Stream editor — `s///[gI]`, `d`, `p`, `=`, `q`, line/regex/range addresses |
519
527
  | `sort [files]` | `-r` `-n` `-u` | Sort lines |
520
528
  | `tail [files]` | `-n <N>` | Last N lines |
521
529
  | `tee [files]` | `-a` | Read stdin, write to stdout and files |
@@ -531,8 +539,10 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
531
539
 
532
540
  | Command | Flags | Description |
533
541
  |---------|-------|-------------|
534
- | `gzip <file>` / `gunzip <file>` | | Compress / decompress |
535
- | `tar <archive> [files]` | `-czf` `-xzf` `-tf` | Archive utility |
542
+ | `gzip <file>` / `gunzip <file>` | `-k` `-d` | Compress / decompress (real gzip, browser-native) |
543
+ | `bzip2 <file>` / `bunzip2 <file>` | `-k` `-d` | Compress / decompress bzip2 (VFS round-trip) |
544
+ | `zip [-r] <archive> <files>` / `unzip <archive>` | `-l` `-d <dir>` | Real PKZIP + DEFLATE (interoperable) |
545
+ | `tar <archive> [files]` | `-czf` `-xzf` `-tf` `-v` | Archive utility — real POSIX ustar binary format (interoperable) |
536
546
 
537
547
  ### System
538
548
 
@@ -560,6 +570,9 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
560
570
  | `python3` | `--version` `-c` `-V` | Virtual Python 3 interpreter; alias `python`; **requires `apt install python3`** |
561
571
  | `sleep <seconds>` | | Delay execution |
562
572
  | `uname` | `-a` `-r` `-m` | System information |
573
+ | `bc` | | Arithmetic calculator (integer; `+` `-` `*` `/` `%` `**` `()`) |
574
+ | `lsof` | `-i` | List open files (simulated) |
575
+ | `strace <cmd>` | `-e` `-o` | Trace system calls (stub with realistic output) |
563
576
  | `uptime` | `-p` `-s` | Running time |
564
577
  | `w` | | Who is logged on and what they are doing |
565
578
  | `who` | | Active sessions |
@@ -586,12 +599,16 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
586
599
  | `false` | | Return exit code 1 |
587
600
  | `help [command]` | | List commands or show command usage |
588
601
  | `history [n]` | | Command history |
602
+ | `jobs` | | List active jobs |
603
+ | `bg [%n]` | | Resume job in background |
604
+ | `fg [%n]` | | Resume job in foreground |
589
605
  | `man <command>` | | Command reference manual |
590
606
  | `printf <fmt> [args...]` | | Format and print (`%s` `%d` `%f` `%x` `\n` `\t`) |
591
607
  | `read [-r] <var...>` | `-r` `-p` | Read stdin into variable(s) |
592
608
  | `return [n]` | | Return from shell function |
593
- | `set [VAR=val]` | | Display or set shell variables |
594
- | `sh` | `-c <script>` `[file]` | Execute shell script — `if`/`for`/`while`/`case`/functions, `$((expr))`, single-quote-safe |
609
+ | `set [VAR=val]` | `-e` `-x` `+e` `+x` | Display or set shell variables; `-e` exit on error, `-x` trace execution |
610
+ | `sh` | `-c <script>` `[file]` | Execute shell script — `if`/`for`/`while`/`until`/`case`/functions, arrays `arr=(a b c)`, `$((expr))`, single-quote-safe |
611
+ | `perl` | `-e` `-p` `-n` | One-liner interpreter (`print`/`say`, `s///`, `-p`/`-n` loop) |
595
612
  | `shift [n]` | | Shift positional parameters |
596
613
  | `source <file>` | | Execute file in current env; alias `.` |
597
614
  | `test <expr>` / `[ <expr> ]` | | POSIX conditional: `-f` `-d` `-e` `-z` `-n` `-x` `-s` `=` `!=` `-eq` `-lt` `-gt` `-le` `-ge` `!` `-a` `-o` |
@@ -635,7 +652,7 @@ Type `help` in the shell for a grouped, colorized listing. Type `help <command>`
635
652
  | `su [user]` | | Switch user |
636
653
  | `sudo <cmd>` | `-i` | Run as root |
637
654
 
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.
655
+ **ℹ️ All 118 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.
639
656
 
640
657
  Custom commands: `shell.addCommand(name, params, callback)`.
641
658
 
@@ -670,8 +687,22 @@ echo "${UNSET:-default}" # default
670
687
  echo "${NAME:+alternate}" # alternate (only if NAME is set)
671
688
  echo "${UNSET:=assigned}" # assigns and returns "assigned"
672
689
  echo "${#NAME}" # 5 (string length)
690
+ echo "${NAME:2}" # rld (substring from offset 2)
691
+ echo "${NAME:1:3}" # orl (substring offset 1, length 3)
692
+ echo "${NAME/o/0}" # w0rld (replace first)
693
+ echo "${NAME//l/L}" # worLd (replace all)
694
+ echo "${PATH##*/}" # strip longest prefix match
695
+ echo "${FILE%.txt}" # strip shortest suffix match
673
696
  echo "$?" # last exit code
697
+ echo "$RANDOM" # random integer 0–32767
698
+ echo "$LINENO" # current line number
674
699
  echo ~ # /home/<user> (tilde expansion)
700
+
701
+ # Arrays
702
+ arr=(alpha beta gamma)
703
+ echo "${arr[0]}" # alpha
704
+ echo "${arr[@]}" # alpha beta gamma
705
+ echo "${#arr[@]}" # 3
675
706
  ```
676
707
 
677
708
  > **Single-quote isolation** — `$VAR` and `$((...))` are never expanded inside `'...'`.
@@ -711,6 +742,12 @@ while [ $COUNT -lt 3 ]; do
711
742
  echo "Count: $COUNT"
712
743
  COUNT=$((COUNT + 1))
713
744
  done
745
+
746
+ COUNT=5
747
+ until [ $COUNT -eq 0 ]; do
748
+ echo "Countdown: $COUNT"
749
+ COUNT=$((COUNT - 1))
750
+ done
714
751
  ```
715
752
 
716
753
  ### Functions and case
@@ -728,6 +765,30 @@ case "$1" in
728
765
  esac
729
766
  ```
730
767
 
768
+ ### Heredoc
769
+
770
+ ```bash
771
+ cat << EOF
772
+ line one
773
+ line two
774
+ EOF
775
+
776
+ # write to file
777
+ cat > /tmp/config << EOF
778
+ HOST=localhost
779
+ PORT=3000
780
+ EOF
781
+ ```
782
+
783
+ ### set -e / set -x
784
+
785
+ ```bash
786
+ set -e # exit immediately on any non-zero exit code
787
+ set -x # print each command before executing (trace)
788
+ set +e # disable errexit
789
+ set +x # disable xtrace
790
+ ```
791
+
731
792
  ### Script Files
732
793
 
733
794
  ```typescript
@@ -740,9 +801,13 @@ done
740
801
  await client.exec("sh /usr/local/bin/setup.sh");
741
802
  ```
742
803
 
743
- ### .bashrc
804
+ ### Login Files
744
805
 
745
- Sourced automatically on every interactive session from `/home/<user>/.bashrc`:
806
+ Sourced automatically at session start, in order:
807
+
808
+ 1. `/etc/environment` — `KEY=VALUE` pairs only, no shell syntax
809
+ 2. `~/.profile` — user login script
810
+ 3. `~/.bashrc` — interactive shell config
746
811
 
747
812
  ```bash
748
813
  export EDITOR=nano
@@ -750,6 +815,20 @@ alias ll="ls -l"
750
815
  echo "Welcome, $USER!"
751
816
  ```
752
817
 
818
+ ### Line Editing
819
+
820
+ Interactive shell supports full readline-style key bindings:
821
+
822
+ | Key | Action |
823
+ |-----|--------|
824
+ | `←` / `→` | Move cursor left / right |
825
+ | `Home` / `Ctrl+A` | Jump to start of line |
826
+ | `End` / `Ctrl+E` | Jump to end of line |
827
+ | `Ctrl+K` | Kill to end of line |
828
+ | `Ctrl+U` | Kill to start of line |
829
+ | `Ctrl+W` | Kill word backward |
830
+ | `!!` | Expand to last command |
831
+
753
832
  </details>
754
833
 
755
834
  ---
@@ -1158,18 +1237,21 @@ Open:
1158
1237
  - [x] Pure in-memory VFS · symlinks · binary snapshot format (VFSB, ~27% smaller than JSON+base64)
1159
1238
  - [x] Linux rootfs on boot — `/etc`, `/proc`, `/sys`, `/dev`, `/usr`, `/var`
1160
1239
  - [x] Virtual package manager — `apt`/`dpkg`, 25 packages, VFS file writes
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++ ))`
1240
+ - [x] 118 built-in commands across 11 categories (added `zip`, `unzip`, `bzip2`, `bunzip2`, `lsof`, `strace`, `perl`, `w`, `ip`, `dmesg`, `last`, `basename`, `dirname`, `file`, `tput`, `stty`, `yes`, `fortune`, `cowsay`, `cowthink`, `cmatrix`, `sl`, `bc`, `jobs`, `bg`, `fg`)
1241
+ - [x] Real shell interpreter — `if`/`for`/`while`/`until`/`case`/functions, arrays `arr=(...)`, `$(cmd)`, `$((expr))`, `${#VAR}`, `${var#pfx}` `${var##pfx}` `${var%sfx}` `${var%%sfx}` `${var/p/r}` `${var//p/r}` `${var:off:len}` `${arr[@]}`, `{a,b,c}` brace expansion, `{1..N}` ranges, `*.glob` expansion, `!!` history expansion, `\` line continuation, `2>/dev/null` stderr redirect, `2>&1`, `(( x++ ))`, heredoc `<< EOF`, `set -e`/`set -x`, `$RANDOM`/`$LINENO`
1163
1242
  - [x] `curl`/`wget` as pure `fetch()` · VFS PATH resolution · `/sbin` root-only
1164
1243
  - [x] `/proc/self` and `/proc/<pid>` per-session entries
1165
1244
  - [x] Snapshot diff tooling — `diffSnapshots`, `formatDiff`, `assertDiff`
1166
1245
  - [x] `node`/`python3`/`npm`/`npx` — package-gated virtual REPL stubs
1167
1246
  <!-- BUILD:changelog -->
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
1247
+ - [x] Web shell bundles (`fortune-nyx-v1.5.7-web.min.js`) — fully browser-native with IndexedDB VFS
1248
+ - [x] Self-standalone CLI (`fortune-nyx-v1.5.7-directbash-k6.1.0.mjs`) — single-file interactive shell, per-user history, tab completion
1170
1249
  <!-- /BUILD:changelog -->
1171
1250
  - [x] 120+ `man` pages — all built-in commands documented via `man <cmd>`
1172
1251
  - [x] Shared `tokenize.ts` — unified tokenizer for shell parser and runtime (eliminates duplication)
1252
+ - [x] Full readline line editing — `Ctrl+A/E/K/U/W`, `Home`/`End`, `!!` history expansion, `/etc/environment` + `~/.profile` login sourcing
1253
+ - [x] Interoperable archive formats — `tar` writes real POSIX ustar binary; `zip`/`unzip` use PKZIP+DEFLATE (fflate); files extracted by real system tools via SFTP
1254
+ - [x] Overhauled `sed` — `d`/`p`/`=`/`q`, `-n` suppress, line/regex/range/`$` addresses; overhauled `awk` — `-v`, field assignment, `gsub`/`sub`/`substr`/`split`/`length`/`printf`/`next`; overhauled `find` — `-exec`, `-maxdepth`, `-iname`, `-not`/`!`, `-o`/`-a`, `-empty`, `-size`
1173
1255
  - [x] `PasswordChallenge` type — generic interactive password flow for `adduser`, `passwd`, `deluser`
1174
1256
  - [x] `VirtualFileSystem.mount(vPath, hostPath, { readOnly })` — bind-mount host directories into the VM; read-only by default; browser-safe (silent no-op)
1175
1257