typescript-virtual-container 1.2.5 → 1.2.7

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 (248) hide show
  1. package/README.md +387 -193
  2. package/benchmark-results.txt +21 -21
  3. package/biome.json +1 -1
  4. package/bun.lock +15 -41
  5. package/dist/SSHMimic/exec.js +2 -2
  6. package/dist/SSHMimic/executor.d.ts +6 -7
  7. package/dist/SSHMimic/executor.d.ts.map +1 -1
  8. package/dist/SSHMimic/executor.js +77 -60
  9. package/dist/SSHMimic/index.d.ts.map +1 -1
  10. package/dist/SSHMimic/index.js +6 -20
  11. package/dist/SSHMimic/sftp.d.ts.map +1 -1
  12. package/dist/SSHMimic/sftp.js +14 -0
  13. package/dist/VirtualFileSystem/index.d.ts.map +1 -1
  14. package/dist/VirtualFileSystem/index.js +13 -36
  15. package/dist/VirtualShell/shell.d.ts.map +1 -1
  16. package/dist/VirtualShell/shell.js +19 -2
  17. package/dist/VirtualShell/shellParser.d.ts +20 -2
  18. package/dist/VirtualShell/shellParser.d.ts.map +1 -1
  19. package/dist/VirtualShell/shellParser.js +229 -120
  20. package/dist/VirtualUserManager/index.d.ts.map +1 -1
  21. package/dist/commands/adduser.d.ts.map +1 -1
  22. package/dist/commands/adduser.js +2 -0
  23. package/dist/commands/awk.d.ts +3 -0
  24. package/dist/commands/awk.d.ts.map +1 -0
  25. package/dist/commands/awk.js +29 -0
  26. package/dist/commands/base64.d.ts +3 -0
  27. package/dist/commands/base64.d.ts.map +1 -0
  28. package/dist/commands/base64.js +20 -0
  29. package/dist/commands/cat.d.ts.map +1 -1
  30. package/dist/commands/cat.js +2 -0
  31. package/dist/commands/cd.d.ts.map +1 -1
  32. package/dist/commands/cd.js +2 -0
  33. package/dist/commands/chmod.d.ts.map +1 -1
  34. package/dist/commands/chmod.js +2 -0
  35. package/dist/commands/clear.d.ts.map +1 -1
  36. package/dist/commands/clear.js +4 -1
  37. package/dist/commands/cp.d.ts.map +1 -1
  38. package/dist/commands/cp.js +2 -0
  39. package/dist/commands/curl.d.ts.map +1 -1
  40. package/dist/commands/curl.js +2 -0
  41. package/dist/commands/cut.d.ts +3 -0
  42. package/dist/commands/cut.d.ts.map +1 -0
  43. package/dist/commands/cut.js +27 -0
  44. package/dist/commands/date.d.ts +3 -0
  45. package/dist/commands/date.d.ts.map +1 -0
  46. package/dist/commands/date.js +22 -0
  47. package/dist/commands/deluser.d.ts.map +1 -1
  48. package/dist/commands/deluser.js +2 -0
  49. package/dist/commands/df.d.ts +3 -0
  50. package/dist/commands/df.d.ts.map +1 -0
  51. package/dist/commands/df.js +16 -0
  52. package/dist/commands/diff.d.ts +3 -0
  53. package/dist/commands/diff.d.ts.map +1 -0
  54. package/dist/commands/diff.js +40 -0
  55. package/dist/commands/du.d.ts +3 -0
  56. package/dist/commands/du.d.ts.map +1 -0
  57. package/dist/commands/du.js +39 -0
  58. package/dist/commands/echo.d.ts.map +1 -1
  59. package/dist/commands/echo.js +2 -0
  60. package/dist/commands/env.d.ts +1 -0
  61. package/dist/commands/env.d.ts.map +1 -1
  62. package/dist/commands/env.js +6 -14
  63. package/dist/commands/export.d.ts.map +1 -1
  64. package/dist/commands/export.js +11 -21
  65. package/dist/commands/find.d.ts.map +1 -1
  66. package/dist/commands/find.js +2 -0
  67. package/dist/commands/grep.d.ts.map +1 -1
  68. package/dist/commands/grep.js +4 -7
  69. package/dist/commands/groups.d.ts +3 -0
  70. package/dist/commands/groups.d.ts.map +1 -0
  71. package/dist/commands/groups.js +12 -0
  72. package/dist/commands/gzip.d.ts +4 -0
  73. package/dist/commands/gzip.d.ts.map +1 -0
  74. package/dist/commands/gzip.js +40 -0
  75. package/dist/commands/head.d.ts.map +1 -1
  76. package/dist/commands/head.js +2 -0
  77. package/dist/commands/help.d.ts +1 -1
  78. package/dist/commands/help.d.ts.map +1 -1
  79. package/dist/commands/help.js +66 -3
  80. package/dist/commands/hostname.d.ts.map +1 -1
  81. package/dist/commands/hostname.js +2 -0
  82. package/dist/commands/htop.d.ts.map +1 -1
  83. package/dist/commands/htop.js +2 -0
  84. package/dist/commands/id.d.ts +3 -0
  85. package/dist/commands/id.d.ts.map +1 -0
  86. package/dist/commands/id.js +14 -0
  87. package/dist/commands/index.d.ts +5 -2
  88. package/dist/commands/index.d.ts.map +1 -1
  89. package/dist/commands/index.js +89 -62
  90. package/dist/commands/kill.d.ts +3 -0
  91. package/dist/commands/kill.d.ts.map +1 -0
  92. package/dist/commands/kill.js +13 -0
  93. package/dist/commands/ln.d.ts.map +1 -1
  94. package/dist/commands/ln.js +2 -0
  95. package/dist/commands/ls.d.ts.map +1 -1
  96. package/dist/commands/ls.js +2 -0
  97. package/dist/commands/mkdir.d.ts.map +1 -1
  98. package/dist/commands/mkdir.js +2 -0
  99. package/dist/commands/mv.d.ts.map +1 -1
  100. package/dist/commands/mv.js +2 -0
  101. package/dist/commands/nano.d.ts.map +1 -1
  102. package/dist/commands/nano.js +2 -0
  103. package/dist/commands/neofetch.d.ts.map +1 -1
  104. package/dist/commands/neofetch.js +2 -0
  105. package/dist/commands/passwd.d.ts.map +1 -1
  106. package/dist/commands/passwd.js +2 -0
  107. package/dist/commands/ping.d.ts +3 -0
  108. package/dist/commands/ping.d.ts.map +1 -0
  109. package/dist/commands/ping.js +18 -0
  110. package/dist/commands/ps.d.ts +3 -0
  111. package/dist/commands/ps.d.ts.map +1 -0
  112. package/dist/commands/ps.js +17 -0
  113. package/dist/commands/pwd.d.ts.map +1 -1
  114. package/dist/commands/pwd.js +2 -0
  115. package/dist/commands/rm.d.ts.map +1 -1
  116. package/dist/commands/rm.js +2 -0
  117. package/dist/commands/sed.d.ts +3 -0
  118. package/dist/commands/sed.d.ts.map +1 -0
  119. package/dist/commands/sed.js +47 -0
  120. package/dist/commands/set.d.ts +3 -0
  121. package/dist/commands/set.d.ts.map +1 -1
  122. package/dist/commands/set.js +19 -46
  123. package/dist/commands/sh.d.ts +0 -1
  124. package/dist/commands/sh.d.ts.map +1 -1
  125. package/dist/commands/sh.js +229 -35
  126. package/dist/commands/sleep.d.ts +3 -0
  127. package/dist/commands/sleep.d.ts.map +1 -0
  128. package/dist/commands/sleep.js +13 -0
  129. package/dist/commands/sort.d.ts +3 -0
  130. package/dist/commands/sort.d.ts.map +1 -0
  131. package/dist/commands/sort.js +37 -0
  132. package/dist/commands/su.d.ts.map +1 -1
  133. package/dist/commands/su.js +2 -0
  134. package/dist/commands/sudo.d.ts.map +1 -1
  135. package/dist/commands/sudo.js +2 -0
  136. package/dist/commands/tail.d.ts.map +1 -1
  137. package/dist/commands/tail.js +2 -0
  138. package/dist/commands/tar.d.ts +3 -0
  139. package/dist/commands/tar.d.ts.map +1 -0
  140. package/dist/commands/tar.js +64 -0
  141. package/dist/commands/tee.d.ts +3 -0
  142. package/dist/commands/tee.d.ts.map +1 -0
  143. package/dist/commands/tee.js +29 -0
  144. package/dist/commands/touch.d.ts.map +1 -1
  145. package/dist/commands/touch.js +2 -0
  146. package/dist/commands/tr.d.ts +3 -0
  147. package/dist/commands/tr.d.ts.map +1 -0
  148. package/dist/commands/tr.js +24 -0
  149. package/dist/commands/tree.d.ts.map +1 -1
  150. package/dist/commands/tree.js +2 -0
  151. package/dist/commands/uname.d.ts +3 -0
  152. package/dist/commands/uname.d.ts.map +1 -0
  153. package/dist/commands/uname.js +21 -0
  154. package/dist/commands/uniq.d.ts +3 -0
  155. package/dist/commands/uniq.d.ts.map +1 -0
  156. package/dist/commands/uniq.js +33 -0
  157. package/dist/commands/unset.d.ts.map +1 -1
  158. package/dist/commands/unset.js +6 -10
  159. package/dist/commands/wc.d.ts.map +1 -1
  160. package/dist/commands/wc.js +2 -0
  161. package/dist/commands/wget.d.ts.map +1 -1
  162. package/dist/commands/wget.js +2 -0
  163. package/dist/commands/who.d.ts.map +1 -1
  164. package/dist/commands/who.js +2 -0
  165. package/dist/commands/whoami.d.ts.map +1 -1
  166. package/dist/commands/whoami.js +2 -0
  167. package/dist/commands/xargs.d.ts +3 -0
  168. package/dist/commands/xargs.d.ts.map +1 -0
  169. package/dist/commands/xargs.js +16 -0
  170. package/dist/types/commands.d.ts +13 -0
  171. package/dist/types/commands.d.ts.map +1 -1
  172. package/dist/types/pipeline.d.ts +20 -0
  173. package/dist/types/pipeline.d.ts.map +1 -1
  174. package/package.json +3 -3
  175. package/src/SSHMimic/exec.ts +2 -2
  176. package/src/SSHMimic/executor.ts +95 -98
  177. package/src/SSHMimic/index.ts +15 -49
  178. package/src/SSHMimic/sftp.ts +15 -0
  179. package/src/VirtualFileSystem/index.ts +27 -75
  180. package/src/VirtualShell/shell.ts +19 -2
  181. package/src/VirtualShell/shellParser.ts +202 -168
  182. package/src/VirtualUserManager/index.ts +2 -7
  183. package/src/commands/adduser.ts +2 -0
  184. package/src/commands/awk.ts +30 -0
  185. package/src/commands/base64.ts +18 -0
  186. package/src/commands/cat.ts +2 -0
  187. package/src/commands/cd.ts +2 -0
  188. package/src/commands/chmod.ts +2 -0
  189. package/src/commands/clear.ts +4 -1
  190. package/src/commands/cp.ts +2 -0
  191. package/src/commands/curl.ts +2 -0
  192. package/src/commands/cut.ts +29 -0
  193. package/src/commands/date.ts +24 -0
  194. package/src/commands/deluser.ts +2 -0
  195. package/src/commands/df.ts +18 -0
  196. package/src/commands/diff.ts +29 -0
  197. package/src/commands/du.ts +39 -0
  198. package/src/commands/echo.ts +2 -0
  199. package/src/commands/env.ts +7 -16
  200. package/src/commands/export.ts +11 -24
  201. package/src/commands/find.ts +2 -0
  202. package/src/commands/grep.ts +4 -7
  203. package/src/commands/groups.ts +14 -0
  204. package/src/commands/gzip.ts +31 -0
  205. package/src/commands/head.ts +2 -0
  206. package/src/commands/help.ts +72 -3
  207. package/src/commands/hostname.ts +2 -0
  208. package/src/commands/htop.ts +2 -0
  209. package/src/commands/id.ts +16 -0
  210. package/src/commands/index.ts +98 -99
  211. package/src/commands/kill.ts +14 -0
  212. package/src/commands/ln.ts +2 -0
  213. package/src/commands/ls.ts +2 -0
  214. package/src/commands/mkdir.ts +2 -0
  215. package/src/commands/mv.ts +2 -0
  216. package/src/commands/nano.ts +2 -0
  217. package/src/commands/neofetch.ts +2 -0
  218. package/src/commands/passwd.ts +2 -0
  219. package/src/commands/ping.ts +20 -0
  220. package/src/commands/ps.ts +19 -0
  221. package/src/commands/pwd.ts +2 -0
  222. package/src/commands/rm.ts +2 -0
  223. package/src/commands/sed.ts +45 -0
  224. package/src/commands/set.ts +19 -50
  225. package/src/commands/sh.ts +193 -43
  226. package/src/commands/sleep.ts +14 -0
  227. package/src/commands/sort.ts +37 -0
  228. package/src/commands/su.ts +2 -0
  229. package/src/commands/sudo.ts +2 -0
  230. package/src/commands/tail.ts +2 -0
  231. package/src/commands/tar.ts +58 -0
  232. package/src/commands/tee.ts +25 -0
  233. package/src/commands/touch.ts +2 -0
  234. package/src/commands/tr.ts +24 -0
  235. package/src/commands/tree.ts +2 -0
  236. package/src/commands/uname.ts +20 -0
  237. package/src/commands/uniq.ts +28 -0
  238. package/src/commands/unset.ts +5 -12
  239. package/src/commands/wc.ts +2 -0
  240. package/src/commands/wget.ts +2 -0
  241. package/src/commands/who.ts +2 -0
  242. package/src/commands/whoami.ts +2 -0
  243. package/src/commands/xargs.ts +17 -0
  244. package/src/types/commands.ts +14 -0
  245. package/src/types/pipeline.ts +23 -0
  246. package/standalone.js +92 -64
  247. package/standalone.js.map +4 -4
  248. package/tests/users.test.ts +5 -34
@@ -1,40 +1,40 @@
1
1
  Benchmarking VirtualShell concurrency:
2
2
 
3
3
  Running 1 shells...
4
- Initialized 1 shells in 50ms, RSS 82 MB
5
- Executed shell commands in 4ms, RSS now 83 MB (+0 MB)
4
+ Initialized 1 shells in 67ms, RSS 82 MB
5
+ Executed shell commands in 2ms, RSS now 82 MB (+0 MB)
6
6
 
7
7
  Running 2 shells...
8
- Initialized 2 shells in 2ms, RSS 83 MB
9
- Executed shell commands in 0ms, RSS now 83 MB (+0 MB)
8
+ Initialized 2 shells in 2ms, RSS 82 MB
9
+ Executed shell commands in 0ms, RSS now 82 MB (+0 MB)
10
10
 
11
11
  Running 5 shells...
12
- Initialized 5 shells in 3ms, RSS 83 MB
13
- Executed shell commands in 1ms, RSS now 83 MB (+0 MB)
12
+ Initialized 5 shells in 1ms, RSS 82 MB
13
+ Executed shell commands in 1ms, RSS now 82 MB (+0 MB)
14
14
 
15
15
  Running 10 shells...
16
16
  Initialized 10 shells in 4ms, RSS 83 MB
17
- Executed shell commands in 4ms, RSS now 84 MB (+1 MB)
17
+ Executed shell commands in 3ms, RSS now 84 MB (+0 MB)
18
18
 
19
19
  Running 20 shells...
20
- Initialized 20 shells in 7ms, RSS 84 MB
21
- Executed shell commands in 5ms, RSS now 85 MB (+0 MB)
20
+ Initialized 20 shells in 5ms, RSS 84 MB
21
+ Executed shell commands in 3ms, RSS now 86 MB (+1 MB)
22
22
 
23
23
  Running 50 shells...
24
- Initialized 50 shells in 23ms, RSS 85 MB
25
- Executed shell commands in 12ms, RSS now 87 MB (+2 MB)
24
+ Initialized 50 shells in 10ms, RSS 88 MB
25
+ Executed shell commands in 7ms, RSS now 89 MB (+1 MB)
26
26
 
27
27
  Running 100 shells...
28
- Initialized 100 shells in 36ms, RSS 89 MB
29
- Executed shell commands in 33ms, RSS now 91 MB (+2 MB)
28
+ Initialized 100 shells in 18ms, RSS 92 MB
29
+ Executed shell commands in 9ms, RSS now 95 MB (+3 MB)
30
30
 
31
31
  Summary:
32
32
 
33
- count init_ms cmd_ms init_rss final_rss
34
- 1 50 4 82 MB 83 MB 0 MB
35
- 2 2 0 83 MB 83 MB 0 MB
36
- 5 3 1 83 MB 83 MB 0 MB
37
- 10 4 4 83 MB 84 MB 1 MB
38
- 20 7 5 84 MB 85 MB 0 MB
39
- 50 23 12 85 MB 87 MB 2 MB
40
- 100 36 33 89 MB 91 MB 2 MB
33
+ count init_ms cmd_ms init_rss final_rss delta_rss
34
+ 1 67 2 82 MB 82 MB 0 MB
35
+ 2 2 0 82 MB 82 MB 0 MB
36
+ 5 1 1 82 MB 82 MB 0 MB
37
+ 10 4 3 83 MB 84 MB 0 MB
38
+ 20 5 3 84 MB 86 MB 1 MB
39
+ 50 10 7 88 MB 89 MB 1 MB
40
+ 100 18 9 92 MB 95 MB 3 MB
package/biome.json CHANGED
@@ -19,7 +19,7 @@
19
19
  }
20
20
  },
21
21
  "formatter": {
22
- "enabled": true,
22
+ "enabled": false,
23
23
  "formatWithErrors": false,
24
24
  "attributePosition": "auto",
25
25
  "indentStyle": "tab",
package/bun.lock CHANGED
@@ -6,13 +6,13 @@
6
6
  "name": "virtual-env-js",
7
7
  "dependencies": {
8
8
  "ssh2": "^1.17.0",
9
- "tar-stream": "^3.1.8",
10
9
  },
11
10
  "devDependencies": {
12
- "@biomejs/biome": "^2.4.11",
13
- "@types/bun": "latest",
11
+ "@biomejs/biome": "^2.4.13",
12
+ "@types/bun": "^1.3.13",
14
13
  "@types/node": "^25.6.0",
15
14
  "@types/ssh2": "^1.15.5",
15
+ "typescript": "^6.0.3",
16
16
  },
17
17
  "peerDependencies": {
18
18
  "typescript": "^5",
@@ -20,25 +20,25 @@
20
20
  },
21
21
  },
22
22
  "packages": {
23
- "@biomejs/biome": ["@biomejs/biome@2.4.11", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.11", "@biomejs/cli-darwin-x64": "2.4.11", "@biomejs/cli-linux-arm64": "2.4.11", "@biomejs/cli-linux-arm64-musl": "2.4.11", "@biomejs/cli-linux-x64": "2.4.11", "@biomejs/cli-linux-x64-musl": "2.4.11", "@biomejs/cli-win32-arm64": "2.4.11", "@biomejs/cli-win32-x64": "2.4.11" }, "bin": { "biome": "bin/biome" } }, "sha512-nWxHX8tf3Opb/qRgZpBbsTOqOodkbrkJ7S+JxJAruxOReaDPPmPuLBAGQ8vigyUgo0QBB+oQltNEAvalLcjggA=="],
23
+ "@biomejs/biome": ["@biomejs/biome@2.4.13", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.13", "@biomejs/cli-darwin-x64": "2.4.13", "@biomejs/cli-linux-arm64": "2.4.13", "@biomejs/cli-linux-arm64-musl": "2.4.13", "@biomejs/cli-linux-x64": "2.4.13", "@biomejs/cli-linux-x64-musl": "2.4.13", "@biomejs/cli-win32-arm64": "2.4.13", "@biomejs/cli-win32-x64": "2.4.13" }, "bin": { "biome": "bin/biome" } }, "sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA=="],
24
24
 
25
- "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wOt+ed+L2dgZanWyL6i29qlXMc088N11optzpo10peayObBaAshbTcxKUchzEMp9QSY8rh5h6VfAFE3WTS1rqg=="],
25
+ "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg=="],
26
26
 
27
- "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-gZ6zR8XmZlExfi/Pz/PffmdpWOQ8Qhy7oBztgkR8/ylSRyLwfRPSadmiVCV8WQ8PoJ2MWUy2fgID9zmtgUUJmw=="],
27
+ "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg=="],
28
28
 
29
- "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-avdJaEElXrKceK0va9FkJ4P5ci3N01TGkc6ni3P8l3BElqbOz42Wg2IyX3gbh0ZLEd4HVKEIrmuVu/AMuSeFFA=="],
29
+ "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ=="],
30
30
 
31
- "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-+Sbo1OAmlegtdwqFE8iOxFIWLh1B3OEgsuZfBpyyN/kWuqZ8dx9ZEes6zVnDMo+zRHF2wLynRVhoQmV7ohxl2Q=="],
31
+ "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg=="],
32
32
 
33
- "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.11", "", { "os": "linux", "cpu": "x64" }, "sha512-TagWV0iomp5LnEnxWFg4nQO+e52Fow349vaX0Q/PIcX6Zhk4GGBgp3qqZ8PVkpC+cuehRctMf3+6+FgQ8jCEFQ=="],
33
+ "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ=="],
34
34
 
35
- "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.11", "", { "os": "linux", "cpu": "x64" }, "sha512-bexd2IklK7ZgPhrz6jXzpIL6dEAH9MlJU1xGTrypx+FICxrXUp4CqtwfiuoDKse+UlgAlWtzML3jrMqeEAHEhA=="],
35
+ "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ=="],
36
36
 
37
- "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-RJhaTnY8byzxDt4bDVb7AFPHkPcjOPK3xBip4ZRTrN3TEfyhjLRm3r3mqknqydgVTB74XG8l4jMLwEACEeihVg=="],
37
+ "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A=="],
38
38
 
39
- "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.11", "", { "os": "win32", "cpu": "x64" }, "sha512-A8D3JM/00C2KQgUV3oj8Ba15EHEYwebAGCy5Sf9GAjr5Y3+kJIYOiESoqRDeuRZueuMdCsbLZIUqmPhpYXJE9A=="],
39
+ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.13", "", { "os": "win32", "cpu": "x64" }, "sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ=="],
40
40
 
41
- "@types/bun": ["@types/bun@1.3.12", "", { "dependencies": { "bun-types": "1.3.12" } }, "sha512-DBv81elK+/VSwXHDlnH3Qduw+KxkTIWi7TXkAeh24zpi5l0B2kUg9Ga3tb4nJaPcOFswflgi/yAvMVBPrxMB+A=="],
41
+ "@types/bun": ["@types/bun@1.3.13", "", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="],
42
42
 
43
43
  "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
44
44
 
@@ -46,49 +46,23 @@
46
46
 
47
47
  "asn1": ["asn1@0.2.6", "", { "dependencies": { "safer-buffer": "~2.1.0" } }, "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ=="],
48
48
 
49
- "b4a": ["b4a@1.8.0", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg=="],
50
-
51
- "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="],
52
-
53
- "bare-fs": ["bare-fs@4.7.0", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA=="],
54
-
55
- "bare-os": ["bare-os@3.8.7", "", {}, "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w=="],
56
-
57
- "bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="],
58
-
59
- "bare-stream": ["bare-stream@2.13.0", "", { "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-abort-controller", "bare-buffer", "bare-events"] }, "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA=="],
60
-
61
- "bare-url": ["bare-url@2.4.0", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA=="],
62
-
63
49
  "bcrypt-pbkdf": ["bcrypt-pbkdf@1.0.2", "", { "dependencies": { "tweetnacl": "^0.14.3" } }, "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w=="],
64
50
 
65
51
  "buildcheck": ["buildcheck@0.0.7", "", {}, "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA=="],
66
52
 
67
- "bun-types": ["bun-types@1.3.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-HqOLj5PoFajAQciOMRiIZGNoKxDJSr6qigAttOX40vJuSp6DN/CxWp9s3C1Xwm4oH7ybueITwiaOcWXoYVoRkA=="],
53
+ "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="],
68
54
 
69
55
  "cpu-features": ["cpu-features@0.0.10", "", { "dependencies": { "buildcheck": "~0.0.6", "nan": "^2.19.0" } }, "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA=="],
70
56
 
71
- "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="],
72
-
73
- "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
74
-
75
57
  "nan": ["nan@2.26.2", "", {}, "sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw=="],
76
58
 
77
59
  "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
78
60
 
79
61
  "ssh2": ["ssh2@1.17.0", "", { "dependencies": { "asn1": "^0.2.6", "bcrypt-pbkdf": "^1.0.2" }, "optionalDependencies": { "cpu-features": "~0.0.10", "nan": "^2.23.0" } }, "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ=="],
80
62
 
81
- "streamx": ["streamx@2.25.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg=="],
82
-
83
- "tar-stream": ["tar-stream@3.1.8", "", { "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ=="],
84
-
85
- "teex": ["teex@1.0.1", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg=="],
86
-
87
- "text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="],
88
-
89
63
  "tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="],
90
64
 
91
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
65
+ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
92
66
 
93
67
  "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
94
68
 
@@ -1,4 +1,4 @@
1
- import { runCommand } from "../commands";
1
+ import { makeDefaultEnv, runCommand } from "../commands";
2
2
  function toTtyLines(text) {
3
3
  return text
4
4
  .replace(/\r\n/g, "\n")
@@ -6,7 +6,7 @@ function toTtyLines(text) {
6
6
  .replace(/\n/g, "\r\n");
7
7
  }
8
8
  export function runExec(stream, cmd, authUser, hostname, shell) {
9
- Promise.resolve(runCommand(cmd, authUser, hostname, "exec", `/home/${authUser}`, shell))
9
+ Promise.resolve(runCommand(cmd, authUser, hostname, "exec", `/home/${authUser}`, shell, undefined, makeDefaultEnv(authUser, hostname)))
10
10
  .then((result) => {
11
11
  if (result.stdout) {
12
12
  stream.write(`${toTtyLines(result.stdout)}\r\n`);
@@ -1,9 +1,8 @@
1
- import type { CommandMode, CommandResult } from "../types/commands";
2
- import type { Pipeline } from "../types/pipeline";
1
+ import type { CommandMode, CommandResult, ShellEnv } from "../types/commands";
2
+ import type { Pipeline, Script, Statement } from "../types/pipeline";
3
3
  import type { VirtualShell } from "../VirtualShell";
4
- /**
5
- * Execute a parsed pipeline, chaining commands and handling redirections.
6
- * Manages stdout/stderr flow between commands and file I/O.
7
- */
8
- export declare function executePipeline(pipeline: Pipeline, authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell): Promise<CommandResult>;
4
+ export declare function executeScript(script: Script, authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, env: ShellEnv): Promise<CommandResult>;
5
+ /** Execute statements connected by &&/||/; */
6
+ export declare function executeStatements(statements: Statement[], authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, env: ShellEnv): Promise<CommandResult>;
7
+ export declare function executePipeline(pipeline: Pipeline, authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, env?: ShellEnv): Promise<CommandResult>;
9
8
  //# sourceMappingURL=executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;GAGG;AACH,wBAAsB,eAAe,CACpC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,GACjB,OAAO,CAAC,aAAa,CAAC,CA0BxB"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,wBAAsB,aAAa,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,QAAQ,GACX,OAAO,CAAC,aAAa,CAAC,CAiBxB;AAED,8CAA8C;AAC9C,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,SAAS,EAAE,EACvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,QAAQ,GACX,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAID,wBAAsB,eAAe,CACpC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,GAAG,CAAC,EAAE,QAAQ,GACZ,OAAO,CAAC,aAAa,CAAC,CAiBxB"}
@@ -1,25 +1,66 @@
1
1
  import { runCommand as runSingleCommand } from "../commands";
2
2
  import { resolvePath } from "../commands/helpers";
3
- /**
4
- * Execute a parsed pipeline, chaining commands and handling redirections.
5
- * Manages stdout/stderr flow between commands and file I/O.
6
- */
7
- export async function executePipeline(pipeline, authUser, hostname, mode, cwd, shell) {
8
- if (pipeline.commands.length === 0) {
9
- return { exitCode: 0 };
3
+ // ── Script executor (handles &&/||/;) ────────────────────────────────────────
4
+ export async function executeScript(script, authUser, hostname, mode, cwd, shell, env) {
5
+ if (!script.isValid)
6
+ return { stderr: script.error || "Syntax error", exitCode: 1 };
7
+ let lastResult = { exitCode: 0 };
8
+ for (const stmt of script.statements) {
9
+ // Decide whether to run this statement based on previous op
10
+ lastResult = await executePipeline(stmt.pipeline, authUser, hostname, mode, cwd, shell, env);
11
+ env.lastExitCode = lastResult.exitCode ?? 0;
12
+ // Propagate session-control signals
13
+ if (lastResult.closeSession || lastResult.switchUser || lastResult.nextCwd) {
14
+ break;
15
+ }
16
+ }
17
+ return lastResult;
18
+ }
19
+ /** Execute statements connected by &&/||/; */
20
+ export async function executeStatements(statements, authUser, hostname, mode, cwd, shell, env) {
21
+ let last = { exitCode: 0 };
22
+ let i = 0;
23
+ while (i < statements.length) {
24
+ const stmt = statements[i];
25
+ last = await executePipeline(stmt.pipeline, authUser, hostname, mode, cwd, shell, env);
26
+ env.lastExitCode = last.exitCode ?? 0;
27
+ if (last.closeSession || last.switchUser)
28
+ return last;
29
+ const op = stmt.op;
30
+ if (!op || op === ";") {
31
+ // always run next
32
+ }
33
+ else if (op === "&&") {
34
+ if ((last.exitCode ?? 0) !== 0) {
35
+ // skip until next ; or end
36
+ while (i < statements.length && statements[i]?.op === "&&")
37
+ i++;
38
+ }
39
+ }
40
+ else if (op === "||") {
41
+ if ((last.exitCode ?? 0) === 0) {
42
+ // skip until next ; or end
43
+ while (i < statements.length && statements[i]?.op === "||")
44
+ i++;
45
+ }
46
+ }
47
+ i++;
10
48
  }
49
+ return last;
50
+ }
51
+ // ── Pipeline executor ─────────────────────────────────────────────────────────
52
+ export async function executePipeline(pipeline, authUser, hostname, mode, cwd, shell, env) {
53
+ if (!pipeline.isValid)
54
+ return { stderr: pipeline.error || "Syntax error", exitCode: 1 };
55
+ if (pipeline.commands.length === 0)
56
+ return { exitCode: 0 };
57
+ const shellEnv = env ?? { vars: {}, lastExitCode: 0 };
11
58
  if (pipeline.commands.length === 1) {
12
- // Single command with possible redirections
13
- return executeSingleCommandWithRedirections(pipeline.commands[0], authUser, hostname, mode, cwd, shell);
59
+ return executeSingleCommandWithRedirections(pipeline.commands[0], authUser, hostname, mode, cwd, shell, shellEnv);
14
60
  }
15
- // Multiple commands in a pipeline
16
- return executePipelineChain(pipeline.commands, authUser, hostname, mode, cwd, shell);
61
+ return executePipelineChain(pipeline.commands, authUser, hostname, mode, cwd, shell, shellEnv);
17
62
  }
18
- /**
19
- * Execute a single command with input/output redirections
20
- */
21
- async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mode, cwd, shell) {
22
- // Prepare input if input file specified
63
+ async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mode, cwd, shell, env) {
23
64
  let stdin;
24
65
  if (cmd.inputFile) {
25
66
  const inputPath = resolvePath(cwd, cmd.inputFile);
@@ -27,29 +68,23 @@ async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mod
27
68
  stdin = shell.vfs.readFile(inputPath);
28
69
  }
29
70
  catch {
30
- return {
31
- stderr: `cat: ${cmd.inputFile}: No such file or directory`,
32
- exitCode: 1,
33
- };
71
+ return { stderr: `${cmd.inputFile}: No such file or directory`, exitCode: 1 };
34
72
  }
35
73
  }
36
- // Build raw input for the command
37
74
  const rawInput = [cmd.name, ...cmd.args].join(" ");
38
- // Run the command with potential input
39
- const result = await runSingleCommand(rawInput, authUser, hostname, mode, cwd, shell, stdin);
40
- // Handle output redirection
75
+ const result = await runSingleCommand(rawInput, authUser, hostname, mode, cwd, shell, stdin, env);
41
76
  if (cmd.outputFile) {
42
77
  const outputPath = resolvePath(cwd, cmd.outputFile);
43
78
  const output = result.stdout || "";
44
79
  try {
45
80
  if (cmd.appendOutput) {
46
- try {
47
- const existing = shell.vfs.readFile(outputPath);
48
- shell.writeFileAsUser(authUser, outputPath, existing + output);
81
+ const existing = (() => { try {
82
+ return shell.vfs.readFile(outputPath);
49
83
  }
50
84
  catch {
51
- shell.writeFileAsUser(authUser, outputPath, output);
52
- }
85
+ return "";
86
+ } })();
87
+ shell.writeFileAsUser(authUser, outputPath, existing + output);
53
88
  }
54
89
  else {
55
90
  shell.writeFileAsUser(authUser, outputPath, output);
@@ -57,55 +92,40 @@ async function executeSingleCommandWithRedirections(cmd, authUser, hostname, mod
57
92
  return { ...result, stdout: "" };
58
93
  }
59
94
  catch {
60
- return {
61
- ...result,
62
- stderr: `Failed to write to ${cmd.outputFile}`,
63
- exitCode: 1,
64
- };
95
+ return { ...result, stderr: `Failed to write to ${cmd.outputFile}`, exitCode: 1 };
65
96
  }
66
97
  }
67
98
  return result;
68
99
  }
69
- /**
70
- * Execute a chain of commands connected by pipes
71
- */
72
- async function executePipelineChain(commands, authUser, hostname, mode, cwd, shell) {
100
+ async function executePipelineChain(commands, authUser, hostname, mode, cwd, shell, env) {
73
101
  let currentOutput = "";
74
102
  let exitCode = 0;
75
103
  for (let i = 0; i < commands.length; i++) {
76
104
  const cmd = commands[i];
77
- // Handle input file for first command
78
105
  if (i === 0 && cmd.inputFile) {
79
106
  const inputPath = resolvePath(cwd, cmd.inputFile);
80
107
  try {
81
108
  currentOutput = shell.vfs.readFile(inputPath);
82
109
  }
83
110
  catch {
84
- return {
85
- stderr: `cat: ${cmd.inputFile}: No such file or directory`,
86
- exitCode: 1,
87
- };
111
+ return { stderr: `${cmd.inputFile}: No such file or directory`, exitCode: 1 };
88
112
  }
89
113
  }
90
- // Build raw input
91
114
  const rawInput = [cmd.name, ...cmd.args].join(" ");
92
- // Create a modified context that might accept stdin
93
- // For now, we'll append input as an additional arg for commands that support it
94
- const result = await runSingleCommand(rawInput, authUser, hostname, mode, cwd, shell, currentOutput);
115
+ const result = await runSingleCommand(rawInput, authUser, hostname, mode, cwd, shell, currentOutput, env);
95
116
  exitCode = result.exitCode ?? 0;
96
- // Handle output redirection (only for last command)
97
117
  if (i === commands.length - 1 && cmd.outputFile) {
98
118
  const outputPath = resolvePath(cwd, cmd.outputFile);
99
119
  const output = result.stdout || "";
100
120
  try {
101
121
  if (cmd.appendOutput) {
102
- try {
103
- const existing = shell.vfs.readFile(outputPath);
104
- shell.writeFileAsUser(authUser, outputPath, existing + output);
122
+ const existing = (() => { try {
123
+ return shell.vfs.readFile(outputPath);
105
124
  }
106
125
  catch {
107
- shell.writeFileAsUser(authUser, outputPath, output);
108
- }
126
+ return "";
127
+ } })();
128
+ shell.writeFileAsUser(authUser, outputPath, existing + output);
109
129
  }
110
130
  else {
111
131
  shell.writeFileAsUser(authUser, outputPath, output);
@@ -113,19 +133,16 @@ async function executePipelineChain(commands, authUser, hostname, mode, cwd, she
113
133
  currentOutput = "";
114
134
  }
115
135
  catch {
116
- return {
117
- stderr: `Failed to write to ${cmd.outputFile}`,
118
- exitCode: 1,
119
- };
136
+ return { stderr: `Failed to write to ${cmd.outputFile}`, exitCode: 1 };
120
137
  }
121
138
  }
122
139
  else {
123
- // Pass output to next command
124
140
  currentOutput = result.stdout || "";
125
141
  }
126
- if (result.stderr && exitCode !== 0) {
142
+ if (result.stderr && exitCode !== 0)
127
143
  return { stderr: result.stderr, exitCode };
128
- }
144
+ if (result.closeSession || result.switchUser)
145
+ return result;
129
146
  }
130
147
  return { stdout: currentOutput, exitCode };
131
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA0B/C,cAAM,QAAS,SAAQ,YAAY;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,KAAK,CAAe;IAE5B,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAElE;;;;;;;;OAQG;gBACS,EACX,IAAI,EACJ,QAA0B,EAC1B,KAAkC,EAClC,eAAmB,EACnB,iBAA0B,GAC1B,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAYD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,aAAa;IAcrB;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IA6LrC;;OAEG;IACI,IAAI,IAAI,IAAI;IAUnB;;;OAGG;IACI,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAGrC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA0B/C,cAAM,QAAS,SAAQ,YAAY;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,KAAK,CAAe;IAE5B,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAElE;;;;;;;;OAQG;gBACS,EACX,IAAI,EACJ,QAA0B,EAC1B,KAAkC,EAClC,eAAmB,EACnB,iBAA0B,GAC1B,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAYD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,aAAa;IAcrB;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IA0JrC;;OAEG;IACI,IAAI,IAAI,IAAI;IAUnB;;;OAGG;IACI,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAGrC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -103,11 +103,7 @@ class SshMimic extends EventEmitter {
103
103
  remoteAddress = ctx.ip ?? remoteAddress;
104
104
  // Rate-limit check
105
105
  if (this.isLockedOut(remoteAddress)) {
106
- this.emit("auth:failure", {
107
- username: candidateUser,
108
- remoteAddress,
109
- reason: "lockout",
110
- });
106
+ this.emit("auth:failure", { username: candidateUser, remoteAddress, reason: "lockout" });
111
107
  ctx.reject();
112
108
  return;
113
109
  }
@@ -127,10 +123,7 @@ class SshMimic extends EventEmitter {
127
123
  ctx.password === "" ||
128
124
  !shell.users.verifyPassword(candidateUser, ctx.password)) {
129
125
  this.recordFailure(remoteAddress);
130
- this.emit("auth:failure", {
131
- username: candidateUser,
132
- remoteAddress,
133
- });
126
+ this.emit("auth:failure", { username: candidateUser, remoteAddress });
134
127
  ctx.reject();
135
128
  return;
136
129
  }
@@ -151,14 +144,11 @@ class SshMimic extends EventEmitter {
151
144
  return;
152
145
  }
153
146
  const incomingKey = ctx.key;
154
- const keyMatches = authorizedKeys.some((k) => k.algo === incomingKey.algo && k.data.equals(incomingKey.data));
147
+ const keyMatches = authorizedKeys.some((k) => k.algo === incomingKey.algo &&
148
+ k.data.equals(incomingKey.data));
155
149
  if (!keyMatches) {
156
150
  this.recordFailure(remoteAddress);
157
- this.emit("auth:failure", {
158
- username: candidateUser,
159
- remoteAddress,
160
- method: "publickey",
161
- });
151
+ this.emit("auth:failure", { username: candidateUser, remoteAddress, method: "publickey" });
162
152
  ctx.reject();
163
153
  return;
164
154
  }
@@ -167,11 +157,7 @@ class SshMimic extends EventEmitter {
167
157
  authUser = candidateUser;
168
158
  sessionId = shell.users.registerSession(authUser, remoteAddress).id;
169
159
  this.recordSuccess(remoteAddress);
170
- this.emit("auth:success", {
171
- username: authUser,
172
- remoteAddress,
173
- method: "publickey",
174
- });
160
+ this.emit("auth:success", { username: authUser, remoteAddress, method: "publickey" });
175
161
  this.ensureHomeDir(authUser);
176
162
  ctx.accept();
177
163
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sftp.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/sftp.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAI3C,OAAO,KAAK,iBAAiB,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AA4HhE,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,iBAAiB,CAAC;IACxB,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC3B;AAED,qBAAa,SAAU,SAAQ,YAAY;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAAiC;gBAEpC,EACX,IAAI,EACJ,QAA0B,EAC1B,KAAK,EACL,GAAG,EACH,KAAK,GACL,EAAE,gBAAgB;IAwBnB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,QAAQ;IAIH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAyJ9B,IAAI,IAAI,IAAI;IAUnB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;CA6a1B"}
1
+ {"version":3,"file":"sftp.d.ts","sourceRoot":"","sources":["../../src/SSHMimic/sftp.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAI3C,OAAO,KAAK,iBAAiB,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AA4HhE,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,iBAAiB,CAAC;IACxB,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC3B;AAED,qBAAa,SAAU,SAAQ,YAAY;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAAiC;gBAEpC,EACX,IAAI,EACJ,QAA0B,EAC1B,KAAK,EACL,GAAG,EACH,KAAK,GACL,EAAE,gBAAgB;IAwBnB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,QAAQ;IAIH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAwK9B,IAAI,IAAI,IAAI;IAUnB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;CA6a1B"}
@@ -110,6 +110,13 @@ export class SftpMimic extends EventEmitter {
110
110
  remoteAddress = ctx.ip ?? remoteAddress;
111
111
  console.log(`[SFTP] Auth attempt: user=${candidateUser}, method=${ctx.method}, ip=${remoteAddress}`);
112
112
  if (ctx.method === "password") {
113
+ // If no password is set for the user, allow login without verification
114
+ if (!this.getUsers().hasPassword(candidateUser)) {
115
+ acceptSession(candidateUser);
116
+ this.emit("auth:success", { username: authUser, remoteAddress });
117
+ ctx.accept();
118
+ return;
119
+ }
113
120
  if (!this.getUsers().verifyPassword(candidateUser, ctx.password ?? "")) {
114
121
  this.emit("auth:failure", {
115
122
  username: candidateUser,
@@ -125,6 +132,13 @@ export class SftpMimic extends EventEmitter {
125
132
  }
126
133
  if (ctx.method === "keyboard-interactive") {
127
134
  const keyboardCtx = ctx;
135
+ // If no password is set, accept immediately
136
+ if (!this.getUsers().hasPassword(candidateUser)) {
137
+ acceptSession(candidateUser);
138
+ this.emit("auth:success", { username: authUser, remoteAddress });
139
+ keyboardCtx.accept();
140
+ return;
141
+ }
128
142
  keyboardCtx.prompt([{ prompt: "Password: ", echo: false }], (answers) => {
129
143
  const password = answers[0] ?? "";
130
144
  if (!this.getUsers().verifyPassword(candidateUser, password)) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/VirtualFileSystem/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/VirtualFileSystem/index.ts"],"names":[],"mappings":"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"}