typescript-virtual-container 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +457 -42
  2. package/dist/SSHMimic/executor.js +3 -5
  3. package/dist/VirtualFileSystem/binaryPack.d.ts +49 -0
  4. package/dist/VirtualFileSystem/binaryPack.d.ts.map +1 -0
  5. package/dist/VirtualFileSystem/binaryPack.js +193 -0
  6. package/dist/VirtualFileSystem/index.d.ts +7 -5
  7. package/dist/VirtualFileSystem/index.d.ts.map +1 -1
  8. package/dist/VirtualFileSystem/index.js +20 -9
  9. package/dist/VirtualPackageManager/index.d.ts +202 -0
  10. package/dist/VirtualPackageManager/index.d.ts.map +1 -0
  11. package/dist/VirtualPackageManager/index.js +676 -0
  12. package/dist/VirtualShell/index.d.ts +87 -12
  13. package/dist/VirtualShell/index.d.ts.map +1 -1
  14. package/dist/VirtualShell/index.js +83 -12
  15. package/dist/VirtualUserManager/index.d.ts +52 -20
  16. package/dist/VirtualUserManager/index.d.ts.map +1 -1
  17. package/dist/VirtualUserManager/index.js +54 -20
  18. package/dist/commands/alias.d.ts +4 -0
  19. package/dist/commands/alias.d.ts.map +1 -0
  20. package/dist/commands/alias.js +58 -0
  21. package/dist/commands/apt.d.ts +4 -0
  22. package/dist/commands/apt.d.ts.map +1 -0
  23. package/dist/commands/apt.js +182 -0
  24. package/dist/commands/cat.d.ts.map +1 -1
  25. package/dist/commands/cat.js +27 -8
  26. package/dist/commands/chmod.d.ts.map +1 -1
  27. package/dist/commands/chmod.js +52 -3
  28. package/dist/commands/command-helpers.d.ts +78 -4
  29. package/dist/commands/command-helpers.d.ts.map +1 -1
  30. package/dist/commands/command-helpers.js +78 -4
  31. package/dist/commands/curl.d.ts.map +1 -1
  32. package/dist/commands/curl.js +81 -29
  33. package/dist/commands/dpkg.d.ts +4 -0
  34. package/dist/commands/dpkg.d.ts.map +1 -0
  35. package/dist/commands/dpkg.js +144 -0
  36. package/dist/commands/echo.d.ts.map +1 -1
  37. package/dist/commands/echo.js +24 -12
  38. package/dist/commands/free.d.ts +3 -0
  39. package/dist/commands/free.d.ts.map +1 -0
  40. package/dist/commands/free.js +38 -0
  41. package/dist/commands/helpers.d.ts +3 -0
  42. package/dist/commands/helpers.d.ts.map +1 -1
  43. package/dist/commands/helpers.js +3 -0
  44. package/dist/commands/history.d.ts +3 -0
  45. package/dist/commands/history.d.ts.map +1 -0
  46. package/dist/commands/history.js +21 -0
  47. package/dist/commands/index.d.ts +8 -1
  48. package/dist/commands/index.d.ts.map +1 -1
  49. package/dist/commands/index.js +120 -11
  50. package/dist/commands/ls.d.ts.map +1 -1
  51. package/dist/commands/ls.js +4 -3
  52. package/dist/commands/lsb-release.d.ts +3 -0
  53. package/dist/commands/lsb-release.d.ts.map +1 -0
  54. package/dist/commands/lsb-release.js +50 -0
  55. package/dist/commands/man.d.ts +3 -0
  56. package/dist/commands/man.d.ts.map +1 -0
  57. package/dist/commands/man.js +155 -0
  58. package/dist/commands/neofetch.d.ts.map +1 -1
  59. package/dist/commands/neofetch.js +5 -0
  60. package/dist/commands/ping.d.ts.map +1 -1
  61. package/dist/commands/ping.js +5 -2
  62. package/dist/commands/ps.d.ts.map +1 -1
  63. package/dist/commands/ps.js +27 -6
  64. package/dist/commands/sh.d.ts.map +1 -1
  65. package/dist/commands/sh.js +29 -11
  66. package/dist/commands/source.d.ts +3 -0
  67. package/dist/commands/source.d.ts.map +1 -0
  68. package/dist/commands/source.js +31 -0
  69. package/dist/commands/test.d.ts +3 -0
  70. package/dist/commands/test.d.ts.map +1 -0
  71. package/dist/commands/test.js +92 -0
  72. package/dist/commands/type.d.ts +3 -0
  73. package/dist/commands/type.d.ts.map +1 -0
  74. package/dist/commands/type.js +34 -0
  75. package/dist/commands/uptime.d.ts +3 -0
  76. package/dist/commands/uptime.d.ts.map +1 -0
  77. package/dist/commands/uptime.js +40 -0
  78. package/dist/commands/wget.d.ts.map +1 -1
  79. package/dist/commands/wget.js +71 -100
  80. package/dist/commands/which.d.ts +3 -0
  81. package/dist/commands/which.d.ts.map +1 -0
  82. package/dist/commands/which.js +32 -0
  83. package/dist/index.d.ts +5 -2
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +2 -1
  86. package/dist/modules/linuxRootfs.d.ts +24 -0
  87. package/dist/modules/linuxRootfs.d.ts.map +1 -0
  88. package/dist/modules/linuxRootfs.js +297 -0
  89. package/dist/modules/neofetch.d.ts.map +1 -1
  90. package/dist/modules/neofetch.js +1 -0
  91. package/dist/standalone.js +4 -1
  92. package/package.json +2 -1
  93. package/src/SSHMimic/executor.ts +3 -5
  94. package/src/VirtualFileSystem/binaryPack.ts +219 -0
  95. package/src/VirtualFileSystem/index.ts +21 -11
  96. package/src/VirtualPackageManager/index.ts +820 -0
  97. package/src/VirtualShell/index.ts +104 -13
  98. package/src/VirtualUserManager/index.ts +55 -20
  99. package/src/commands/alias.ts +60 -0
  100. package/src/commands/apt.ts +198 -0
  101. package/src/commands/cat.ts +32 -8
  102. package/src/commands/chmod.ts +48 -3
  103. package/src/commands/command-helpers.ts +78 -4
  104. package/src/commands/curl.ts +78 -37
  105. package/src/commands/dpkg.ts +158 -0
  106. package/src/commands/echo.ts +30 -14
  107. package/src/commands/free.ts +40 -0
  108. package/src/commands/helpers.ts +8 -0
  109. package/src/commands/history.ts +29 -0
  110. package/src/commands/index.ts +116 -11
  111. package/src/commands/ls.ts +5 -4
  112. package/src/commands/lsb-release.ts +52 -0
  113. package/src/commands/man.ts +166 -0
  114. package/src/commands/neofetch.ts +5 -0
  115. package/src/commands/ping.ts +5 -2
  116. package/src/commands/ps.ts +28 -6
  117. package/src/commands/sh.ts +33 -11
  118. package/src/commands/source.ts +35 -0
  119. package/src/commands/test.ts +100 -0
  120. package/src/commands/type.ts +40 -0
  121. package/src/commands/uptime.ts +46 -0
  122. package/src/commands/wget.ts +70 -123
  123. package/src/commands/which.ts +34 -0
  124. package/src/index.ts +10 -0
  125. package/src/modules/linuxRootfs.ts +439 -0
  126. package/src/modules/neofetch.ts +1 -0
  127. package/src/standalone.ts +4 -1
  128. package/standalone.js +418 -103
  129. package/standalone.js.map +4 -4
  130. package/tests/new-features.test.ts +626 -0
@@ -1,46 +1,98 @@
1
- import { parseArgs } from "./command-helpers";
2
- import { assertPathAccess, normalizeTerminalOutput, resolvePath, runHostCommand, } from "./helpers";
1
+ import { ifFlag, parseArgs } from "./command-helpers";
2
+ import { assertPathAccess, resolvePath } from "./helpers";
3
3
  export const curlCommand = {
4
4
  name: "curl",
5
- description: "HTTP client",
5
+ description: "Transfer data from or to a server (pure fetch)",
6
6
  category: "network",
7
- params: ["[-o file] <url>"],
7
+ params: ["[options] <url>"],
8
8
  run: async ({ authUser, cwd, args, shell }) => {
9
9
  const { flagsWithValues, positionals } = parseArgs(args, {
10
- flagsWithValue: ["-o", "--output"],
10
+ flagsWithValue: ["-o", "--output", "-X", "--request", "-d", "--data", "-H", "--header", "-u", "--user"],
11
11
  });
12
- const outputPath = flagsWithValues.get("-o") || flagsWithValues.get("--output") || null;
13
- const url = positionals[0];
14
- if (!url) {
15
- return { stderr: "curl: missing URL", exitCode: 1 };
16
- }
17
- const passthroughArgs = outputPath
18
- ? [...positionals, "-o", "-"]
19
- : positionals;
20
- const result = await runHostCommand("curl", passthroughArgs);
21
- if (result.exitCode !== 0) {
12
+ if (ifFlag(args, ["--help", "-h"])) {
22
13
  return {
23
- stderr: normalizeTerminalOutput(result.stderr || `curl: exited with code ${result.exitCode}`),
24
- exitCode: result.exitCode,
14
+ stdout: [
15
+ "Usage: curl [options] <url>",
16
+ " -o, --output <file> Write to file",
17
+ " -X, --request <method> HTTP method",
18
+ " -d, --data <data> POST data",
19
+ " -H, --header <hdr> Extra header",
20
+ " -s, --silent Silent mode",
21
+ " -I, --head Fetch headers only",
22
+ " -L, --location Follow redirects",
23
+ " -v, --verbose Verbose",
24
+ ].join("\n"),
25
+ exitCode: 0,
25
26
  };
26
27
  }
28
+ const url = positionals[0];
29
+ if (!url)
30
+ return { stderr: "curl: no URL specified", exitCode: 1 };
31
+ const outputPath = flagsWithValues.get("-o") ?? flagsWithValues.get("--output") ?? null;
32
+ const method = (flagsWithValues.get("-X") ?? flagsWithValues.get("--request") ?? "GET").toUpperCase();
33
+ const postData = flagsWithValues.get("-d") ?? flagsWithValues.get("--data") ?? null;
34
+ const headerRaw = flagsWithValues.get("-H") ?? flagsWithValues.get("--header") ?? null;
35
+ const silent = ifFlag(args, ["-s", "--silent"]);
36
+ const headOnly = ifFlag(args, ["-I", "--head"]);
37
+ const followRedirects = ifFlag(args, ["-L", "--location"]);
38
+ const verbose = ifFlag(args, ["-v", "--verbose"]);
39
+ const extraHeaders = { "User-Agent": "curl/7.88.1" };
40
+ if (headerRaw) {
41
+ const idx = headerRaw.indexOf(":");
42
+ if (idx !== -1)
43
+ extraHeaders[headerRaw.slice(0, idx).trim()] = headerRaw.slice(idx + 1).trim();
44
+ }
45
+ const finalMethod = postData && method === "GET" ? "POST" : method;
46
+ const fetchOpts = {
47
+ method: finalMethod,
48
+ headers: extraHeaders,
49
+ redirect: followRedirects ? "follow" : "manual",
50
+ };
51
+ if (postData) {
52
+ extraHeaders["Content-Type"] ??= "application/x-www-form-urlencoded";
53
+ fetchOpts.body = postData;
54
+ }
55
+ const stderrLines = [];
56
+ if (verbose) {
57
+ stderrLines.push(`* Trying ${url}...`, `* Connected`);
58
+ stderrLines.push(`> ${finalMethod} / HTTP/1.1`, `> Host: ${new URL(url).host}`);
59
+ }
60
+ let response;
61
+ try {
62
+ response = await fetch(url, fetchOpts);
63
+ }
64
+ catch (err) {
65
+ const msg = err instanceof Error ? err.message : String(err);
66
+ return { stderr: `curl: (6) Could not resolve host: ${msg}`, exitCode: 6 };
67
+ }
68
+ if (verbose) {
69
+ stderrLines.push(`< HTTP/1.1 ${response.status} ${response.statusText}`);
70
+ }
71
+ if (headOnly) {
72
+ const lines = [`HTTP/1.1 ${response.status} ${response.statusText}`];
73
+ for (const [k, v] of response.headers.entries())
74
+ lines.push(`${k}: ${v}`);
75
+ return { stdout: `${lines.join("\r\n")}\r\n`, exitCode: 0 };
76
+ }
77
+ let body;
78
+ try {
79
+ body = await response.text();
80
+ }
81
+ catch {
82
+ return { stderr: "curl: failed to read response body", exitCode: 1 };
83
+ }
27
84
  if (outputPath) {
28
85
  const target = resolvePath(cwd, outputPath);
29
86
  assertPathAccess(authUser, target, "curl");
30
- shell.writeFileAsUser(authUser, target, result.stdout);
31
- return {
32
- stderr: result.stderr
33
- ? normalizeTerminalOutput(result.stderr)
34
- : undefined,
35
- exitCode: 0,
36
- };
87
+ shell.writeFileAsUser(authUser, target, body);
88
+ if (!silent)
89
+ stderrLines.push(` % Total % Received\n100 ${body.length} 100 ${body.length}`);
90
+ return { stderr: stderrLines.join("\n") || undefined, exitCode: response.ok ? 0 : 22 };
37
91
  }
38
92
  return {
39
- stdout: result.stdout,
40
- stderr: result.stderr
41
- ? normalizeTerminalOutput(result.stderr)
42
- : undefined,
43
- exitCode: 0,
93
+ stdout: body,
94
+ stderr: stderrLines.length > 0 ? stderrLines.join("\n") : undefined,
95
+ exitCode: response.ok ? 0 : 22,
44
96
  };
45
97
  },
46
98
  };
@@ -0,0 +1,4 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const dpkgCommand: ShellModule;
3
+ export declare const dpkgQueryCommand: ShellModule;
4
+ //# sourceMappingURL=dpkg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpkg.d.ts","sourceRoot":"","sources":["../../src/commands/dpkg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,WAAW,EAAE,WA2GzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,WA4C9B,CAAC"}
@@ -0,0 +1,144 @@
1
+ import { ifFlag, parseArgs } from "./command-helpers";
2
+ import { getPackageManager } from "./helpers";
3
+ export const dpkgCommand = {
4
+ name: "dpkg",
5
+ description: "Debian package manager low-level tool",
6
+ category: "system",
7
+ params: ["[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]"],
8
+ run: ({ args, authUser, shell }) => {
9
+ const pm = getPackageManager(shell);
10
+ if (!pm)
11
+ return { stderr: "dpkg: package manager not initialised", exitCode: 1 };
12
+ const listFlag = ifFlag(args, ["-l", "--list"]);
13
+ const statusFlag = ifFlag(args, ["-s", "--status"]);
14
+ const listFilesFlag = ifFlag(args, ["-L", "--listfiles"]);
15
+ const removeFlag = ifFlag(args, ["-r", "--remove"]);
16
+ const purgeFlag = ifFlag(args, ["-P", "--purge"]);
17
+ const { positionals } = parseArgs(args, {
18
+ flags: ["-l", "--list", "-s", "--status", "-L", "--listfiles", "-r", "--remove", "-P", "--purge"],
19
+ });
20
+ if (listFlag) {
21
+ const pkgList = pm.listInstalled();
22
+ if (pkgList.length === 0) {
23
+ return {
24
+ stdout: [
25
+ "Desired=Unknown/Install/Remove/Purge/Hold",
26
+ "|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend",
27
+ "|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)",
28
+ "||/ Name Version Architecture Description",
29
+ "+++-==============-===============-============-========================================",
30
+ "(no packages installed)",
31
+ ].join("\n"),
32
+ exitCode: 0,
33
+ };
34
+ }
35
+ const header = [
36
+ "Desired=Unknown/Install/Remove/Purge/Hold",
37
+ "|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend",
38
+ "|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)",
39
+ "||/ Name Version Architecture Description",
40
+ "+++-==============-===============-============-========================================",
41
+ ];
42
+ const rows = pkgList.map((p) => {
43
+ const name = p.name.padEnd(14).slice(0, 14);
44
+ const ver = p.version.padEnd(15).slice(0, 15);
45
+ const arch = p.architecture.padEnd(12).slice(0, 12);
46
+ const desc = (p.description || "").slice(0, 40);
47
+ return `ii ${name} ${ver} ${arch} ${desc}`;
48
+ });
49
+ return { stdout: [...header, ...rows].join("\n"), exitCode: 0 };
50
+ }
51
+ if (statusFlag) {
52
+ const pkgName = positionals[0];
53
+ if (!pkgName)
54
+ return { stderr: "dpkg: -s needs a package name", exitCode: 1 };
55
+ const info = pm.show(pkgName);
56
+ if (!info)
57
+ return {
58
+ stderr: `dpkg-query: package '${pkgName}' is not installed and no information is available`,
59
+ exitCode: 1,
60
+ };
61
+ return { stdout: info, exitCode: 0 };
62
+ }
63
+ if (listFilesFlag) {
64
+ const pkgName = positionals[0];
65
+ if (!pkgName)
66
+ return { stderr: "dpkg: -L needs a package name", exitCode: 1 };
67
+ const installed = pm.listInstalled().find((p) => p.name === pkgName);
68
+ if (!installed)
69
+ return {
70
+ stderr: `dpkg-query: package '${pkgName}' is not installed`,
71
+ exitCode: 1,
72
+ };
73
+ if (installed.files.length === 0)
74
+ return { stdout: "/.keep", exitCode: 0 };
75
+ return { stdout: installed.files.join("\n"), exitCode: 0 };
76
+ }
77
+ if (removeFlag || purgeFlag) {
78
+ if (authUser !== "root")
79
+ return {
80
+ stderr: "dpkg: error: requested operation requires superuser privilege",
81
+ exitCode: 2,
82
+ };
83
+ if (positionals.length === 0)
84
+ return { stderr: "dpkg: error: need an action option", exitCode: 2 };
85
+ const { output, exitCode } = pm.remove(positionals, { purge: purgeFlag });
86
+ return { stdout: output || undefined, exitCode };
87
+ }
88
+ // Default: show help
89
+ return {
90
+ stdout: [
91
+ "Usage: dpkg [<option>...] <command>",
92
+ "",
93
+ "Commands:",
94
+ " -l, --list List packages matching given pattern",
95
+ " -s, --status <pkg>... Report status of specified package",
96
+ " -L, --listfiles <pkg>... List files owned by package",
97
+ " -r, --remove <pkg>... Remove <pkg> but leave its configuration",
98
+ " -P, --purge <pkg>... Remove <pkg> and its configuration",
99
+ ].join("\n"),
100
+ exitCode: 0,
101
+ };
102
+ },
103
+ };
104
+ export const dpkgQueryCommand = {
105
+ name: "dpkg-query",
106
+ description: "Show information about installed packages",
107
+ category: "system",
108
+ params: ["-W [pkg] | -l [pattern]"],
109
+ run: ({ args, shell }) => {
110
+ const pm = getPackageManager(shell);
111
+ if (!pm)
112
+ return { stderr: "dpkg-query: package manager not initialised", exitCode: 1 };
113
+ const listFlag = ifFlag(args, ["-l"]);
114
+ const showFlag = ifFlag(args, ["-W", "--show"]);
115
+ const { positionals } = parseArgs(args, {
116
+ flags: ["-l", "-W", "--show"],
117
+ });
118
+ if (listFlag || showFlag) {
119
+ const pkgList = pm.listInstalled();
120
+ const pattern = positionals[0];
121
+ const filtered = pattern
122
+ ? pkgList.filter((p) => p.name.includes(pattern))
123
+ : pkgList;
124
+ if (showFlag) {
125
+ return {
126
+ stdout: filtered
127
+ .map((p) => `${p.name}\t${p.version}`)
128
+ .join("\n"),
129
+ exitCode: 0,
130
+ };
131
+ }
132
+ const rows = filtered.map((p) => {
133
+ const name = p.name.padEnd(14).slice(0, 14);
134
+ const ver = p.version.padEnd(15).slice(0, 15);
135
+ return `ii ${name} ${ver} amd64 ${(p.description || "").slice(0, 40)}`;
136
+ });
137
+ return {
138
+ stdout: rows.join("\n") || "(no packages match)",
139
+ exitCode: 0,
140
+ };
141
+ }
142
+ return { stderr: "dpkg-query: need a flag (-l, -W)", exitCode: 1 };
143
+ },
144
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../../src/commands/echo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAUrD,eAAO,MAAM,WAAW,EAAE,WAkBzB,CAAC"}
1
+ {"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../../src/commands/echo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrD,eAAO,MAAM,WAAW,EAAE,WAwBzB,CAAC"}
@@ -1,23 +1,35 @@
1
1
  import { parseArgs } from "./command-helpers";
2
- import { getAllEnvVars } from "./set";
3
- function expandEnvVars(input, env) {
4
- return input.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g, (_, name) => {
5
- return env[name] ?? "";
6
- });
2
+ /**
3
+ * Expand escape sequences for `echo -e`.
4
+ * Handles \n \t \r \\ \a \b \f \v and \0NNN (octal).
5
+ */
6
+ function expandEscapes(text) {
7
+ return text
8
+ .replace(/\\n/g, "\n")
9
+ .replace(/\\t/g, "\t")
10
+ .replace(/\\r/g, "\r")
11
+ .replace(/\\\\/g, "\\")
12
+ .replace(/\\a/g, "\x07")
13
+ .replace(/\\b/g, "\x08")
14
+ .replace(/\\f/g, "\x0C")
15
+ .replace(/\\v/g, "\x0B")
16
+ .replace(/\\0(\d{1,3})/g, (_, oct) => String.fromCharCode(parseInt(oct, 8)));
7
17
  }
8
18
  export const echoCommand = {
9
19
  name: "echo",
10
20
  description: "Display text",
11
21
  category: "shell",
12
- params: ["[options] [text...]"],
13
- run: ({ args, authUser, stdin }) => {
14
- const { flags, positionals } = parseArgs(args, { flags: ["-n"] });
15
- const newline = !flags.has("-n");
22
+ params: ["[-n] [-e] [text...]"],
23
+ run: ({ args, stdin, env }) => {
24
+ const { flags, positionals } = parseArgs(args, { flags: ["-n", "-e", "-E"] });
25
+ const noNewline = flags.has("-n");
26
+ const escapes = flags.has("-e");
16
27
  const rawText = positionals.length > 0 ? positionals.join(" ") : (stdin ?? "");
17
- const env = getAllEnvVars(authUser);
18
- const text = expandEnvVars(rawText, env);
28
+ // Expand $VAR references using the session env (not the legacy global store)
29
+ const varsExpanded = rawText.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g, (_, name) => env?.vars[name] ?? "");
30
+ const text = escapes ? expandEscapes(varsExpanded) : varsExpanded;
19
31
  return {
20
- stdout: newline ? text : text.trimEnd(),
32
+ stdout: noNewline ? text : `${text}\n`,
21
33
  exitCode: 0,
22
34
  };
23
35
  },
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const freeCommand: ShellModule;
3
+ //# sourceMappingURL=free.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"free.d.ts","sourceRoot":"","sources":["../../src/commands/free.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,WAmCzB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import * as os from "node:os";
2
+ import { ifFlag } from "./command-helpers";
3
+ export const freeCommand = {
4
+ name: "free",
5
+ description: "Display amount of free and used memory",
6
+ category: "system",
7
+ params: ["[-h] [-m] [-g]"],
8
+ run: ({ args }) => {
9
+ const human = ifFlag(args, ["-h", "--human"]);
10
+ const mb = ifFlag(args, ["-m"]);
11
+ const gb = ifFlag(args, ["-g"]);
12
+ const osTotalB = os.totalmem();
13
+ const osFreeB = os.freemem();
14
+ const usedB = osTotalB - osFreeB;
15
+ const sharedB = Math.floor(osTotalB * 0.02);
16
+ const buffersB = Math.floor(osTotalB * 0.05);
17
+ const availableB = Math.floor(osFreeB * 0.95);
18
+ const swapB = Math.floor(osTotalB * 0.5);
19
+ const fmt = (bytes) => {
20
+ if (human) {
21
+ if (bytes >= 1024 * 1024 * 1024)
22
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}G`;
23
+ if (bytes >= 1024 * 1024)
24
+ return `${(bytes / (1024 * 1024)).toFixed(1)}M`;
25
+ return `${(bytes / 1024).toFixed(1)}K`;
26
+ }
27
+ if (gb)
28
+ return String(Math.floor(bytes / (1024 * 1024 * 1024)));
29
+ if (mb)
30
+ return String(Math.floor(bytes / (1024 * 1024)));
31
+ return String(Math.floor(bytes / 1024));
32
+ };
33
+ const header = ` total used free shared buff/cache available`;
34
+ const memRow = `Mem: ${fmt(osTotalB).padStart(12)} ${fmt(usedB).padStart(11)} ${fmt(osFreeB).padStart(11)} ${fmt(sharedB).padStart(11)} ${fmt(buffersB).padStart(11)} ${fmt(availableB).padStart(11)}`;
35
+ const swapRow = `Swap: ${fmt(swapB).padStart(12)} ${fmt(0).padStart(11)} ${fmt(swapB).padStart(11)}`;
36
+ return { stdout: [header, memRow, swapRow].join("\n"), exitCode: 0 };
37
+ },
38
+ };
@@ -1,4 +1,6 @@
1
1
  import type VirtualFileSystem from "../VirtualFileSystem";
2
+ import type { VirtualPackageManager } from "../VirtualPackageManager";
3
+ import type { VirtualShell } from "../VirtualShell";
2
4
  export declare function normalizeTerminalOutput(text: string): string;
3
5
  export declare function resolvePath(cwd: string, inputPath: string): string;
4
6
  export declare function assertPathAccess(authUser: string, targetPath: string, operation: string): void;
@@ -23,4 +25,5 @@ export declare function resolveReadablePath(vfs: VirtualFileSystem, cwd: string,
23
25
  export declare function joinListWithType(cwd: string, items: string[], statAt: (p: string) => {
24
26
  type: "file" | "directory";
25
27
  }): string;
28
+ export declare function getPackageManager(shell: VirtualShell): VirtualPackageManager | undefined;
26
29
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/commands/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,iBAAiB,MAAM,sBAAsB,CAAC;AAY1D,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY5D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOlE;AAYD,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GACf,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAQvE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,GACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA8D/D;AA4BD,wBAAgB,mBAAmB,CAClC,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GACf,MAAM,CAyBR;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GACnD,MAAM,CAQR"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/commands/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,iBAAiB,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAYpD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY5D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOlE;AAYD,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GACf,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAQvE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,GACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA8D/D;AA4BD,wBAAgB,mBAAmB,CAClC,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GACf,MAAM,CAyBR;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GACnD,MAAM,CAQR;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,YAAY,GACjB,qBAAqB,GAAG,SAAS,CAEnC"}
@@ -158,3 +158,6 @@ export function joinListWithType(cwd, items, statAt) {
158
158
  })
159
159
  .join(" ");
160
160
  }
161
+ export function getPackageManager(shell) {
162
+ return shell.packageManager;
163
+ }
@@ -0,0 +1,3 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ export declare const historyCommand: ShellModule;
3
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,cAAc,EAAE,WA0B5B,CAAC"}
@@ -0,0 +1,21 @@
1
+ export const historyCommand = {
2
+ name: "history",
3
+ description: "Display command history",
4
+ category: "shell",
5
+ params: ["[n]"],
6
+ run: ({ args, shell }) => {
7
+ // History is persisted in the VFS by the interactive shell
8
+ const histPath = "/virtual-env-js/.bash_history";
9
+ if (!shell.vfs.exists(histPath)) {
10
+ return { stdout: "", exitCode: 0 };
11
+ }
12
+ const raw = shell.vfs.readFile(histPath);
13
+ const lines = raw.split("\n").filter(Boolean);
14
+ const nArg = args[0];
15
+ const n = nArg ? parseInt(nArg, 10) : null;
16
+ const slice = n && !Number.isNaN(n) ? lines.slice(-n) : lines;
17
+ const offset = lines.length - slice.length + 1;
18
+ const numbered = slice.map((line, i) => `${String(offset + i).padStart(5)} ${line}`);
19
+ return { stdout: numbered.join("\n"), exitCode: 0 };
20
+ },
21
+ };
@@ -1,4 +1,3 @@
1
- /** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */
2
1
  import type { VirtualShell } from "../VirtualShell";
3
2
  import type { CommandContext, CommandMode, CommandResult, ShellEnv, ShellModule } from "../types/commands";
4
3
  export declare function registerCommand(module: ShellModule): void;
@@ -7,5 +6,13 @@ export declare function getCommandNames(): string[];
7
6
  export declare function getCommandModulesPublic(): ShellModule[];
8
7
  export declare function resolveModule(name: string): ShellModule | undefined;
9
8
  export declare function makeDefaultEnv(authUser: string, hostname: string): ShellEnv;
9
+ /**
10
+ * Execute a pre-parsed command directly by name and argument list.
11
+ *
12
+ * Unlike `runCommand`, this function does NOT re-join name+args into a string
13
+ * and re-parse — so arguments that contain special characters (`;`, `|`, `>`,
14
+ * quotes) are passed through verbatim. Use this from the pipeline executor.
15
+ */
16
+ export declare function runCommandDirect(name: string, args: string[], authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, stdin: string | undefined, env: ShellEnv): Promise<CommandResult>;
10
17
  export declare function runCommand(rawInput: string, authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, stdin?: string, env?: ShellEnv): Promise<CommandResult>;
11
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EACX,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,EACR,WAAW,EACX,MAAM,mBAAmB,CAAC;AA8G3B,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAYzD;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EAAE,EAChB,GAAG,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,GAClE,WAAW,CAEb;AAED,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAG1C;AAED,wBAAgB,uBAAuB,IAAI,WAAW,EAAE,CAEvD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAGnE;AA8BD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAc3E;AAED,wBAAsB,UAAU,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,QAAQ,GACZ,OAAO,CAAC,aAAa,CAAC,CA+CxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,KAAK,EACX,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,EACR,WAAW,EACX,MAAM,mBAAmB,CAAC;AAiI3B,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAYzD;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EAAE,EAChB,GAAG,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,GAClE,WAAW,CAEb;AAED,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAG1C;AAED,wBAAgB,uBAAuB,IAAI,WAAW,EAAE,CAEvD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAGnE;AA8BD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAc3E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,GAAG,EAAE,QAAQ,GACX,OAAO,CAAC,aAAa,CAAC,CA2BxB;AAED,wBAAsB,UAAU,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,QAAQ,GACZ,OAAO,CAAC,aAAa,CAAC,CAqFxB"}