typescript-virtual-container 1.2.4 → 1.2.6

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 (267) hide show
  1. package/README.md +1056 -1239
  2. package/benchmark-results.txt +20 -20
  3. package/dist/SSHMimic/exec.js +2 -2
  4. package/dist/SSHMimic/executor.d.ts +6 -7
  5. package/dist/SSHMimic/executor.d.ts.map +1 -1
  6. package/dist/SSHMimic/executor.js +77 -60
  7. package/dist/SSHMimic/index.d.ts +19 -2
  8. package/dist/SSHMimic/index.d.ts.map +1 -1
  9. package/dist/SSHMimic/index.js +106 -24
  10. package/dist/SSHMimic/sftp.d.ts.map +1 -1
  11. package/dist/SSHMimic/sftp.js +14 -0
  12. package/dist/VirtualFileSystem/index.d.ts +115 -88
  13. package/dist/VirtualFileSystem/index.d.ts.map +1 -1
  14. package/dist/VirtualFileSystem/index.js +389 -264
  15. package/dist/VirtualShell/index.d.ts +3 -4
  16. package/dist/VirtualShell/index.d.ts.map +1 -1
  17. package/dist/VirtualShell/index.js +4 -6
  18. package/dist/VirtualShell/shell.d.ts.map +1 -1
  19. package/dist/VirtualShell/shell.js +19 -2
  20. package/dist/VirtualShell/shellParser.d.ts +20 -2
  21. package/dist/VirtualShell/shellParser.d.ts.map +1 -1
  22. package/dist/VirtualShell/shellParser.js +229 -120
  23. package/dist/VirtualUserManager/index.d.ts +25 -0
  24. package/dist/VirtualUserManager/index.d.ts.map +1 -1
  25. package/dist/VirtualUserManager/index.js +33 -0
  26. package/dist/commands/adduser.d.ts.map +1 -1
  27. package/dist/commands/adduser.js +2 -0
  28. package/dist/commands/awk.d.ts +3 -0
  29. package/dist/commands/awk.d.ts.map +1 -0
  30. package/dist/commands/awk.js +29 -0
  31. package/dist/commands/base64.d.ts +3 -0
  32. package/dist/commands/base64.d.ts.map +1 -0
  33. package/dist/commands/base64.js +20 -0
  34. package/dist/commands/cat.d.ts.map +1 -1
  35. package/dist/commands/cat.js +2 -0
  36. package/dist/commands/cd.d.ts.map +1 -1
  37. package/dist/commands/cd.js +2 -0
  38. package/dist/commands/chmod.d.ts +3 -0
  39. package/dist/commands/chmod.d.ts.map +1 -0
  40. package/dist/commands/chmod.js +33 -0
  41. package/dist/commands/clear.d.ts.map +1 -1
  42. package/dist/commands/clear.js +4 -1
  43. package/dist/commands/cp.d.ts +3 -0
  44. package/dist/commands/cp.d.ts.map +1 -0
  45. package/dist/commands/cp.js +70 -0
  46. package/dist/commands/curl.d.ts.map +1 -1
  47. package/dist/commands/curl.js +2 -0
  48. package/dist/commands/cut.d.ts +3 -0
  49. package/dist/commands/cut.d.ts.map +1 -0
  50. package/dist/commands/cut.js +27 -0
  51. package/dist/commands/date.d.ts +3 -0
  52. package/dist/commands/date.d.ts.map +1 -0
  53. package/dist/commands/date.js +22 -0
  54. package/dist/commands/deluser.d.ts.map +1 -1
  55. package/dist/commands/deluser.js +2 -0
  56. package/dist/commands/df.d.ts +3 -0
  57. package/dist/commands/df.d.ts.map +1 -0
  58. package/dist/commands/df.js +16 -0
  59. package/dist/commands/diff.d.ts +3 -0
  60. package/dist/commands/diff.d.ts.map +1 -0
  61. package/dist/commands/diff.js +40 -0
  62. package/dist/commands/du.d.ts +3 -0
  63. package/dist/commands/du.d.ts.map +1 -0
  64. package/dist/commands/du.js +39 -0
  65. package/dist/commands/echo.d.ts.map +1 -1
  66. package/dist/commands/echo.js +2 -0
  67. package/dist/commands/env.d.ts.map +1 -1
  68. package/dist/commands/env.js +6 -14
  69. package/dist/commands/export.d.ts.map +1 -1
  70. package/dist/commands/export.js +11 -21
  71. package/dist/commands/find.d.ts +3 -0
  72. package/dist/commands/find.d.ts.map +1 -0
  73. package/dist/commands/find.js +50 -0
  74. package/dist/commands/grep.d.ts.map +1 -1
  75. package/dist/commands/grep.js +58 -35
  76. package/dist/commands/groups.d.ts +3 -0
  77. package/dist/commands/groups.d.ts.map +1 -0
  78. package/dist/commands/groups.js +12 -0
  79. package/dist/commands/gzip.d.ts +4 -0
  80. package/dist/commands/gzip.d.ts.map +1 -0
  81. package/dist/commands/gzip.js +40 -0
  82. package/dist/commands/head.d.ts +3 -0
  83. package/dist/commands/head.d.ts.map +1 -0
  84. package/dist/commands/head.js +32 -0
  85. package/dist/commands/help.d.ts +1 -1
  86. package/dist/commands/help.d.ts.map +1 -1
  87. package/dist/commands/help.js +75 -3
  88. package/dist/commands/hostname.d.ts.map +1 -1
  89. package/dist/commands/hostname.js +2 -0
  90. package/dist/commands/htop.d.ts.map +1 -1
  91. package/dist/commands/htop.js +2 -0
  92. package/dist/commands/id.d.ts +3 -0
  93. package/dist/commands/id.d.ts.map +1 -0
  94. package/dist/commands/id.js +14 -0
  95. package/dist/commands/index.d.ts +5 -2
  96. package/dist/commands/index.d.ts.map +1 -1
  97. package/dist/commands/index.js +104 -87
  98. package/dist/commands/kill.d.ts +3 -0
  99. package/dist/commands/kill.d.ts.map +1 -0
  100. package/dist/commands/kill.js +13 -0
  101. package/dist/commands/ln.d.ts +3 -0
  102. package/dist/commands/ln.d.ts.map +1 -0
  103. package/dist/commands/ln.js +44 -0
  104. package/dist/commands/ls.d.ts.map +1 -1
  105. package/dist/commands/ls.js +2 -0
  106. package/dist/commands/mkdir.d.ts.map +1 -1
  107. package/dist/commands/mkdir.js +2 -0
  108. package/dist/commands/mv.d.ts +3 -0
  109. package/dist/commands/mv.d.ts.map +1 -0
  110. package/dist/commands/mv.js +37 -0
  111. package/dist/commands/nano.d.ts.map +1 -1
  112. package/dist/commands/nano.js +2 -0
  113. package/dist/commands/neofetch.d.ts.map +1 -1
  114. package/dist/commands/neofetch.js +2 -0
  115. package/dist/commands/passwd.d.ts.map +1 -1
  116. package/dist/commands/passwd.js +2 -0
  117. package/dist/commands/ping.d.ts +3 -0
  118. package/dist/commands/ping.d.ts.map +1 -0
  119. package/dist/commands/ping.js +18 -0
  120. package/dist/commands/ps.d.ts +3 -0
  121. package/dist/commands/ps.d.ts.map +1 -0
  122. package/dist/commands/ps.js +17 -0
  123. package/dist/commands/pwd.d.ts.map +1 -1
  124. package/dist/commands/pwd.js +2 -0
  125. package/dist/commands/rm.d.ts.map +1 -1
  126. package/dist/commands/rm.js +2 -0
  127. package/dist/commands/sed.d.ts +3 -0
  128. package/dist/commands/sed.d.ts.map +1 -0
  129. package/dist/commands/sed.js +47 -0
  130. package/dist/commands/set.d.ts +3 -0
  131. package/dist/commands/set.d.ts.map +1 -1
  132. package/dist/commands/set.js +19 -46
  133. package/dist/commands/sh.d.ts +0 -1
  134. package/dist/commands/sh.d.ts.map +1 -1
  135. package/dist/commands/sh.js +228 -35
  136. package/dist/commands/sleep.d.ts +3 -0
  137. package/dist/commands/sleep.d.ts.map +1 -0
  138. package/dist/commands/sleep.js +13 -0
  139. package/dist/commands/sort.d.ts +3 -0
  140. package/dist/commands/sort.d.ts.map +1 -0
  141. package/dist/commands/sort.js +37 -0
  142. package/dist/commands/su.d.ts.map +1 -1
  143. package/dist/commands/su.js +2 -0
  144. package/dist/commands/sudo.d.ts.map +1 -1
  145. package/dist/commands/sudo.js +2 -0
  146. package/dist/commands/tail.d.ts +3 -0
  147. package/dist/commands/tail.d.ts.map +1 -0
  148. package/dist/commands/tail.js +35 -0
  149. package/dist/commands/tar.d.ts +3 -0
  150. package/dist/commands/tar.d.ts.map +1 -0
  151. package/dist/commands/tar.js +64 -0
  152. package/dist/commands/tee.d.ts +3 -0
  153. package/dist/commands/tee.d.ts.map +1 -0
  154. package/dist/commands/tee.js +29 -0
  155. package/dist/commands/touch.d.ts.map +1 -1
  156. package/dist/commands/touch.js +2 -0
  157. package/dist/commands/tr.d.ts +3 -0
  158. package/dist/commands/tr.d.ts.map +1 -0
  159. package/dist/commands/tr.js +24 -0
  160. package/dist/commands/tree.d.ts.map +1 -1
  161. package/dist/commands/tree.js +2 -0
  162. package/dist/commands/uname.d.ts +3 -0
  163. package/dist/commands/uname.d.ts.map +1 -0
  164. package/dist/commands/uname.js +21 -0
  165. package/dist/commands/uniq.d.ts +3 -0
  166. package/dist/commands/uniq.d.ts.map +1 -0
  167. package/dist/commands/uniq.js +33 -0
  168. package/dist/commands/unset.d.ts.map +1 -1
  169. package/dist/commands/unset.js +6 -10
  170. package/dist/commands/wc.d.ts +3 -0
  171. package/dist/commands/wc.d.ts.map +1 -0
  172. package/dist/commands/wc.js +50 -0
  173. package/dist/commands/wget.d.ts.map +1 -1
  174. package/dist/commands/wget.js +2 -0
  175. package/dist/commands/who.d.ts.map +1 -1
  176. package/dist/commands/who.js +2 -0
  177. package/dist/commands/whoami.d.ts.map +1 -1
  178. package/dist/commands/whoami.js +2 -0
  179. package/dist/commands/xargs.d.ts +3 -0
  180. package/dist/commands/xargs.d.ts.map +1 -0
  181. package/dist/commands/xargs.js +16 -0
  182. package/dist/index.d.ts +1 -0
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/types/commands.d.ts +13 -0
  185. package/dist/types/commands.d.ts.map +1 -1
  186. package/dist/types/pipeline.d.ts +20 -0
  187. package/dist/types/pipeline.d.ts.map +1 -1
  188. package/package.json +5 -2
  189. package/scripts/publish-package.sh +70 -0
  190. package/src/SSHMimic/exec.ts +2 -2
  191. package/src/SSHMimic/executor.ts +95 -98
  192. package/src/SSHMimic/index.ts +138 -57
  193. package/src/SSHMimic/sftp.ts +15 -0
  194. package/src/VirtualFileSystem/index.ts +464 -292
  195. package/src/VirtualShell/index.ts +4 -6
  196. package/src/VirtualShell/shell.ts +19 -2
  197. package/src/VirtualShell/shellParser.ts +202 -168
  198. package/src/VirtualUserManager/index.ts +36 -0
  199. package/src/commands/adduser.ts +2 -0
  200. package/src/commands/awk.ts +30 -0
  201. package/src/commands/base64.ts +18 -0
  202. package/src/commands/cat.ts +2 -0
  203. package/src/commands/cd.ts +2 -0
  204. package/src/commands/chmod.ts +35 -0
  205. package/src/commands/clear.ts +4 -1
  206. package/src/commands/cp.ts +78 -0
  207. package/src/commands/curl.ts +2 -0
  208. package/src/commands/cut.ts +29 -0
  209. package/src/commands/date.ts +24 -0
  210. package/src/commands/deluser.ts +2 -0
  211. package/src/commands/df.ts +18 -0
  212. package/src/commands/diff.ts +29 -0
  213. package/src/commands/du.ts +39 -0
  214. package/src/commands/echo.ts +2 -0
  215. package/src/commands/env.ts +6 -16
  216. package/src/commands/export.ts +11 -24
  217. package/src/commands/find.ts +63 -0
  218. package/src/commands/grep.ts +51 -38
  219. package/src/commands/groups.ts +14 -0
  220. package/src/commands/gzip.ts +31 -0
  221. package/src/commands/head.ts +37 -0
  222. package/src/commands/help.ts +81 -3
  223. package/src/commands/hostname.ts +2 -0
  224. package/src/commands/htop.ts +2 -0
  225. package/src/commands/id.ts +16 -0
  226. package/src/commands/index.ts +114 -133
  227. package/src/commands/kill.ts +14 -0
  228. package/src/commands/ln.ts +49 -0
  229. package/src/commands/ls.ts +2 -0
  230. package/src/commands/mkdir.ts +2 -0
  231. package/src/commands/mv.ts +45 -0
  232. package/src/commands/nano.ts +2 -0
  233. package/src/commands/neofetch.ts +2 -0
  234. package/src/commands/passwd.ts +2 -0
  235. package/src/commands/ping.ts +20 -0
  236. package/src/commands/ps.ts +19 -0
  237. package/src/commands/pwd.ts +2 -0
  238. package/src/commands/rm.ts +2 -0
  239. package/src/commands/sed.ts +45 -0
  240. package/src/commands/set.ts +19 -50
  241. package/src/commands/sh.ts +192 -43
  242. package/src/commands/sleep.ts +14 -0
  243. package/src/commands/sort.ts +37 -0
  244. package/src/commands/su.ts +2 -0
  245. package/src/commands/sudo.ts +2 -0
  246. package/src/commands/tail.ts +39 -0
  247. package/src/commands/tar.ts +58 -0
  248. package/src/commands/tee.ts +25 -0
  249. package/src/commands/touch.ts +2 -0
  250. package/src/commands/tr.ts +24 -0
  251. package/src/commands/tree.ts +2 -0
  252. package/src/commands/uname.ts +20 -0
  253. package/src/commands/uniq.ts +28 -0
  254. package/src/commands/unset.ts +5 -12
  255. package/src/commands/wc.ts +50 -0
  256. package/src/commands/wget.ts +2 -0
  257. package/src/commands/who.ts +2 -0
  258. package/src/commands/whoami.ts +2 -0
  259. package/src/commands/xargs.ts +17 -0
  260. package/src/index.ts +1 -0
  261. package/src/types/commands.ts +14 -0
  262. package/src/types/pipeline.ts +23 -0
  263. package/standalone.js +93 -55
  264. package/standalone.js.map +4 -4
  265. package/tests/bun-test-shim.ts +1 -0
  266. package/tests/sftp.test.ts +115 -191
  267. package/tests/users.test.ts +42 -88
@@ -1,6 +1,8 @@
1
1
  import { assertPathAccess, resolvePath } from "./helpers";
2
2
  export const touchCommand = {
3
3
  name: "touch",
4
+ description: "Create or update files",
5
+ category: "files",
4
6
  params: ["<file>"],
5
7
  run: ({ authUser, shell, cwd, args }) => {
6
8
  if (args.length === 0) {
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const trCommand: ShellModule;
3
+ //# sourceMappingURL=tr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../src/commands/tr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,SAAS,EAAE,WAoBvB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { ifFlag } from "./command-helpers";
2
+ export const trCommand = {
3
+ name: "tr",
4
+ description: "Translate or delete characters",
5
+ category: "text",
6
+ params: ["[-d] <set1> [set2]"],
7
+ run: ({ args, stdin }) => {
8
+ const del = ifFlag(args, ["-d"]);
9
+ const positionals = args.filter((a) => !a.startsWith("-"));
10
+ const set1 = positionals[0] ?? "";
11
+ const set2 = positionals[1] ?? "";
12
+ let input = stdin ?? "";
13
+ if (del) {
14
+ for (const c of set1)
15
+ input = input.split(c).join("");
16
+ }
17
+ else if (set2) {
18
+ for (let i = 0; i < set1.length; i++) {
19
+ input = input.split(set1[i]).join(set2[i] ?? set2[set2.length - 1] ?? "");
20
+ }
21
+ }
22
+ return { stdout: input, exitCode: 0 };
23
+ },
24
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/commands/tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,WAQzB,CAAC"}
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/commands/tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,WAUzB,CAAC"}
@@ -2,6 +2,8 @@ import { getArg } from "./command-helpers";
2
2
  import { assertPathAccess, resolvePath } from "./helpers";
3
3
  export const treeCommand = {
4
4
  name: "tree",
5
+ description: "Display directory tree",
6
+ category: "navigation",
5
7
  params: ["[path]"],
6
8
  run: ({ authUser, shell, cwd, args }) => {
7
9
  const target = resolvePath(cwd, getArg(args, 0) ?? cwd);
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const unameCommand: ShellModule;
3
+ //# sourceMappingURL=uname.d.ts.map
@@ -0,0 +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,WAgB1B,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ifFlag } from "./command-helpers";
2
+ export const unameCommand = {
3
+ name: "uname",
4
+ description: "Print system information",
5
+ category: "system",
6
+ params: ["[-a] [-s] [-r] [-m]"],
7
+ run: ({ shell, args }) => {
8
+ const all = ifFlag(args, ["-a"]);
9
+ const sysname = "Linux";
10
+ const release = shell.properties?.kernel ?? "5.15.0";
11
+ const machine = shell.properties?.arch ?? "x86_64";
12
+ const hostname = shell.hostname;
13
+ if (all)
14
+ return { stdout: `${sysname} ${hostname} ${release} #1 SMP ${machine} GNU/Linux`, exitCode: 0 };
15
+ if (ifFlag(args, ["-r"]))
16
+ return { stdout: release, exitCode: 0 };
17
+ if (ifFlag(args, ["-m"]))
18
+ return { stdout: machine, exitCode: 0 };
19
+ return { stdout: sysname, exitCode: 0 };
20
+ },
21
+ };
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const uniqCommand: ShellModule;
3
+ //# sourceMappingURL=uniq.d.ts.map
@@ -0,0 +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,WAwBzB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { ifFlag } from "./command-helpers";
2
+ export const uniqCommand = {
3
+ name: "uniq",
4
+ description: "Report or filter out repeated lines",
5
+ category: "text",
6
+ params: ["[-c] [-d] [-u] [file]"],
7
+ run: ({ args, stdin }) => {
8
+ const count = ifFlag(args, ["-c"]);
9
+ const dupOnly = ifFlag(args, ["-d"]);
10
+ const uniqOnly = ifFlag(args, ["-u"]);
11
+ const lines = (stdin ?? "").split("\n");
12
+ const out = [];
13
+ let i = 0;
14
+ while (i < lines.length) {
15
+ let j = i;
16
+ while (j < lines.length && lines[j] === lines[i])
17
+ j++;
18
+ const n = j - i;
19
+ const line = lines[i];
20
+ if (dupOnly && n === 1) {
21
+ i = j;
22
+ continue;
23
+ }
24
+ if (uniqOnly && n > 1) {
25
+ i = j;
26
+ continue;
27
+ }
28
+ out.push(count ? `${String(n).padStart(4)} ${line}` : line);
29
+ i = j;
30
+ }
31
+ return { stdout: out.join("\n"), exitCode: 0 };
32
+ },
33
+ };
@@ -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;AAGrD,eAAO,MAAM,YAAY,EAAE,WAe1B,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,eAAO,MAAM,YAAY,EAAE,WAS1B,CAAC"}
@@ -1,15 +1,11 @@
1
- import { setEnvVar } from "./set";
2
1
  export const unsetCommand = {
3
2
  name: "unset",
4
- params: ["<VAR...>"],
5
- run: ({ args }) => {
6
- if (args.length === 0) {
7
- return { stderr: "unset: missing variable name", exitCode: 1 };
8
- }
9
- // Unset (remove) all specified variables
10
- for (const varName of args) {
11
- setEnvVar(varName, "");
12
- }
3
+ description: "Remove shell variable",
4
+ category: "shell",
5
+ params: ["<VAR>"],
6
+ run: ({ args, env }) => {
7
+ for (const name of args)
8
+ delete env.vars[name];
13
9
  return { exitCode: 0 };
14
10
  },
15
11
  };
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const wcCommand: ShellModule;
3
+ //# sourceMappingURL=wc.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,50 @@
1
+ import { ifFlag } from "./command-helpers";
2
+ import { assertPathAccess, resolvePath } from "./helpers";
3
+ export const wcCommand = {
4
+ name: "wc",
5
+ description: "Count words/lines/bytes",
6
+ category: "text",
7
+ params: ["[-l] [-w] [-c] [file...]"],
8
+ run: ({ authUser, shell, cwd, args, stdin }) => {
9
+ const lines = ifFlag(args, ["-l"]);
10
+ const words = ifFlag(args, ["-w"]);
11
+ const bytes = ifFlag(args, ["-c"]);
12
+ const showAll = !lines && !words && !bytes;
13
+ const positionals = args.filter((a) => !a.startsWith("-"));
14
+ const count = (content, label) => {
15
+ const l = content.split("\n").length - (content.endsWith("\n") ? 1 : 0);
16
+ const w = content.trim().split(/\s+/).filter(Boolean).length;
17
+ const c = Buffer.byteLength(content, "utf8");
18
+ const parts = [];
19
+ if (showAll || lines)
20
+ parts.push(String(l).padStart(7));
21
+ if (showAll || words)
22
+ parts.push(String(w).padStart(7));
23
+ if (showAll || bytes)
24
+ parts.push(String(c).padStart(7));
25
+ if (label)
26
+ parts.push(` ${label}`);
27
+ return parts.join("");
28
+ };
29
+ if (positionals.length === 0) {
30
+ const content = stdin ?? "";
31
+ return { stdout: count(content, ""), exitCode: 0 };
32
+ }
33
+ const results = [];
34
+ for (const file of positionals) {
35
+ const filePath = resolvePath(cwd, file);
36
+ try {
37
+ assertPathAccess(authUser, filePath, "wc");
38
+ const content = shell.vfs.readFile(filePath);
39
+ results.push(count(content, file));
40
+ }
41
+ catch {
42
+ return {
43
+ stderr: `wc: ${file}: No such file or directory`,
44
+ exitCode: 1,
45
+ };
46
+ }
47
+ }
48
+ return { stdout: results.join("\n"), exitCode: 0 };
49
+ },
50
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../src/commands/wget.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA8ErD,eAAO,MAAM,WAAW,EAAE,WA6DzB,CAAC"}
1
+ {"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../src/commands/wget.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA8ErD,eAAO,MAAM,WAAW,EAAE,WA+DzB,CAAC"}
@@ -61,6 +61,8 @@ function runHostWget(args) {
61
61
  }
62
62
  export const wgetCommand = {
63
63
  name: "wget",
64
+ description: "File downloader",
65
+ category: "network",
64
66
  params: ["[url]"],
65
67
  run: async ({ authUser, cwd, args, shell }) => {
66
68
  const { flagsWithValues, positionals } = parseArgs(args, {
@@ -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,WAcxB,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,eAAO,MAAM,UAAU,EAAE,WAgBxB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { formatLoginDate } from "../SSHMimic/loginFormat";
2
2
  export const whoCommand = {
3
3
  name: "who",
4
+ description: "Show active sessions",
5
+ category: "system",
4
6
  params: [],
5
7
  run: ({ shell }) => {
6
8
  const lines = shell.users.listActiveSessions().map((session) => {
@@ -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,WAI3B,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,eAAO,MAAM,aAAa,EAAE,WAM3B,CAAC"}
@@ -1,5 +1,7 @@
1
1
  export const whoamiCommand = {
2
2
  name: "whoami",
3
+ description: "Print current user",
4
+ category: "system",
3
5
  params: [],
4
6
  run: ({ authUser }) => ({ stdout: authUser, exitCode: 0 }),
5
7
  };
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const xargsCommand: ShellModule;
3
+ //# sourceMappingURL=xargs.d.ts.map
@@ -0,0 +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,WAa1B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { runCommand } from "./index";
2
+ export const xargsCommand = {
3
+ name: "xargs",
4
+ description: "Build and execute command lines from stdin",
5
+ category: "text",
6
+ params: ["[command] [args...]"],
7
+ run: async ({ authUser, hostname, mode, cwd, args, stdin, shell, env }) => {
8
+ const baseCmd = args[0] ?? "echo";
9
+ const extraArgs = args.slice(1);
10
+ const items = (stdin ?? "").trim().split(/\s+/).filter(Boolean);
11
+ if (items.length === 0)
12
+ return { exitCode: 0 };
13
+ const fullCmd = [baseCmd, ...extraArgs, ...items].join(" ");
14
+ return runCommand(fullCmd, authUser, hostname, mode, cwd, shell, undefined, env);
15
+ },
16
+ };
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export type { AuditLogEntry, HoneyPotStats, } from "./Honeypot/index";
8
8
  export type { CommandContext, CommandMode, CommandOutcome, CommandResult, NanoEditorSession, ShellModule, SudoChallenge, } from "./types/commands";
9
9
  export type { ExecStream, ShellStream } from "./types/streams";
10
10
  export type { RemoveOptions, VfsBaseNode, VfsDirectoryNode, VfsFileNode, VfsNodeStats, VfsNodeType, VfsSnapshot, VfsSnapshotBaseNode, VfsSnapshotDirectoryNode, VfsSnapshotFileNode, VfsSnapshotNode, WriteFileOptions, } from "./types/vfs";
11
+ export type { VfsOptions, VfsPersistenceMode } from "./VirtualFileSystem/index";
11
12
  export { HoneyPot, SshClient, VirtualFileSystem, SftpMimic as VirtualSftpServer, VirtualShell, SshMimic as VirtualSshServer, VirtualUserManager, };
12
13
  export { getArg, getFlag, ifFlag, } from "./commands/command-helpers";
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,iBAAiB,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,YAAY,EACX,aAAa,EACb,aAAa,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACX,cAAc,EACd,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,aAAa,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/D,YAAY,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,SAAS,IAAI,iBAAiB,EAC9B,YAAY,EACZ,QAAQ,IAAI,gBAAgB,EAC5B,kBAAkB,GAClB,CAAC;AAEF,OAAO,EACN,MAAM,EACN,OAAO,EACP,MAAM,GACN,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,iBAAiB,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,YAAY,EACX,aAAa,EACb,aAAa,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACX,cAAc,EACd,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,aAAa,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/D,YAAY,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EACN,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,SAAS,IAAI,iBAAiB,EAC9B,YAAY,EACZ,QAAQ,IAAI,gBAAgB,EAC5B,kBAAkB,GAClB,CAAC;AAEF,OAAO,EACN,MAAM,EACN,OAAO,EACP,MAAM,GACN,MAAM,4BAA4B,CAAC"}
@@ -52,6 +52,13 @@ export interface NanoEditorSession {
52
52
  /** Initial editor content shown to user. */
53
53
  initialContent: string;
54
54
  }
55
+ /** Per-session shell environment (variables, last exit code). */
56
+ export interface ShellEnv {
57
+ /** Environment variables visible to commands. */
58
+ vars: Record<string, string>;
59
+ /** Exit status of the last executed command. */
60
+ lastExitCode: number;
61
+ }
55
62
  /** Runtime context object passed to each command module. */
56
63
  export interface CommandContext {
57
64
  /** Authenticated user currently bound to stream. */
@@ -72,6 +79,8 @@ export interface CommandContext {
72
79
  stdin?: string;
73
80
  /** Current working directory for command execution. */
74
81
  cwd: string;
82
+ /** Per-session environment available to command modules. */
83
+ env: ShellEnv;
75
84
  }
76
85
  /** Contract implemented by each shell command module. */
77
86
  export interface ShellModule {
@@ -83,6 +92,10 @@ export interface ShellModule {
83
92
  run: (ctx: CommandContext) => CommandResult | Promise<CommandResult>;
84
93
  /** Optional alternative command names. */
85
94
  aliases?: string[];
95
+ /** Short description shown in `help`. */
96
+ description?: string;
97
+ /** Category used for grouped help output. */
98
+ category?: string;
86
99
  }
87
100
  /** Command return union allowing sync or async handlers. */
88
101
  export type CommandOutcome = CommandResult | Promise<CommandResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/types/commands.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC7B,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gDAAgD;IAChD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC7B,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2DAA2D;IAC3D,UAAU,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;CACf;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IACjC,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,IAAI,EAAE,WAAW,CAAC;IAClB,kDAAkD;IAClD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,8BAA8B;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC3B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,sCAAsC;IACtC,GAAG,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACrE,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/types/commands.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,8 @@ export interface PipelineCommand {
11
11
  /** Append to output file (>> file) */
12
12
  appendOutput?: boolean;
13
13
  }
14
+ /** Logical operator connecting two statement groups. */
15
+ export type LogicalOp = "&&" | "||" | ";";
14
16
  /** Represents a parsed shell pipeline */
15
17
  export interface Pipeline {
16
18
  /** List of commands in the pipeline */
@@ -20,4 +22,22 @@ export interface Pipeline {
20
22
  /** Error message if parsing failed */
21
23
  error?: string;
22
24
  }
25
+ /** A statement: one pipeline optionally followed by && / || / ; and the next statement */
26
+ export interface Statement {
27
+ /** Pipeline to execute for this statement. */
28
+ pipeline: Pipeline;
29
+ /** Operator connecting this statement to the next one. */
30
+ op?: LogicalOp;
31
+ /** Optional next statement in sequence. */
32
+ next?: Statement;
33
+ }
34
+ /** Top-level parse result for a script. */
35
+ export interface Script {
36
+ /** Statements contained in the script. */
37
+ statements: Statement[];
38
+ /** Whether the script was parsed successfully. */
39
+ isValid: boolean;
40
+ /** Optional parse error message. */
41
+ error?: string;
42
+ }
23
43
  //# sourceMappingURL=pipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/types/pipeline.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC/B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,yCAAyC;AACzC,MAAM,WAAW,QAAQ;IACxB,uCAAuC;IACvC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/types/pipeline.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC/B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC;AAE1C,yCAAyC;AACzC,MAAM,WAAW,QAAQ;IACxB,uCAAuC;IACvC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,0FAA0F;AAC1F,MAAM,WAAW,SAAS;IACzB,8CAA8C;IAC9C,QAAQ,EAAE,QAAQ,CAAC;IACnB,0DAA0D;IAC1D,EAAE,CAAC,EAAE,SAAS,CAAC;IACf,2CAA2C;IAC3C,IAAI,CAAC,EAAE,SAAS,CAAC;CACjB;AAED,2CAA2C;AAC3C,MAAM,WAAW,MAAM;IACtB,0CAA0C;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CACf"}
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.4",
7
+ "version": "1.2.6",
8
8
  "license": "MIT",
9
9
  "repository": {
10
10
  "type": "git",
@@ -27,13 +27,16 @@
27
27
  "test": "bunx --bun @biomejs/biome test ./src",
28
28
  "build": "tsc --project tsconfig.json",
29
29
  "deploy:npm": "npm publish --access public",
30
+ "bench": "rm -rf .benchmark-shells/ && bun benchmark-virtualshell.ts",
31
+ "publish-package": "bash ./scripts/publish-package.sh",
30
32
  "standalone-build": "bunx esbuild src/standalone.ts --bundle --platform=node --target=node18 --outfile=standalone.js --tree-shaking=true --minify --sourcemap"
31
33
  },
32
34
  "devDependencies": {
33
35
  "@biomejs/biome": "^2.4.11",
34
36
  "@types/bun": "latest",
35
37
  "@types/node": "^25.6.0",
36
- "@types/ssh2": "^1.15.5"
38
+ "@types/ssh2": "^1.15.5",
39
+ "typescript": "^6.0.3"
37
40
  },
38
41
  "peerDependencies": {
39
42
  "typescript": "^5"
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
5
+ echo "Error: this command must run inside a git repository."
6
+ exit 1
7
+ fi
8
+
9
+ if [[ -n "$(git status --porcelain)" ]]; then
10
+ echo "Error: working tree is not clean. Commit or stash your changes first."
11
+ exit 1
12
+ fi
13
+
14
+ VERSION="$(node -p "require('./package.json').version")"
15
+ TAG="v${VERSION}"
16
+
17
+ if [[ -z "${VERSION}" ]]; then
18
+ echo "Error: package.json version is empty."
19
+ exit 1
20
+ fi
21
+
22
+ git fetch --tags --quiet
23
+
24
+ TAG_EXISTS_LOCAL="false"
25
+ TAG_EXISTS_REMOTE="false"
26
+
27
+ if git rev-parse --verify --quiet "refs/tags/${TAG}" >/dev/null; then
28
+ TAG_EXISTS_LOCAL="true"
29
+ fi
30
+
31
+ if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then
32
+ TAG_EXISTS_REMOTE="true"
33
+ fi
34
+
35
+ if [[ "${TAG_EXISTS_LOCAL}" == "true" || "${TAG_EXISTS_REMOTE}" == "true" ]]; then
36
+ echo "Tag ${TAG} already exists. Deleting existing release/tag before republishing."
37
+
38
+ if command -v gh >/dev/null 2>&1; then
39
+ if gh release view "${TAG}" >/dev/null 2>&1; then
40
+ gh release delete "${TAG}" --yes
41
+ echo "GitHub release ${TAG} deleted."
42
+ fi
43
+ else
44
+ echo "gh CLI not found; skipping GitHub release deletion."
45
+ fi
46
+
47
+ if [[ "${TAG_EXISTS_LOCAL}" == "true" ]]; then
48
+ git tag -d "${TAG}" >/dev/null
49
+ echo "Local tag ${TAG} deleted."
50
+ fi
51
+
52
+ if [[ "${TAG_EXISTS_REMOTE}" == "true" ]]; then
53
+ git push --delete origin "${TAG}" >/dev/null
54
+ echo "Remote tag ${TAG} deleted."
55
+ fi
56
+ fi
57
+
58
+ git tag -a "${TAG}" -m "Release ${TAG}"
59
+ git push origin "${TAG}"
60
+
61
+ echo "Tag ${TAG} pushed."
62
+
63
+ if command -v gh >/dev/null 2>&1; then
64
+ gh release create "${TAG}" --title "${TAG}" --generate-notes
65
+ echo "GitHub release ${TAG} created."
66
+ else
67
+ echo "gh CLI not found; skipping GitHub release creation."
68
+ fi
69
+
70
+ echo "Done. The publish workflow should run from tag ${TAG}."
@@ -1,4 +1,4 @@
1
- import { runCommand } from "../commands";
1
+ import { makeDefaultEnv, runCommand } from "../commands";
2
2
  import type { ExecStream } from "../types/streams";
3
3
  import type { VirtualShell } from "../VirtualShell";
4
4
 
@@ -17,7 +17,7 @@ export function runExec(
17
17
  shell: VirtualShell,
18
18
  ): void {
19
19
  Promise.resolve(
20
- runCommand(cmd, authUser, hostname, "exec", `/home/${authUser}`, shell),
20
+ runCommand(cmd, authUser, hostname, "exec", `/home/${authUser}`, shell, undefined, makeDefaultEnv(authUser, hostname)),
21
21
  )
22
22
  .then((result) => {
23
23
  if (result.stdout) {