typescript-virtual-container 1.5.11 → 1.6.0

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 (132) hide show
  1. package/README.md +236 -456
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/Honeypot/index.d.ts +9 -0
  4. package/dist/Honeypot/index.js +57 -0
  5. package/dist/SSHMimic/exec.d.ts +4 -0
  6. package/dist/SSHMimic/exec.js +4 -0
  7. package/dist/SSHMimic/executor.d.ts +10 -1
  8. package/dist/SSHMimic/executor.js +18 -8
  9. package/dist/SSHMimic/hostKey.d.ts +5 -0
  10. package/dist/SSHMimic/hostKey.js +5 -0
  11. package/dist/SSHMimic/loginBanner.d.ts +7 -0
  12. package/dist/SSHMimic/loginBanner.js +4 -0
  13. package/dist/SSHMimic/loginFormat.d.ts +4 -0
  14. package/dist/SSHMimic/loginFormat.js +4 -0
  15. package/dist/SSHMimic/prompt.d.ts +9 -0
  16. package/dist/SSHMimic/prompt.js +9 -0
  17. package/dist/SSHMimic/scp.d.ts +18 -0
  18. package/dist/SSHMimic/scp.js +14 -0
  19. package/dist/VirtualFileSystem/binaryPack.d.ts +7 -3
  20. package/dist/VirtualFileSystem/binaryPack.js +32 -10
  21. package/dist/VirtualFileSystem/index.d.ts +29 -0
  22. package/dist/VirtualFileSystem/index.js +126 -5
  23. package/dist/VirtualFileSystem/internalTypes.d.ts +4 -0
  24. package/dist/VirtualFileSystem/journal.d.ts +10 -4
  25. package/dist/VirtualFileSystem/journal.js +12 -2
  26. package/dist/VirtualFileSystem/path.d.ts +23 -1
  27. package/dist/VirtualFileSystem/path.js +23 -3
  28. package/dist/VirtualPackageManager/index.js +1 -1
  29. package/dist/VirtualShell/index.d.ts +3 -0
  30. package/dist/VirtualShell/index.js +12 -3
  31. package/dist/VirtualUserManager/index.d.ts +20 -1
  32. package/dist/VirtualUserManager/index.js +52 -15
  33. package/dist/commands/bc.d.ts +5 -0
  34. package/dist/commands/bc.js +5 -0
  35. package/dist/commands/cat.js +2 -2
  36. package/dist/commands/chgrp.d.ts +7 -0
  37. package/dist/commands/chgrp.js +42 -0
  38. package/dist/commands/chown.d.ts +7 -0
  39. package/dist/commands/chown.js +79 -0
  40. package/dist/commands/cp.js +4 -3
  41. package/dist/commands/dd.d.ts +7 -0
  42. package/dist/commands/dd.js +60 -0
  43. package/dist/commands/declare.js +0 -2
  44. package/dist/commands/expr.d.ts +7 -0
  45. package/dist/commands/expr.js +63 -0
  46. package/dist/commands/fun.d.ts +5 -0
  47. package/dist/commands/fun.js +5 -1
  48. package/dist/commands/help.d.ts +5 -0
  49. package/dist/commands/help.js +5 -0
  50. package/dist/commands/helpers.d.ts +43 -0
  51. package/dist/commands/helpers.js +61 -0
  52. package/dist/commands/id.d.ts +5 -0
  53. package/dist/commands/id.js +5 -0
  54. package/dist/commands/ip.d.ts +1 -0
  55. package/dist/commands/ip.js +50 -23
  56. package/dist/commands/jobs.js +43 -9
  57. package/dist/commands/kill.d.ts +1 -0
  58. package/dist/commands/kill.js +13 -5
  59. package/dist/commands/last.js +1 -1
  60. package/dist/commands/ln.d.ts +5 -0
  61. package/dist/commands/ln.js +5 -0
  62. package/dist/commands/ls.d.ts +5 -0
  63. package/dist/commands/ls.js +19 -4
  64. package/dist/commands/lsb-release.js +1 -1
  65. package/dist/commands/man.d.ts +5 -0
  66. package/dist/commands/man.js +5 -0
  67. package/dist/commands/manuals-bundle.js +242 -0
  68. package/dist/commands/miscutils.d.ts +43 -0
  69. package/dist/commands/miscutils.js +233 -0
  70. package/dist/commands/mkdir.js +3 -2
  71. package/dist/commands/mv.js +4 -3
  72. package/dist/commands/netcat.d.ts +7 -0
  73. package/dist/commands/netcat.js +64 -0
  74. package/dist/commands/nice.d.ts +7 -0
  75. package/dist/commands/nice.js +22 -0
  76. package/dist/commands/nohup.d.ts +7 -0
  77. package/dist/commands/nohup.js +18 -0
  78. package/dist/commands/ping.d.ts +2 -1
  79. package/dist/commands/ping.js +46 -8
  80. package/dist/commands/procUtils.d.ts +13 -0
  81. package/dist/commands/procUtils.js +72 -0
  82. package/dist/commands/pwd.d.ts +5 -0
  83. package/dist/commands/pwd.js +5 -0
  84. package/dist/commands/python.js +0 -4
  85. package/dist/commands/read.js +0 -1
  86. package/dist/commands/registry.d.ts +37 -0
  87. package/dist/commands/registry.js +73 -0
  88. package/dist/commands/rm.js +3 -2
  89. package/dist/commands/runtime.d.ts +47 -1
  90. package/dist/commands/runtime.js +60 -5
  91. package/dist/commands/sh.d.ts +5 -0
  92. package/dist/commands/sh.js +5 -0
  93. package/dist/commands/stat.js +3 -2
  94. package/dist/commands/strace.js +0 -1
  95. package/dist/commands/sysinfo.d.ts +19 -0
  96. package/dist/commands/sysinfo.js +73 -0
  97. package/dist/commands/test.d.ts +5 -0
  98. package/dist/commands/test.js +5 -0
  99. package/dist/commands/textutils.d.ts +25 -0
  100. package/dist/commands/textutils.js +171 -0
  101. package/dist/commands/top.d.ts +7 -0
  102. package/dist/commands/top.js +54 -0
  103. package/dist/commands/touch.js +6 -2
  104. package/dist/commands/tr.d.ts +5 -0
  105. package/dist/commands/tr.js +5 -0
  106. package/dist/commands/w.js +1 -1
  107. package/dist/commands/which.d.ts +5 -0
  108. package/dist/commands/which.js +5 -0
  109. package/dist/index.d.ts +10 -2
  110. package/dist/index.js +4 -0
  111. package/dist/modules/VirtualNetworkManager.d.ts +54 -0
  112. package/dist/modules/VirtualNetworkManager.js +144 -0
  113. package/dist/modules/linuxRootfs.d.ts +4 -3
  114. package/dist/modules/linuxRootfs.js +115 -74
  115. package/dist/modules/neofetch.d.ts +2 -0
  116. package/dist/modules/neofetch.js +3 -2
  117. package/dist/modules/pacmanGame.d.ts +2 -0
  118. package/dist/modules/pacmanGame.js +1 -0
  119. package/dist/modules/shellInteractive.d.ts +2 -0
  120. package/dist/modules/shellInteractive.js +2 -0
  121. package/dist/modules/shellRuntime.d.ts +7 -0
  122. package/dist/modules/shellRuntime.js +6 -0
  123. package/dist/modules/webTermRenderer.js +0 -7
  124. package/dist/types/commands.d.ts +1 -1
  125. package/dist/types/vfs.d.ts +8 -0
  126. package/dist/utils/argv.d.ts +22 -3
  127. package/dist/utils/argv.js +22 -3
  128. package/dist/utils/perfLogger.d.ts +10 -2
  129. package/dist/utils/perfLogger.js +7 -14
  130. package/dist/utils/shellSession.d.ts +35 -0
  131. package/dist/utils/shellSession.js +35 -0
  132. package/package.json +1 -1
@@ -209,6 +209,17 @@ EXAMPLES
209
209
  mount | column -t
210
210
  cat /etc/passwd | column -t -s:
211
211
  column -t file.txt`,
212
+ "comm": `COMM(1) User Commands COMM(1)
213
+
214
+ NAME
215
+ comm - compare two sorted files line by line
216
+
217
+ SYNOPSIS
218
+ comm [OPTION]... FILE1 FILE2
219
+
220
+ DESCRIPTION
221
+ Compare FILE1 and FILE2 line by line, producing
222
+ three-column output of common and unique lines.`,
212
223
  "cowsay": `COWSAY(1) User Commands COWSAY(1)
213
224
 
214
225
  NAME
@@ -240,6 +251,17 @@ SYNOPSIS
240
251
 
241
252
  OPTIONS
242
253
  -r copy directories recursively`,
254
+ "csplit": `CSPLIT(1) User Commands CSPLIT(1)
255
+
256
+ NAME
257
+ csplit - split a file into pieces by context
258
+
259
+ SYNOPSIS
260
+ csplit [OPTION]... FILE PATTERN...
261
+
262
+ DESCRIPTION
263
+ Split FILE into pieces based on context lines
264
+ matching PATTERN, creating numbered output files.`,
243
265
  "curl": `CURL(1) User Commands CURL(1)
244
266
 
245
267
  NAME
@@ -292,6 +314,18 @@ DESCRIPTION
292
314
  EXAMPLES
293
315
  date
294
316
  date +%Y-%m-%d`,
317
+ "dd": `DD(1) User Commands DD(1)
318
+
319
+ NAME
320
+ dd - convert and copy a file
321
+
322
+ SYNOPSIS
323
+ dd [OPERAND...]
324
+
325
+ DESCRIPTION
326
+ Copy a file with optional conversions. Operands
327
+ specify input file, output file, block size, and
328
+ count.`,
295
329
  "declare": `DECLARE(1) Shell Builtins DECLARE(1)
296
330
 
297
331
  NAME
@@ -464,6 +498,17 @@ EXAMPLES
464
498
  exit # exit with last command's status
465
499
  exit 0 # exit successfully
466
500
  exit 1 # exit with error`,
501
+ "expand": `EXPAND(1) User Commands EXPAND(1)
502
+
503
+ NAME
504
+ expand - convert tabs to spaces
505
+
506
+ SYNOPSIS
507
+ expand [OPTION]... [FILE...]
508
+
509
+ DESCRIPTION
510
+ Convert tabs in each FILE to spaces, writing to
511
+ standard output.`,
467
512
  "export": `EXPORT(1) User Commands EXPORT(1)
468
513
 
469
514
  NAME
@@ -484,6 +529,17 @@ EXAMPLES
484
529
  export PATH="$PATH:/usr/local/bin"
485
530
  export NODE_ENV=production
486
531
  export -p`,
532
+ "expr": `EXPR(1) User Commands EXPR(1)
533
+
534
+ NAME
535
+ expr - evaluate arithmetic expressions
536
+
537
+ SYNOPSIS
538
+ expr EXPRESSION
539
+
540
+ DESCRIPTION
541
+ Evaluate an EXPRESSION and print its result.
542
+ Supports arithmetic, string, and logical operators.`,
487
543
  "false": `FALSE(1) User Commands FALSE(1)
488
544
 
489
545
  NAME
@@ -526,6 +582,28 @@ SYNOPSIS
526
582
  OPTIONS
527
583
  -name PATTERN base name matches shell PATTERN
528
584
  -type TYPE file type, e.g. f for file, d for directory`,
585
+ "fmt": `FMT(1) User Commands FMT(1)
586
+
587
+ NAME
588
+ fmt - simple text formatter
589
+
590
+ SYNOPSIS
591
+ fmt [OPTION]... [FILE...]
592
+
593
+ DESCRIPTION
594
+ Reformat paragraphs from each FILE to a specified
595
+ width, filling and joining lines.`,
596
+ "fold": `FOLD(1) User Commands FOLD(1)
597
+
598
+ NAME
599
+ fold - wrap each input line to fit specified width
600
+
601
+ SYNOPSIS
602
+ fold [OPTION]... [FILE...]
603
+
604
+ DESCRIPTION
605
+ Wrap lines from each FILE to a specified width
606
+ (default 80), breaking at character boundaries.`,
529
607
  "fortune": `FORTUNE(6) Games and Amusements FORTUNE(6)
530
608
 
531
609
  NAME
@@ -710,6 +788,17 @@ EXAMPLES
710
788
  ip addr show eth0 # show eth0 address
711
789
  ip route # show routing table
712
790
  ip link # show link info`,
791
+ "join": `JOIN(1) User Commands JOIN(1)
792
+
793
+ NAME
794
+ join - join lines of two files on a common field
795
+
796
+ SYNOPSIS
797
+ join [OPTION]... FILE1 FILE2
798
+
799
+ DESCRIPTION
800
+ Join lines from FILE1 and FILE2 based on a common
801
+ field, writing to standard output.`,
713
802
  "kill": `KILL(1) User Commands KILL(1)
714
803
 
715
804
  NAME
@@ -800,6 +889,39 @@ EXAMPLES
800
889
  lsb_release -a
801
890
  lsb_release -d
802
891
  lsb_release -rs`,
892
+ "lscpu": `LSCPU(1) User Commands LSCPU(1)
893
+
894
+ NAME
895
+ lscpu - display CPU architecture information
896
+
897
+ SYNOPSIS
898
+ lscpu
899
+
900
+ DESCRIPTION
901
+ Display information about the CPU architecture,
902
+ including cores, threads, caches, and flags.`,
903
+ "lspci": `LSPCI(1) User Commands LSPCI(1)
904
+
905
+ NAME
906
+ lspci - list PCI devices
907
+
908
+ SYNOPSIS
909
+ lspci [OPTION]...
910
+
911
+ DESCRIPTION
912
+ Display information about PCI buses and devices
913
+ connected to the system.`,
914
+ "lsusb": `LSUSB(1) User Commands LSUSB(1)
915
+
916
+ NAME
917
+ lsusb - list USB devices
918
+
919
+ SYNOPSIS
920
+ lsusb [OPTION]...
921
+
922
+ DESCRIPTION
923
+ Display information about USB buses and devices
924
+ connected to the system.`,
803
925
  "man": `MAN(1) User Commands MAN(1)
804
926
 
805
927
  NAME
@@ -822,6 +944,16 @@ EXAMPLES
822
944
  man ls
823
945
  man 1 printf
824
946
  man grep`,
947
+ "md5sum": `MD5SUM(1) User Commands MD5SUM(1)
948
+
949
+ NAME
950
+ md5sum - compute and check MD5 message digest
951
+
952
+ SYNOPSIS
953
+ md5sum [FILE...]
954
+
955
+ DESCRIPTION
956
+ Print or check MD5 (128-bit) checksums for each FILE.`,
825
957
  "mkdir": `MKDIR(1) User Commands MKDIR(1)
826
958
 
827
959
  NAME
@@ -878,6 +1010,17 @@ SYNOPSIS
878
1010
  DESCRIPTION
879
1011
  Open FILE in an interactive editor.
880
1012
  Save with Ctrl+O, exit with Ctrl+X.`,
1013
+ "nc": `NC(1) User Commands NC(1)
1014
+
1015
+ NAME
1016
+ nc - arbitrary TCP and UDP connections
1017
+
1018
+ SYNOPSIS
1019
+ nc [OPTION]... HOST PORT
1020
+
1021
+ DESCRIPTION
1022
+ Open TCP or UDP connections to arbitrary ports,
1023
+ useful for debugging and network exploration.`,
881
1024
  "neofetch": `NEOFETCH(1) User Commands NEOFETCH(1)
882
1025
 
883
1026
  NAME
@@ -888,6 +1031,17 @@ SYNOPSIS
888
1031
 
889
1032
  DESCRIPTION
890
1033
  Print OS, kernel, uptime, package count, and related system details.`,
1034
+ "nice": `NICE(1) User Commands NICE(1)
1035
+
1036
+ NAME
1037
+ nice - run a command with modified niceness
1038
+
1039
+ SYNOPSIS
1040
+ nice [OPTION]... COMMAND [ARG...]
1041
+
1042
+ DESCRIPTION
1043
+ Run COMMAND with an adjusted scheduling priority
1044
+ (niceness). Higher niceness means lower priority.`,
891
1045
  "nl": `NL(1) User Commands NL(1)
892
1046
 
893
1047
  NAME
@@ -925,6 +1079,17 @@ DESCRIPTION
925
1079
 
926
1080
  NOTES
927
1081
  Requires package installation: apt install nodejs.`,
1082
+ "nohup": `NOHUP(1) User Commands NOHUP(1)
1083
+
1084
+ NAME
1085
+ nohup - run a command immune to hangups
1086
+
1087
+ SYNOPSIS
1088
+ nohup COMMAND [ARG...]
1089
+
1090
+ DESCRIPTION
1091
+ Run COMMAND such that it ignores HUP signals and
1092
+ continues running after the terminal is closed.`,
928
1093
  "npm": `NPM(1) User Commands NPM(1)
929
1094
 
930
1095
  NAME
@@ -1035,6 +1200,17 @@ EXAMPLES
1035
1200
  paste file1 file2
1036
1201
  paste -d: /etc/passwd /etc/shadow
1037
1202
  paste -d, a.txt b.txt c.txt`,
1203
+ "pgrep": `PGREP(1) User Commands PGREP(1)
1204
+
1205
+ NAME
1206
+ pgrep - look up processes by pattern
1207
+
1208
+ SYNOPSIS
1209
+ pgrep [OPTION]... PATTERN
1210
+
1211
+ DESCRIPTION
1212
+ List process IDs matching PATTERN. By default
1213
+ matches against process names.`,
1038
1214
  "ping": `PING(8) User Commands PING(8)
1039
1215
 
1040
1216
  NAME
@@ -1045,6 +1221,17 @@ SYNOPSIS
1045
1221
 
1046
1222
  OPTIONS
1047
1223
  -c COUNT stop after sending COUNT packets`,
1224
+ "pkill": `PKILL(1) User Commands PKILL(1)
1225
+
1226
+ NAME
1227
+ pkill - kill processes by pattern
1228
+
1229
+ SYNOPSIS
1230
+ pkill [OPTION]... PATTERN
1231
+
1232
+ DESCRIPTION
1233
+ Send signals to processes matching PATTERN. By
1234
+ default sends SIGTERM.`,
1048
1235
  "printf": `PRINTF(1) User Commands PRINTF(1)
1049
1236
 
1050
1237
  NAME
@@ -1118,6 +1305,17 @@ SYNOPSIS
1118
1305
 
1119
1306
  OPTIONS
1120
1307
  -f canonicalize by following every symlink in every component`,
1308
+ "realpath": `REALPATH(1) User Commands REALPATH(1)
1309
+
1310
+ NAME
1311
+ realpath - print resolved absolute file name
1312
+
1313
+ SYNOPSIS
1314
+ realpath [FILE...]
1315
+
1316
+ DESCRIPTION
1317
+ Print the resolved absolute path for each FILE,
1318
+ with all symbolic links resolved.`,
1121
1319
  "return": `RETURN(1) Shell Builtins RETURN(1)
1122
1320
 
1123
1321
  NAME
@@ -1214,6 +1412,17 @@ EXAMPLES
1214
1412
  sh -c 'echo hello'
1215
1413
  sh script.sh
1216
1414
  sh -c 'for i in 1 2 3; do echo $i; done'`,
1415
+ "sha256sum": `SHA256SUM(1) User Commands SHA256SUM(1)
1416
+
1417
+ NAME
1418
+ sha256sum - compute and check SHA-256 message digest
1419
+
1420
+ SYNOPSIS
1421
+ sha256sum [FILE...]
1422
+
1423
+ DESCRIPTION
1424
+ Print or check SHA-256 (256-bit) checksums for each
1425
+ FILE.`,
1217
1426
  "shift": `SHIFT(1) Shell Builtins SHIFT(1)
1218
1427
 
1219
1428
  NAME
@@ -1295,6 +1504,17 @@ SYNOPSIS
1295
1504
 
1296
1505
  DESCRIPTION
1297
1506
  Read and execute commands from FILE in the current shell context.`,
1507
+ "split": `SPLIT(1) User Commands SPLIT(1)
1508
+
1509
+ NAME
1510
+ split - split a file into pieces
1511
+
1512
+ SYNOPSIS
1513
+ split [OPTION]... [FILE [PREFIX]]
1514
+
1515
+ DESCRIPTION
1516
+ Split FILE into fixed-size pieces, creating output
1517
+ files named PREFIXaa, PREFIXab, etc.`,
1298
1518
  "ssh": `SSH(1) OpenSSH SSH(1)
1299
1519
 
1300
1520
  NAME
@@ -1316,6 +1536,17 @@ SYNOPSIS
1316
1536
 
1317
1537
  OPTIONS
1318
1538
  -c, --format=FORMAT use the specified output format`,
1539
+ "strings": `STRINGS(1) User Commands STRINGS(1)
1540
+
1541
+ NAME
1542
+ strings - print printable strings in binary files
1543
+
1544
+ SYNOPSIS
1545
+ strings [FILE...]
1546
+
1547
+ DESCRIPTION
1548
+ For each FILE, print sequences of printable
1549
+ characters found in binary data.`,
1319
1550
  "stty": `STTY(1) User Commands STTY(1)
1320
1551
 
1321
1552
  NAME
@@ -1452,6 +1683,17 @@ EXIT STATUS
1452
1683
  EXAMPLES
1453
1684
  timeout 5 sleep 10
1454
1685
  timeout 30 curl http://example.com/`,
1686
+ "top": `TOP(1) User Commands TOP(1)
1687
+
1688
+ NAME
1689
+ top - display process information
1690
+
1691
+ SYNOPSIS
1692
+ top [OPTION]...
1693
+
1694
+ DESCRIPTION
1695
+ Display a dynamic, real-time view of running
1696
+ processes and system resource usage.`,
1455
1697
  "touch": `TOUCH(1) User Commands TOUCH(1)
1456
1698
 
1457
1699
  NAME
@@ -0,0 +1,43 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Resolve symlinks and print absolute path
4
+ * @category files
5
+ * @params ["<path>"]
6
+ */
7
+ export declare const realpathCommand: ShellModule;
8
+ /**
9
+ * Compute MD5 hash of a file
10
+ * @category text
11
+ * @params ["<file>"]
12
+ */
13
+ export declare const md5sumCommand: ShellModule;
14
+ /**
15
+ * Compute SHA256 hash of a file
16
+ * @category text
17
+ * @params ["<file>"]
18
+ */
19
+ export declare const sha256sumCommand: ShellModule;
20
+ /**
21
+ * Find printable strings in a file
22
+ * @category text
23
+ * @params ["<file>"]
24
+ */
25
+ export declare const stringsCommand: ShellModule;
26
+ /**
27
+ * Wrap lines to a specified width
28
+ * @category text
29
+ * @params ["[-w width] <file>"]
30
+ */
31
+ export declare const foldCommand: ShellModule;
32
+ /**
33
+ * Convert tabs to spaces
34
+ * @category text
35
+ * @params ["[-t tabs] <file>"]
36
+ */
37
+ export declare const expandCommand: ShellModule;
38
+ /**
39
+ * Simple text formatter
40
+ * @category text
41
+ * @params ["[-w width] <file>"]
42
+ */
43
+ export declare const fmtCommand: ShellModule;
@@ -0,0 +1,233 @@
1
+ import { createHash } from "node:crypto";
2
+ import * as path from "node:path";
3
+ import { parseArgs } from "./command-helpers";
4
+ import { resolvePath } from "./helpers";
5
+ /**
6
+ * Resolve symlinks and print absolute path
7
+ * @category files
8
+ * @params ["<path>"]
9
+ */
10
+ export const realpathCommand = {
11
+ name: "realpath",
12
+ description: "Resolve symlinks and print absolute path",
13
+ category: "files",
14
+ params: ["<path>"],
15
+ run: ({ shell, cwd, args }) => {
16
+ const target = args.find((a) => !a.startsWith("-"));
17
+ if (!target)
18
+ return { stderr: "realpath: missing operand\n", exitCode: 1 };
19
+ const p = resolvePath(cwd, target);
20
+ if (!shell.vfs.exists(p)) {
21
+ return { stderr: `realpath: ${target}: No such file or directory\n`, exitCode: 1 };
22
+ }
23
+ const resolved = shell.vfs.isSymlink(p)
24
+ ? shell.vfs.resolveSymlink(p)
25
+ : p;
26
+ return { stdout: path.posix.normalize(resolved) + "\n", exitCode: 0 };
27
+ },
28
+ };
29
+ /**
30
+ * Compute MD5 hash of a file
31
+ * @category text
32
+ * @params ["<file>"]
33
+ */
34
+ export const md5sumCommand = {
35
+ name: "md5sum",
36
+ description: "Compute MD5 hash of a file",
37
+ category: "text",
38
+ params: ["<file>"],
39
+ run: ({ shell, cwd, args }) => {
40
+ const fileArg = args.find((a) => !a.startsWith("-"));
41
+ if (!fileArg)
42
+ return { stderr: "md5sum: missing file operand\n", exitCode: 1 };
43
+ const p = resolvePath(cwd, fileArg);
44
+ if (!shell.vfs.exists(p)) {
45
+ return { stderr: `md5sum: ${fileArg}: No such file or directory\n`, exitCode: 1 };
46
+ }
47
+ const content = shell.vfs.readFile(p);
48
+ const hash = createHash("md5").update(content).digest("hex");
49
+ return { stdout: `${hash} ${fileArg}\n`, exitCode: 0 };
50
+ },
51
+ };
52
+ /**
53
+ * Compute SHA256 hash of a file
54
+ * @category text
55
+ * @params ["<file>"]
56
+ */
57
+ export const sha256sumCommand = {
58
+ name: "sha256sum",
59
+ description: "Compute SHA256 hash of a file",
60
+ category: "text",
61
+ params: ["<file>"],
62
+ run: ({ shell, cwd, args }) => {
63
+ const fileArg = args.find((a) => !a.startsWith("-"));
64
+ if (!fileArg)
65
+ return { stderr: "sha256sum: missing file operand\n", exitCode: 1 };
66
+ const p = resolvePath(cwd, fileArg);
67
+ if (!shell.vfs.exists(p)) {
68
+ return { stderr: `sha256sum: ${fileArg}: No such file or directory\n`, exitCode: 1 };
69
+ }
70
+ const content = shell.vfs.readFile(p);
71
+ const hash = createHash("sha256").update(content).digest("hex");
72
+ return { stdout: `${hash} ${fileArg}\n`, exitCode: 0 };
73
+ },
74
+ };
75
+ /**
76
+ * Find printable strings in a file
77
+ * @category text
78
+ * @params ["<file>"]
79
+ */
80
+ export const stringsCommand = {
81
+ name: "strings",
82
+ description: "Find printable strings in a file",
83
+ category: "text",
84
+ params: ["<file>"],
85
+ run: ({ shell, cwd, args }) => {
86
+ const fileArg = args.find((a) => !a.startsWith("-"));
87
+ if (!fileArg)
88
+ return { stderr: "strings: missing file operand\n", exitCode: 1 };
89
+ const p = resolvePath(cwd, fileArg);
90
+ if (!shell.vfs.exists(p)) {
91
+ return { stderr: `strings: ${fileArg}: No such file or directory\n`, exitCode: 1 };
92
+ }
93
+ const buf = shell.vfs.readFileRaw(p);
94
+ let current = "";
95
+ const results = [];
96
+ for (let i = 0; i < buf.length; i++) {
97
+ const ch = buf[i];
98
+ if (ch >= 32 && ch <= 126) {
99
+ current += String.fromCharCode(ch);
100
+ }
101
+ else {
102
+ if (current.length >= 4)
103
+ results.push(current);
104
+ current = "";
105
+ }
106
+ }
107
+ if (current.length >= 4)
108
+ results.push(current);
109
+ return { stdout: results.join("\n") + "\n", exitCode: 0 };
110
+ },
111
+ };
112
+ /**
113
+ * Wrap lines to a specified width
114
+ * @category text
115
+ * @params ["[-w width] <file>"]
116
+ */
117
+ export const foldCommand = {
118
+ name: "fold",
119
+ description: "Wrap lines to a specified width",
120
+ category: "text",
121
+ params: ["[-w width] <file>"],
122
+ run: ({ shell, cwd, args, stdin }) => {
123
+ const { flagsWithValues, positionals } = parseArgs(args, {
124
+ flagsWithValue: ["-w"],
125
+ });
126
+ const width = parseInt(flagsWithValues.get("-w") || "80", 10);
127
+ const fileArg = positionals[0];
128
+ let input;
129
+ if (fileArg) {
130
+ const p = resolvePath(cwd, fileArg);
131
+ if (!shell.vfs.exists(p)) {
132
+ return { stderr: `fold: ${fileArg}: No such file or directory\n`, exitCode: 1 };
133
+ }
134
+ input = shell.vfs.readFile(p);
135
+ }
136
+ else {
137
+ input = stdin;
138
+ }
139
+ if (!input)
140
+ return { exitCode: 0 };
141
+ const lines = input.split("\n");
142
+ const folded = lines.map((line) => {
143
+ if (line.length <= width)
144
+ return line;
145
+ const parts = [];
146
+ for (let i = 0; i < line.length; i += width) {
147
+ parts.push(line.slice(i, i + width));
148
+ }
149
+ return parts.join("\n");
150
+ });
151
+ return { stdout: folded.join("\n"), exitCode: 0 };
152
+ },
153
+ };
154
+ /**
155
+ * Convert tabs to spaces
156
+ * @category text
157
+ * @params ["[-t tabs] <file>"]
158
+ */
159
+ export const expandCommand = {
160
+ name: "expand",
161
+ description: "Convert tabs to spaces",
162
+ category: "text",
163
+ params: ["[-t tabs] <file>"],
164
+ run: ({ shell, cwd, args, stdin }) => {
165
+ const { flagsWithValues, positionals } = parseArgs(args, {
166
+ flagsWithValue: ["-t", "--tabs"],
167
+ });
168
+ const tabstop = parseInt(flagsWithValues.get("-t") || flagsWithValues.get("--tabs") || "8", 10);
169
+ const fileArg = positionals[0];
170
+ let input;
171
+ if (fileArg) {
172
+ const p = resolvePath(cwd, fileArg);
173
+ if (!shell.vfs.exists(p)) {
174
+ return { stderr: `expand: ${fileArg}: No such file or directory\n`, exitCode: 1 };
175
+ }
176
+ input = shell.vfs.readFile(p);
177
+ }
178
+ else {
179
+ input = stdin;
180
+ }
181
+ if (!input)
182
+ return { exitCode: 0 };
183
+ const expanded = input.replace(/\t/g, " ".repeat(tabstop));
184
+ return { stdout: expanded, exitCode: 0 };
185
+ },
186
+ };
187
+ /**
188
+ * Simple text formatter
189
+ * @category text
190
+ * @params ["[-w width] <file>"]
191
+ */
192
+ export const fmtCommand = {
193
+ name: "fmt",
194
+ description: "Simple text formatter",
195
+ category: "text",
196
+ params: ["[-w width] <file>"],
197
+ run: ({ shell, cwd, args, stdin }) => {
198
+ const { flagsWithValues, positionals } = parseArgs(args, {
199
+ flagsWithValue: ["-w"],
200
+ });
201
+ const width = parseInt(flagsWithValues.get("-w") || "75", 10);
202
+ const fileArg = positionals[0];
203
+ let input;
204
+ if (fileArg) {
205
+ const p = resolvePath(cwd, fileArg);
206
+ if (!shell.vfs.exists(p)) {
207
+ return { stderr: `fmt: ${fileArg}: No such file or directory\n`, exitCode: 1 };
208
+ }
209
+ input = shell.vfs.readFile(p);
210
+ }
211
+ else {
212
+ input = stdin;
213
+ }
214
+ if (!input)
215
+ return { exitCode: 0 };
216
+ const words = input.replace(/\n/g, " ").split(/\s+/).filter(Boolean);
217
+ const lines = [];
218
+ let current = "";
219
+ for (const word of words) {
220
+ if (current.length + word.length + (current ? 1 : 0) > width) {
221
+ if (current)
222
+ lines.push(current);
223
+ current = word;
224
+ }
225
+ else {
226
+ current = current ? `${current} ${word}` : word;
227
+ }
228
+ }
229
+ if (current)
230
+ lines.push(current);
231
+ return { stdout: lines.join("\n") + "\n", exitCode: 0 };
232
+ },
233
+ };
@@ -1,5 +1,6 @@
1
+ import * as path from "node:path";
1
2
  import { getArg } from "./command-helpers";
2
- import { assertPathAccess, resolvePath } from "./helpers";
3
+ import { checkFilePermission, resolvePath } from "./helpers";
3
4
  /**
4
5
  * Create one or more directories.
5
6
  * @category files
@@ -20,7 +21,7 @@ export const mkdirCommand = {
20
21
  return { stderr: "mkdir: missing operand", exitCode: 1 };
21
22
  }
22
23
  const target = resolvePath(cwd, dir);
23
- assertPathAccess(authUser, target, "mkdir");
24
+ checkFilePermission(shell.vfs, shell.users, authUser, path.posix.dirname(target), 2);
24
25
  shell.vfs.mkdir(target);
25
26
  }
26
27
  return { exitCode: 0 };
@@ -1,4 +1,5 @@
1
- import { assertPathAccess, resolvePath } from "./helpers";
1
+ import * as path from "node:path";
2
+ import { checkFilePermission, resolvePath } from "./helpers";
2
3
  /**
3
4
  * Move or rename files and directories.
4
5
  * @category files
@@ -18,8 +19,8 @@ export const mvCommand = {
18
19
  const srcPath = resolvePath(cwd, srcArg);
19
20
  const destPath = resolvePath(cwd, destArg);
20
21
  try {
21
- assertPathAccess(authUser, srcPath, "mv");
22
- assertPathAccess(authUser, destPath, "mv");
22
+ checkFilePermission(shell.vfs, shell.users, authUser, srcPath, 2);
23
+ checkFilePermission(shell.vfs, shell.users, authUser, path.posix.dirname(destPath), 2);
23
24
  if (!shell.vfs.exists(srcPath)) {
24
25
  return {
25
26
  stderr: `mv: ${srcArg}: No such file or directory`,
@@ -0,0 +1,7 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Netcat network utility
4
+ * @category net
5
+ * @params ["[-l] [-p port] [-v]"]
6
+ */
7
+ export declare const ncCommand: ShellModule;