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
@@ -1,358 +0,0 @@
1
- import { existsSync, readdirSync, readFileSync } from "node:fs";
2
- import * as os from "node:os";
3
- import * as path from "node:path";
4
- import type { ShellProperties } from "../VirtualShell";
5
-
6
- function formatUptime(seconds: number): string {
7
- const totalMinutes = Math.max(1, Math.floor(seconds / 60));
8
- const days = Math.floor(totalMinutes / (24 * 60));
9
- const hours = Math.floor((totalMinutes % (24 * 60)) / 60);
10
- const minutes = totalMinutes % 60;
11
-
12
- const parts: string[] = [];
13
- if (days > 0) {
14
- parts.push(`${days} day${days > 1 ? "s" : ""}`);
15
- }
16
- if (hours > 0) {
17
- parts.push(`${hours} hour${hours > 1 ? "s" : ""}`);
18
- }
19
- if (minutes > 0 || parts.length === 0) {
20
- parts.push(`${minutes} min${minutes > 1 ? "s" : ""}`);
21
- }
22
-
23
- return parts.join(", ");
24
- }
25
-
26
- function colorBlock(code: number): string {
27
- return `\u001b[${code}m \u001b[0m`;
28
- }
29
-
30
- function buildColorBars(): string[] {
31
- const normal = [40, 41, 42, 43, 44, 45, 46, 47].map(colorBlock).join("");
32
- const bright = [100, 101, 102, 103, 104, 105, 106, 107]
33
- .map(colorBlock)
34
- .join("");
35
- return [normal, bright];
36
- }
37
-
38
- function colorizeLogoLine(line: string, index: number, total: number): string {
39
- if (line.trim().length === 0) {
40
- return line;
41
- }
42
-
43
- const start = { r: 255, g: 255, b: 255 };
44
- const end = { r: 168, g: 85, b: 247 };
45
- const ratio = total <= 1 ? 0 : index / (total - 1);
46
-
47
- const r = Math.round(start.r + (end.r - start.r) * ratio);
48
- const g = Math.round(start.g + (end.g - start.g) * ratio);
49
- const b = Math.round(start.b + (end.b - start.b) * ratio);
50
-
51
- return `\u001b[38;2;${r};${g};${b}m${line}\u001b[0m`;
52
- }
53
-
54
- function colorizeDetailLine(line: string): string {
55
- if (line.trim().length === 0) {
56
- return line;
57
- }
58
-
59
- const colonIndex = line.indexOf(":");
60
-
61
- if (colonIndex === -1) {
62
- // Pas de ':', chercher '@' pour identifier user@host
63
- if (line.includes("@")) {
64
- // C'est user@host, appliquer dégradé horizontal
65
- return applyHorizontalGradient(line);
66
- }
67
- // Sinon c'est un separator ou autre, laisser tel quel
68
- return line;
69
- }
70
-
71
- // Il y a un ':', c'est titre: valeur
72
- const title = line.substring(0, colonIndex + 1);
73
- const value = line.substring(colonIndex + 1);
74
-
75
- // Appliquer le dégradé seulement au titre
76
- const colorized = applyHorizontalGradient(title);
77
- return colorized + value;
78
- }
79
-
80
- function applyHorizontalGradient(text: string): string {
81
- // Nettoyer les codes ANSI existants
82
- const ansiRegex = new RegExp(`${String.fromCharCode(27)}\\[[\\d;]*m`, "g");
83
- const cleaned = text.replace(ansiRegex, "");
84
-
85
- if (cleaned.trim().length === 0) {
86
- return text;
87
- }
88
-
89
- const start = { r: 255, g: 255, b: 255 };
90
- const end = { r: 168, g: 85, b: 247 };
91
- let result = "";
92
-
93
- for (let i = 0; i < cleaned.length; i += 1) {
94
- const ratio = cleaned.length <= 1 ? 0 : i / (cleaned.length - 1);
95
-
96
- const r = Math.round(start.r + (end.r - start.r) * ratio);
97
- const g = Math.round(start.g + (end.g - start.g) * ratio);
98
- const b = Math.round(start.b + (end.b - start.b) * ratio);
99
-
100
- result += `\u001b[38;2;${r};${g};${b}m${cleaned[i]}\u001b[0m`;
101
- }
102
-
103
- return result;
104
- }
105
-
106
- export interface NeofetchInfo {
107
- user: string;
108
- host: string;
109
- osName?: string;
110
- kernel?: string;
111
- uptimeSeconds?: number;
112
- packages?: string;
113
- shell?: string;
114
- shellProps?: ShellProperties;
115
- resolution?: string;
116
- terminal?: string;
117
- cpu?: string;
118
- gpu?: string;
119
- memoryUsedMiB?: number;
120
- memoryTotalMiB?: number;
121
- }
122
-
123
- function toMiB(bytes: number): number {
124
- return Math.max(0, Math.round(bytes / (1024 * 1024)));
125
- }
126
-
127
- function readOsPrettyName(): string | undefined {
128
- try {
129
- const data = readFileSync("/etc/os-release", "utf8");
130
- for (const line of data.split("\n")) {
131
- if (!line.startsWith("PRETTY_NAME=")) {
132
- continue;
133
- }
134
-
135
- const value = line.slice("PRETTY_NAME=".length).trim();
136
- return value.replace(/^"|"$/g, "");
137
- }
138
- } catch {
139
- return undefined;
140
- }
141
-
142
- return undefined;
143
- }
144
-
145
- function readFirstLine(filePath: string): string | undefined {
146
- try {
147
- const data = readFileSync(filePath, "utf8").split("\n")[0]?.trim();
148
- if (!data || data.length === 0) {
149
- return undefined;
150
- }
151
- return data;
152
- } catch {
153
- return undefined;
154
- }
155
- }
156
-
157
- function resolveHostLabel(fallback: string): string {
158
- const vendor = readFirstLine("/sys/devices/virtual/dmi/id/sys_vendor");
159
- const product = readFirstLine("/sys/devices/virtual/dmi/id/product_name");
160
-
161
- if (vendor && product) {
162
- return `${vendor} ${product}`;
163
- }
164
- if (product) {
165
- return product;
166
- }
167
-
168
- return fallback;
169
- }
170
-
171
- function countDpkgPackages(): number | undefined {
172
- const candidates = ["/var/lib/dpkg/status", "/usr/local/var/lib/dpkg/status"];
173
-
174
- for (const filePath of candidates) {
175
- if (!existsSync(filePath)) {
176
- continue;
177
- }
178
-
179
- try {
180
- const data = readFileSync(filePath, "utf8");
181
- const matches = data.match(/^Package:\s+/gm);
182
- return matches?.length ?? 0;
183
- } catch {}
184
- }
185
-
186
- return undefined;
187
- }
188
-
189
- function countSnapPackages(): number | undefined {
190
- const candidates = ["/snap", "/var/lib/snapd/snaps"];
191
-
192
- for (const dirPath of candidates) {
193
- if (!existsSync(dirPath)) {
194
- continue;
195
- }
196
-
197
- try {
198
- const entries = readdirSync(dirPath, { withFileTypes: true });
199
- const count = entries.filter((entry) => entry.isDirectory()).length;
200
- return count;
201
- } catch {}
202
- }
203
-
204
- return undefined;
205
- }
206
-
207
- function resolvePackagesLabel(): string {
208
- const dpkgCount = countDpkgPackages();
209
- const snapCount = countSnapPackages();
210
-
211
- if (dpkgCount !== undefined && snapCount !== undefined) {
212
- return `${dpkgCount} (dpkg), ${snapCount} (snap)`;
213
- }
214
- if (dpkgCount !== undefined) {
215
- return `${dpkgCount} (dpkg)`;
216
- }
217
- if (snapCount !== undefined) {
218
- return `${snapCount} (snap)`;
219
- }
220
-
221
- return "n/a";
222
- }
223
-
224
- function resolveCpuLabel(): string {
225
- const cpus = os.cpus();
226
- if (cpus.length === 0) {
227
- return "unknown";
228
- }
229
-
230
- const first = cpus[0];
231
- if (!first) {
232
- return "unknown";
233
- }
234
-
235
- const ghz = (first.speed / 1000).toFixed(2);
236
- return `${first.model} (${cpus.length}) @ ${ghz}GHz`;
237
- }
238
-
239
- function resolveShellLabel(shell?: string): string {
240
- if (!shell || shell.trim().length === 0) {
241
- return "unknown";
242
- }
243
-
244
- return path.posix.basename(shell.trim());
245
- }
246
-
247
- function resolveDefaults(info: NeofetchInfo): Required<NeofetchInfo> {
248
- const totalMem = os.totalmem();
249
- const freeMem = os.freemem();
250
- const usedMem = Math.max(0, totalMem - freeMem);
251
- const shellProps = info.shellProps;
252
-
253
- const processUptime = process.uptime();
254
- if (info.uptimeSeconds === undefined) {
255
- info.uptimeSeconds = Math.round(processUptime);
256
- }
257
-
258
- return {
259
- user: info.user,
260
- host: info.host,
261
- osName:
262
- shellProps?.os ??
263
- info.osName ??
264
- `${readOsPrettyName() ?? os.type()} ${os.arch()}`,
265
- kernel: shellProps?.kernel ?? info.kernel ?? os.release(),
266
- uptimeSeconds: info.uptimeSeconds ?? os.uptime(),
267
- packages: info.packages ?? resolvePackagesLabel(),
268
- shell: resolveShellLabel(info.shell),
269
- shellProps: (info.shellProps as ShellProperties) ?? {
270
- kernel: info.kernel ?? os.release(),
271
- os: info.osName ?? `${readOsPrettyName() ?? os.type()} ${os.arch()}`,
272
- arch: os.arch(),
273
- },
274
- resolution: info.resolution ?? "n/a (ssh)",
275
- terminal: info.terminal ?? "unknown",
276
- cpu: info.cpu ?? resolveCpuLabel(),
277
- gpu: info.gpu ?? "n/a",
278
- memoryUsedMiB: info.memoryUsedMiB ?? toMiB(usedMem),
279
- memoryTotalMiB: info.memoryTotalMiB ?? toMiB(totalMem),
280
- };
281
- }
282
-
283
- export function buildNeofetchOutput(info: NeofetchInfo): string {
284
- const fields = resolveDefaults(info);
285
- const uptime = formatUptime(fields.uptimeSeconds);
286
- const colorBars = buildColorBars();
287
-
288
- const distroLogo = [
289
- " .. .:. ",
290
- " .::.. .. .. ",
291
- ". .... ... .. ",
292
- ": .... .:. .. ",
293
- ": .:.:........:. .. ",
294
- ": .. ",
295
- ". : ",
296
- ". : ",
297
- ".. : ",
298
- " :. .. ",
299
- " .. .. ",
300
- " :-. :: ",
301
- " .:. :. ",
302
- " ..: ... ",
303
- " ..: :.. ",
304
- " :... :....",
305
- " .. ....",
306
- " . .. ",
307
- " .:. .: ",
308
- " :. .. ",
309
- " ::. .. ",
310
- "..... ..:... ",
311
- "...:. .. ",
312
- ".:...:. ::. .. ",
313
- " ... ..:::::.. ..:::::::.. ",
314
- ];
315
-
316
- const details = [
317
- `${fields.user}@${fields.host}`,
318
- "-------------------------",
319
- `OS: ${fields.osName}`,
320
- `Host: ${resolveHostLabel(fields.host)}`,
321
- `Kernel: ${fields.kernel}`,
322
- `Uptime: ${uptime}`,
323
- // `Packages: ${fields.packages}`,
324
- `Packages: ${fields.packages}`,
325
- `Shell: ${fields.shell}`,
326
- // `Shell Props: ${fields.shellProps}`,
327
- `Resolution: ${fields.resolution}`,
328
- `Terminal: ${fields.terminal}`,
329
- `CPU: ${fields.cpu}`,
330
- `GPU: ${fields.gpu}`,
331
- `Memory: ${fields.memoryUsedMiB}MiB / ${fields.memoryTotalMiB}MiB`,
332
- "",
333
- colorBars[0],
334
- colorBars[1],
335
- ];
336
-
337
- const width = Math.max(distroLogo.length, details.length);
338
- const lines: string[] = [];
339
-
340
- for (let i = 0; i < width; i += 1) {
341
- const rawLeft = distroLogo[i] ?? "";
342
- const right = details[i] ?? "";
343
- if (right.length > 0) {
344
- const left = colorizeLogoLine(
345
- rawLeft.padEnd(31, " "),
346
- i,
347
- distroLogo.length,
348
- );
349
- const coloredRight = colorizeDetailLine(right);
350
- lines.push(`${left} ${coloredRight}`);
351
- continue;
352
- }
353
-
354
- lines.push(colorizeLogoLine(rawLeft, i, distroLogo.length));
355
- }
356
-
357
- return lines.join("\n");
358
- }
@@ -1,57 +0,0 @@
1
- import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process";
2
- import type { ShellStream } from "../types/streams";
3
- import {
4
- shellQuote,
5
- type TerminalSize,
6
- withTerminalSize,
7
- } from "./shellRuntime";
8
-
9
- function spawnScriptProcess(
10
- command: string,
11
- terminalSize: TerminalSize,
12
- stream: ShellStream,
13
- ): ChildProcessWithoutNullStreams {
14
- const formatted = withTerminalSize(command, terminalSize);
15
- const proc = spawn("script", ["-qfec", formatted, "/dev/null"], {
16
- stdio: ["pipe", "pipe", "pipe"],
17
- env: {
18
- ...process.env,
19
- // biome-ignore lint/style/useNamingConvention: env variable should be uppercase
20
- TERM: process.env.TERM ?? "xterm-256color",
21
- },
22
- });
23
-
24
- proc.stdout.on("data", (data: Buffer) => {
25
- stream.write(data.toString("utf8"));
26
- });
27
-
28
- proc.stderr.on("data", (data: Buffer) => {
29
- stream.write(data.toString("utf8"));
30
- });
31
-
32
- return proc;
33
- }
34
-
35
- export function spawnNanoEditorProcess(
36
- tempPath: string,
37
- terminalSize: TerminalSize,
38
- stream: ShellStream,
39
- ): ChildProcessWithoutNullStreams {
40
- return spawnScriptProcess(
41
- `nano -- ${shellQuote(tempPath)}`,
42
- terminalSize,
43
- stream,
44
- );
45
- }
46
-
47
- export function spawnHtopProcess(
48
- pidList: string,
49
- terminalSize: TerminalSize,
50
- stream: ShellStream,
51
- ): ChildProcessWithoutNullStreams {
52
- return spawnScriptProcess(
53
- `htop -p ${shellQuote(pidList)}`,
54
- terminalSize,
55
- stream,
56
- );
57
- }
@@ -1,76 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import * as path from "node:path";
3
-
4
- export interface TerminalSize {
5
- cols: number;
6
- rows: number;
7
- }
8
-
9
- export function shellQuote(value: string): string {
10
- return `'${value.replace(/'/g, `'\\''`)}'`;
11
- }
12
-
13
- export function toTtyLines(text: string): string {
14
- return text
15
- .replace(/\r\n/g, "\n")
16
- .replace(/\r/g, "\n")
17
- .replace(/\n/g, "\r\n");
18
- }
19
-
20
- export function withTerminalSize(
21
- command: string,
22
- terminalSize: TerminalSize,
23
- ): string {
24
- const cols =
25
- Number.isFinite(terminalSize.cols) && terminalSize.cols > 0
26
- ? Math.floor(terminalSize.cols)
27
- : 80;
28
- const rows =
29
- Number.isFinite(terminalSize.rows) && terminalSize.rows > 0
30
- ? Math.floor(terminalSize.rows)
31
- : 24;
32
- return `stty cols ${cols} rows ${rows} 2>/dev/null; ${command}`;
33
- }
34
-
35
- export function resolvePath(base: string, inputPath: string): string {
36
- if (!inputPath || inputPath.trim() === "" || inputPath === ".") {
37
- return base;
38
- }
39
- return inputPath.startsWith("/")
40
- ? path.posix.normalize(inputPath)
41
- : path.posix.normalize(path.posix.join(base, inputPath));
42
- }
43
-
44
- export async function collectChildPids(parentPid: number): Promise<number[]> {
45
- try {
46
- const childrenRaw = await readFile(
47
- `/proc/${parentPid}/task/${parentPid}/children`,
48
- "utf8",
49
- );
50
- const directChildren = childrenRaw
51
- .trim()
52
- .split(/\s+/)
53
- .filter(Boolean)
54
- .map((value) => Number.parseInt(value, 10))
55
- .filter((pid) => Number.isInteger(pid) && pid > 0);
56
-
57
- const nested = await Promise.all(
58
- directChildren.map((pid) => collectChildPids(pid)),
59
- );
60
- return [...directChildren, ...nested.flat()];
61
- } catch {
62
- return [];
63
- }
64
- }
65
-
66
- export async function getVisibleHtopPidList(
67
- rootPid = process.pid,
68
- ): Promise<string | null> {
69
- const descendants = await collectChildPids(rootPid);
70
- const unique = Array.from(new Set(descendants)).sort((a, b) => a - b);
71
- if (unique.length === 0) {
72
- return null;
73
- }
74
-
75
- return unique.join(",");
76
- }