typescript-virtual-container 1.5.3 → 1.5.5

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 (371) hide show
  1. package/README.md +44 -532
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/SSHMimic/executor.js +23 -5
  4. package/dist/VirtualPackageManager/index.js +10 -0
  5. package/dist/VirtualShell/shell.js +158 -11
  6. package/dist/commands/basename.d.ts +13 -0
  7. package/dist/commands/basename.js +45 -0
  8. package/dist/commands/bc.d.ts +2 -0
  9. package/dist/commands/bc.js +28 -0
  10. package/dist/commands/file.d.ts +8 -0
  11. package/dist/commands/file.js +57 -0
  12. package/dist/commands/fun.d.ts +32 -0
  13. package/dist/commands/fun.js +172 -0
  14. package/dist/commands/ip.d.ts +7 -0
  15. package/dist/commands/ip.js +52 -0
  16. package/dist/commands/jobs.d.ts +4 -0
  17. package/dist/commands/jobs.js +27 -0
  18. package/dist/commands/last.d.ts +13 -0
  19. package/dist/commands/last.js +68 -0
  20. package/dist/commands/manuals-bundle.js +598 -6
  21. package/dist/commands/registry.js +30 -2
  22. package/dist/commands/runtime.js +24 -3
  23. package/dist/commands/set.js +20 -0
  24. package/dist/commands/sh.js +74 -1
  25. package/dist/commands/tput.d.ts +13 -0
  26. package/dist/commands/tput.js +76 -0
  27. package/dist/commands/w.d.ts +7 -0
  28. package/dist/commands/w.js +38 -0
  29. package/dist/utils/expand.d.ts +12 -0
  30. package/dist/utils/expand.js +87 -1
  31. package/package.json +9 -3
  32. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -50
  33. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -31
  34. package/.github/dependabot.yml +0 -27
  35. package/.github/pull_request_template.md +0 -21
  36. package/.github/workflows/create-pull-request.yml +0 -85
  37. package/.github/workflows/publish.yml +0 -25
  38. package/.github/workflows/test-battery.yml +0 -102
  39. package/.vscode/settings.json +0 -20
  40. package/CODE_OF_CONDUCT.md +0 -39
  41. package/CONTRIBUTING.md +0 -59
  42. package/HONEYPOT.md +0 -358
  43. package/SECURITY.md +0 -33
  44. package/benchmark-results.txt +0 -40
  45. package/benchmark-virtualshell.ts +0 -88
  46. package/biome.json +0 -37
  47. package/build.js +0 -22
  48. package/builds/fortune-nyx-v1.5.3-directbash-k6.1.0.mjs +0 -1764
  49. package/builds/fortune-nyx-v1.5.3-ssh-nosftp.js +0 -1764
  50. package/builds/fortune-nyx-v1.5.3-ssh.cjs +0 -1765
  51. package/builds/fortune-nyx-v1.5.3-web.min.js +0 -17036
  52. package/bun.lock +0 -244
  53. package/docs/.nojekyll +0 -1
  54. package/docs/app.js +0 -1751
  55. package/docs/assets/hierarchy.js +0 -1
  56. package/docs/assets/highlight.css +0 -162
  57. package/docs/assets/icons.js +0 -18
  58. package/docs/assets/icons.svg +0 -1
  59. package/docs/assets/main.js +0 -60
  60. package/docs/assets/navigation.js +0 -1
  61. package/docs/assets/search.js +0 -1
  62. package/docs/assets/style.css +0 -1633
  63. package/docs/classes/HoneyPot.html +0 -31
  64. package/docs/classes/IdleManager.html +0 -162
  65. package/docs/classes/SshClient.html +0 -66
  66. package/docs/classes/VirtualFileSystem.html +0 -279
  67. package/docs/classes/VirtualPackageManager.html +0 -63
  68. package/docs/classes/VirtualSftpServer.html +0 -169
  69. package/docs/classes/VirtualShell.html +0 -285
  70. package/docs/classes/VirtualSshServer.html +0 -182
  71. package/docs/classes/VirtualUserManager.html +0 -276
  72. package/docs/demo.html +0 -82
  73. package/docs/functions/assertDiff.html +0 -6
  74. package/docs/functions/diffSnapshots.html +0 -7
  75. package/docs/functions/formatDiff.html +0 -6
  76. package/docs/functions/getArg.html +0 -13
  77. package/docs/functions/getFlag.html +0 -15
  78. package/docs/functions/ifFlag.html +0 -11
  79. package/docs/hierarchy.html +0 -1
  80. package/docs/index.html +0 -1869
  81. package/docs/interfaces/AuditLogEntry.html +0 -6
  82. package/docs/interfaces/CommandContext.html +0 -22
  83. package/docs/interfaces/CommandResult.html +0 -26
  84. package/docs/interfaces/ExecStream.html +0 -11
  85. package/docs/interfaces/HoneyPotStats.html +0 -16
  86. package/docs/interfaces/IdleManagerOptions.html +0 -7
  87. package/docs/interfaces/InstalledPackage.html +0 -20
  88. package/docs/interfaces/NanoEditorSession.html +0 -8
  89. package/docs/interfaces/PackageDefinition.html +0 -30
  90. package/docs/interfaces/PackageFile.html +0 -8
  91. package/docs/interfaces/PasswordChallenge.html +0 -16
  92. package/docs/interfaces/RemoveOptions.html +0 -4
  93. package/docs/interfaces/ShellEnv.html +0 -6
  94. package/docs/interfaces/ShellModule.html +0 -14
  95. package/docs/interfaces/ShellProperties.html +0 -14
  96. package/docs/interfaces/ShellStream.html +0 -11
  97. package/docs/interfaces/SudoChallenge.html +0 -24
  98. package/docs/interfaces/VfsBaseNode.html +0 -12
  99. package/docs/interfaces/VfsDiff.html +0 -10
  100. package/docs/interfaces/VfsDiffEntry.html +0 -6
  101. package/docs/interfaces/VfsDiffModified.html +0 -10
  102. package/docs/interfaces/VfsDirectoryNode.html +0 -15
  103. package/docs/interfaces/VfsFileNode.html +0 -17
  104. package/docs/interfaces/VfsOptions.html +0 -26
  105. package/docs/interfaces/VfsSnapshot.html +0 -3
  106. package/docs/interfaces/VfsSnapshotBaseNode.html +0 -8
  107. package/docs/interfaces/VfsSnapshotDirectoryNode.html +0 -10
  108. package/docs/interfaces/VfsSnapshotFileNode.html +0 -12
  109. package/docs/interfaces/VirtualActiveSession.html +0 -12
  110. package/docs/interfaces/VirtualSftpServerOptions.html +0 -7
  111. package/docs/interfaces/VirtualShellVfsLike.html +0 -15
  112. package/docs/interfaces/VirtualShellVfsOptions.html +0 -3
  113. package/docs/interfaces/WriteFileOptions.html +0 -6
  114. package/docs/media/LICENSE +0 -21
  115. package/docs/modules.html +0 -1
  116. package/docs/types/ArgParseOptions.html +0 -4
  117. package/docs/types/CommandMode.html +0 -2
  118. package/docs/types/CommandOutcome.html +0 -2
  119. package/docs/types/IdleState.html +0 -1
  120. package/docs/types/VfsNodeStats.html +0 -2
  121. package/docs/types/VfsNodeType.html +0 -2
  122. package/docs/types/VfsPersistenceMode.html +0 -5
  123. package/docs/types/VfsSnapshotNode.html +0 -2
  124. package/examples/README.md +0 -288
  125. package/examples/app.js +0 -1751
  126. package/examples/app.ts +0 -299
  127. package/examples/build.js +0 -27
  128. package/examples/demo.html +0 -33
  129. package/examples/honeypot-audit.ts +0 -180
  130. package/examples/honeypot-export.ts +0 -253
  131. package/examples/honeypot-quickstart.ts +0 -110
  132. package/examples/index.html +0 -82
  133. package/examples/server.js +0 -55
  134. package/polyfills/buffer.js +0 -117
  135. package/polyfills/node_child_process/index.js +0 -2
  136. package/polyfills/node_crypto/index.js +0 -167
  137. package/polyfills/node_events/index.js +0 -9
  138. package/polyfills/node_fs/index.js +0 -202
  139. package/polyfills/node_fs/promises.js +0 -4
  140. package/polyfills/node_os/index.js +0 -9
  141. package/polyfills/node_path/index.js +0 -28
  142. package/polyfills/node_vm/index.js +0 -7
  143. package/polyfills/node_zlib/index.js +0 -3
  144. package/polyfills/process.js +0 -14
  145. package/polyfills/ssh2/index.js +0 -75
  146. package/scripts/build-all.mjs +0 -226
  147. package/scripts/build-names.mjs +0 -43
  148. package/scripts/generate-manuals-bundle.mjs +0 -49
  149. package/scripts/postinstall.js +0 -42
  150. package/scripts/publish-package.sh +0 -70
  151. package/src/Honeypot/index.ts +0 -457
  152. package/src/SSHClient/index.ts +0 -270
  153. package/src/SSHMimic/exec.ts +0 -49
  154. package/src/SSHMimic/executor.ts +0 -251
  155. package/src/SSHMimic/hostKey.ts +0 -21
  156. package/src/SSHMimic/index.ts +0 -337
  157. package/src/SSHMimic/loginBanner.ts +0 -36
  158. package/src/SSHMimic/loginFormat.ts +0 -10
  159. package/src/SSHMimic/prompt.ts +0 -14
  160. package/src/SSHMimic/sftp.ts +0 -883
  161. package/src/VirtualFileSystem/binaryPack.ts +0 -258
  162. package/src/VirtualFileSystem/index.ts +0 -1193
  163. package/src/VirtualFileSystem/internalTypes.ts +0 -43
  164. package/src/VirtualFileSystem/journal.ts +0 -171
  165. package/src/VirtualFileSystem/path.ts +0 -74
  166. package/src/VirtualPackageManager/index.ts +0 -996
  167. package/src/VirtualShell/idleManager.ts +0 -137
  168. package/src/VirtualShell/index.ts +0 -475
  169. package/src/VirtualShell/shell.ts +0 -700
  170. package/src/VirtualShell/shellParser.ts +0 -285
  171. package/src/VirtualUserManager/index.ts +0 -758
  172. package/src/bun.d.ts +0 -1
  173. package/src/commands/adduser.ts +0 -103
  174. package/src/commands/alias.ts +0 -69
  175. package/src/commands/apt.ts +0 -233
  176. package/src/commands/awk.ts +0 -168
  177. package/src/commands/base64.ts +0 -29
  178. package/src/commands/cat.ts +0 -52
  179. package/src/commands/cd.ts +0 -25
  180. package/src/commands/chmod.ts +0 -85
  181. package/src/commands/clear.ts +0 -15
  182. package/src/commands/command-helpers.ts +0 -286
  183. package/src/commands/cp.ts +0 -83
  184. package/src/commands/curl.ts +0 -147
  185. package/src/commands/cut.ts +0 -36
  186. package/src/commands/date.ts +0 -30
  187. package/src/commands/declare.ts +0 -49
  188. package/src/commands/deluser.ts +0 -98
  189. package/src/commands/df.ts +0 -23
  190. package/src/commands/diff.ts +0 -43
  191. package/src/commands/dpkg.ts +0 -180
  192. package/src/commands/du.ts +0 -56
  193. package/src/commands/echo.ts +0 -58
  194. package/src/commands/env.ts +0 -23
  195. package/src/commands/exit.ts +0 -18
  196. package/src/commands/export.ts +0 -34
  197. package/src/commands/find.ts +0 -68
  198. package/src/commands/free.ts +0 -47
  199. package/src/commands/grep.ts +0 -116
  200. package/src/commands/groups.ts +0 -19
  201. package/src/commands/gzip.ts +0 -88
  202. package/src/commands/head.ts +0 -52
  203. package/src/commands/help.ts +0 -152
  204. package/src/commands/helpers.ts +0 -234
  205. package/src/commands/history.ts +0 -34
  206. package/src/commands/hostname.ts +0 -14
  207. package/src/commands/htop.ts +0 -20
  208. package/src/commands/id.ts +0 -19
  209. package/src/commands/index.ts +0 -9
  210. package/src/commands/kill.ts +0 -19
  211. package/src/commands/ln.ts +0 -71
  212. package/src/commands/ls.ts +0 -243
  213. package/src/commands/lsb-release.ts +0 -63
  214. package/src/commands/man.ts +0 -31
  215. package/src/commands/manuals/adduser.txt +0 -11
  216. package/src/commands/manuals/apt-cache.txt +0 -12
  217. package/src/commands/manuals/apt.txt +0 -20
  218. package/src/commands/manuals/awk.txt +0 -13
  219. package/src/commands/manuals/cat.txt +0 -14
  220. package/src/commands/manuals/cd.txt +0 -16
  221. package/src/commands/manuals/chmod.txt +0 -16
  222. package/src/commands/manuals/clear.txt +0 -10
  223. package/src/commands/manuals/cp.txt +0 -10
  224. package/src/commands/manuals/curl.txt +0 -20
  225. package/src/commands/manuals/date.txt +0 -14
  226. package/src/commands/manuals/declare.txt +0 -12
  227. package/src/commands/manuals/deluser.txt +0 -10
  228. package/src/commands/manuals/df.txt +0 -10
  229. package/src/commands/manuals/dpkg-query.txt +0 -11
  230. package/src/commands/manuals/dpkg.txt +0 -14
  231. package/src/commands/manuals/du.txt +0 -11
  232. package/src/commands/manuals/echo.txt +0 -11
  233. package/src/commands/manuals/false.txt +0 -10
  234. package/src/commands/manuals/find.txt +0 -11
  235. package/src/commands/manuals/free.txt +0 -12
  236. package/src/commands/manuals/grep.txt +0 -13
  237. package/src/commands/manuals/groups.txt +0 -10
  238. package/src/commands/manuals/gzip.txt +0 -11
  239. package/src/commands/manuals/head.txt +0 -10
  240. package/src/commands/manuals/help.txt +0 -11
  241. package/src/commands/manuals/history.txt +0 -11
  242. package/src/commands/manuals/hostname.txt +0 -10
  243. package/src/commands/manuals/id.txt +0 -10
  244. package/src/commands/manuals/kill.txt +0 -13
  245. package/src/commands/manuals/ls.txt +0 -20
  246. package/src/commands/manuals/lsb_release.txt +0 -14
  247. package/src/commands/manuals/mkdir.txt +0 -10
  248. package/src/commands/manuals/mv.txt +0 -10
  249. package/src/commands/manuals/nano.txt +0 -11
  250. package/src/commands/manuals/neofetch.txt +0 -10
  251. package/src/commands/manuals/node.txt +0 -13
  252. package/src/commands/manuals/npm.txt +0 -13
  253. package/src/commands/manuals/npx.txt +0 -13
  254. package/src/commands/manuals/passwd.txt +0 -11
  255. package/src/commands/manuals/ping.txt +0 -10
  256. package/src/commands/manuals/printf.txt +0 -11
  257. package/src/commands/manuals/ps.txt +0 -10
  258. package/src/commands/manuals/pwd.txt +0 -10
  259. package/src/commands/manuals/python3.txt +0 -13
  260. package/src/commands/manuals/readlink.txt +0 -10
  261. package/src/commands/manuals/return.txt +0 -10
  262. package/src/commands/manuals/rm.txt +0 -10
  263. package/src/commands/manuals/sed.txt +0 -11
  264. package/src/commands/manuals/set.txt +0 -11
  265. package/src/commands/manuals/shift.txt +0 -10
  266. package/src/commands/manuals/sleep.txt +0 -10
  267. package/src/commands/manuals/sort.txt +0 -12
  268. package/src/commands/manuals/source.txt +0 -11
  269. package/src/commands/manuals/ssh.txt +0 -11
  270. package/src/commands/manuals/stat.txt +0 -10
  271. package/src/commands/manuals/su.txt +0 -13
  272. package/src/commands/manuals/sudo.txt +0 -11
  273. package/src/commands/manuals/tail.txt +0 -10
  274. package/src/commands/manuals/tar.txt +0 -19
  275. package/src/commands/manuals/tee.txt +0 -10
  276. package/src/commands/manuals/test.txt +0 -11
  277. package/src/commands/manuals/touch.txt +0 -11
  278. package/src/commands/manuals/tr.txt +0 -10
  279. package/src/commands/manuals/trap.txt +0 -10
  280. package/src/commands/manuals/true.txt +0 -10
  281. package/src/commands/manuals/type.txt +0 -10
  282. package/src/commands/manuals/uname.txt +0 -12
  283. package/src/commands/manuals/uniq.txt +0 -12
  284. package/src/commands/manuals/unset.txt +0 -10
  285. package/src/commands/manuals/uptime.txt +0 -11
  286. package/src/commands/manuals/wc.txt +0 -12
  287. package/src/commands/manuals/wget.txt +0 -12
  288. package/src/commands/manuals/which.txt +0 -10
  289. package/src/commands/manuals/whoami.txt +0 -10
  290. package/src/commands/manuals/xargs.txt +0 -10
  291. package/src/commands/manuals-bundle.ts +0 -898
  292. package/src/commands/mkdir.ts +0 -31
  293. package/src/commands/mv.ts +0 -50
  294. package/src/commands/nano.ts +0 -38
  295. package/src/commands/neofetch.ts +0 -53
  296. package/src/commands/node.ts +0 -341
  297. package/src/commands/npm.ts +0 -132
  298. package/src/commands/passwd.ts +0 -50
  299. package/src/commands/ping.ts +0 -32
  300. package/src/commands/printf.ts +0 -129
  301. package/src/commands/ps.ts +0 -58
  302. package/src/commands/pwd.ts +0 -9
  303. package/src/commands/python.ts +0 -2229
  304. package/src/commands/read.ts +0 -46
  305. package/src/commands/registry.ts +0 -249
  306. package/src/commands/rm.ts +0 -42
  307. package/src/commands/runtime.ts +0 -421
  308. package/src/commands/sed.ts +0 -68
  309. package/src/commands/seq.ts +0 -43
  310. package/src/commands/set.ts +0 -29
  311. package/src/commands/sh.ts +0 -467
  312. package/src/commands/shift.ts +0 -63
  313. package/src/commands/sleep.ts +0 -20
  314. package/src/commands/sort.ts +0 -46
  315. package/src/commands/source.ts +0 -52
  316. package/src/commands/stat.ts +0 -61
  317. package/src/commands/su.ts +0 -72
  318. package/src/commands/sudo.ts +0 -76
  319. package/src/commands/tail.ts +0 -53
  320. package/src/commands/tar.ts +0 -102
  321. package/src/commands/tee.ts +0 -36
  322. package/src/commands/test.ts +0 -137
  323. package/src/commands/touch.ts +0 -28
  324. package/src/commands/tr.ts +0 -70
  325. package/src/commands/tree.ts +0 -20
  326. package/src/commands/true.ts +0 -27
  327. package/src/commands/type.ts +0 -48
  328. package/src/commands/uname.ts +0 -29
  329. package/src/commands/uniq.ts +0 -39
  330. package/src/commands/unset.ts +0 -17
  331. package/src/commands/uptime.ts +0 -54
  332. package/src/commands/wc.ts +0 -55
  333. package/src/commands/wget.ts +0 -148
  334. package/src/commands/which.ts +0 -37
  335. package/src/commands/who.ts +0 -25
  336. package/src/commands/whoami.ts +0 -14
  337. package/src/commands/xargs.ts +0 -31
  338. package/src/index.ts +0 -67
  339. package/src/modules/linuxRootfs.ts +0 -1961
  340. package/src/modules/neofetch.ts +0 -358
  341. package/src/modules/shellInteractive.ts +0 -57
  342. package/src/modules/shellRuntime.ts +0 -76
  343. package/src/self-standalone.ts +0 -542
  344. package/src/standalone-wo-sftp.ts +0 -38
  345. package/src/standalone.ts +0 -72
  346. package/src/types/commands.ts +0 -146
  347. package/src/types/pipeline.ts +0 -52
  348. package/src/types/streams.ts +0 -32
  349. package/src/types/tar-stream.d.ts +0 -38
  350. package/src/types/vfs.ts +0 -98
  351. package/src/utils/expand.ts +0 -491
  352. package/src/utils/perfLogger.ts +0 -72
  353. package/src/utils/tokenize.ts +0 -98
  354. package/src/utils/vfsDiff.ts +0 -275
  355. package/tests/command-helpers.test.ts +0 -116
  356. package/tests/commands-admin-net.test.ts +0 -441
  357. package/tests/commands-advanced.test.ts +0 -456
  358. package/tests/commands-core.test.ts +0 -562
  359. package/tests/commands-missing.test.ts +0 -570
  360. package/tests/commands-specific-units.test.ts +0 -327
  361. package/tests/commands-text-sys.test.ts +0 -445
  362. package/tests/expand.test.ts +0 -170
  363. package/tests/helpers.test.ts +0 -97
  364. package/tests/new-features.test.ts +0 -1036
  365. package/tests/parser-executor.test.ts +0 -37
  366. package/tests/sftp.test.ts +0 -323
  367. package/tests/ssh-exec.test.ts +0 -45
  368. package/tests/test-helper.ts +0 -79
  369. package/tests/users.test.ts +0 -86
  370. package/tsconfig.json +0 -49
  371. package/typedoc.json +0 -47
@@ -0,0 +1,57 @@
1
+ import { resolvePath } from "./helpers";
2
+ const MAGIC = [
3
+ [s => s.startsWith('\x7fELF'), "ELF 64-bit LSB executable, x86-64"],
4
+ [/^#!\/bin\/sh/, "POSIX shell script, ASCII text executable"],
5
+ [/^#!\/bin\/bash/, "Bourne-Again shell script, ASCII text executable"],
6
+ [/^#!\/usr\/bin\/env (node|bun)/, "Node.js script, ASCII text executable"],
7
+ [/^#!\/usr\/bin\/env python/, "Python script, ASCII text executable"],
8
+ [/^\x89PNG/, "PNG image data"],
9
+ [/^GIF8/, "GIF image data"],
10
+ [/^\xff\xd8\xff/, "JPEG image data"],
11
+ [/^PK\x03\x04/, "Zip archive data"],
12
+ [/^\x1f\x8b/, "gzip compressed data"],
13
+ [s => s.trimStart().startsWith('{') || s.trimStart().startsWith('['), "JSON data"],
14
+ [/^<\?xml/, "XML document, ASCII text"],
15
+ [/^<!DOCTYPE html/i, "HTML document, ASCII text"],
16
+ [/^[^\x00-\x08\x0e-\x1f\x7f-\x9f]*$/, "ASCII text"],
17
+ ];
18
+ /**
19
+ * Determine file type.
20
+ * @category files
21
+ * @params ["<file>..."]
22
+ */
23
+ export const fileCommand = {
24
+ name: "file",
25
+ description: "Determine file type",
26
+ category: "files",
27
+ params: ["<file>..."],
28
+ run: ({ args, cwd, shell }) => {
29
+ if (!args.length)
30
+ return { stderr: "file: missing operand", exitCode: 1 };
31
+ const lines = [];
32
+ let exitCode = 0;
33
+ for (const arg of args) {
34
+ const p = resolvePath(cwd, arg);
35
+ if (!shell.vfs.exists(p)) {
36
+ lines.push(`${arg}: ERROR: No such file or directory`);
37
+ exitCode = 1;
38
+ continue;
39
+ }
40
+ const st = shell.vfs.stat(p);
41
+ if (st.type === "directory") {
42
+ lines.push(`${arg}: directory`);
43
+ continue;
44
+ }
45
+ const content = shell.vfs.readFile(p);
46
+ let type = "data";
47
+ for (const [matcher, label] of MAGIC) {
48
+ if (typeof matcher === "function" ? matcher(content) : matcher.test(content)) {
49
+ type = label;
50
+ break;
51
+ }
52
+ }
53
+ lines.push(`${arg}: ${type}`);
54
+ }
55
+ return { stdout: lines.join("\n"), exitCode };
56
+ },
57
+ };
@@ -0,0 +1,32 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Output a string repeatedly until killed.
4
+ * @category misc
5
+ * @params ["[string]"]
6
+ */
7
+ export declare const yesCommand: ShellModule;
8
+ /**
9
+ * Print a random, hopefully interesting adage.
10
+ * @category misc
11
+ * @params [""]
12
+ */
13
+ export declare const fortuneCommand: ShellModule;
14
+ /**
15
+ * Generate an ASCII picture of a cow with a message.
16
+ * @category misc
17
+ * @params ["[message]"]
18
+ */
19
+ export declare const cowsayCommand: ShellModule;
20
+ export declare const cowthinkCommand: ShellModule;
21
+ /**
22
+ * Show falling characters in the terminal like the Matrix movie.
23
+ * @category misc
24
+ * @params [""]
25
+ */
26
+ export declare const cmatrixCommand: ShellModule;
27
+ /**
28
+ * You have SL.
29
+ * @category misc
30
+ * @params [""]
31
+ */
32
+ export declare const slCommand: ShellModule;
@@ -0,0 +1,172 @@
1
+ // ── yes ───────────────────────────────────────────────────────────────────────
2
+ /**
3
+ * Output a string repeatedly until killed.
4
+ * @category misc
5
+ * @params ["[string]"]
6
+ */
7
+ export const yesCommand = {
8
+ name: "yes",
9
+ description: "Output a string repeatedly until killed",
10
+ category: "misc",
11
+ params: ["[string]"],
12
+ run: ({ args }) => {
13
+ const word = args.length ? args.join(" ") : "y";
14
+ // Output 200 lines (simulate before Ctrl+C which isn't supported in virtual shell)
15
+ return { stdout: Array(200).fill(word).join("\n"), exitCode: 0 };
16
+ },
17
+ };
18
+ // ── fortune ──────────────────────────────────────────────────────────────────
19
+ const FORTUNES = [
20
+ "The best way to predict the future is to invent it. — Alan Kay",
21
+ "Any sufficiently advanced technology is indistinguishable from magic. — Arthur C. Clarke",
22
+ "Talk is cheap. Show me the code. — Linus Torvalds",
23
+ "Programs must be written for people to read, and only incidentally for machines to execute. — Harold Abelson",
24
+ "Debugging is twice as hard as writing the code in the first place. — Brian W. Kernighan",
25
+ "The most powerful tool we have as developers is automation. — Scott Hanselman",
26
+ "First, solve the problem. Then, write the code. — John Johnson",
27
+ "Make it work, make it right, make it fast. — Kent Beck",
28
+ "The function of good software is to make the complex appear simple. — Grady Booch",
29
+ "Premature optimization is the root of all evil. — Donald Knuth",
30
+ "There are only two hard things in Computer Science: cache invalidation and naming things. — Phil Karlton",
31
+ "The best code is no code at all. — Jeff Atwood",
32
+ "Linux is only free if your time has no value. — Jamie Zawinski",
33
+ "Software is like sex: it's better when it's free. — Linus Torvalds",
34
+ "Real programmers don't comment their code. If it was hard to write, it should be hard to understand.",
35
+ "It's not a bug — it's an undocumented feature.",
36
+ "The cloud is just someone else's computer.",
37
+ "There's no place like 127.0.0.1",
38
+ "sudo make me a sandwich.",
39
+ "To understand recursion, you must first understand recursion.",
40
+ ];
41
+ /**
42
+ * Print a random, hopefully interesting adage.
43
+ * @category misc
44
+ * @params [""]
45
+ */
46
+ export const fortuneCommand = {
47
+ name: "fortune",
48
+ description: "Print a random adage",
49
+ category: "misc",
50
+ params: [],
51
+ run: () => {
52
+ const idx = Math.floor(Math.random() * FORTUNES.length);
53
+ return { stdout: FORTUNES[idx], exitCode: 0 };
54
+ },
55
+ };
56
+ // ── cowsay ───────────────────────────────────────────────────────────────────
57
+ function cowsay(message, dead = false) {
58
+ const lines = message.split("\n");
59
+ const maxLen = Math.max(...lines.map(l => l.length));
60
+ const _border = "-".repeat(maxLen + 2);
61
+ const body = lines.length === 1
62
+ ? `< ${lines[0]} >`
63
+ : lines.map((l, i) => {
64
+ const pad = " ".repeat(maxLen - l.length);
65
+ if (i === 0)
66
+ return `/ ${l}${pad} \\`;
67
+ if (i === lines.length - 1)
68
+ return `\\ ${l}${pad} /`;
69
+ return `| ${l}${pad} |`;
70
+ }).join("\n");
71
+ const eyes = dead ? "xx" : "oo";
72
+ return [
73
+ ` ${"_".repeat(maxLen + 2)}`,
74
+ `( ${body} )`,
75
+ ` ${"‾".repeat(maxLen + 2)}`,
76
+ ` \\ ^__^`,
77
+ ` \\ (${eyes})\\_______`,
78
+ ` (__)\\ )\\/\\`,
79
+ ` ||----w |`,
80
+ ` || ||`,
81
+ ].join("\n");
82
+ }
83
+ /**
84
+ * Generate an ASCII picture of a cow with a message.
85
+ * @category misc
86
+ * @params ["[message]"]
87
+ */
88
+ export const cowsayCommand = {
89
+ name: "cowsay",
90
+ description: "Generate ASCII cow with message",
91
+ category: "misc",
92
+ params: ["[message]"],
93
+ run: ({ args, stdin }) => {
94
+ const msg = args.length ? args.join(" ") : (stdin?.trim() ?? "Moo.");
95
+ return { stdout: cowsay(msg), exitCode: 0 };
96
+ },
97
+ };
98
+ export const cowthinkCommand = {
99
+ name: "cowthink",
100
+ description: "Generate ASCII cow thinking",
101
+ category: "misc",
102
+ params: ["[message]"],
103
+ run: ({ args, stdin }) => {
104
+ const msg = args.length ? args.join(" ") : (stdin?.trim() ?? "Hmm...");
105
+ return { stdout: cowsay(msg).replace(/\\\s*\^__\^/, "o ^__^").replace(/\\\s*\(oo\)/, "o (oo)"), exitCode: 0 };
106
+ },
107
+ };
108
+ // ── cmatrix ──────────────────────────────────────────────────────────────────
109
+ /**
110
+ * Show falling characters in the terminal like the Matrix movie.
111
+ * @category misc
112
+ * @params [""]
113
+ */
114
+ export const cmatrixCommand = {
115
+ name: "cmatrix",
116
+ description: "Show falling characters like the Matrix",
117
+ category: "misc",
118
+ params: [],
119
+ run: () => {
120
+ const cols = 80;
121
+ const rows = 24;
122
+ const chars = "ハミヒーウシナモニサワツオリアホテマケメエカキムユラセネスタヌヘ01234567890ABCDEF";
123
+ const green = "\x1b[32m";
124
+ const bright = "\x1b[1;32m";
125
+ const reset = "\x1b[0m";
126
+ const lines = [];
127
+ for (let r = 0; r < rows; r++) {
128
+ let line = "";
129
+ for (let c = 0; c < cols; c++) {
130
+ const ch = chars[Math.floor(Math.random() * chars.length)];
131
+ if (Math.random() < 0.05)
132
+ line += bright + ch + reset;
133
+ else if (Math.random() < 0.7)
134
+ line += green + ch + reset;
135
+ else
136
+ line += " ";
137
+ }
138
+ lines.push(line);
139
+ }
140
+ return { stdout: `\x1b[2J\x1b[H${lines.join("\n")}\n${reset}[cmatrix: press Ctrl+C to exit]`, exitCode: 0 };
141
+ },
142
+ };
143
+ // ── sl (Steam Locomotive) ─────────────────────────────────────────────────────
144
+ const TRAIN = [
145
+ " ==== ________ ___________ ",
146
+ " _D _| |_______/ \\__I_I_____===__|_________| ",
147
+ " |(_)--- | H\\________/ | | =|___ ___| ___",
148
+ " / | | H | | | | ||_| |_|| _| |_",
149
+ " | | | H |__--------------------| [___] | =| |",
150
+ " | ________|___H__/__|_____/[][]~\\_______| | -| __ |",
151
+ " |/ | |-----------I_____I [][] [] D |=======|____|__| |_|_|",
152
+ "__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__| |___|o |",
153
+ " |/-=|___|= || || || |_____/~\\___/ |___| |_|",
154
+ " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ |",
155
+ ];
156
+ /**
157
+ * You have SL.
158
+ * @category misc
159
+ * @params [""]
160
+ */
161
+ export const slCommand = {
162
+ name: "sl",
163
+ description: "Steam Locomotive — you have sl",
164
+ category: "misc",
165
+ params: [],
166
+ run: () => {
167
+ return {
168
+ stdout: `\n\n${TRAIN.join("\n")}\n\n choo choo! 🚂\n`,
169
+ exitCode: 0,
170
+ };
171
+ },
172
+ };
@@ -0,0 +1,7 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Show/manipulate routing, network devices, interfaces and tunnels.
4
+ * @category network
5
+ * @params ["<object> <command>"]
6
+ */
7
+ export declare const ipCommand: ShellModule;
@@ -0,0 +1,52 @@
1
+ const ADDR_OUTPUT = `1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
2
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3
+ inet 127.0.0.1/8 scope host lo
4
+ valid_lft forever preferred_lft forever
5
+ inet6 ::1/128 scope host
6
+ valid_lft forever preferred_lft forever
7
+ 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
8
+ link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
9
+ inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0
10
+ valid_lft forever preferred_lft forever
11
+ inet6 fe80::42:aff:fe00:2/64 scope link
12
+ valid_lft forever preferred_lft forever`;
13
+ const ROUTE_OUTPUT = `default via 10.0.0.1 dev eth0
14
+ 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.2`;
15
+ const LINK_OUTPUT = `1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
16
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
17
+ 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
18
+ link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff`;
19
+ /**
20
+ * Show/manipulate routing, network devices, interfaces and tunnels.
21
+ * @category network
22
+ * @params ["<object> <command>"]
23
+ */
24
+ export const ipCommand = {
25
+ name: "ip",
26
+ description: "Show/manipulate routing, network devices, interfaces",
27
+ category: "network",
28
+ params: ["<object> <command>"],
29
+ run: ({ args }) => {
30
+ const obj = args[0]?.toLowerCase();
31
+ const cmd = args[1]?.toLowerCase() ?? "show";
32
+ if (!obj) {
33
+ return { stderr: "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\nOBJECT := { link | addr | route | neigh }", exitCode: 1 };
34
+ }
35
+ if (obj === "addr" || obj === "address" || obj === "a") {
36
+ return { stdout: ADDR_OUTPUT, exitCode: 0 };
37
+ }
38
+ if (obj === "route" || obj === "r" || obj === "ro") {
39
+ return { stdout: ROUTE_OUTPUT, exitCode: 0 };
40
+ }
41
+ if (obj === "link" || obj === "l") {
42
+ return { stdout: LINK_OUTPUT, exitCode: 0 };
43
+ }
44
+ if (obj === "neigh" || obj === "n") {
45
+ return { stdout: "10.0.0.1 dev eth0 lladdr 02:42:0a:00:00:01 REACHABLE", exitCode: 0 };
46
+ }
47
+ if (["set", "add", "del", "flush", "change", "replace"].includes(cmd)) {
48
+ return { exitCode: 0 }; // silently succeed mutations
49
+ }
50
+ return { stderr: `ip: Object "${obj}" is unknown, try "ip help".`, exitCode: 1 };
51
+ },
52
+ };
@@ -0,0 +1,4 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const jobsCommand: ShellModule;
3
+ export declare const bgCommand: ShellModule;
4
+ export declare const fgCommand: ShellModule;
@@ -0,0 +1,27 @@
1
+ export const jobsCommand = {
2
+ name: "jobs",
3
+ description: "List active jobs",
4
+ category: "shell",
5
+ params: [],
6
+ run: () => ({ stdout: "", exitCode: 0 }),
7
+ };
8
+ export const bgCommand = {
9
+ name: "bg",
10
+ description: "Resume a suspended job in the background",
11
+ category: "shell",
12
+ params: ["[%jobspec]"],
13
+ run: ({ args }) => ({
14
+ stderr: `bg: ${args[0] ?? "%1"}: no such job`,
15
+ exitCode: 1,
16
+ }),
17
+ };
18
+ export const fgCommand = {
19
+ name: "fg",
20
+ description: "Resume a suspended job in the foreground",
21
+ category: "shell",
22
+ params: ["[%jobspec]"],
23
+ run: ({ args }) => ({
24
+ stderr: `fg: ${args[0] ?? "%1"}: no such job`,
25
+ exitCode: 1,
26
+ }),
27
+ };
@@ -0,0 +1,13 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Show listing of last logged in users.
4
+ * @category system
5
+ * @params ["[username]"]
6
+ */
7
+ export declare const lastCommand: ShellModule;
8
+ /**
9
+ * Show system log messages.
10
+ * @category system
11
+ * @params ["[-n n]"]
12
+ */
13
+ export declare const dmesgCommand: ShellModule;
@@ -0,0 +1,68 @@
1
+ import { userHome } from "./runtime";
2
+ /**
3
+ * Show listing of last logged in users.
4
+ * @category system
5
+ * @params ["[username]"]
6
+ */
7
+ export const lastCommand = {
8
+ name: "last",
9
+ description: "Show listing of last logged in users",
10
+ category: "system",
11
+ params: ["[username]"],
12
+ run: ({ args, shell, authUser }) => {
13
+ const target = args[0] ?? authUser;
14
+ const logPath = `${userHome(target)}/.lastlog`;
15
+ const lines = [];
16
+ if (shell.vfs.exists(logPath)) {
17
+ try {
18
+ const log = JSON.parse(shell.vfs.readFile(logPath));
19
+ const d = new Date(log.at);
20
+ const ds = `${d.toDateString().slice(0, 3)} ${d.toLocaleString("en-US", {
21
+ month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false,
22
+ }).replace(",", "")}`;
23
+ lines.push(`${target.padEnd(10)} pts/0 ${(log.from ?? "browser").padEnd(16)} ${ds} still logged in`);
24
+ }
25
+ catch { }
26
+ }
27
+ lines.push("");
28
+ lines.push(`wtmp begins ${new Date().toDateString()}`);
29
+ return { stdout: lines.join("\n"), exitCode: 0 };
30
+ },
31
+ };
32
+ /**
33
+ * Show system log messages.
34
+ * @category system
35
+ * @params ["[-n n]"]
36
+ */
37
+ export const dmesgCommand = {
38
+ name: "dmesg",
39
+ description: "Print or control the kernel ring buffer",
40
+ category: "system",
41
+ params: ["[-n n]"],
42
+ run: ({ args }) => {
43
+ const n = args.includes("-n") ? parseInt(args[args.indexOf("-n") + 1] ?? "20", 10) : 20;
44
+ const msgs = [
45
+ "[ 0.000000] Booting Linux on physical CPU 0x0",
46
+ "[ 0.000000] Linux version 6.1.0-fortune (gcc version 12.2.0)",
47
+ "[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.1.0 root=/dev/sda1 ro quiet",
48
+ "[ 0.000000] BIOS-provided physical RAM map:",
49
+ "[ 0.000000] ACPI: IRQ0 used by override.",
50
+ "[ 0.125000] PCI: Using configuration type 1 for base access",
51
+ "[ 0.250000] clocksource: tsc-early: mask: 0xffffffffffffffff",
52
+ "[ 0.375000] CPU: Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz",
53
+ "[ 0.500000] Calibrating delay loop... 5800.00 BogoMIPS",
54
+ "[ 1.000000] NET: Registered PF_INET protocol family",
55
+ "[ 1.125000] virtio_net virtio0 eth0: renamed from eth0",
56
+ "[ 1.250000] EXT4-fs (sda1): mounted filesystem with ordered data mode",
57
+ "[ 1.375000] systemd[1]: systemd 252 running in system mode",
58
+ "[ 1.500000] systemd[1]: Reached target basic.system",
59
+ "[ 2.000000] audit: type=1403 audit(0.0:2): policy loaded",
60
+ "[ 2.125000] NET: Registered PF_PACKET protocol family",
61
+ "[ 2.250000] 8021q: 802.1Q VLAN Support v1.8",
62
+ "[ 2.375000] bridge: filtering via arp/ip/ip6tables is no longer available",
63
+ "[ 2.500000] Bluetooth: Core ver 2.22",
64
+ "[ 3.000000] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0",
65
+ ].slice(0, n);
66
+ return { stdout: msgs.join("\n"), exitCode: 0 };
67
+ },
68
+ };