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,441 +0,0 @@
1
- import { beforeAll, describe, expect, test } from "bun:test";
2
- import { SshClient } from "../src";
3
- import { createTestEnv, runCmd } from "./test-helper";
4
-
5
- let client: InstanceType<typeof SshClient>;
6
-
7
- beforeAll(async () => {
8
- const env = await createTestEnv("test-admin");
9
- client = env.client;
10
- });
11
-
12
- // ─── USERADD tests ────────────────────────────────────────────────────────
13
-
14
- describe("useradd command", () => {
15
- test("useradd creates user", async () => {
16
- const r = await runCmd(client, "useradd -m testuser || echo 'created'");
17
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
18
- });
19
-
20
- test("useradd with comment", async () => {
21
- const r = await runCmd(client, "useradd -c 'Test User' -m testuser2 || echo 'created'");
22
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
23
- });
24
-
25
- test("useradd with specific uid", async () => {
26
- const r = await runCmd(client, "useradd -u 2000 -m testuser3 || echo 'created'");
27
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
28
- });
29
-
30
- test("useradd duplicate fails", async () => {
31
- await runCmd(client, "useradd -m duplicate");
32
- const r = await runCmd(client, "useradd -m duplicate");
33
- expect(r.exitCode).not.toBe(0);
34
- });
35
-
36
- test("useradd non-root fails", async () => {
37
- const env = await createTestEnv("test-admin-nonroot");
38
- const nonrootClient = new SshClient(env.shell, "testuser");
39
- const r = await runCmd(nonrootClient, "useradd -m newuser");
40
- expect(r.exitCode).not.toBe(0);
41
- });
42
- });
43
-
44
- // ─── DELUSER tests ────────────────────────────────────────────────────────
45
-
46
- describe("deluser command", () => {
47
- test("deluser removes user", async () => {
48
- await runCmd(client, "useradd -m deltest 2>/dev/null || true");
49
- const r = await runCmd(client, "deluser deltest 2>&1 || echo 'deleted'");
50
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
51
- });
52
-
53
- test("deluser with home removal", async () => {
54
- await runCmd(client, "useradd -m delhome 2>/dev/null || true");
55
- const r = await runCmd(client, "deluser --remove-home delhome 2>&1 || echo 'deleted'");
56
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
57
- });
58
-
59
- test("deluser non-existent user", async () => {
60
- const r = await runCmd(client, "deluser nonexistent");
61
- expect(r.exitCode).not.toBe(0);
62
- });
63
- });
64
-
65
- // ─── PASSWD tests ────────────────────────────────────────────────────────
66
-
67
- describe("passwd command", () => {
68
- test("passwd requires root", async () => {
69
- const r = await runCmd(client, "passwd root");
70
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
71
- });
72
-
73
- test("passwd non-existent user fails", async () => {
74
- const r = await runCmd(client, "passwd nonexistent");
75
- expect(r.exitCode).not.toBe(0);
76
- });
77
- });
78
-
79
- // ─── SUDO tests ───────────────────────────────────────────────────────────
80
-
81
- describe("sudo command", () => {
82
- test("sudo as root runs command", async () => {
83
- const r = await runCmd(client, "sudo whoami");
84
- expect(r.exitCode).toBe(0);
85
- expect(r.stdout?.trim()).toBe("root");
86
- });
87
-
88
- test("sudo -u changes user", async () => {
89
- await runCmd(client, "useradd -m sudouser");
90
- const r = await runCmd(client, "sudo -u sudouser whoami");
91
- expect(r.exitCode).toBe(0);
92
- expect(r.stdout?.trim()).toBe("sudouser");
93
- });
94
-
95
- test("sudo preserves args", async () => {
96
- const r = await runCmd(client, "sudo echo test");
97
- expect(r.exitCode).toBe(0);
98
- expect(r.stdout?.trim()).toBe("test");
99
- });
100
- });
101
-
102
- // ─── SU tests ──────────────────────────────────────────────────────────────
103
-
104
- describe("su command", () => {
105
- test("su as root", async () => {
106
- const r = await runCmd(client, "su - -c whoami");
107
- expect(r.exitCode).toBe(0);
108
- });
109
-
110
- test("su with command execution", async () => {
111
- const r = await runCmd(client, "su - root -c 'echo hello'");
112
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
113
- });
114
- });
115
-
116
- // ─── CURL tests ───────────────────────────────────────────────────────────
117
-
118
- describe("curl command", () => {
119
- test("curl basic request", async () => {
120
- const r = await runCmd(client, "curl http://example.com 2>/dev/null | head -c 10 || echo 'response'");
121
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
122
- });
123
-
124
- test("curl localhost", async () => {
125
- const r = await runCmd(client, "curl -s http://localhost:8080 2>/dev/null || echo 'no server'");
126
- expect(r.exitCode).toBe(0);
127
- });
128
-
129
- test("curl invalid URL", async () => {
130
- const r = await runCmd(client, "curl http://invalid.example.test 2>&1 | grep -i error || echo 'error'");
131
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
132
- });
133
-
134
- test("curl -o saves to file", async () => {
135
- const r = await runCmd(client, "curl -s -o /tmp/curlout.html http://example.com 2>/dev/null || echo 'done'");
136
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
137
- });
138
-
139
- test("curl -I head request", async () => {
140
- const r = await runCmd(client, "curl -I http://example.com 2>/dev/null | head -1 || echo 'header'");
141
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
142
- });
143
-
144
- test("curl with headers", async () => {
145
- const r = await runCmd(client, "curl -H 'User-Agent: test' http://example.com 2>/dev/null | head -c 5 || echo 'data'");
146
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
147
- });
148
- });
149
-
150
- // ─── WGET tests ───────────────────────────────────────────────────────────
151
-
152
- describe("wget command", () => {
153
- test("wget basic download", async () => {
154
- const r = await runCmd(client, "wget -q http://example.com -O /tmp/wget.html 2>/dev/null || echo 'done'");
155
- expect(r.exitCode).toBe(0);
156
- });
157
-
158
- test("wget -q quiet mode", async () => {
159
- const r = await runCmd(client, "wget -q http://example.com -O /tmp/wgetq.html 2>/dev/null || echo 'done'");
160
- expect(r.exitCode).toBe(0);
161
- });
162
-
163
- test("wget --spider check url", async () => {
164
- const r = await runCmd(client, "wget --spider http://example.com 2>/dev/null || echo 'checked'");
165
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
166
- });
167
- });
168
-
169
- // ─── PING tests ───────────────────────────────────────────────────────────
170
-
171
- describe("ping command", () => {
172
- test("ping localhost", async () => {
173
- const r = await runCmd(client, "ping -c 1 localhost");
174
- expect(r.exitCode).toBe(0);
175
- expect(r.stdout).toContain("localhost");
176
- });
177
-
178
- test("ping -c count", async () => {
179
- const r = await runCmd(client, "ping -c 2 127.0.0.1");
180
- expect(r.exitCode).toBe(0);
181
- });
182
-
183
- test("ping invalid host", async () => {
184
- const r = await runCmd(client, "ping -c 1 invalid.test 2>&1 || echo 'error'");
185
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
186
- });
187
-
188
- test("ping ipv4", async () => {
189
- const r = await runCmd(client, "ping -c 1 127.0.0.1");
190
- expect(r.exitCode).toBe(0);
191
- expect(r.stdout).toContain("127.0.0.1");
192
- });
193
- });
194
-
195
- // ─── NETSTAT-like tests ────────────────────────────────────────────────────
196
-
197
- describe("network info commands", () => {
198
- test("hostname shows system name", async () => {
199
- const r = await runCmd(client, "hostname");
200
- expect(r.exitCode).toBe(0);
201
- expect(r.stdout?.length).toBeGreaterThan(0);
202
- });
203
-
204
- test("host lookup", async () => {
205
- const r = await runCmd(client, "host localhost 2>/dev/null || echo 'no DNS'");
206
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
207
- });
208
-
209
- test("nslookup query", async () => {
210
- const r = await runCmd(client, "nslookup localhost 2>/dev/null || echo 'no DNS'");
211
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
212
- });
213
- });
214
-
215
- // ─── ADDUSER tests ────────────────────────────────────────────────────────
216
-
217
- describe("adduser command", () => {
218
- test("adduser creates user", async () => {
219
- const r = await runCmd(client, "adduser -m -s /bin/bash newuser || echo 'created'");
220
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
221
- });
222
-
223
- test("adduser duplicate", async () => {
224
- await runCmd(client, "adduser -m addup 2>/dev/null || true");
225
- const r = await runCmd(client, "adduser -m addup 2>&1 || echo 'exists'");
226
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
227
- });
228
- });
229
-
230
- // ─── DPKG tests ───────────────────────────────────────────────────────────
231
-
232
- describe("dpkg command", () => {
233
- test("dpkg -l lists packages", async () => {
234
- const r = await runCmd(client, "dpkg -l");
235
- expect(r.exitCode).toBe(0);
236
- expect(r.stdout?.length).toBeGreaterThan(0);
237
- });
238
-
239
- test("dpkg -s check package", async () => {
240
- const r = await runCmd(client, "dpkg -s bash 2>/dev/null || echo 'not found'");
241
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
242
- });
243
-
244
- test("dpkg status output", async () => {
245
- const r = await runCmd(client, "dpkg -l | head");
246
- expect(r.exitCode).toBe(0);
247
- });
248
- });
249
-
250
- // ─── APT tests ────────────────────────────────────────────────────────────
251
-
252
- describe("apt command", () => {
253
- test("apt update list", async () => {
254
- const r = await runCmd(client, "apt update 2>&1 | head -5");
255
- expect(r.exitCode).toBe(0);
256
- });
257
-
258
- test("apt list packages", async () => {
259
- const r = await runCmd(client, "apt list --installed 2>/dev/null | head");
260
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
261
- });
262
-
263
- test("apt search package", async () => {
264
- const r = await runCmd(client, "apt search bash 2>&1 | grep -i bash || echo 'searched'");
265
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
266
- });
267
- });
268
-
269
- // ─── NPM tests ────────────────────────────────────────────────────────────
270
-
271
- describe("npm command", () => {
272
- test("npm -v version", async () => {
273
- const r = await runCmd(client, "npm -v");
274
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
275
- });
276
-
277
- test("npm list global", async () => {
278
- const r = await runCmd(client, "npm list -g 2>/dev/null || npm list -g --depth 0 2>/dev/null || echo 'packages'");
279
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
280
- });
281
-
282
- test("npm help", async () => {
283
- const r = await runCmd(client, "npm help 2>&1 | head");
284
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
285
- });
286
- });
287
-
288
- // ─── PYTHON tests ────────────────────────────────────────────────────────
289
-
290
- describe("python command", () => {
291
- test("python -c executes code", async () => {
292
- const r = await runCmd(client, "python -c 'print(1+1)'");
293
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
294
- });
295
-
296
- test("python -v version", async () => {
297
- const r = await runCmd(client, "python --version 2>&1");
298
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
299
- });
300
- });
301
-
302
- // ─── NODE tests ───────────────────────────────────────────────────────────
303
-
304
- describe("node command", () => {
305
- test("node -v version", async () => {
306
- const r = await runCmd(client, "node -v");
307
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
308
- });
309
-
310
- test("node -e executes code", async () => {
311
- const r = await runCmd(client, "node -e 'console.log(1+1)'");
312
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
313
- });
314
-
315
- test("node eval arithmetic", async () => {
316
- const r = await runCmd(client, "node -e 'console.log(2*3)'");
317
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
318
- if (r.stdout) expect(r.stdout).toContain("6");
319
- });
320
- });
321
-
322
- // ─── WHICH tests ───────────────────────────────────────────────────────────
323
-
324
- describe("which command", () => {
325
- test("which finds command", async () => {
326
- const r = await runCmd(client, "which ls");
327
- expect(r.exitCode).toBe(0);
328
- expect(r.stdout?.trim()).toMatch(/ls|bin/);
329
- });
330
-
331
- test("which multiple commands", async () => {
332
- const r = await runCmd(client, "which ls cat grep");
333
- expect(r.exitCode).toBe(0);
334
- });
335
-
336
- test("which non-existent", async () => {
337
- const r = await runCmd(client, "which nonexistcommand");
338
- expect(r.exitCode).not.toBe(0);
339
- });
340
- });
341
-
342
- // ─── TYPE tests ───────────────────────────────────────────────────────────
343
-
344
- describe("type command", () => {
345
- test("type shows command type", async () => {
346
- const r = await runCmd(client, "type ls");
347
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
348
- });
349
-
350
- test("type builtin", async () => {
351
- const r = await runCmd(client, "type echo");
352
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
353
- });
354
-
355
- test("type alias", async () => {
356
- const r = await runCmd(client, "alias myls=ls && type myls");
357
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
358
- });
359
- });
360
-
361
- // ─── HELP tests ───────────────────────────────────────────────────────────
362
-
363
- describe("help command", () => {
364
- test("help lists commands", async () => {
365
- const r = await runCmd(client, "help");
366
- expect(r.exitCode).toBe(0);
367
- expect(r.stdout?.length).toBeGreaterThan(0);
368
- });
369
-
370
- test("help specific command", async () => {
371
- const r = await runCmd(client, "help echo");
372
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
373
- });
374
-
375
- test("help lists builtins", async () => {
376
- const r = await runCmd(client, "help | wc -l");
377
- expect(r.exitCode).toBe(0);
378
- });
379
- });
380
-
381
- // ─── MAN tests ────────────────────────────────────────────────────────────
382
-
383
- describe("man command", () => {
384
- test("man ls shows manual", async () => {
385
- const r = await runCmd(client, "man ls 2>/dev/null | head -5 || echo 'no man'");
386
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
387
- });
388
-
389
- test("man non-existent", async () => {
390
- const r = await runCmd(client, "man nonexistent 2>&1");
391
- expect(r.exitCode).not.toBe(0);
392
- });
393
- });
394
-
395
- // ─── ALIAS tests ───────────────────────────────────────────────────────────
396
-
397
- describe("alias command", () => {
398
- test("alias creates shortcut", async () => {
399
- const r = await runCmd(client, "alias myecho=echo && myecho hello");
400
- expect(r.exitCode).toBe(0);
401
- expect(r.stdout?.trim()).toBe("hello");
402
- });
403
-
404
- test("alias lists all", async () => {
405
- const r = await runCmd(client, "alias");
406
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
407
- });
408
-
409
- test("alias with args", async () => {
410
- const r = await runCmd(client, "alias ll='ls -l' && ll /tmp | head -1");
411
- expect(r.exitCode).toBe(0);
412
- });
413
- });
414
-
415
- // ─── HISTORY tests ───────────────────────────────────────────────────────
416
-
417
- describe("history command", () => {
418
- test("history lists command history", async () => {
419
- const r = await runCmd(client, "history");
420
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
421
- });
422
-
423
- test("history shows entries", async () => {
424
- const r = await runCmd(client, "history 5");
425
- expect(r.exitCode).toBeGreaterThanOrEqual(0);
426
- });
427
- });
428
-
429
- // ─── EXIT tests ───────────────────────────────────────────────────────────
430
-
431
- describe("exit command", () => {
432
- test("exit with code 0", async () => {
433
- const r = await runCmd(client, "exit 0");
434
- expect(r.exitCode).toBe(0);
435
- });
436
-
437
- test("exit with code 1", async () => {
438
- const r = await runCmd(client, "exit 1");
439
- expect(r.exitCode).not.toBe(0);
440
- });
441
- });