typescript-virtual-container 1.2.8 → 1.2.9

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 (120) hide show
  1. package/README.md +359 -32
  2. package/dist/SSHMimic/executor.js +3 -5
  3. package/dist/VirtualPackageManager/index.d.ts +202 -0
  4. package/dist/VirtualPackageManager/index.d.ts.map +1 -0
  5. package/dist/VirtualPackageManager/index.js +676 -0
  6. package/dist/VirtualShell/index.d.ts +87 -12
  7. package/dist/VirtualShell/index.d.ts.map +1 -1
  8. package/dist/VirtualShell/index.js +83 -12
  9. package/dist/VirtualUserManager/index.d.ts +52 -20
  10. package/dist/VirtualUserManager/index.d.ts.map +1 -1
  11. package/dist/VirtualUserManager/index.js +54 -20
  12. package/dist/commands/alias.d.ts +4 -0
  13. package/dist/commands/alias.d.ts.map +1 -0
  14. package/dist/commands/alias.js +58 -0
  15. package/dist/commands/apt.d.ts +4 -0
  16. package/dist/commands/apt.d.ts.map +1 -0
  17. package/dist/commands/apt.js +182 -0
  18. package/dist/commands/cat.d.ts.map +1 -1
  19. package/dist/commands/cat.js +27 -8
  20. package/dist/commands/chmod.d.ts.map +1 -1
  21. package/dist/commands/chmod.js +52 -3
  22. package/dist/commands/command-helpers.d.ts +78 -4
  23. package/dist/commands/command-helpers.d.ts.map +1 -1
  24. package/dist/commands/command-helpers.js +78 -4
  25. package/dist/commands/curl.d.ts.map +1 -1
  26. package/dist/commands/curl.js +81 -29
  27. package/dist/commands/dpkg.d.ts +4 -0
  28. package/dist/commands/dpkg.d.ts.map +1 -0
  29. package/dist/commands/dpkg.js +144 -0
  30. package/dist/commands/echo.d.ts.map +1 -1
  31. package/dist/commands/echo.js +24 -12
  32. package/dist/commands/free.d.ts +3 -0
  33. package/dist/commands/free.d.ts.map +1 -0
  34. package/dist/commands/free.js +38 -0
  35. package/dist/commands/helpers.d.ts +3 -0
  36. package/dist/commands/helpers.d.ts.map +1 -1
  37. package/dist/commands/helpers.js +3 -0
  38. package/dist/commands/history.d.ts +3 -0
  39. package/dist/commands/history.d.ts.map +1 -0
  40. package/dist/commands/history.js +21 -0
  41. package/dist/commands/index.d.ts +8 -1
  42. package/dist/commands/index.d.ts.map +1 -1
  43. package/dist/commands/index.js +120 -11
  44. package/dist/commands/ls.d.ts.map +1 -1
  45. package/dist/commands/ls.js +4 -3
  46. package/dist/commands/lsb-release.d.ts +3 -0
  47. package/dist/commands/lsb-release.d.ts.map +1 -0
  48. package/dist/commands/lsb-release.js +50 -0
  49. package/dist/commands/man.d.ts +3 -0
  50. package/dist/commands/man.d.ts.map +1 -0
  51. package/dist/commands/man.js +155 -0
  52. package/dist/commands/neofetch.d.ts.map +1 -1
  53. package/dist/commands/neofetch.js +5 -0
  54. package/dist/commands/ping.d.ts.map +1 -1
  55. package/dist/commands/ping.js +5 -2
  56. package/dist/commands/ps.d.ts.map +1 -1
  57. package/dist/commands/ps.js +27 -6
  58. package/dist/commands/sh.d.ts.map +1 -1
  59. package/dist/commands/sh.js +29 -11
  60. package/dist/commands/source.d.ts +3 -0
  61. package/dist/commands/source.d.ts.map +1 -0
  62. package/dist/commands/source.js +31 -0
  63. package/dist/commands/test.d.ts +3 -0
  64. package/dist/commands/test.d.ts.map +1 -0
  65. package/dist/commands/test.js +92 -0
  66. package/dist/commands/type.d.ts +3 -0
  67. package/dist/commands/type.d.ts.map +1 -0
  68. package/dist/commands/type.js +34 -0
  69. package/dist/commands/uptime.d.ts +3 -0
  70. package/dist/commands/uptime.d.ts.map +1 -0
  71. package/dist/commands/uptime.js +40 -0
  72. package/dist/commands/wget.d.ts.map +1 -1
  73. package/dist/commands/wget.js +71 -100
  74. package/dist/commands/which.d.ts +3 -0
  75. package/dist/commands/which.d.ts.map +1 -0
  76. package/dist/commands/which.js +32 -0
  77. package/dist/index.d.ts +5 -2
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +2 -1
  80. package/dist/modules/linuxRootfs.d.ts +24 -0
  81. package/dist/modules/linuxRootfs.d.ts.map +1 -0
  82. package/dist/modules/linuxRootfs.js +297 -0
  83. package/dist/modules/neofetch.d.ts.map +1 -1
  84. package/dist/modules/neofetch.js +1 -0
  85. package/package.json +2 -1
  86. package/src/SSHMimic/executor.ts +3 -5
  87. package/src/VirtualPackageManager/index.ts +820 -0
  88. package/src/VirtualShell/index.ts +104 -13
  89. package/src/VirtualUserManager/index.ts +55 -20
  90. package/src/commands/alias.ts +60 -0
  91. package/src/commands/apt.ts +198 -0
  92. package/src/commands/cat.ts +32 -8
  93. package/src/commands/chmod.ts +48 -3
  94. package/src/commands/command-helpers.ts +78 -4
  95. package/src/commands/curl.ts +78 -37
  96. package/src/commands/dpkg.ts +158 -0
  97. package/src/commands/echo.ts +30 -14
  98. package/src/commands/free.ts +40 -0
  99. package/src/commands/helpers.ts +8 -0
  100. package/src/commands/history.ts +29 -0
  101. package/src/commands/index.ts +116 -11
  102. package/src/commands/ls.ts +5 -4
  103. package/src/commands/lsb-release.ts +52 -0
  104. package/src/commands/man.ts +166 -0
  105. package/src/commands/neofetch.ts +5 -0
  106. package/src/commands/ping.ts +5 -2
  107. package/src/commands/ps.ts +28 -6
  108. package/src/commands/sh.ts +33 -11
  109. package/src/commands/source.ts +35 -0
  110. package/src/commands/test.ts +100 -0
  111. package/src/commands/type.ts +40 -0
  112. package/src/commands/uptime.ts +46 -0
  113. package/src/commands/wget.ts +70 -123
  114. package/src/commands/which.ts +34 -0
  115. package/src/index.ts +10 -0
  116. package/src/modules/linuxRootfs.ts +439 -0
  117. package/src/modules/neofetch.ts +1 -0
  118. package/standalone.js +418 -103
  119. package/standalone.js.map +4 -4
  120. package/tests/new-features.test.ts +626 -0
@@ -0,0 +1,297 @@
1
+ /**
2
+ * linuxRootfs.ts
3
+ *
4
+ * Bootstraps a realistic Linux directory hierarchy in the VFS.
5
+ * Called once during VirtualShell initialization. Idempotent — skips
6
+ * paths that already exist so FS-mode snapshots survive restarts.
7
+ */
8
+ import * as os from "node:os";
9
+ // ─── helpers ────────────────────────────────────────────────────────────────
10
+ function ensureDir(vfs, path, mode = 0o755) {
11
+ if (!vfs.exists(path))
12
+ vfs.mkdir(path, mode);
13
+ }
14
+ function ensureFile(vfs, path, content, mode = 0o644) {
15
+ if (!vfs.exists(path))
16
+ vfs.writeFile(path, content, { mode });
17
+ }
18
+ // ─── /etc ────────────────────────────────────────────────────────────────────
19
+ function bootstrapEtc(vfs, hostname, props) {
20
+ ensureDir(vfs, "/etc");
21
+ // os-release — authoritative distro identity used by neofetch, lsb_release
22
+ ensureFile(vfs, "/etc/os-release", `${[
23
+ `NAME="Fortune GNU/Linux"`,
24
+ `PRETTY_NAME="${props.os}"`,
25
+ `ID=fortune`,
26
+ `ID_LIKE=debian`,
27
+ `HOME_URL="https://github.com/itsrealfortune/typescript-virtual-container"`,
28
+ `VERSION_CODENAME=aurora`,
29
+ `VERSION_ID="1.0"`,
30
+ ].join("\n")}\n`);
31
+ ensureFile(vfs, "/etc/debian_version", "12.0\n");
32
+ ensureFile(vfs, "/etc/hostname", `${hostname}\n`);
33
+ ensureFile(vfs, "/etc/shells", "/bin/sh\n/bin/bash\n/usr/bin/bash\n");
34
+ ensureFile(vfs, "/etc/profile", `${[
35
+ "export PATH=/usr/local/bin:/usr/bin:/bin",
36
+ "export PS1='\\u@\\h:\\w\\$ '",
37
+ ].join("\n")}\n`);
38
+ ensureFile(vfs, "/etc/issue", `Fortune GNU/Linux 1.0 \\n \\l\n`);
39
+ ensureFile(vfs, "/etc/motd", [
40
+ "",
41
+ `Welcome to ${props.os}`,
42
+ `Kernel: ${props.kernel}`,
43
+ "",
44
+ ].join("\n"));
45
+ // APT sources
46
+ ensureDir(vfs, "/etc/apt");
47
+ ensureDir(vfs, "/etc/apt/sources.list.d");
48
+ ensureFile(vfs, "/etc/apt/sources.list", `${[
49
+ "# Fortune GNU/Linux package sources",
50
+ "deb [virtual] fortune://packages.fortune.local aurora main contrib",
51
+ "deb [virtual] fortune://security.fortune.local aurora-security main",
52
+ ].join("\n")}\n`);
53
+ // network stubs
54
+ ensureDir(vfs, "/etc/network");
55
+ ensureFile(vfs, "/etc/network/interfaces", `${[
56
+ "auto lo",
57
+ "iface lo inet loopback",
58
+ "",
59
+ "auto eth0",
60
+ "iface eth0 inet dhcp",
61
+ ].join("\n")}\n`);
62
+ ensureFile(vfs, "/etc/resolv.conf", "nameserver 1.1.1.1\nnameserver 8.8.8.8\n");
63
+ ensureFile(vfs, "/etc/hosts", `${[
64
+ "127.0.0.1 localhost",
65
+ `127.0.1.1 ${hostname}`,
66
+ "::1 localhost ip6-localhost ip6-loopback",
67
+ ].join("\n")}\n`);
68
+ ensureDir(vfs, "/etc/cron.d");
69
+ ensureDir(vfs, "/etc/init.d");
70
+ ensureDir(vfs, "/etc/systemd");
71
+ ensureDir(vfs, "/etc/systemd/system");
72
+ }
73
+ // ─── /etc/passwd + /etc/group + /etc/shadow ─────────────────────────────────
74
+ export function syncEtcPasswd(vfs, users) {
75
+ const userList = users.listUsers();
76
+ const passwdLines = [
77
+ "root:x:0:0:root:/root:/bin/bash",
78
+ "daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin",
79
+ "www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin",
80
+ "nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin",
81
+ ];
82
+ let uid = 1000;
83
+ for (const u of userList) {
84
+ if (u === "root")
85
+ continue;
86
+ passwdLines.push(`${u}:x:${uid}:${uid}::/home/${u}:/bin/bash`);
87
+ uid++;
88
+ }
89
+ vfs.writeFile("/etc/passwd", `${passwdLines.join("\n")}\n`);
90
+ const groupLines = [
91
+ "root:x:0:",
92
+ "daemon:x:1:",
93
+ `sudo:x:27:${userList.filter((u) => users.isSudoer(u)).join(",")}`,
94
+ `users:x:100:${userList.filter((u) => u !== "root").join(",")}`,
95
+ "nogroup:x:65534:",
96
+ ];
97
+ vfs.writeFile("/etc/group", `${groupLines.join("\n")}\n`);
98
+ // shadow — fake hashes, never real
99
+ const shadowLines = [
100
+ "root:*:19000:0:99999:7:::",
101
+ "daemon:*:19000:0:99999:7:::",
102
+ ];
103
+ for (const u of userList) {
104
+ if (u === "root")
105
+ continue;
106
+ shadowLines.push(`${u}:!:19000:0:99999:7:::`);
107
+ }
108
+ vfs.writeFile("/etc/shadow", `${shadowLines.join("\n")}\n`, { mode: 0o640 });
109
+ }
110
+ // ─── /proc ───────────────────────────────────────────────────────────────────
111
+ export function refreshProc(vfs, props, hostname, shellStartTime) {
112
+ ensureDir(vfs, "/proc");
113
+ const uptimeSec = Math.floor((Date.now() - shellStartTime) / 1000);
114
+ vfs.writeFile("/proc/uptime", `${uptimeSec}.00 ${Math.floor(uptimeSec * 0.9)}.00\n`);
115
+ const totalMemKb = Math.floor(os.totalmem() / 1024);
116
+ const freeMemKb = Math.floor(os.freemem() / 1024);
117
+ const availMemKb = Math.floor(freeMemKb * 0.95);
118
+ vfs.writeFile("/proc/meminfo", `${[
119
+ `MemTotal: ${String(totalMemKb).padStart(10)} kB`,
120
+ `MemFree: ${String(freeMemKb).padStart(10)} kB`,
121
+ `MemAvailable: ${String(availMemKb).padStart(10)} kB`,
122
+ `Buffers: ${String(Math.floor(totalMemKb * 0.02)).padStart(10)} kB`,
123
+ `Cached: ${String(Math.floor(totalMemKb * 0.15)).padStart(10)} kB`,
124
+ `SwapTotal: ${String(Math.floor(totalMemKb * 0.5)).padStart(10)} kB`,
125
+ `SwapFree: ${String(Math.floor(totalMemKb * 0.5)).padStart(10)} kB`,
126
+ ].join("\n")}\n`);
127
+ const cpus = os.cpus();
128
+ const cpuLines = [];
129
+ for (let i = 0; i < cpus.length; i++) {
130
+ const c = cpus[i];
131
+ if (!c)
132
+ continue;
133
+ const mhz = (c.speed).toFixed(3);
134
+ cpuLines.push(`processor\t: ${i}`, `model name\t: ${c.model}`, `cpu MHz\t\t: ${mhz}`, `cache size\t: 8192 KB`, "");
135
+ }
136
+ vfs.writeFile("/proc/cpuinfo", `${cpuLines.join("\n")}\n`);
137
+ vfs.writeFile("/proc/version", `Linux version ${props.kernel} (fortune@build) (gcc version 12.2.0) #1 SMP\n`);
138
+ vfs.writeFile("/proc/hostname", `${hostname}\n`);
139
+ // /proc/loadavg
140
+ const load = (Math.random() * 0.5).toFixed(2);
141
+ vfs.writeFile("/proc/loadavg", `${load} ${load} ${load} 1/1 1\n`);
142
+ // /proc/net stubs
143
+ ensureDir(vfs, "/proc/net");
144
+ ensureFile(vfs, "/proc/net/dev", `${[
145
+ "Inter-| Receive | Transmit",
146
+ " face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed",
147
+ " lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
148
+ " eth0: 131072 1024 0 0 0 0 0 0 65536 512 0 0 0 0 0 0",
149
+ ].join("\n")}\n`);
150
+ }
151
+ // ─── /sys ─────────────────────────────────────────────────────────────────────
152
+ function bootstrapSys(vfs, props) {
153
+ ensureDir(vfs, "/sys");
154
+ ensureDir(vfs, "/sys/devices");
155
+ ensureDir(vfs, "/sys/devices/virtual");
156
+ ensureDir(vfs, "/sys/devices/virtual/dmi");
157
+ ensureDir(vfs, "/sys/devices/virtual/dmi/id");
158
+ ensureFile(vfs, "/sys/devices/virtual/dmi/id/sys_vendor", "Fortune Systems\n");
159
+ ensureFile(vfs, "/sys/devices/virtual/dmi/id/product_name", "VirtualContainer v1\n");
160
+ ensureFile(vfs, "/sys/devices/virtual/dmi/id/board_name", "fortune-board\n");
161
+ ensureDir(vfs, "/sys/class");
162
+ ensureDir(vfs, "/sys/class/net");
163
+ ensureDir(vfs, "/sys/kernel");
164
+ ensureFile(vfs, "/sys/kernel/hostname", "fortune-vm\n");
165
+ ensureFile(vfs, "/sys/kernel/osrelease", `${props.kernel}\n`);
166
+ ensureFile(vfs, "/sys/kernel/ostype", "Linux\n");
167
+ }
168
+ // ─── /dev ─────────────────────────────────────────────────────────────────────
169
+ function bootstrapDev(vfs) {
170
+ ensureDir(vfs, "/dev");
171
+ ensureFile(vfs, "/dev/null", "", 0o666);
172
+ ensureFile(vfs, "/dev/zero", "", 0o666);
173
+ ensureFile(vfs, "/dev/random", "", 0o444);
174
+ ensureFile(vfs, "/dev/urandom", "", 0o444);
175
+ ensureDir(vfs, "/dev/pts");
176
+ ensureDir(vfs, "/dev/shm");
177
+ }
178
+ // ─── /usr ─────────────────────────────────────────────────────────────────────
179
+ function bootstrapUsr(vfs) {
180
+ ensureDir(vfs, "/usr");
181
+ ensureDir(vfs, "/usr/bin");
182
+ ensureDir(vfs, "/usr/sbin");
183
+ ensureDir(vfs, "/usr/local");
184
+ ensureDir(vfs, "/usr/local/bin");
185
+ ensureDir(vfs, "/usr/local/lib");
186
+ ensureDir(vfs, "/usr/local/share");
187
+ ensureDir(vfs, "/usr/share");
188
+ ensureDir(vfs, "/usr/share/doc");
189
+ ensureDir(vfs, "/usr/share/man");
190
+ ensureDir(vfs, "/usr/share/man/man1");
191
+ ensureDir(vfs, "/usr/lib");
192
+ // Stub binaries so `which` can find built-in commands
193
+ const builtins = [
194
+ "sh", "bash", "ls", "cat", "echo", "grep", "find", "sort",
195
+ "head", "tail", "cut", "tr", "sed", "awk", "wc", "tee",
196
+ "tar", "gzip", "gunzip", "touch", "mkdir", "rm", "mv", "cp",
197
+ "chmod", "ln", "pwd", "env", "date", "sleep", "id", "whoami",
198
+ "hostname", "uname", "ps", "kill", "df", "du", "curl", "wget",
199
+ "nano", "diff", "uniq", "xargs", "base64",
200
+ ];
201
+ for (const bin of builtins) {
202
+ ensureFile(vfs, `/usr/bin/${bin}`, `#!/bin/sh\nexec builtin ${bin} "$@"\n`, 0o755);
203
+ }
204
+ // lsb_release script
205
+ ensureFile(vfs, "/usr/bin/lsb_release", "#!/bin/sh\nexec lsb_release \"$@\"\n", 0o755);
206
+ }
207
+ // ─── /var ─────────────────────────────────────────────────────────────────────
208
+ function bootstrapVar(vfs) {
209
+ ensureDir(vfs, "/var");
210
+ ensureDir(vfs, "/var/log");
211
+ ensureDir(vfs, "/var/tmp");
212
+ ensureDir(vfs, "/var/run");
213
+ ensureDir(vfs, "/var/cache");
214
+ ensureDir(vfs, "/var/cache/apt");
215
+ ensureDir(vfs, "/var/cache/apt/archives");
216
+ ensureDir(vfs, "/var/lib");
217
+ ensureDir(vfs, "/var/lib/apt");
218
+ ensureDir(vfs, "/var/lib/apt/lists");
219
+ ensureDir(vfs, "/var/lib/dpkg");
220
+ ensureDir(vfs, "/var/lib/dpkg/info");
221
+ // dpkg status — starts empty, apt install populates it
222
+ ensureFile(vfs, "/var/lib/dpkg/status", "");
223
+ ensureFile(vfs, "/var/lib/dpkg/available", "");
224
+ // syslog stub
225
+ ensureFile(vfs, "/var/log/syslog", `${new Date().toUTCString()} fortune kernel: Virtual container started\n`);
226
+ ensureFile(vfs, "/var/log/auth.log", "");
227
+ ensureFile(vfs, "/var/log/dpkg.log", "");
228
+ ensureFile(vfs, "/var/log/apt/history.log", "");
229
+ ensureFile(vfs, "/var/log/apt/term.log", "");
230
+ }
231
+ // ─── /bin + /sbin symlinks ────────────────────────────────────────────────────
232
+ function bootstrapBin(vfs) {
233
+ // On modern Debian/Ubuntu /bin is a symlink to /usr/bin
234
+ if (!vfs.exists("/bin")) {
235
+ vfs.symlink("/usr/bin", "/bin");
236
+ }
237
+ if (!vfs.exists("/sbin")) {
238
+ vfs.symlink("/usr/sbin", "/sbin");
239
+ }
240
+ if (!vfs.exists("/lib")) {
241
+ ensureDir(vfs, "/lib");
242
+ }
243
+ if (!vfs.exists("/lib64")) {
244
+ ensureDir(vfs, "/lib64");
245
+ }
246
+ }
247
+ // ─── /tmp ─────────────────────────────────────────────────────────────────────
248
+ function bootstrapTmp(vfs) {
249
+ ensureDir(vfs, "/tmp", 0o1777);
250
+ }
251
+ // ─── /root ────────────────────────────────────────────────────────────────────
252
+ function bootstrapRoot(vfs) {
253
+ ensureDir(vfs, "/root", 0o700);
254
+ ensureFile(vfs, "/root/.bashrc", `${[
255
+ "# root .bashrc",
256
+ "export PS1='\\[\\033[0;31m\\]\\u@\\h\\[\\033[0m\\]:\\[\\033[0;34m\\]\\w\\[\\033[0m\\]# '",
257
+ "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
258
+ "alias ll='ls -la'",
259
+ "alias la='ls -A'",
260
+ ].join("\n")}\n`);
261
+ ensureFile(vfs, "/root/.profile", "[ -f ~/.bashrc ] && . ~/.bashrc\n");
262
+ // Fix: /home/root should map to /root for root user
263
+ if (!vfs.exists("/home/root")) {
264
+ vfs.symlink("/root", "/home/root");
265
+ }
266
+ }
267
+ // ─── /opt + /srv + /mnt + /media ─────────────────────────────────────────────
268
+ function bootstrapMisc(vfs) {
269
+ ensureDir(vfs, "/opt");
270
+ ensureDir(vfs, "/srv");
271
+ ensureDir(vfs, "/mnt");
272
+ ensureDir(vfs, "/media");
273
+ }
274
+ // ─── main entry point ─────────────────────────────────────────────────────────
275
+ /**
276
+ * Bootstraps the full Linux rootfs hierarchy in the VFS.
277
+ * Safe to call multiple times — idempotent.
278
+ *
279
+ * @param vfs Target virtual filesystem.
280
+ * @param users User manager (for /etc/passwd sync).
281
+ * @param hostname Virtual hostname.
282
+ * @param props Shell properties (kernel, os, arch).
283
+ * @param shellStartTime Unix ms of shell creation (for uptime).
284
+ */
285
+ export function bootstrapLinuxRootfs(vfs, users, hostname, props, shellStartTime) {
286
+ bootstrapEtc(vfs, hostname, props);
287
+ bootstrapSys(vfs, props);
288
+ bootstrapDev(vfs);
289
+ bootstrapUsr(vfs);
290
+ bootstrapVar(vfs);
291
+ bootstrapBin(vfs);
292
+ bootstrapTmp(vfs);
293
+ bootstrapRoot(vfs);
294
+ bootstrapMisc(vfs);
295
+ refreshProc(vfs, props, hostname, shellStartTime);
296
+ syncEtcPasswd(vfs, users);
297
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"neofetch.d.ts","sourceRoot":"","sources":["../../src/modules/neofetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAsGvD,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAkKD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA0E9D"}
1
+ {"version":3,"file":"neofetch.d.ts","sourceRoot":"","sources":["../../src/modules/neofetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAsGvD,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAkKD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA2E9D"}
@@ -255,6 +255,7 @@ export function buildNeofetchOutput(info) {
255
255
  `Kernel: ${fields.kernel}`,
256
256
  `Uptime: ${uptime}`,
257
257
  // `Packages: ${fields.packages}`,
258
+ `Packages: ${fields.packages}`,
258
259
  `Shell: ${fields.shell}`,
259
260
  // `Shell Props: ${fields.shellProps}`,
260
261
  `Resolution: ${fields.resolution}`,
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
7
- "version": "1.2.8",
7
+ "version": "1.2.9",
8
8
  "license": "MIT",
9
9
  "repository": {
10
10
  "type": "git",
@@ -25,6 +25,7 @@
25
25
  "lint": "bunx --bun @biomejs/biome lint ./src",
26
26
  "lint:write": "bunx --bun @biomejs/biome lint --write ./src",
27
27
  "test": "bunx --bun @biomejs/biome test ./src",
28
+ "test-battery": "bun test tests/",
28
29
  "build": "tsc --project tsconfig.json",
29
30
  "deploy:npm": "npm publish --access public",
30
31
  "bench": "rm -rf .benchmark-shells/ && bun benchmark-virtualshell.ts",
@@ -1,4 +1,4 @@
1
- import { runCommand as runSingleCommand } from "../commands";
1
+ import { runCommandDirect } from "../commands";
2
2
  import { resolvePath } from "../commands/helpers";
3
3
  import type { CommandMode, CommandResult, ShellEnv } from "../types/commands";
4
4
  import type { Pipeline, PipelineCommand, Script, Statement } from "../types/pipeline";
@@ -117,8 +117,7 @@ async function executeSingleCommandWithRedirections(
117
117
  catch { return { stderr: `${cmd.inputFile}: No such file or directory`, exitCode: 1 }; }
118
118
  }
119
119
 
120
- const rawInput = [cmd.name, ...cmd.args].join(" ");
121
- const result = await runSingleCommand(rawInput, authUser, hostname, mode, cwd, shell, stdin, env);
120
+ const result = await runCommandDirect(cmd.name, cmd.args, authUser, hostname, mode, cwd, shell, stdin, env);
122
121
 
123
122
  if (cmd.outputFile) {
124
123
  const outputPath = resolvePath(cwd, cmd.outputFile);
@@ -160,8 +159,7 @@ async function executePipelineChain(
160
159
  catch { return { stderr: `${cmd.inputFile}: No such file or directory`, exitCode: 1 }; }
161
160
  }
162
161
 
163
- const rawInput = [cmd.name, ...cmd.args].join(" ");
164
- const result = await runSingleCommand(rawInput, authUser, hostname, mode, cwd, shell, currentOutput, env);
162
+ const result = await runCommandDirect(cmd.name, cmd.args, authUser, hostname, mode, cwd, shell, currentOutput, env);
165
163
  exitCode = result.exitCode ?? 0;
166
164
 
167
165
  if (i === commands.length - 1 && cmd.outputFile) {