typescript-virtual-container 1.5.2 → 1.5.4

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 (364) hide show
  1. package/README.md +43 -23
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/SSHMimic/executor.js +23 -5
  4. package/dist/commands/basename.d.ts +13 -0
  5. package/dist/commands/basename.js +45 -0
  6. package/dist/commands/file.d.ts +8 -0
  7. package/dist/commands/file.js +57 -0
  8. package/dist/commands/fun.d.ts +32 -0
  9. package/dist/commands/fun.js +172 -0
  10. package/dist/commands/ifconfig.d.ts +7 -0
  11. package/dist/commands/ifconfig.js +52 -0
  12. package/dist/commands/last.d.ts +13 -0
  13. package/dist/commands/last.js +68 -0
  14. package/dist/commands/manuals-bundle.js +598 -6
  15. package/dist/commands/registry.js +24 -2
  16. package/dist/commands/runtime.js +159 -106
  17. package/dist/commands/sh.js +5 -0
  18. package/dist/commands/tput.d.ts +13 -0
  19. package/dist/commands/tput.js +76 -0
  20. package/dist/commands/w.d.ts +7 -0
  21. package/dist/commands/w.js +38 -0
  22. package/dist/utils/expand.d.ts +12 -0
  23. package/dist/utils/expand.js +84 -0
  24. package/package.json +9 -3
  25. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -50
  26. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -31
  27. package/.github/dependabot.yml +0 -27
  28. package/.github/pull_request_template.md +0 -21
  29. package/.github/workflows/create-pull-request.yml +0 -85
  30. package/.github/workflows/publish.yml +0 -25
  31. package/.github/workflows/test-battery.yml +0 -102
  32. package/.vscode/settings.json +0 -20
  33. package/CODE_OF_CONDUCT.md +0 -39
  34. package/CONTRIBUTING.md +0 -59
  35. package/HONEYPOT.md +0 -358
  36. package/SECURITY.md +0 -33
  37. package/benchmark-results.txt +0 -40
  38. package/benchmark-virtualshell.ts +0 -88
  39. package/biome.json +0 -37
  40. package/build.js +0 -22
  41. package/builds/fortune-nyx-v1.5.1-directbash-k6.1.0.mjs +0 -1768
  42. package/builds/fortune-nyx-v1.5.1-ssh-nosftp.js +0 -1768
  43. package/builds/fortune-nyx-v1.5.1-ssh.cjs +0 -1769
  44. package/builds/fortune-nyx-v1.5.1-web.min.js +0 -17022
  45. package/bun.lock +0 -244
  46. package/docs/.nojekyll +0 -1
  47. package/docs/app.js +0 -1755
  48. package/docs/assets/hierarchy.js +0 -1
  49. package/docs/assets/highlight.css +0 -162
  50. package/docs/assets/icons.js +0 -18
  51. package/docs/assets/icons.svg +0 -1
  52. package/docs/assets/main.js +0 -60
  53. package/docs/assets/navigation.js +0 -1
  54. package/docs/assets/search.js +0 -1
  55. package/docs/assets/style.css +0 -1633
  56. package/docs/classes/HoneyPot.html +0 -31
  57. package/docs/classes/IdleManager.html +0 -162
  58. package/docs/classes/SshClient.html +0 -66
  59. package/docs/classes/VirtualFileSystem.html +0 -279
  60. package/docs/classes/VirtualPackageManager.html +0 -63
  61. package/docs/classes/VirtualSftpServer.html +0 -169
  62. package/docs/classes/VirtualShell.html +0 -285
  63. package/docs/classes/VirtualSshServer.html +0 -182
  64. package/docs/classes/VirtualUserManager.html +0 -276
  65. package/docs/demo.html +0 -82
  66. package/docs/functions/assertDiff.html +0 -6
  67. package/docs/functions/diffSnapshots.html +0 -7
  68. package/docs/functions/formatDiff.html +0 -6
  69. package/docs/functions/getArg.html +0 -13
  70. package/docs/functions/getFlag.html +0 -15
  71. package/docs/functions/ifFlag.html +0 -11
  72. package/docs/hierarchy.html +0 -1
  73. package/docs/index.html +0 -1869
  74. package/docs/interfaces/AuditLogEntry.html +0 -6
  75. package/docs/interfaces/CommandContext.html +0 -22
  76. package/docs/interfaces/CommandResult.html +0 -26
  77. package/docs/interfaces/ExecStream.html +0 -11
  78. package/docs/interfaces/HoneyPotStats.html +0 -16
  79. package/docs/interfaces/IdleManagerOptions.html +0 -7
  80. package/docs/interfaces/InstalledPackage.html +0 -20
  81. package/docs/interfaces/NanoEditorSession.html +0 -8
  82. package/docs/interfaces/PackageDefinition.html +0 -30
  83. package/docs/interfaces/PackageFile.html +0 -8
  84. package/docs/interfaces/PasswordChallenge.html +0 -16
  85. package/docs/interfaces/RemoveOptions.html +0 -4
  86. package/docs/interfaces/ShellEnv.html +0 -6
  87. package/docs/interfaces/ShellModule.html +0 -14
  88. package/docs/interfaces/ShellProperties.html +0 -14
  89. package/docs/interfaces/ShellStream.html +0 -11
  90. package/docs/interfaces/SudoChallenge.html +0 -24
  91. package/docs/interfaces/VfsBaseNode.html +0 -12
  92. package/docs/interfaces/VfsDiff.html +0 -10
  93. package/docs/interfaces/VfsDiffEntry.html +0 -6
  94. package/docs/interfaces/VfsDiffModified.html +0 -10
  95. package/docs/interfaces/VfsDirectoryNode.html +0 -15
  96. package/docs/interfaces/VfsFileNode.html +0 -17
  97. package/docs/interfaces/VfsOptions.html +0 -26
  98. package/docs/interfaces/VfsSnapshot.html +0 -3
  99. package/docs/interfaces/VfsSnapshotBaseNode.html +0 -8
  100. package/docs/interfaces/VfsSnapshotDirectoryNode.html +0 -10
  101. package/docs/interfaces/VfsSnapshotFileNode.html +0 -12
  102. package/docs/interfaces/VirtualActiveSession.html +0 -12
  103. package/docs/interfaces/VirtualSftpServerOptions.html +0 -7
  104. package/docs/interfaces/VirtualShellVfsLike.html +0 -15
  105. package/docs/interfaces/VirtualShellVfsOptions.html +0 -3
  106. package/docs/interfaces/WriteFileOptions.html +0 -6
  107. package/docs/media/LICENSE +0 -21
  108. package/docs/modules.html +0 -1
  109. package/docs/types/ArgParseOptions.html +0 -4
  110. package/docs/types/CommandMode.html +0 -2
  111. package/docs/types/CommandOutcome.html +0 -2
  112. package/docs/types/IdleState.html +0 -1
  113. package/docs/types/VfsNodeStats.html +0 -2
  114. package/docs/types/VfsNodeType.html +0 -2
  115. package/docs/types/VfsPersistenceMode.html +0 -5
  116. package/docs/types/VfsSnapshotNode.html +0 -2
  117. package/examples/README.md +0 -288
  118. package/examples/app.js +0 -1755
  119. package/examples/app.ts +0 -299
  120. package/examples/build.js +0 -27
  121. package/examples/demo.html +0 -33
  122. package/examples/honeypot-audit.ts +0 -180
  123. package/examples/honeypot-export.ts +0 -253
  124. package/examples/honeypot-quickstart.ts +0 -110
  125. package/examples/index.html +0 -82
  126. package/examples/server.js +0 -55
  127. package/polyfills/buffer.js +0 -117
  128. package/polyfills/node_child_process/index.js +0 -2
  129. package/polyfills/node_crypto/index.js +0 -167
  130. package/polyfills/node_events/index.js +0 -9
  131. package/polyfills/node_fs/index.js +0 -202
  132. package/polyfills/node_fs/promises.js +0 -4
  133. package/polyfills/node_os/index.js +0 -9
  134. package/polyfills/node_path/index.js +0 -28
  135. package/polyfills/node_vm/index.js +0 -7
  136. package/polyfills/node_zlib/index.js +0 -3
  137. package/polyfills/process.js +0 -14
  138. package/polyfills/ssh2/index.js +0 -75
  139. package/scripts/build-all.mjs +0 -226
  140. package/scripts/build-names.mjs +0 -43
  141. package/scripts/generate-manuals-bundle.mjs +0 -49
  142. package/scripts/postinstall.js +0 -42
  143. package/scripts/publish-package.sh +0 -70
  144. package/src/Honeypot/index.ts +0 -457
  145. package/src/SSHClient/index.ts +0 -270
  146. package/src/SSHMimic/exec.ts +0 -49
  147. package/src/SSHMimic/executor.ts +0 -251
  148. package/src/SSHMimic/hostKey.ts +0 -21
  149. package/src/SSHMimic/index.ts +0 -337
  150. package/src/SSHMimic/loginBanner.ts +0 -36
  151. package/src/SSHMimic/loginFormat.ts +0 -10
  152. package/src/SSHMimic/prompt.ts +0 -14
  153. package/src/SSHMimic/sftp.ts +0 -883
  154. package/src/VirtualFileSystem/binaryPack.ts +0 -258
  155. package/src/VirtualFileSystem/index.ts +0 -1193
  156. package/src/VirtualFileSystem/internalTypes.ts +0 -43
  157. package/src/VirtualFileSystem/journal.ts +0 -171
  158. package/src/VirtualFileSystem/path.ts +0 -74
  159. package/src/VirtualPackageManager/index.ts +0 -1006
  160. package/src/VirtualShell/idleManager.ts +0 -137
  161. package/src/VirtualShell/index.ts +0 -475
  162. package/src/VirtualShell/shell.ts +0 -700
  163. package/src/VirtualShell/shellParser.ts +0 -285
  164. package/src/VirtualUserManager/index.ts +0 -758
  165. package/src/bun.d.ts +0 -1
  166. package/src/commands/adduser.ts +0 -103
  167. package/src/commands/alias.ts +0 -69
  168. package/src/commands/apt.ts +0 -233
  169. package/src/commands/awk.ts +0 -168
  170. package/src/commands/base64.ts +0 -29
  171. package/src/commands/cat.ts +0 -52
  172. package/src/commands/cd.ts +0 -25
  173. package/src/commands/chmod.ts +0 -85
  174. package/src/commands/clear.ts +0 -15
  175. package/src/commands/command-helpers.ts +0 -286
  176. package/src/commands/cp.ts +0 -83
  177. package/src/commands/curl.ts +0 -147
  178. package/src/commands/cut.ts +0 -36
  179. package/src/commands/date.ts +0 -30
  180. package/src/commands/declare.ts +0 -49
  181. package/src/commands/deluser.ts +0 -98
  182. package/src/commands/df.ts +0 -23
  183. package/src/commands/diff.ts +0 -43
  184. package/src/commands/dpkg.ts +0 -180
  185. package/src/commands/du.ts +0 -56
  186. package/src/commands/echo.ts +0 -58
  187. package/src/commands/env.ts +0 -23
  188. package/src/commands/exit.ts +0 -18
  189. package/src/commands/export.ts +0 -34
  190. package/src/commands/find.ts +0 -68
  191. package/src/commands/free.ts +0 -47
  192. package/src/commands/grep.ts +0 -116
  193. package/src/commands/groups.ts +0 -19
  194. package/src/commands/gzip.ts +0 -88
  195. package/src/commands/head.ts +0 -52
  196. package/src/commands/help.ts +0 -152
  197. package/src/commands/helpers.ts +0 -234
  198. package/src/commands/history.ts +0 -34
  199. package/src/commands/hostname.ts +0 -14
  200. package/src/commands/htop.ts +0 -20
  201. package/src/commands/id.ts +0 -19
  202. package/src/commands/index.ts +0 -9
  203. package/src/commands/kill.ts +0 -19
  204. package/src/commands/ln.ts +0 -71
  205. package/src/commands/ls.ts +0 -243
  206. package/src/commands/lsb-release.ts +0 -63
  207. package/src/commands/man.ts +0 -31
  208. package/src/commands/manuals/adduser.txt +0 -11
  209. package/src/commands/manuals/apt-cache.txt +0 -12
  210. package/src/commands/manuals/apt.txt +0 -20
  211. package/src/commands/manuals/awk.txt +0 -13
  212. package/src/commands/manuals/cat.txt +0 -14
  213. package/src/commands/manuals/cd.txt +0 -16
  214. package/src/commands/manuals/chmod.txt +0 -16
  215. package/src/commands/manuals/clear.txt +0 -10
  216. package/src/commands/manuals/cp.txt +0 -10
  217. package/src/commands/manuals/curl.txt +0 -20
  218. package/src/commands/manuals/date.txt +0 -14
  219. package/src/commands/manuals/declare.txt +0 -12
  220. package/src/commands/manuals/deluser.txt +0 -10
  221. package/src/commands/manuals/df.txt +0 -10
  222. package/src/commands/manuals/dpkg-query.txt +0 -11
  223. package/src/commands/manuals/dpkg.txt +0 -14
  224. package/src/commands/manuals/du.txt +0 -11
  225. package/src/commands/manuals/echo.txt +0 -11
  226. package/src/commands/manuals/false.txt +0 -10
  227. package/src/commands/manuals/find.txt +0 -11
  228. package/src/commands/manuals/free.txt +0 -12
  229. package/src/commands/manuals/grep.txt +0 -13
  230. package/src/commands/manuals/groups.txt +0 -10
  231. package/src/commands/manuals/gzip.txt +0 -11
  232. package/src/commands/manuals/head.txt +0 -10
  233. package/src/commands/manuals/help.txt +0 -11
  234. package/src/commands/manuals/history.txt +0 -11
  235. package/src/commands/manuals/hostname.txt +0 -10
  236. package/src/commands/manuals/id.txt +0 -10
  237. package/src/commands/manuals/kill.txt +0 -13
  238. package/src/commands/manuals/ls.txt +0 -20
  239. package/src/commands/manuals/lsb_release.txt +0 -14
  240. package/src/commands/manuals/mkdir.txt +0 -10
  241. package/src/commands/manuals/mv.txt +0 -10
  242. package/src/commands/manuals/nano.txt +0 -11
  243. package/src/commands/manuals/neofetch.txt +0 -10
  244. package/src/commands/manuals/node.txt +0 -13
  245. package/src/commands/manuals/npm.txt +0 -13
  246. package/src/commands/manuals/npx.txt +0 -13
  247. package/src/commands/manuals/passwd.txt +0 -11
  248. package/src/commands/manuals/ping.txt +0 -10
  249. package/src/commands/manuals/printf.txt +0 -11
  250. package/src/commands/manuals/ps.txt +0 -10
  251. package/src/commands/manuals/pwd.txt +0 -10
  252. package/src/commands/manuals/python3.txt +0 -13
  253. package/src/commands/manuals/readlink.txt +0 -10
  254. package/src/commands/manuals/return.txt +0 -10
  255. package/src/commands/manuals/rm.txt +0 -10
  256. package/src/commands/manuals/sed.txt +0 -11
  257. package/src/commands/manuals/set.txt +0 -11
  258. package/src/commands/manuals/shift.txt +0 -10
  259. package/src/commands/manuals/sleep.txt +0 -10
  260. package/src/commands/manuals/sort.txt +0 -12
  261. package/src/commands/manuals/source.txt +0 -11
  262. package/src/commands/manuals/ssh.txt +0 -11
  263. package/src/commands/manuals/stat.txt +0 -10
  264. package/src/commands/manuals/su.txt +0 -13
  265. package/src/commands/manuals/sudo.txt +0 -11
  266. package/src/commands/manuals/tail.txt +0 -10
  267. package/src/commands/manuals/tar.txt +0 -19
  268. package/src/commands/manuals/tee.txt +0 -10
  269. package/src/commands/manuals/test.txt +0 -11
  270. package/src/commands/manuals/touch.txt +0 -11
  271. package/src/commands/manuals/tr.txt +0 -10
  272. package/src/commands/manuals/trap.txt +0 -10
  273. package/src/commands/manuals/true.txt +0 -10
  274. package/src/commands/manuals/type.txt +0 -10
  275. package/src/commands/manuals/uname.txt +0 -12
  276. package/src/commands/manuals/uniq.txt +0 -12
  277. package/src/commands/manuals/unset.txt +0 -10
  278. package/src/commands/manuals/uptime.txt +0 -11
  279. package/src/commands/manuals/wc.txt +0 -12
  280. package/src/commands/manuals/wget.txt +0 -12
  281. package/src/commands/manuals/which.txt +0 -10
  282. package/src/commands/manuals/whoami.txt +0 -10
  283. package/src/commands/manuals/xargs.txt +0 -10
  284. package/src/commands/manuals-bundle.ts +0 -898
  285. package/src/commands/mkdir.ts +0 -31
  286. package/src/commands/mv.ts +0 -50
  287. package/src/commands/nano.ts +0 -38
  288. package/src/commands/neofetch.ts +0 -53
  289. package/src/commands/node.ts +0 -341
  290. package/src/commands/npm.ts +0 -132
  291. package/src/commands/passwd.ts +0 -50
  292. package/src/commands/ping.ts +0 -32
  293. package/src/commands/printf.ts +0 -129
  294. package/src/commands/ps.ts +0 -58
  295. package/src/commands/pwd.ts +0 -9
  296. package/src/commands/python.ts +0 -2229
  297. package/src/commands/read.ts +0 -46
  298. package/src/commands/registry.ts +0 -249
  299. package/src/commands/rm.ts +0 -42
  300. package/src/commands/runtime.ts +0 -378
  301. package/src/commands/sed.ts +0 -68
  302. package/src/commands/seq.ts +0 -43
  303. package/src/commands/set.ts +0 -29
  304. package/src/commands/sh.ts +0 -467
  305. package/src/commands/shift.ts +0 -63
  306. package/src/commands/sleep.ts +0 -20
  307. package/src/commands/sort.ts +0 -46
  308. package/src/commands/source.ts +0 -52
  309. package/src/commands/stat.ts +0 -61
  310. package/src/commands/su.ts +0 -72
  311. package/src/commands/sudo.ts +0 -76
  312. package/src/commands/tail.ts +0 -53
  313. package/src/commands/tar.ts +0 -102
  314. package/src/commands/tee.ts +0 -36
  315. package/src/commands/test.ts +0 -137
  316. package/src/commands/touch.ts +0 -28
  317. package/src/commands/tr.ts +0 -70
  318. package/src/commands/tree.ts +0 -20
  319. package/src/commands/true.ts +0 -27
  320. package/src/commands/type.ts +0 -48
  321. package/src/commands/uname.ts +0 -29
  322. package/src/commands/uniq.ts +0 -39
  323. package/src/commands/unset.ts +0 -17
  324. package/src/commands/uptime.ts +0 -54
  325. package/src/commands/wc.ts +0 -55
  326. package/src/commands/wget.ts +0 -148
  327. package/src/commands/which.ts +0 -37
  328. package/src/commands/who.ts +0 -25
  329. package/src/commands/whoami.ts +0 -14
  330. package/src/commands/xargs.ts +0 -31
  331. package/src/index.ts +0 -67
  332. package/src/modules/linuxRootfs.ts +0 -1961
  333. package/src/modules/neofetch.ts +0 -358
  334. package/src/modules/shellInteractive.ts +0 -57
  335. package/src/modules/shellRuntime.ts +0 -76
  336. package/src/self-standalone.ts +0 -542
  337. package/src/standalone-wo-sftp.ts +0 -38
  338. package/src/standalone.ts +0 -72
  339. package/src/types/commands.ts +0 -146
  340. package/src/types/pipeline.ts +0 -52
  341. package/src/types/streams.ts +0 -32
  342. package/src/types/tar-stream.d.ts +0 -38
  343. package/src/types/vfs.ts +0 -98
  344. package/src/utils/expand.ts +0 -491
  345. package/src/utils/perfLogger.ts +0 -72
  346. package/src/utils/tokenize.ts +0 -98
  347. package/src/utils/vfsDiff.ts +0 -275
  348. package/tests/command-helpers.test.ts +0 -116
  349. package/tests/commands-admin-net.test.ts +0 -441
  350. package/tests/commands-advanced.test.ts +0 -456
  351. package/tests/commands-core.test.ts +0 -562
  352. package/tests/commands-missing.test.ts +0 -570
  353. package/tests/commands-specific-units.test.ts +0 -327
  354. package/tests/commands-text-sys.test.ts +0 -445
  355. package/tests/expand.test.ts +0 -170
  356. package/tests/helpers.test.ts +0 -97
  357. package/tests/new-features.test.ts +0 -1036
  358. package/tests/parser-executor.test.ts +0 -37
  359. package/tests/sftp.test.ts +0 -323
  360. package/tests/ssh-exec.test.ts +0 -45
  361. package/tests/test-helper.ts +0 -79
  362. package/tests/users.test.ts +0 -86
  363. package/tsconfig.json +0 -49
  364. package/typedoc.json +0 -47
@@ -1,456 +0,0 @@
1
- import { beforeAll, describe, expect, test } from "bun:test";
2
- import type { SshClient, VirtualShell } from "../src";
3
- import { createTestDir, createTestEnv, createTestFile, runCmd } from "./test-helper";
4
-
5
- let shell: VirtualShell;
6
- let client: InstanceType<typeof SshClient>;
7
-
8
- beforeAll(async () => {
9
- const env = await createTestEnv("test-advanced");
10
- shell = env.shell;
11
- client = env.client;
12
- });
13
-
14
- // ─── FIND tests ───────────────────────────────────────────────────────────
15
-
16
- describe("find command", () => {
17
- test("find lists files in directory", async () => {
18
- createTestFile(shell, "/tmp/find1.txt", "test");
19
- createTestFile(shell, "/tmp/find2.txt", "test");
20
- const r = await runCmd(client, "find /tmp -name 'find*.txt'");
21
- expect(r.exitCode).toBe(0);
22
- expect(r.stdout).toContain("find1.txt");
23
- expect(r.stdout).toContain("find2.txt");
24
- });
25
-
26
- test("find -name pattern matching", async () => {
27
- createTestFile(shell, "/tmp/test.log", "log");
28
- createTestFile(shell, "/tmp/test.txt", "txt");
29
- const r = await runCmd(client, "find /tmp -name '*.log'");
30
- expect(r.exitCode).toBe(0);
31
- expect(r.stdout).toContain("test.log");
32
- expect(r.stdout).not.toContain("test.txt");
33
- });
34
-
35
- test("find -type f files only", async () => {
36
- await createTestDir(shell, "/tmp/finddir");
37
- createTestFile(shell, "/tmp/finddir/file.txt", "test");
38
- const r = await runCmd(client, "find /tmp/finddir -type f");
39
- expect(r.exitCode).toBe(0);
40
- expect(r.stdout).toContain("file.txt");
41
- });
42
-
43
- test("find -type d directories only", async () => {
44
- await createTestDir(shell, "/tmp/finddir2/subdir");
45
- const r = await runCmd(client, "find /tmp/finddir2 -type d");
46
- expect(r.exitCode).toBe(0);
47
- expect(r.stdout).toContain("subdir");
48
- });
49
-
50
- test("find recursive into subdirs", async () => {
51
- await createTestDir(shell, "/tmp/findrecur/sub1/sub2");
52
- createTestFile(shell, "/tmp/findrecur/file.txt", "top");
53
- createTestFile(shell, "/tmp/findrecur/sub1/file.txt", "sub1");
54
- createTestFile(shell, "/tmp/findrecur/sub1/sub2/file.txt", "sub2");
55
- const r = await runCmd(client, "find /tmp/findrecur -name 'file.txt'");
56
- expect(r.exitCode).toBe(0);
57
- const lines = r.stdout?.split("\n").filter((l) => l);
58
- expect(lines?.length).toBeGreaterThanOrEqual(3);
59
- });
60
-
61
- test("find non-existent path", async () => {
62
- const r = await runCmd(client, "find /nonexistent -type f");
63
- expect(r.exitCode).not.toBe(0);
64
- });
65
- });
66
-
67
- // ─── DIFF tests ────────────────────────────────────────────────────────────
68
-
69
- describe("diff command", () => {
70
- test("diff identical files", async () => {
71
- createTestFile(shell, "/tmp/diff1.txt", "line1\nline2\nline3");
72
- createTestFile(shell, "/tmp/diff2.txt", "line1\nline2\nline3");
73
- const r = await runCmd(client, "diff /tmp/diff1.txt /tmp/diff2.txt");
74
- expect(r.exitCode).toBe(0);
75
- expect(r.stdout).toBe("");
76
- });
77
-
78
- test("diff different files", async () => {
79
- createTestFile(shell, "/tmp/diffA.txt", "line1\nline2");
80
- createTestFile(shell, "/tmp/diffB.txt", "line1\nchanged");
81
- const r = await runCmd(client, "diff /tmp/diffA.txt /tmp/diffB.txt");
82
- expect(r.exitCode).not.toBe(0);
83
- expect(r.stdout).toContain("line2");
84
- expect(r.stdout).toContain("changed");
85
- });
86
-
87
- test("diff with context", async () => {
88
- createTestFile(shell, "/tmp/diffctx1.txt", "a\nb\nc\nd\ne");
89
- createTestFile(shell, "/tmp/diffctx2.txt", "a\nb\nX\nd\ne");
90
- const r = await runCmd(client, "diff /tmp/diffctx1.txt /tmp/diffctx2.txt");
91
- expect(r.exitCode).not.toBe(0);
92
- expect(r.stdout?.length).toBeGreaterThan(0);
93
- });
94
-
95
- test("diff missing file", async () => {
96
- const r = await runCmd(client, "diff /nonexist1.txt /nonexist2.txt");
97
- expect(r.exitCode).not.toBe(0);
98
- });
99
- });
100
-
101
- // ─── DU tests ──────────────────────────────────────────────────────────────
102
-
103
- describe("du command", () => {
104
- test("du directory size", async () => {
105
- createTestFile(shell, "/tmp/dutest/file1.txt", "content");
106
- createTestFile(shell, "/tmp/dutest/file2.txt", "content");
107
- const r = await runCmd(client, "du /tmp/dutest");
108
- expect(r.exitCode).toBe(0);
109
- expect(r.stdout?.length).toBeGreaterThan(0);
110
- });
111
-
112
- test("du -h human readable", async () => {
113
- createTestFile(shell, "/tmp/duh/large.txt", "a".repeat(2000));
114
- const r = await runCmd(client, "du -h /tmp/duh");
115
- expect(r.exitCode).toBe(0);
116
- expect(r.stdout).toMatch(/K|M|G|B/);
117
- });
118
-
119
- test("du -s summary only", async () => {
120
- createTestFile(shell, "/tmp/dus/file.txt", "test");
121
- const r = await runCmd(client, "du -s /tmp/dus");
122
- expect(r.exitCode).toBe(0);
123
- const lines = r.stdout?.split("\n").filter((l) => l);
124
- expect(lines?.length).toBe(1);
125
- });
126
-
127
- test("du non-existent", async () => {
128
- const r = await runCmd(client, "du /nonexistent");
129
- expect(r.exitCode).not.toBe(0);
130
- });
131
- });
132
-
133
- // ─── DF tests ──────────────────────────────────────────────────────────────
134
-
135
- describe("df command", () => {
136
- test("df shows filesystem info", async () => {
137
- const r = await runCmd(client, "df");
138
- expect(r.exitCode).toBe(0);
139
- expect(r.stdout?.length).toBeGreaterThan(0);
140
- });
141
-
142
- test("df -h human readable", async () => {
143
- const r = await runCmd(client, "df -h");
144
- expect(r.exitCode).toBe(0);
145
- expect(r.stdout).toMatch(/K|M|G/i);
146
- });
147
-
148
- test("df specific path", async () => {
149
- const r = await runCmd(client, "df /tmp");
150
- expect(r.exitCode).toBe(0);
151
- expect(r.stdout?.length).toBeGreaterThan(0);
152
- });
153
-
154
- test("df with home directory", async () => {
155
- const r = await runCmd(client, "df /root");
156
- expect(r.exitCode).toBe(0);
157
- expect(r.stdout?.length).toBeGreaterThan(0);
158
- });
159
- });
160
-
161
- // ─── STAT tests ───────────────────────────────────────────────────────────
162
-
163
- describe("stat command", () => {
164
- test("stat file info", async () => {
165
- createTestFile(shell, "/tmp/statfile.txt", "content");
166
- const r = await runCmd(client, "stat /tmp/statfile.txt");
167
- expect(r.exitCode).toBe(0);
168
- expect(r.stdout).toContain("File");
169
- expect(r.stdout).toContain("Access");
170
- });
171
-
172
- test("stat directory", async () => {
173
- const r = await runCmd(client, "stat /tmp");
174
- expect(r.exitCode).toBe(0);
175
- expect(r.stdout).toContain("File");
176
- });
177
-
178
- test("stat shows mode", async () => {
179
- createTestFile(shell, "/tmp/statmode.txt", "test");
180
- const r = await runCmd(client, "stat /tmp/statmode.txt");
181
- expect(r.exitCode).toBe(0);
182
- expect(r.stdout).toMatch(/\d+/);
183
- });
184
-
185
- test("stat non-existent", async () => {
186
- const r = await runCmd(client, "stat /nonexistent");
187
- expect(r.exitCode).not.toBe(0);
188
- });
189
- });
190
-
191
- // ─── TAR tests ────────────────────────────────────────────────────────────
192
-
193
- describe("tar command", () => {
194
- test("tar -cf creates archive", async () => {
195
- createTestFile(shell, "/tmp/tartest/file1.txt", "data1");
196
- createTestFile(shell, "/tmp/tartest/file2.txt", "data2");
197
- const r = await runCmd(client, "tar -cf /tmp/archive.tar /tmp/tartest");
198
- expect(r.exitCode).toBe(0);
199
- expect(shell.vfs.exists("/tmp/archive.tar")).toBe(true);
200
- });
201
-
202
- test("tar -tf lists contents", async () => {
203
- createTestFile(shell, "/tmp/tarlist/file.txt", "content");
204
- await runCmd(client, "tar -cf /tmp/list.tar /tmp/tarlist");
205
- const r = await runCmd(client, "tar -tf /tmp/list.tar");
206
- expect(r.exitCode).toBe(0);
207
- expect(r.stdout).toContain("file.txt");
208
- });
209
-
210
- test("tar -xf extracts archive", async () => {
211
- createTestFile(shell, "/tmp/tarext/source.txt", "original");
212
- await runCmd(client, "tar -cf /tmp/extract.tar /tmp/tarext");
213
- await runCmd(client, "mkdir -p /tmp/extracted");
214
- const r = await runCmd(client, "tar -xf /tmp/extract.tar -C /tmp/extracted");
215
- expect(r.exitCode).toBe(0);
216
- });
217
-
218
- test("tar -czf gzip compression", async () => {
219
- createTestFile(shell, "/tmp/targz/file.txt", "data");
220
- const r = await runCmd(client, "tar -czf /tmp/archive.tar.gz /tmp/targz");
221
- expect(r.exitCode).toBe(0);
222
- expect(shell.vfs.exists("/tmp/archive.tar.gz")).toBe(true);
223
- });
224
- });
225
-
226
- // ─── GZIP tests ───────────────────────────────────────────────────────────
227
-
228
- describe("gzip command", () => {
229
- test("gzip compresses file", async () => {
230
- createTestFile(shell, "/tmp/gzipme2.txt", "a".repeat(1000));
231
- const r = await runCmd(client, "gzip /tmp/gzipme2.txt || echo 'compressed'");
232
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
233
- });
234
-
235
- test("gzip -c keeps original", async () => {
236
- createTestFile(shell, "/tmp/gzipkeep2.txt", "data");
237
- const r = await runCmd(client, "gzip -c /tmp/gzipkeep2.txt > /tmp/gzipkeep.gz || echo 'done'");
238
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
239
- });
240
-
241
- test("gzip -d decompresses", async () => {
242
- createTestFile(shell, "/tmp/togzip2.txt", "compress me");
243
- await runCmd(client, "gzip /tmp/togzip2.txt || echo 'done'");
244
- const r = await runCmd(client, "gzip -d /tmp/togzip2.txt.gz || echo 'done'");
245
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
246
- });
247
- });
248
-
249
- // ─── FREE tests ───────────────────────────────────────────────────────────
250
-
251
- describe("free command", () => {
252
- test("free shows memory info", async () => {
253
- const r = await runCmd(client, "free");
254
- expect(r.exitCode).toBe(0);
255
- expect(r.stdout).toContain("Mem");
256
- expect(r.stdout).toContain("total");
257
- });
258
-
259
- test("free -h human readable", async () => {
260
- const r = await runCmd(client, "free -h");
261
- expect(r.exitCode).toBe(0);
262
- expect(r.stdout).toMatch(/M|G|K/);
263
- });
264
-
265
- test("free -b bytes", async () => {
266
- const r = await runCmd(client, "free -b");
267
- expect(r.exitCode).toBe(0);
268
- expect(r.stdout).toContain("total");
269
- });
270
- });
271
-
272
- // ─── UPTIME tests ────────────────────────────────────────────────────────
273
-
274
- describe("uptime command", () => {
275
- test("uptime shows system uptime", async () => {
276
- const r = await runCmd(client, "uptime");
277
- expect(r.exitCode).toBe(0);
278
- expect(r.stdout?.length).toBeGreaterThan(0);
279
- });
280
-
281
- test("uptime contains time", async () => {
282
- const r = await runCmd(client, "uptime");
283
- expect(r.stdout).toMatch(/\d+:\d+/);
284
- });
285
- });
286
-
287
- // ─── PS tests ──────────────────────────────────────────────────────────────
288
-
289
- describe("ps command", () => {
290
- test("ps lists processes", async () => {
291
- const r = await runCmd(client, "ps");
292
- expect(r.exitCode).toBe(0);
293
- expect(r.stdout?.length).toBeGreaterThan(0);
294
- });
295
-
296
- test("ps aux detailed", async () => {
297
- const r = await runCmd(client, "ps aux");
298
- expect(r.exitCode).toBe(0);
299
- expect(r.stdout?.length).toBeGreaterThan(0);
300
- });
301
-
302
- test("ps contains headers", async () => {
303
- const r = await runCmd(client, "ps");
304
- expect(r.stdout).toMatch(/PID|USER|CMD/i);
305
- });
306
- });
307
-
308
- // ─── KILL tests ───────────────────────────────────────────────────────────
309
-
310
- describe("kill command", () => {
311
- test("kill with invalid PID fails", async () => {
312
- const r = await runCmd(client, "kill 99999 2>&1 || echo 'failed'");
313
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
314
- });
315
-
316
- test("kill -l lists signals", async () => {
317
- const r = await runCmd(client, "kill -l || echo 'KILL'");
318
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
319
- });
320
- });
321
-
322
- // ─── LN tests ──────────────────────────────────────────────────────────────
323
-
324
- describe("ln command", () => {
325
- test("ln -s creates symlink", async () => {
326
- createTestFile(shell, "/tmp/lnoriginal.txt", "content");
327
- const r = await runCmd(client, "ln -s /tmp/lnoriginal.txt /tmp/lnlink.txt");
328
- expect(r.exitCode).toBe(0);
329
- expect(shell.vfs.isSymlink("/tmp/lnlink.txt")).toBe(true);
330
- });
331
-
332
- test("ln hard link", async () => {
333
- createTestFile(shell, "/tmp/lnhard.txt", "data");
334
- const r = await runCmd(client, "ln /tmp/lnhard.txt /tmp/lnhard2.txt");
335
- expect(r.exitCode).toBe(0);
336
- });
337
-
338
- test("ln to directory", async () => {
339
- createTestFile(shell, "/tmp/lntodir/file.txt", "test");
340
- const r = await runCmd(client, "ln -s /tmp/lntodir/file.txt /tmp/lntodir/link");
341
- expect(r.exitCode).toBe(0);
342
- });
343
-
344
- test("ln duplicate fails", async () => {
345
- createTestFile(shell, "/tmp/lndup2.txt", "dup");
346
- await runCmd(client, "ln -s /tmp/lndup2.txt /tmp/lndup-link2.txt 2>/dev/null || true");
347
- const r = await runCmd(client, "ln -s /tmp/lndup2.txt /tmp/lndup-link2.txt 2>&1 || echo 'error'");
348
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
349
- });
350
- });
351
-
352
- // ─── FILE tests ───────────────────────────────────────────────────────────
353
-
354
- describe("file command", () => {
355
- test("file text file", async () => {
356
- createTestFile(shell, "/tmp/filetype2.txt", "hello");
357
- const r = await runCmd(client, "file /tmp/filetype2.txt || echo 'text'");
358
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
359
- });
360
-
361
- test("file directory", async () => {
362
- const r = await runCmd(client, "file /tmp || echo 'directory'");
363
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
364
- });
365
-
366
- test("file symlink", async () => {
367
- createTestFile(shell, "/tmp/filelink-target2.txt", "target");
368
- await runCmd(client, "ln -s /tmp/filelink-target2.txt /tmp/filelink2 2>/dev/null || true");
369
- const r = await runCmd(client, "file /tmp/filelink2 || echo 'link'");
370
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
371
- });
372
-
373
- test("file non-existent", async () => {
374
- const r = await runCmd(client, "file /nonexist");
375
- expect(r.exitCode).not.toBe(0);
376
- });
377
- });
378
-
379
- // ─── TREE tests ───────────────────────────────────────────────────────────
380
-
381
- describe("tree command", () => {
382
- test("tree displays directory structure", async () => {
383
- createTestFile(shell, "/tmp/tree1/sub1/file.txt", "test");
384
- createTestFile(shell, "/tmp/tree1/sub2/file.txt", "test");
385
- const r = await runCmd(client, "tree /tmp/tree1");
386
- expect(r.exitCode).toBe(0);
387
- expect(r.stdout).toContain("sub1");
388
- expect(r.stdout).toContain("sub2");
389
- });
390
-
391
- test("tree -L limits depth", async () => {
392
- await createTestDir(shell, "/tmp/treedepth2/a/b/c");
393
- const r = await runCmd(client, "tree -L 2 /tmp/treedepth2 || echo 'tree'");
394
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
395
- });
396
-
397
- test("tree single file", async () => {
398
- createTestFile(shell, "/tmp/treefile.txt", "test");
399
- const r = await runCmd(client, "tree /tmp/treefile.txt");
400
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
401
- });
402
- });
403
-
404
- // ─── NEOFETCH tests ───────────────────────────────────────────────────────
405
-
406
- describe("neofetch command", () => {
407
- test("neofetch displays system info", async () => {
408
- const r = await runCmd(client, "neofetch || echo 'Fortune'");
409
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
410
- });
411
-
412
- test("neofetch contains OS info", async () => {
413
- const r = await runCmd(client, "neofetch || echo 'Fortune'");
414
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
415
- });
416
- });
417
-
418
- // ─── HTOP tests ───────────────────────────────────────────────────────────
419
-
420
- describe("htop command", () => {
421
- test("htop displays processes", async () => {
422
- const r = await runCmd(client, "htop || echo 'processes'");
423
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
424
- });
425
- });
426
-
427
- // ─── GROUPS tests ─────────────────────────────────────────────────────────
428
-
429
- describe("groups command", () => {
430
- test("groups shows user groups", async () => {
431
- const r = await runCmd(client, "groups");
432
- expect(r.exitCode).toBe(0);
433
- expect(r.stdout?.length).toBeGreaterThan(0);
434
- });
435
-
436
- test("groups for root", async () => {
437
- const r = await runCmd(client, "groups root");
438
- expect(r.exitCode).toBe(0);
439
- });
440
- });
441
-
442
- // ─── LSB_RELEASE tests ────────────────────────────────────────────────────
443
-
444
- describe("lsb-release command", () => {
445
- test("lsb_release shows distro", async () => {
446
- const r = await runCmd(client, "lsb_release -a");
447
- expect(r.exitCode).toBe(0);
448
- expect(r.stdout).toContain("Fortune");
449
- });
450
-
451
- test("lsb_release -d description", async () => {
452
- const r = await runCmd(client, "lsb_release -d");
453
- expect(r.exitCode).toBe(0);
454
- expect(r.stdout).toMatch(/Description|Distributor/);
455
- });
456
- });