typescript-virtual-container 1.3.4 → 1.4.1

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 (368) hide show
  1. package/.vscode/settings.json +0 -1
  2. package/README.md +674 -1504
  3. package/benchmark-results.txt +21 -21
  4. package/builds/self-standalone.js +282 -332
  5. package/builds/self-standalone.js.map +4 -4
  6. package/builds/standalone-wo-sftp.js +218 -282
  7. package/builds/standalone-wo-sftp.js.map +4 -4
  8. package/builds/standalone.js +271 -335
  9. package/builds/standalone.js.map +4 -4
  10. package/builds/web-full-api.min.js +3 -3
  11. package/builds/web-full-api.min.js.map +4 -4
  12. package/builds/web.min.js +2 -2
  13. package/builds/web.min.js.map +4 -4
  14. package/bun.lock +14 -12
  15. package/dist/SSHClient/index.d.ts.map +1 -1
  16. package/dist/SSHClient/index.js +5 -3
  17. package/dist/SSHMimic/executor.d.ts +1 -3
  18. package/dist/SSHMimic/executor.d.ts.map +1 -1
  19. package/dist/SSHMimic/executor.js +20 -22
  20. package/dist/SSHMimic/index.d.ts.map +1 -1
  21. package/dist/SSHMimic/index.js +5 -3
  22. package/dist/SSHMimic/sftp.d.ts.map +1 -1
  23. package/dist/SSHMimic/sftp.js +26 -21
  24. package/dist/VirtualPackageManager/index.d.ts.map +1 -1
  25. package/dist/VirtualPackageManager/index.js +29 -1
  26. package/dist/VirtualShell/shell.d.ts.map +1 -1
  27. package/dist/VirtualShell/shell.js +25 -3
  28. package/dist/VirtualShell/shellParser.d.ts +1 -8
  29. package/dist/VirtualShell/shellParser.d.ts.map +1 -1
  30. package/dist/VirtualShell/shellParser.js +2 -81
  31. package/dist/VirtualUserManager/index.d.ts +7 -1
  32. package/dist/VirtualUserManager/index.d.ts.map +1 -1
  33. package/dist/VirtualUserManager/index.js +47 -16
  34. package/dist/commands/adduser.d.ts +10 -4
  35. package/dist/commands/adduser.d.ts.map +1 -1
  36. package/dist/commands/adduser.js +75 -12
  37. package/dist/commands/alias.d.ts +5 -0
  38. package/dist/commands/alias.d.ts.map +1 -1
  39. package/dist/commands/alias.js +5 -0
  40. package/dist/commands/apt.d.ts +5 -0
  41. package/dist/commands/apt.d.ts.map +1 -1
  42. package/dist/commands/apt.js +5 -0
  43. package/dist/commands/awk.d.ts +10 -8
  44. package/dist/commands/awk.d.ts.map +1 -1
  45. package/dist/commands/awk.js +156 -28
  46. package/dist/commands/cd.d.ts.map +1 -1
  47. package/dist/commands/cd.js +0 -3
  48. package/dist/commands/clear.d.ts +5 -0
  49. package/dist/commands/clear.d.ts.map +1 -1
  50. package/dist/commands/clear.js +5 -0
  51. package/dist/commands/command-helpers.d.ts.map +1 -1
  52. package/dist/commands/command-helpers.js +8 -0
  53. package/dist/commands/curl.d.ts.map +1 -1
  54. package/dist/commands/curl.js +2 -1
  55. package/dist/commands/declare.d.ts +5 -0
  56. package/dist/commands/declare.d.ts.map +1 -1
  57. package/dist/commands/declare.js +5 -0
  58. package/dist/commands/deluser.d.ts +12 -0
  59. package/dist/commands/deluser.d.ts.map +1 -1
  60. package/dist/commands/deluser.js +72 -6
  61. package/dist/commands/df.d.ts +5 -0
  62. package/dist/commands/df.d.ts.map +1 -1
  63. package/dist/commands/df.js +5 -0
  64. package/dist/commands/du.d.ts +5 -0
  65. package/dist/commands/du.d.ts.map +1 -1
  66. package/dist/commands/du.js +5 -0
  67. package/dist/commands/export.d.ts +5 -0
  68. package/dist/commands/export.d.ts.map +1 -1
  69. package/dist/commands/export.js +5 -0
  70. package/dist/commands/grep.d.ts.map +1 -1
  71. package/dist/commands/grep.js +22 -4
  72. package/dist/commands/groups.d.ts +5 -0
  73. package/dist/commands/groups.d.ts.map +1 -1
  74. package/dist/commands/groups.js +5 -0
  75. package/dist/commands/gzip.d.ts +5 -2
  76. package/dist/commands/gzip.d.ts.map +1 -1
  77. package/dist/commands/gzip.js +54 -28
  78. package/dist/commands/head.d.ts.map +1 -1
  79. package/dist/commands/head.js +12 -3
  80. package/dist/commands/htop.d.ts +5 -0
  81. package/dist/commands/htop.d.ts.map +1 -1
  82. package/dist/commands/htop.js +5 -0
  83. package/dist/commands/kill.d.ts +5 -0
  84. package/dist/commands/kill.d.ts.map +1 -1
  85. package/dist/commands/kill.js +5 -0
  86. package/dist/commands/ln.d.ts +2 -0
  87. package/dist/commands/ln.d.ts.map +1 -1
  88. package/dist/commands/ln.js +22 -0
  89. package/dist/commands/ls.d.ts.map +1 -1
  90. package/dist/commands/ls.js +15 -0
  91. package/dist/commands/lsb-release.d.ts +5 -0
  92. package/dist/commands/lsb-release.d.ts.map +1 -1
  93. package/dist/commands/lsb-release.js +5 -0
  94. package/dist/commands/man.d.ts.map +1 -1
  95. package/dist/commands/man.js +30 -136
  96. package/dist/commands/mkdir.d.ts +5 -0
  97. package/dist/commands/mkdir.d.ts.map +1 -1
  98. package/dist/commands/mkdir.js +5 -0
  99. package/dist/commands/mv.d.ts +5 -0
  100. package/dist/commands/mv.d.ts.map +1 -1
  101. package/dist/commands/mv.js +5 -0
  102. package/dist/commands/nano.d.ts +5 -0
  103. package/dist/commands/nano.d.ts.map +1 -1
  104. package/dist/commands/nano.js +5 -0
  105. package/dist/commands/neofetch.d.ts +5 -0
  106. package/dist/commands/neofetch.d.ts.map +1 -1
  107. package/dist/commands/neofetch.js +14 -5
  108. package/dist/commands/passwd.d.ts +8 -0
  109. package/dist/commands/passwd.d.ts.map +1 -1
  110. package/dist/commands/passwd.js +32 -11
  111. package/dist/commands/ping.d.ts +5 -0
  112. package/dist/commands/ping.d.ts.map +1 -1
  113. package/dist/commands/ping.js +5 -0
  114. package/dist/commands/printf.d.ts +5 -0
  115. package/dist/commands/printf.d.ts.map +1 -1
  116. package/dist/commands/printf.js +43 -12
  117. package/dist/commands/ps.d.ts +5 -0
  118. package/dist/commands/ps.d.ts.map +1 -1
  119. package/dist/commands/ps.js +5 -0
  120. package/dist/commands/read.d.ts +5 -0
  121. package/dist/commands/read.d.ts.map +1 -1
  122. package/dist/commands/read.js +5 -0
  123. package/dist/commands/registry.d.ts.map +1 -1
  124. package/dist/commands/registry.js +4 -1
  125. package/dist/commands/rm.d.ts +5 -0
  126. package/dist/commands/rm.d.ts.map +1 -1
  127. package/dist/commands/rm.js +5 -0
  128. package/dist/commands/runtime.d.ts.map +1 -1
  129. package/dist/commands/runtime.js +1 -57
  130. package/dist/commands/sed.d.ts +5 -0
  131. package/dist/commands/sed.d.ts.map +1 -1
  132. package/dist/commands/sed.js +5 -0
  133. package/dist/commands/set.d.ts +5 -6
  134. package/dist/commands/set.d.ts.map +1 -1
  135. package/dist/commands/set.js +5 -22
  136. package/dist/commands/sh.d.ts +6 -0
  137. package/dist/commands/sh.d.ts.map +1 -1
  138. package/dist/commands/sh.js +6 -0
  139. package/dist/commands/shift.d.ts +10 -0
  140. package/dist/commands/shift.d.ts.map +1 -1
  141. package/dist/commands/shift.js +10 -0
  142. package/dist/commands/sleep.d.ts +5 -0
  143. package/dist/commands/sleep.d.ts.map +1 -1
  144. package/dist/commands/sleep.js +5 -0
  145. package/dist/commands/sort.d.ts +5 -0
  146. package/dist/commands/sort.d.ts.map +1 -1
  147. package/dist/commands/sort.js +5 -0
  148. package/dist/commands/source.d.ts +5 -0
  149. package/dist/commands/source.d.ts.map +1 -1
  150. package/dist/commands/source.js +5 -0
  151. package/dist/commands/stat.d.ts +7 -0
  152. package/dist/commands/stat.d.ts.map +1 -0
  153. package/dist/commands/stat.js +56 -0
  154. package/dist/commands/su.d.ts +13 -0
  155. package/dist/commands/su.d.ts.map +1 -1
  156. package/dist/commands/su.js +45 -14
  157. package/dist/commands/sudo.d.ts.map +1 -1
  158. package/dist/commands/sudo.js +5 -0
  159. package/dist/commands/tail.d.ts +5 -0
  160. package/dist/commands/tail.d.ts.map +1 -1
  161. package/dist/commands/tail.js +15 -3
  162. package/dist/commands/tar.d.ts +5 -0
  163. package/dist/commands/tar.d.ts.map +1 -1
  164. package/dist/commands/tar.js +40 -10
  165. package/dist/commands/tee.d.ts +5 -0
  166. package/dist/commands/tee.d.ts.map +1 -1
  167. package/dist/commands/tee.js +5 -0
  168. package/dist/commands/touch.d.ts +5 -0
  169. package/dist/commands/touch.d.ts.map +1 -1
  170. package/dist/commands/touch.js +5 -0
  171. package/dist/commands/tr.d.ts.map +1 -1
  172. package/dist/commands/tr.js +45 -10
  173. package/dist/commands/tree.d.ts +5 -0
  174. package/dist/commands/tree.d.ts.map +1 -1
  175. package/dist/commands/tree.js +5 -0
  176. package/dist/commands/true.d.ts +10 -0
  177. package/dist/commands/true.d.ts.map +1 -1
  178. package/dist/commands/true.js +10 -0
  179. package/dist/commands/type.d.ts +5 -0
  180. package/dist/commands/type.d.ts.map +1 -1
  181. package/dist/commands/type.js +5 -0
  182. package/dist/commands/uname.d.ts +5 -0
  183. package/dist/commands/uname.d.ts.map +1 -1
  184. package/dist/commands/uname.js +5 -0
  185. package/dist/commands/uniq.d.ts +5 -0
  186. package/dist/commands/uniq.d.ts.map +1 -1
  187. package/dist/commands/uniq.js +5 -0
  188. package/dist/commands/unset.d.ts +5 -0
  189. package/dist/commands/unset.d.ts.map +1 -1
  190. package/dist/commands/unset.js +5 -0
  191. package/dist/commands/uptime.d.ts +5 -0
  192. package/dist/commands/uptime.d.ts.map +1 -1
  193. package/dist/commands/uptime.js +5 -0
  194. package/dist/commands/wc.d.ts +5 -0
  195. package/dist/commands/wc.d.ts.map +1 -1
  196. package/dist/commands/wc.js +5 -0
  197. package/dist/commands/wget.d.ts +5 -0
  198. package/dist/commands/wget.d.ts.map +1 -1
  199. package/dist/commands/wget.js +16 -1
  200. package/dist/commands/who.d.ts +5 -0
  201. package/dist/commands/who.d.ts.map +1 -1
  202. package/dist/commands/who.js +5 -0
  203. package/dist/commands/whoami.d.ts +5 -0
  204. package/dist/commands/whoami.d.ts.map +1 -1
  205. package/dist/commands/whoami.js +5 -0
  206. package/dist/commands/xargs.d.ts +5 -0
  207. package/dist/commands/xargs.d.ts.map +1 -1
  208. package/dist/commands/xargs.js +5 -0
  209. package/dist/self-standalone.js +254 -30
  210. package/dist/types/commands.d.ts +36 -0
  211. package/dist/types/commands.d.ts.map +1 -1
  212. package/dist/utils/tokenize.d.ts +20 -0
  213. package/dist/utils/tokenize.d.ts.map +1 -0
  214. package/dist/utils/tokenize.js +74 -0
  215. package/examples/web.min.js +2 -2
  216. package/package.json +2 -2
  217. package/src/SSHClient/index.ts +6 -3
  218. package/src/SSHMimic/executor.ts +21 -44
  219. package/src/SSHMimic/index.ts +7 -5
  220. package/src/SSHMimic/sftp.ts +28 -21
  221. package/src/VirtualPackageManager/index.ts +29 -1
  222. package/src/VirtualShell/shell.ts +34 -4
  223. package/src/VirtualShell/shellParser.ts +2 -103
  224. package/src/VirtualUserManager/index.ts +43 -19
  225. package/src/commands/adduser.ts +86 -13
  226. package/src/commands/alias.ts +5 -0
  227. package/src/commands/apt.ts +5 -0
  228. package/src/commands/awk.ts +154 -29
  229. package/src/commands/cd.ts +0 -4
  230. package/src/commands/clear.ts +5 -0
  231. package/src/commands/command-helpers.ts +9 -0
  232. package/src/commands/curl.ts +2 -1
  233. package/src/commands/declare.ts +5 -0
  234. package/src/commands/deluser.ts +84 -7
  235. package/src/commands/df.ts +5 -0
  236. package/src/commands/du.ts +5 -0
  237. package/src/commands/export.ts +5 -0
  238. package/src/commands/grep.ts +21 -8
  239. package/src/commands/groups.ts +5 -0
  240. package/src/commands/gzip.ts +61 -28
  241. package/src/commands/head.ts +14 -4
  242. package/src/commands/htop.ts +5 -0
  243. package/src/commands/kill.ts +5 -0
  244. package/src/commands/ln.ts +22 -0
  245. package/src/commands/ls.ts +17 -0
  246. package/src/commands/lsb-release.ts +5 -0
  247. package/src/commands/man.ts +38 -143
  248. package/src/commands/manuals/adduser.txt +11 -0
  249. package/src/commands/manuals/apt-cache.txt +12 -0
  250. package/src/commands/manuals/apt.txt +20 -0
  251. package/src/commands/manuals/awk.txt +13 -0
  252. package/src/commands/manuals/cat.txt +14 -0
  253. package/src/commands/manuals/cd.txt +16 -0
  254. package/src/commands/manuals/chmod.txt +16 -0
  255. package/src/commands/manuals/clear.txt +10 -0
  256. package/src/commands/manuals/cp.txt +10 -0
  257. package/src/commands/manuals/curl.txt +20 -0
  258. package/src/commands/manuals/date.txt +14 -0
  259. package/src/commands/manuals/declare.txt +12 -0
  260. package/src/commands/manuals/deluser.txt +10 -0
  261. package/src/commands/manuals/df.txt +10 -0
  262. package/src/commands/manuals/dpkg-query.txt +11 -0
  263. package/src/commands/manuals/dpkg.txt +14 -0
  264. package/src/commands/manuals/du.txt +11 -0
  265. package/src/commands/manuals/echo.txt +11 -0
  266. package/src/commands/manuals/false.txt +10 -0
  267. package/src/commands/manuals/find.txt +11 -0
  268. package/src/commands/manuals/free.txt +12 -0
  269. package/src/commands/manuals/grep.txt +13 -0
  270. package/src/commands/manuals/groups.txt +10 -0
  271. package/src/commands/manuals/gzip.txt +11 -0
  272. package/src/commands/manuals/head.txt +10 -0
  273. package/src/commands/manuals/help.txt +11 -0
  274. package/src/commands/manuals/history.txt +11 -0
  275. package/src/commands/manuals/hostname.txt +10 -0
  276. package/src/commands/manuals/id.txt +10 -0
  277. package/src/commands/manuals/kill.txt +13 -0
  278. package/src/commands/manuals/ls.txt +20 -0
  279. package/src/commands/manuals/lsb_release.txt +14 -0
  280. package/src/commands/manuals/mkdir.txt +10 -0
  281. package/src/commands/manuals/mv.txt +10 -0
  282. package/src/commands/manuals/nano.txt +11 -0
  283. package/src/commands/manuals/neofetch.txt +10 -0
  284. package/src/commands/manuals/node.txt +13 -0
  285. package/src/commands/manuals/npm.txt +13 -0
  286. package/src/commands/manuals/npx.txt +13 -0
  287. package/src/commands/manuals/passwd.txt +11 -0
  288. package/src/commands/manuals/ping.txt +10 -0
  289. package/src/commands/manuals/printf.txt +11 -0
  290. package/src/commands/manuals/ps.txt +10 -0
  291. package/src/commands/manuals/pwd.txt +10 -0
  292. package/src/commands/manuals/python3.txt +13 -0
  293. package/src/commands/manuals/readlink.txt +10 -0
  294. package/src/commands/manuals/return.txt +10 -0
  295. package/src/commands/manuals/rm.txt +10 -0
  296. package/src/commands/manuals/sed.txt +11 -0
  297. package/src/commands/manuals/set.txt +11 -0
  298. package/src/commands/manuals/shift.txt +10 -0
  299. package/src/commands/manuals/sleep.txt +10 -0
  300. package/src/commands/manuals/sort.txt +12 -0
  301. package/src/commands/manuals/source.txt +11 -0
  302. package/src/commands/manuals/ssh.txt +11 -0
  303. package/src/commands/manuals/stat.txt +10 -0
  304. package/src/commands/manuals/su.txt +13 -0
  305. package/src/commands/manuals/sudo.txt +11 -0
  306. package/src/commands/manuals/tail.txt +10 -0
  307. package/src/commands/manuals/tar.txt +19 -0
  308. package/src/commands/manuals/tee.txt +10 -0
  309. package/src/commands/manuals/test.txt +11 -0
  310. package/src/commands/manuals/touch.txt +11 -0
  311. package/src/commands/manuals/tr.txt +10 -0
  312. package/src/commands/manuals/trap.txt +10 -0
  313. package/src/commands/manuals/true.txt +10 -0
  314. package/src/commands/manuals/type.txt +10 -0
  315. package/src/commands/manuals/uname.txt +12 -0
  316. package/src/commands/manuals/uniq.txt +12 -0
  317. package/src/commands/manuals/unset.txt +10 -0
  318. package/src/commands/manuals/uptime.txt +11 -0
  319. package/src/commands/manuals/wc.txt +12 -0
  320. package/src/commands/manuals/wget.txt +12 -0
  321. package/src/commands/manuals/which.txt +10 -0
  322. package/src/commands/manuals/whoami.txt +10 -0
  323. package/src/commands/manuals/xargs.txt +10 -0
  324. package/src/commands/mkdir.ts +5 -0
  325. package/src/commands/mv.ts +5 -0
  326. package/src/commands/nano.ts +5 -0
  327. package/src/commands/neofetch.ts +15 -6
  328. package/src/commands/passwd.ts +35 -12
  329. package/src/commands/ping.ts +5 -0
  330. package/src/commands/printf.ts +30 -13
  331. package/src/commands/ps.ts +5 -0
  332. package/src/commands/read.ts +5 -0
  333. package/src/commands/registry.ts +4 -1
  334. package/src/commands/rm.ts +5 -0
  335. package/src/commands/runtime.ts +1 -61
  336. package/src/commands/sed.ts +5 -0
  337. package/src/commands/set.ts +5 -24
  338. package/src/commands/sh.ts +9 -3
  339. package/src/commands/shift.ts +10 -0
  340. package/src/commands/sleep.ts +5 -0
  341. package/src/commands/sort.ts +5 -0
  342. package/src/commands/source.ts +5 -0
  343. package/src/commands/stat.ts +61 -0
  344. package/src/commands/su.ts +54 -16
  345. package/src/commands/sudo.ts +5 -0
  346. package/src/commands/tail.ts +17 -3
  347. package/src/commands/tar.ts +38 -15
  348. package/src/commands/tee.ts +5 -0
  349. package/src/commands/touch.ts +5 -0
  350. package/src/commands/tr.ts +54 -10
  351. package/src/commands/tree.ts +5 -0
  352. package/src/commands/true.ts +10 -0
  353. package/src/commands/type.ts +5 -0
  354. package/src/commands/uname.ts +5 -0
  355. package/src/commands/uniq.ts +5 -0
  356. package/src/commands/unset.ts +5 -0
  357. package/src/commands/uptime.ts +5 -0
  358. package/src/commands/wc.ts +5 -0
  359. package/src/commands/wget.ts +17 -1
  360. package/src/commands/who.ts +5 -0
  361. package/src/commands/whoami.ts +5 -0
  362. package/src/commands/xargs.ts +5 -0
  363. package/src/self-standalone.ts +316 -33
  364. package/src/types/commands.ts +37 -0
  365. package/src/utils/tokenize.ts +78 -0
  366. package/tests/new-features.test.ts +2 -2
  367. package/builds/web-iife.min.js +0 -13
  368. package/builds/web-iife.min.js.map +0 -7
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Print system information (kernel name, version, machine type).
4
+ * @category system
5
+ * @params ["[-a] [-s] [-r] [-m]"]
6
+ */
2
7
  export declare const unameCommand: ShellModule;
3
8
  //# sourceMappingURL=uname.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uname.d.ts","sourceRoot":"","sources":["../../src/commands/uname.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,YAAY,EAAE,WAoB1B,CAAC"}
1
+ {"version":3,"file":"uname.d.ts","sourceRoot":"","sources":["../../src/commands/uname.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAoB1B,CAAC"}
@@ -1,4 +1,9 @@
1
1
  import { ifFlag } from "./command-helpers";
2
+ /**
3
+ * Print system information (kernel name, version, machine type).
4
+ * @category system
5
+ * @params ["[-a] [-s] [-r] [-m]"]
6
+ */
2
7
  export const unameCommand = {
3
8
  name: "uname",
4
9
  description: "Print system information",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Report or filter out repeated consecutive lines.
4
+ * @category text
5
+ * @params ["[-c] [-d] [-u] [file]"]
6
+ */
2
7
  export declare const uniqCommand: ShellModule;
3
8
  //# sourceMappingURL=uniq.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uniq.d.ts","sourceRoot":"","sources":["../../src/commands/uniq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,WA8BzB,CAAC"}
1
+ {"version":3,"file":"uniq.d.ts","sourceRoot":"","sources":["../../src/commands/uniq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,WA8BzB,CAAC"}
@@ -1,4 +1,9 @@
1
1
  import { ifFlag } from "./command-helpers";
2
+ /**
3
+ * Report or filter out repeated consecutive lines.
4
+ * @category text
5
+ * @params ["[-c] [-d] [-u] [file]"]
6
+ */
2
7
  export const uniqCommand = {
3
8
  name: "uniq",
4
9
  description: "Report or filter out repeated lines",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Remove shell variable from the environment.
4
+ * @category shell
5
+ * @params ["<VAR>"]
6
+ */
2
7
  export declare const unsetCommand: ShellModule;
3
8
  //# sourceMappingURL=unset.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"unset.d.ts","sourceRoot":"","sources":["../../src/commands/unset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,WAS1B,CAAC"}
1
+ {"version":3,"file":"unset.d.ts","sourceRoot":"","sources":["../../src/commands/unset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAS1B,CAAC"}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Remove shell variable from the environment.
3
+ * @category shell
4
+ * @params ["<VAR>"]
5
+ */
1
6
  export const unsetCommand = {
2
7
  name: "unset",
3
8
  description: "Remove shell variable",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Tell how long the system has been running.
4
+ * @category system
5
+ * @params ["[-p] [-s]"]
6
+ */
2
7
  export declare const uptimeCommand: ShellModule;
3
8
  //# sourceMappingURL=uptime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uptime.d.ts","sourceRoot":"","sources":["../../src/commands/uptime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,aAAa,EAAE,WA6C3B,CAAC"}
1
+ {"version":3,"file":"uptime.d.ts","sourceRoot":"","sources":["../../src/commands/uptime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WA6C3B,CAAC"}
@@ -1,4 +1,9 @@
1
1
  import { ifFlag } from "./command-helpers";
2
+ /**
3
+ * Tell how long the system has been running.
4
+ * @category system
5
+ * @params ["[-p] [-s]"]
6
+ */
2
7
  export const uptimeCommand = {
3
8
  name: "uptime",
4
9
  description: "Tell how long the system has been running",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Count words, lines, and/or bytes in files or stdin.
4
+ * @category text
5
+ * @params ["[-l] [-w] [-c] [file...]"]
6
+ */
2
7
  export declare const wcCommand: ShellModule;
3
8
  //# sourceMappingURL=wc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wc.d.ts","sourceRoot":"","sources":["../../src/commands/wc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,SAAS,EAAE,WA6CvB,CAAC"}
1
+ {"version":3,"file":"wc.d.ts","sourceRoot":"","sources":["../../src/commands/wc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,WA6CvB,CAAC"}
@@ -1,5 +1,10 @@
1
1
  import { ifFlag } from "./command-helpers";
2
2
  import { assertPathAccess, resolvePath } from "./helpers";
3
+ /**
4
+ * Count words, lines, and/or bytes in files or stdin.
5
+ * @category text
6
+ * @params ["[-l] [-w] [-c] [file...]"]
7
+ */
3
8
  export const wcCommand = {
4
9
  name: "wc",
5
10
  description: "Count words/lines/bytes",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Download files from the web (fetch-based implementation).
4
+ * @category network
5
+ * @params ["[options] <url>"]
6
+ */
2
7
  export declare const wgetCommand: ShellModule;
3
8
  //# sourceMappingURL=wget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../src/commands/wget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,WA+HzB,CAAC"}
1
+ {"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../src/commands/wget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,WA0IzB,CAAC"}
@@ -1,5 +1,10 @@
1
1
  import { ifFlag, parseArgs } from "./command-helpers";
2
2
  import { assertPathAccess, resolvePath, stripUrlFilename } from "./helpers";
3
+ /**
4
+ * Download files from the web (fetch-based implementation).
5
+ * @category network
6
+ * @params ["[options] <url>"]
7
+ */
3
8
  export const wgetCommand = {
4
9
  name: "wget",
5
10
  description: "File downloader (pure fetch)",
@@ -39,7 +44,17 @@ export const wgetCommand = {
39
44
  exitCode: 0,
40
45
  };
41
46
  }
42
- const url = positionals[0];
47
+ const urlWithoutProtocol = positionals[0];
48
+ if (!urlWithoutProtocol) {
49
+ return {
50
+ stderr: "wget: missing URL\nUsage: wget [OPTION]... [URL]...",
51
+ exitCode: 1,
52
+ };
53
+ }
54
+ const url = urlWithoutProtocol.startsWith("http://") ||
55
+ urlWithoutProtocol.startsWith("https://")
56
+ ? urlWithoutProtocol
57
+ : `http://${urlWithoutProtocol}`;
43
58
  if (!url)
44
59
  return {
45
60
  stderr: "wget: missing URL\nUsage: wget [OPTION]... [URL]...",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Show active user sessions.
4
+ * @category system
5
+ * @params []
6
+ */
2
7
  export declare const whoCommand: ShellModule;
3
8
  //# sourceMappingURL=who.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"who.d.ts","sourceRoot":"","sources":["../../src/commands/who.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,UAAU,EAAE,WAgBxB,CAAC"}
1
+ {"version":3,"file":"who.d.ts","sourceRoot":"","sources":["../../src/commands/who.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,WAgBxB,CAAC"}
@@ -1,4 +1,9 @@
1
1
  import { formatLoginDate } from "../SSHMimic/loginFormat";
2
+ /**
3
+ * Show active user sessions.
4
+ * @category system
5
+ * @params []
6
+ */
2
7
  export const whoCommand = {
3
8
  name: "who",
4
9
  description: "Show active sessions",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Print the current user name.
4
+ * @category system
5
+ * @params []
6
+ */
2
7
  export declare const whoamiCommand: ShellModule;
3
8
  //# sourceMappingURL=whoami.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,aAAa,EAAE,WAM3B,CAAC"}
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAM3B,CAAC"}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Print the current user name.
3
+ * @category system
4
+ * @params []
5
+ */
1
6
  export const whoamiCommand = {
2
7
  name: "whoami",
3
8
  description: "Print current user",
@@ -1,3 +1,8 @@
1
1
  import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Build and execute commands from stdin arguments.
4
+ * @category text
5
+ * @params ["[command] [args...]"]
6
+ */
2
7
  export declare const xargsCommand: ShellModule;
3
8
  //# sourceMappingURL=xargs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"xargs.d.ts","sourceRoot":"","sources":["../../src/commands/xargs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,YAAY,EAAE,WAsB1B,CAAC"}
1
+ {"version":3,"file":"xargs.d.ts","sourceRoot":"","sources":["../../src/commands/xargs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAsB1B,CAAC"}
@@ -1,4 +1,9 @@
1
1
  import { runCommand } from "./runtime";
2
+ /**
3
+ * Build and execute commands from stdin arguments.
4
+ * @category text
5
+ * @params ["[command] [args...]"]
6
+ */
2
7
  export const xargsCommand = {
3
8
  name: "xargs",
4
9
  description: "Build and execute command lines from stdin",
@@ -1,7 +1,9 @@
1
+ import { readFile, unlink, writeFile } from "node:fs/promises";
1
2
  import { basename } from "node:path";
2
3
  import { stdin, stdout } from "node:process";
3
4
  import { createInterface } from "node:readline";
4
5
  import { makeDefaultEnv, runCommand } from "./commands/runtime";
6
+ import { spawnNanoEditorProcess } from "./modules/shellInteractive";
5
7
  import { buildLoginBanner } from "./SSHMimic/loginBanner";
6
8
  import { buildPrompt } from "./SSHMimic/prompt";
7
9
  import { VirtualShell } from "./VirtualShell";
@@ -40,9 +42,50 @@ function readLastLogin(username) {
40
42
  return null;
41
43
  }
42
44
  }
43
- function askQuestion(rl, promptText) {
45
+ function askHiddenQuestion(rl, promptText) {
44
46
  return new Promise((resolve) => {
45
- rl.question(promptText, resolve);
47
+ if (!stdin.isTTY || !stdout.isTTY) {
48
+ rl.question(promptText, resolve);
49
+ return;
50
+ }
51
+ const wasRawMode = Boolean(stdin.isRaw);
52
+ let buffer = "";
53
+ const cleanup = () => {
54
+ stdin.off("data", onData);
55
+ if (!wasRawMode) {
56
+ stdin.setRawMode(false);
57
+ }
58
+ rl.resume();
59
+ };
60
+ const finish = (value) => {
61
+ cleanup();
62
+ stdout.write("\n");
63
+ resolve(value);
64
+ };
65
+ const onData = (chunk) => {
66
+ const input = chunk.toString("utf8");
67
+ for (let index = 0; index < input.length; index += 1) {
68
+ const ch = input[index];
69
+ if (ch === "\r" || ch === "\n") {
70
+ finish(buffer);
71
+ return;
72
+ }
73
+ if (ch === "\u007f" || ch === "\b") {
74
+ buffer = buffer.slice(0, -1);
75
+ continue;
76
+ }
77
+ if (ch >= " ") {
78
+ buffer += ch;
79
+ }
80
+ }
81
+ };
82
+ rl.pause();
83
+ stdout.write(promptText);
84
+ if (!wasRawMode) {
85
+ stdin.setRawMode(true);
86
+ }
87
+ stdin.resume();
88
+ stdin.on("data", onData);
46
89
  });
47
90
  }
48
91
  function writeLastLogin(username, from) {
@@ -52,6 +95,42 @@ function writeLastLogin(username, from) {
52
95
  }
53
96
  virtualShell.vfs.writeFile(`/virtual-env-js/.lastlog/${username}.json`, JSON.stringify({ at: new Date().toISOString(), from }));
54
97
  }
98
+ async function flushVfs() {
99
+ await virtualShell.vfs.flushMirror();
100
+ }
101
+ function loadHistory() {
102
+ const historyPath = "/virtual-env-js/.bash_history";
103
+ if (!virtualShell.vfs.exists(historyPath)) {
104
+ virtualShell.vfs.writeFile(historyPath, "");
105
+ return [];
106
+ }
107
+ return virtualShell.vfs
108
+ .readFile(historyPath)
109
+ .split("\n")
110
+ .map((line) => line.trim())
111
+ .filter((line) => line.length > 0);
112
+ }
113
+ function saveHistory(history) {
114
+ const data = history.length > 0 ? `${history.join("\n")}\n` : "";
115
+ virtualShell.vfs.writeFile("/virtual-env-js/.bash_history", data);
116
+ }
117
+ function applySessionState(authUserState, cwdState, result, shellEnvState) {
118
+ let authUser = authUserState;
119
+ let cwd = cwdState;
120
+ if (result.switchUser) {
121
+ authUser = result.switchUser;
122
+ cwd = result.nextCwd ?? `/home/${authUser}`;
123
+ shellEnvState.vars.USER = authUser;
124
+ shellEnvState.vars.LOGNAME = authUser;
125
+ shellEnvState.vars.HOME = `/home/${authUser}`;
126
+ shellEnvState.vars.PWD = cwd;
127
+ }
128
+ else if (result.nextCwd) {
129
+ cwd = result.nextCwd;
130
+ shellEnvState.vars.PWD = cwd;
131
+ }
132
+ return { authUser, cwd };
133
+ }
55
134
  virtualShell.addCommand("demo", [], () => {
56
135
  return {
57
136
  stdout: "This is a demo command. It does nothing useful.",
@@ -61,6 +140,9 @@ virtualShell.addCommand("demo", [], () => {
61
140
  async function runReadlineShell() {
62
141
  const rl = createInterface({ input: stdin, output: stdout, terminal: true });
63
142
  await virtualShell.ensureInitialized();
143
+ let history = loadHistory();
144
+ const rlWithHistory = rl;
145
+ rlWithHistory.history = [...history].reverse();
64
146
  const selectedUser = initialUser.trim() || "root";
65
147
  const userExists = virtualShell.users.getPasswordHash(selectedUser) !== null;
66
148
  if (!userExists) {
@@ -72,8 +154,161 @@ async function runReadlineShell() {
72
154
  let cwd = `/home/${authUser}`;
73
155
  shellEnv.vars.PWD = cwd;
74
156
  const remoteAddress = "localhost";
157
+ const terminalSize = {
158
+ cols: stdout.columns ?? 80,
159
+ rows: stdout.rows ?? 24,
160
+ };
161
+ async function startNanoEditor(targetPath, initialContent, tempPath) {
162
+ if (virtualShell.vfs.exists(targetPath)) {
163
+ await writeFile(tempPath, initialContent, "utf8");
164
+ }
165
+ rl.pause();
166
+ const editor = spawnNanoEditorProcess(tempPath, terminalSize, {
167
+ write: stdout.write.bind(stdout),
168
+ exit: () => undefined,
169
+ end: () => undefined,
170
+ });
171
+ const wasRawMode = Boolean(stdin.isRaw);
172
+ const forwardInput = (chunk) => {
173
+ editor.stdin.write(chunk);
174
+ };
175
+ stdin.resume();
176
+ if (!wasRawMode) {
177
+ stdin.setRawMode(true);
178
+ }
179
+ stdin.on("data", forwardInput);
180
+ await new Promise((resolve) => {
181
+ const cleanup = () => {
182
+ stdin.off("data", forwardInput);
183
+ if (!wasRawMode) {
184
+ stdin.setRawMode(false);
185
+ }
186
+ rl.resume();
187
+ };
188
+ editor.on("error", (error) => {
189
+ cleanup();
190
+ stdout.write(`nano: ${error.message}\r\n`);
191
+ resolve();
192
+ });
193
+ editor.on("close", async () => {
194
+ cleanup();
195
+ rl.write("", { ctrl: true, name: "u" });
196
+ try {
197
+ const updatedContent = await readFile(tempPath, "utf8");
198
+ virtualShell.writeFileAsUser(authUser, targetPath, updatedContent);
199
+ await flushVfs();
200
+ }
201
+ catch {
202
+ // Save skipped or temp file missing.
203
+ }
204
+ await unlink(tempPath).catch(() => undefined);
205
+ stdout.write("\r\n");
206
+ resolve();
207
+ });
208
+ });
209
+ }
210
+ async function handleSudoChallenge(challenge) {
211
+ if (challenge.onPassword) {
212
+ let promptText = challenge.prompt;
213
+ while (true) {
214
+ const typed = await askHiddenQuestion(rl, promptText);
215
+ const step = await challenge.onPassword(typed, virtualShell);
216
+ if (step.result === null) {
217
+ promptText = step.nextPrompt ?? promptText;
218
+ continue;
219
+ }
220
+ await handleCommandResult(step.result);
221
+ return;
222
+ }
223
+ }
224
+ const password = await askHiddenQuestion(rl, challenge.prompt);
225
+ if (!virtualShell.users.verifyPassword(challenge.username, password)) {
226
+ process.stderr.write("Sorry, try again.\n");
227
+ return;
228
+ }
229
+ if (!challenge.commandLine) {
230
+ authUser = challenge.targetUser;
231
+ cwd = `/home/${authUser}`;
232
+ shellEnv.vars.USER = authUser;
233
+ shellEnv.vars.LOGNAME = authUser;
234
+ shellEnv.vars.HOME = `/home/${authUser}`;
235
+ shellEnv.vars.PWD = cwd;
236
+ return;
237
+ }
238
+ const runCwd = challenge.loginShell ? `/home/${challenge.targetUser}` : cwd;
239
+ const nestedResult = await runCommand(challenge.commandLine, challenge.targetUser, hostname, "shell", runCwd, virtualShell, undefined, shellEnv);
240
+ await handleCommandResult(nestedResult);
241
+ }
242
+ async function handlePasswordChallenge(challenge) {
243
+ const first = await askHiddenQuestion(rl, challenge.prompt);
244
+ if (challenge.confirmPrompt) {
245
+ const second = await askHiddenQuestion(rl, challenge.confirmPrompt);
246
+ if (second !== first) {
247
+ process.stderr.write("passwords do not match\n");
248
+ return;
249
+ }
250
+ }
251
+ switch (challenge.action) {
252
+ case "passwd":
253
+ await virtualShell.users.setPassword(challenge.targetUsername, first);
254
+ stdout.write("passwd: password updated successfully\n");
255
+ break;
256
+ case "adduser":
257
+ if (!challenge.newUsername) {
258
+ process.stderr.write("adduser: missing username\n");
259
+ return;
260
+ }
261
+ await virtualShell.users.addUser(challenge.newUsername, first);
262
+ stdout.write(`adduser: user '${challenge.newUsername}' created\n`);
263
+ break;
264
+ case "deluser":
265
+ await virtualShell.users.deleteUser(challenge.targetUsername);
266
+ stdout.write(`Removing user '${challenge.targetUsername}' ...\ndeluser: done.\n`);
267
+ break;
268
+ case "su":
269
+ authUser = challenge.targetUsername;
270
+ cwd = `/home/${authUser}`;
271
+ shellEnv.vars.USER = authUser;
272
+ shellEnv.vars.LOGNAME = authUser;
273
+ shellEnv.vars.HOME = `/home/${authUser}`;
274
+ shellEnv.vars.PWD = cwd;
275
+ break;
276
+ }
277
+ }
278
+ async function handleCommandResult(result) {
279
+ if (result.openEditor) {
280
+ await startNanoEditor(result.openEditor.targetPath, result.openEditor.initialContent, result.openEditor.tempPath);
281
+ return;
282
+ }
283
+ if (result.sudoChallenge) {
284
+ await handleSudoChallenge(result.sudoChallenge);
285
+ return;
286
+ }
287
+ if (result.passwordChallenge) {
288
+ await handlePasswordChallenge(result.passwordChallenge);
289
+ return;
290
+ }
291
+ if (result.stdout) {
292
+ stdout.write(result.stdout.endsWith("\n") ? result.stdout : `${result.stdout}\n`);
293
+ }
294
+ if (result.stderr) {
295
+ process.stderr.write(result.stderr.endsWith("\n") ? result.stderr : `${result.stderr}\n`);
296
+ }
297
+ if (result.clearScreen) {
298
+ stdout.write("\u001b[2J\u001b[H");
299
+ console.clear();
300
+ }
301
+ const updatedState = applySessionState(authUser, cwd, result, shellEnv);
302
+ authUser = updatedState.authUser;
303
+ cwd = updatedState.cwd;
304
+ if (result.closeSession) {
305
+ await flushVfs();
306
+ rl.close();
307
+ process.exit(result.exitCode ?? 0);
308
+ }
309
+ }
75
310
  if (process.env.USER !== "root" && virtualShell.users.hasPassword(authUser)) {
76
- const password = await askQuestion(rl, `Password for ${authUser}: `);
311
+ const password = await askHiddenQuestion(rl, `Password for ${authUser}: `);
77
312
  if (!virtualShell.users.verifyPassword(authUser, password)) {
78
313
  process.stderr.write("self-standalone: authentication failed\n");
79
314
  process.exit(1);
@@ -93,43 +328,32 @@ async function runReadlineShell() {
93
328
  prompt();
94
329
  });
95
330
  rl.on("close", () => {
96
- console.log("");
97
- process.exit(0);
331
+ void (async () => {
332
+ await flushVfs();
333
+ console.log("");
334
+ process.exit(0);
335
+ })();
98
336
  });
99
337
  stdout.write(buildLoginBanner(hostname, virtualShell.properties, readLastLogin(authUser)));
100
338
  writeLastLogin(authUser, remoteAddress);
339
+ await flushVfs();
101
340
  prompt();
102
341
  while (true) {
103
342
  const inputLine = await new Promise((resolve) => {
104
343
  rl.once("line", (line) => resolve(line));
105
344
  });
106
345
  rl.pause();
107
- const result = await runCommand(inputLine, authUser, hostname, "shell", cwd, virtualShell, undefined, shellEnv);
108
- if (result.stdout) {
109
- stdout.write(result.stdout.endsWith("\n") ? result.stdout : `${result.stdout}\n`);
110
- }
111
- if (result.stderr) {
112
- process.stderr.write(result.stderr.endsWith("\n") ? result.stderr : `${result.stderr}\n`);
113
- }
114
- if (result.clearScreen) {
115
- stdout.write("\u001b[2J\u001b[H");
116
- }
117
- if (result.switchUser) {
118
- authUser = result.switchUser;
119
- cwd = result.nextCwd ?? `/home/${authUser}`;
120
- shellEnv.vars.USER = authUser;
121
- shellEnv.vars.LOGNAME = authUser;
122
- shellEnv.vars.HOME = `/home/${authUser}`;
123
- shellEnv.vars.PWD = cwd;
124
- }
125
- else if (result.nextCwd) {
126
- cwd = result.nextCwd;
127
- shellEnv.vars.PWD = cwd;
128
- }
129
- if (result.closeSession) {
130
- rl.close();
131
- process.exit(result.exitCode ?? 0);
346
+ if (inputLine.trim().length > 0) {
347
+ history.push(inputLine);
348
+ if (history.length > 500) {
349
+ history = history.slice(history.length - 500);
350
+ }
351
+ saveHistory(history);
352
+ rlWithHistory.history = [...history].reverse();
132
353
  }
354
+ const result = await runCommand(inputLine, authUser, hostname, "shell", cwd, virtualShell, undefined, shellEnv);
355
+ await handleCommandResult(result);
356
+ await flushVfs();
133
357
  prompt();
134
358
  rl.resume();
135
359
  }
@@ -29,6 +29,8 @@ export interface CommandResult {
29
29
  openHtop?: boolean;
30
30
  /** Request sudo password challenge flow. */
31
31
  sudoChallenge?: SudoChallenge;
32
+ /** Request a generic password challenge (adduser, passwd). */
33
+ passwordChallenge?: PasswordChallenge;
32
34
  }
33
35
  /** Deferred sudo challenge metadata returned by sudo command. */
34
36
  export interface SudoChallenge {
@@ -42,6 +44,40 @@ export interface SudoChallenge {
42
44
  loginShell: boolean;
43
45
  /** Prompt text shown before password input. */
44
46
  prompt: string;
47
+ /**
48
+ * Challenge mode.
49
+ * - `"sudo"` (default): verify `username`'s password, then run `commandLine`.
50
+ * - `"passwd"`: multi-step new-password flow; `onPassword` handles each step.
51
+ * - `"confirm"`: text confirmation flow (e.g. deluser); `onPassword` receives typed text.
52
+ */
53
+ mode?: "sudo" | "passwd" | "confirm";
54
+ /**
55
+ * Optional async handler called when the user submits input.
56
+ * Receives the typed text and the shell instance.
57
+ * Returns a `CommandResult` written to the terminal, or `null` to show
58
+ * another prompt (pass `nextPrompt` to change the prompt text).
59
+ */
60
+ onPassword?: (input: string, shell: import("../VirtualShell").VirtualShell) => Promise<{
61
+ result: CommandResult | null;
62
+ nextPrompt?: string;
63
+ }>;
64
+ }
65
+ /** Generic password challenge — used by adduser, passwd, deluser. */
66
+ export interface PasswordChallenge {
67
+ /** Lines to print before the first prompt. */
68
+ preamble?: string;
69
+ /** Primary prompt text (e.g. "New password: "). */
70
+ prompt: string;
71
+ /** If set, a second prompt is shown for confirmation. */
72
+ confirmPrompt?: string;
73
+ /** Prompt shown for a destructive confirmation (y/N). */
74
+ confirmText?: string;
75
+ /** Tag identifying what to do with the entered value. */
76
+ action: "adduser" | "passwd" | "deluser" | "su";
77
+ /** Username targeted by the action. */
78
+ targetUsername: string;
79
+ /** For adduser: the new user's username (already validated). */
80
+ newUsername?: string;
45
81
  }
46
82
  /** State payload used by nano command interactive editor flow. */
47
83
  export interface NanoEditorSession {
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/types/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/types/commands.ts"],"names":[],"mappings":"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"}