typescript-virtual-container 1.2.5 → 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.
- package/README.md +387 -193
- package/benchmark-results.txt +21 -21
- package/dist/SSHMimic/exec.js +2 -2
- package/dist/SSHMimic/executor.d.ts +6 -7
- package/dist/SSHMimic/executor.d.ts.map +1 -1
- package/dist/SSHMimic/executor.js +77 -60
- package/dist/SSHMimic/index.d.ts.map +1 -1
- package/dist/SSHMimic/index.js +6 -20
- package/dist/SSHMimic/sftp.d.ts.map +1 -1
- package/dist/SSHMimic/sftp.js +14 -0
- package/dist/VirtualFileSystem/index.d.ts.map +1 -1
- package/dist/VirtualFileSystem/index.js +13 -36
- package/dist/VirtualShell/shell.d.ts.map +1 -1
- package/dist/VirtualShell/shell.js +19 -2
- package/dist/VirtualShell/shellParser.d.ts +20 -2
- package/dist/VirtualShell/shellParser.d.ts.map +1 -1
- package/dist/VirtualShell/shellParser.js +229 -120
- package/dist/VirtualUserManager/index.d.ts.map +1 -1
- package/dist/commands/adduser.d.ts.map +1 -1
- package/dist/commands/adduser.js +2 -0
- package/dist/commands/awk.d.ts +3 -0
- package/dist/commands/awk.d.ts.map +1 -0
- package/dist/commands/awk.js +29 -0
- package/dist/commands/base64.d.ts +3 -0
- package/dist/commands/base64.d.ts.map +1 -0
- package/dist/commands/base64.js +20 -0
- package/dist/commands/cat.d.ts.map +1 -1
- package/dist/commands/cat.js +2 -0
- package/dist/commands/cd.d.ts.map +1 -1
- package/dist/commands/cd.js +2 -0
- package/dist/commands/chmod.d.ts.map +1 -1
- package/dist/commands/chmod.js +2 -0
- package/dist/commands/clear.d.ts.map +1 -1
- package/dist/commands/clear.js +4 -1
- package/dist/commands/cp.d.ts.map +1 -1
- package/dist/commands/cp.js +2 -0
- package/dist/commands/curl.d.ts.map +1 -1
- package/dist/commands/curl.js +2 -0
- package/dist/commands/cut.d.ts +3 -0
- package/dist/commands/cut.d.ts.map +1 -0
- package/dist/commands/cut.js +27 -0
- package/dist/commands/date.d.ts +3 -0
- package/dist/commands/date.d.ts.map +1 -0
- package/dist/commands/date.js +22 -0
- package/dist/commands/deluser.d.ts.map +1 -1
- package/dist/commands/deluser.js +2 -0
- package/dist/commands/df.d.ts +3 -0
- package/dist/commands/df.d.ts.map +1 -0
- package/dist/commands/df.js +16 -0
- package/dist/commands/diff.d.ts +3 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +40 -0
- package/dist/commands/du.d.ts +3 -0
- package/dist/commands/du.d.ts.map +1 -0
- package/dist/commands/du.js +39 -0
- package/dist/commands/echo.d.ts.map +1 -1
- package/dist/commands/echo.js +2 -0
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +6 -14
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +11 -21
- package/dist/commands/find.d.ts.map +1 -1
- package/dist/commands/find.js +2 -0
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +4 -7
- package/dist/commands/groups.d.ts +3 -0
- package/dist/commands/groups.d.ts.map +1 -0
- package/dist/commands/groups.js +12 -0
- package/dist/commands/gzip.d.ts +4 -0
- package/dist/commands/gzip.d.ts.map +1 -0
- package/dist/commands/gzip.js +40 -0
- package/dist/commands/head.d.ts.map +1 -1
- package/dist/commands/head.js +2 -0
- package/dist/commands/help.d.ts +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +75 -3
- package/dist/commands/hostname.d.ts.map +1 -1
- package/dist/commands/hostname.js +2 -0
- package/dist/commands/htop.d.ts.map +1 -1
- package/dist/commands/htop.js +2 -0
- package/dist/commands/id.d.ts +3 -0
- package/dist/commands/id.d.ts.map +1 -0
- package/dist/commands/id.js +14 -0
- package/dist/commands/index.d.ts +5 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +89 -62
- package/dist/commands/kill.d.ts +3 -0
- package/dist/commands/kill.d.ts.map +1 -0
- package/dist/commands/kill.js +13 -0
- package/dist/commands/ln.d.ts.map +1 -1
- package/dist/commands/ln.js +2 -0
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +2 -0
- package/dist/commands/mkdir.d.ts.map +1 -1
- package/dist/commands/mkdir.js +2 -0
- package/dist/commands/mv.d.ts.map +1 -1
- package/dist/commands/mv.js +2 -0
- package/dist/commands/nano.d.ts.map +1 -1
- package/dist/commands/nano.js +2 -0
- package/dist/commands/neofetch.d.ts.map +1 -1
- package/dist/commands/neofetch.js +2 -0
- package/dist/commands/passwd.d.ts.map +1 -1
- package/dist/commands/passwd.js +2 -0
- package/dist/commands/ping.d.ts +3 -0
- package/dist/commands/ping.d.ts.map +1 -0
- package/dist/commands/ping.js +18 -0
- package/dist/commands/ps.d.ts +3 -0
- package/dist/commands/ps.d.ts.map +1 -0
- package/dist/commands/ps.js +17 -0
- package/dist/commands/pwd.d.ts.map +1 -1
- package/dist/commands/pwd.js +2 -0
- package/dist/commands/rm.d.ts.map +1 -1
- package/dist/commands/rm.js +2 -0
- package/dist/commands/sed.d.ts +3 -0
- package/dist/commands/sed.d.ts.map +1 -0
- package/dist/commands/sed.js +47 -0
- package/dist/commands/set.d.ts +3 -0
- package/dist/commands/set.d.ts.map +1 -1
- package/dist/commands/set.js +19 -46
- package/dist/commands/sh.d.ts +0 -1
- package/dist/commands/sh.d.ts.map +1 -1
- package/dist/commands/sh.js +228 -35
- package/dist/commands/sleep.d.ts +3 -0
- package/dist/commands/sleep.d.ts.map +1 -0
- package/dist/commands/sleep.js +13 -0
- package/dist/commands/sort.d.ts +3 -0
- package/dist/commands/sort.d.ts.map +1 -0
- package/dist/commands/sort.js +37 -0
- package/dist/commands/su.d.ts.map +1 -1
- package/dist/commands/su.js +2 -0
- package/dist/commands/sudo.d.ts.map +1 -1
- package/dist/commands/sudo.js +2 -0
- package/dist/commands/tail.d.ts.map +1 -1
- package/dist/commands/tail.js +2 -0
- package/dist/commands/tar.d.ts +3 -0
- package/dist/commands/tar.d.ts.map +1 -0
- package/dist/commands/tar.js +64 -0
- package/dist/commands/tee.d.ts +3 -0
- package/dist/commands/tee.d.ts.map +1 -0
- package/dist/commands/tee.js +29 -0
- package/dist/commands/touch.d.ts.map +1 -1
- package/dist/commands/touch.js +2 -0
- package/dist/commands/tr.d.ts +3 -0
- package/dist/commands/tr.d.ts.map +1 -0
- package/dist/commands/tr.js +24 -0
- package/dist/commands/tree.d.ts.map +1 -1
- package/dist/commands/tree.js +2 -0
- package/dist/commands/uname.d.ts +3 -0
- package/dist/commands/uname.d.ts.map +1 -0
- package/dist/commands/uname.js +21 -0
- package/dist/commands/uniq.d.ts +3 -0
- package/dist/commands/uniq.d.ts.map +1 -0
- package/dist/commands/uniq.js +33 -0
- package/dist/commands/unset.d.ts.map +1 -1
- package/dist/commands/unset.js +6 -10
- package/dist/commands/wc.d.ts.map +1 -1
- package/dist/commands/wc.js +2 -0
- package/dist/commands/wget.d.ts.map +1 -1
- package/dist/commands/wget.js +2 -0
- package/dist/commands/who.d.ts.map +1 -1
- package/dist/commands/who.js +2 -0
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +2 -0
- package/dist/commands/xargs.d.ts +3 -0
- package/dist/commands/xargs.d.ts.map +1 -0
- package/dist/commands/xargs.js +16 -0
- package/dist/types/commands.d.ts +13 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/pipeline.d.ts +20 -0
- package/dist/types/pipeline.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/SSHMimic/exec.ts +2 -2
- package/src/SSHMimic/executor.ts +95 -98
- package/src/SSHMimic/index.ts +15 -49
- package/src/SSHMimic/sftp.ts +15 -0
- package/src/VirtualFileSystem/index.ts +27 -75
- package/src/VirtualShell/shell.ts +19 -2
- package/src/VirtualShell/shellParser.ts +202 -168
- package/src/VirtualUserManager/index.ts +2 -7
- package/src/commands/adduser.ts +2 -0
- package/src/commands/awk.ts +30 -0
- package/src/commands/base64.ts +18 -0
- package/src/commands/cat.ts +2 -0
- package/src/commands/cd.ts +2 -0
- package/src/commands/chmod.ts +2 -0
- package/src/commands/clear.ts +4 -1
- package/src/commands/cp.ts +2 -0
- package/src/commands/curl.ts +2 -0
- package/src/commands/cut.ts +29 -0
- package/src/commands/date.ts +24 -0
- package/src/commands/deluser.ts +2 -0
- package/src/commands/df.ts +18 -0
- package/src/commands/diff.ts +29 -0
- package/src/commands/du.ts +39 -0
- package/src/commands/echo.ts +2 -0
- package/src/commands/env.ts +6 -16
- package/src/commands/export.ts +11 -24
- package/src/commands/find.ts +2 -0
- package/src/commands/grep.ts +4 -7
- package/src/commands/groups.ts +14 -0
- package/src/commands/gzip.ts +31 -0
- package/src/commands/head.ts +2 -0
- package/src/commands/help.ts +81 -3
- package/src/commands/hostname.ts +2 -0
- package/src/commands/htop.ts +2 -0
- package/src/commands/id.ts +16 -0
- package/src/commands/index.ts +98 -99
- package/src/commands/kill.ts +14 -0
- package/src/commands/ln.ts +2 -0
- package/src/commands/ls.ts +2 -0
- package/src/commands/mkdir.ts +2 -0
- package/src/commands/mv.ts +2 -0
- package/src/commands/nano.ts +2 -0
- package/src/commands/neofetch.ts +2 -0
- package/src/commands/passwd.ts +2 -0
- package/src/commands/ping.ts +20 -0
- package/src/commands/ps.ts +19 -0
- package/src/commands/pwd.ts +2 -0
- package/src/commands/rm.ts +2 -0
- package/src/commands/sed.ts +45 -0
- package/src/commands/set.ts +19 -50
- package/src/commands/sh.ts +192 -43
- package/src/commands/sleep.ts +14 -0
- package/src/commands/sort.ts +37 -0
- package/src/commands/su.ts +2 -0
- package/src/commands/sudo.ts +2 -0
- package/src/commands/tail.ts +2 -0
- package/src/commands/tar.ts +58 -0
- package/src/commands/tee.ts +25 -0
- package/src/commands/touch.ts +2 -0
- package/src/commands/tr.ts +24 -0
- package/src/commands/tree.ts +2 -0
- package/src/commands/uname.ts +20 -0
- package/src/commands/uniq.ts +28 -0
- package/src/commands/unset.ts +5 -12
- package/src/commands/wc.ts +2 -0
- package/src/commands/wget.ts +2 -0
- package/src/commands/who.ts +2 -0
- package/src/commands/whoami.ts +2 -0
- package/src/commands/xargs.ts +17 -0
- package/src/types/commands.ts +14 -0
- package/src/types/pipeline.ts +23 -0
- package/standalone.js +92 -64
- package/standalone.js.map +4 -4
- package/tests/users.test.ts +5 -34
package/dist/commands/index.js
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import { adduserCommand } from "./adduser";
|
|
2
|
+
import { awkCommand } from "./awk";
|
|
3
|
+
import { base64Command } from "./base64";
|
|
2
4
|
import { catCommand } from "./cat";
|
|
3
5
|
import { cdCommand } from "./cd";
|
|
4
6
|
import { chmodCommand } from "./chmod";
|
|
5
7
|
import { clearCommand } from "./clear";
|
|
6
8
|
import { cpCommand } from "./cp";
|
|
7
9
|
import { curlCommand } from "./curl";
|
|
10
|
+
import { cutCommand } from "./cut";
|
|
11
|
+
import { dateCommand } from "./date";
|
|
8
12
|
import { deluserCommand } from "./deluser";
|
|
13
|
+
import { dfCommand } from "./df";
|
|
14
|
+
import { diffCommand } from "./diff";
|
|
15
|
+
import { duCommand } from "./du";
|
|
9
16
|
import { echoCommand } from "./echo";
|
|
10
17
|
import { envCommand } from "./env";
|
|
11
18
|
import { exitCommand } from "./exit";
|
|
12
19
|
import { exportCommand } from "./export";
|
|
13
20
|
import { findCommand } from "./find";
|
|
14
21
|
import { grepCommand } from "./grep";
|
|
22
|
+
import { groupsCommand } from "./groups";
|
|
23
|
+
import { gunzipCommand, gzipCommand } from "./gzip";
|
|
15
24
|
import { headCommand } from "./head";
|
|
16
25
|
import { createHelpCommand } from "./help";
|
|
17
26
|
import { hostnameCommand } from "./hostname";
|
|
18
27
|
import { htopCommand } from "./htop";
|
|
28
|
+
import { idCommand } from "./id";
|
|
29
|
+
import { killCommand } from "./kill";
|
|
19
30
|
import { lnCommand } from "./ln";
|
|
20
31
|
import { lsCommand } from "./ls";
|
|
21
32
|
import { mkdirCommand } from "./mkdir";
|
|
@@ -23,71 +34,68 @@ import { mvCommand } from "./mv";
|
|
|
23
34
|
import { nanoCommand } from "./nano";
|
|
24
35
|
import { neofetchCommand } from "./neofetch";
|
|
25
36
|
import { passwdCommand } from "./passwd";
|
|
37
|
+
import { pingCommand } from "./ping";
|
|
38
|
+
import { psCommand } from "./ps";
|
|
26
39
|
import { pwdCommand } from "./pwd";
|
|
27
40
|
import { rmCommand } from "./rm";
|
|
41
|
+
import { sedCommand } from "./sed";
|
|
28
42
|
import { setCommand } from "./set";
|
|
29
43
|
import { shCommand } from "./sh";
|
|
44
|
+
import { sleepCommand } from "./sleep";
|
|
45
|
+
import { sortCommand } from "./sort";
|
|
30
46
|
import { suCommand } from "./su";
|
|
31
47
|
import { sudoCommand } from "./sudo";
|
|
32
48
|
import { tailCommand } from "./tail";
|
|
49
|
+
import { tarCommand } from "./tar";
|
|
50
|
+
import { teeCommand } from "./tee";
|
|
33
51
|
import { touchCommand } from "./touch";
|
|
52
|
+
import { trCommand } from "./tr";
|
|
34
53
|
import { treeCommand } from "./tree";
|
|
54
|
+
import { unameCommand } from "./uname";
|
|
55
|
+
import { uniqCommand } from "./uniq";
|
|
35
56
|
import { unsetCommand } from "./unset";
|
|
36
57
|
import { wcCommand } from "./wc";
|
|
37
58
|
import { wgetCommand } from "./wget";
|
|
38
59
|
import { whoCommand } from "./who";
|
|
39
60
|
import { whoamiCommand } from "./whoami";
|
|
61
|
+
import { xargsCommand } from "./xargs";
|
|
40
62
|
const BASE_COMMANDS = [
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
// Navigation
|
|
64
|
+
pwdCommand, cdCommand, lsCommand, treeCommand,
|
|
65
|
+
// Files
|
|
66
|
+
catCommand, touchCommand, rmCommand, mkdirCommand, cpCommand, mvCommand, lnCommand,
|
|
67
|
+
chmodCommand, findCommand,
|
|
68
|
+
// Text processing
|
|
69
|
+
grepCommand, sedCommand, awkCommand, sortCommand, uniqCommand, wcCommand,
|
|
70
|
+
headCommand, tailCommand, cutCommand, trCommand, teeCommand, xargsCommand,
|
|
71
|
+
diffCommand,
|
|
72
|
+
// Archives
|
|
73
|
+
tarCommand, gzipCommand, gunzipCommand, base64Command,
|
|
74
|
+
// System info
|
|
75
|
+
whoamiCommand, whoCommand, hostnameCommand, idCommand, groupsCommand, unameCommand,
|
|
76
|
+
psCommand, killCommand, dfCommand, duCommand, dateCommand, sleepCommand, pingCommand,
|
|
77
|
+
// Shell
|
|
78
|
+
echoCommand, envCommand, exportCommand, setCommand, unsetCommand, shCommand,
|
|
79
|
+
clearCommand, exitCommand,
|
|
80
|
+
// Editors
|
|
81
|
+
nanoCommand, htopCommand,
|
|
82
|
+
// Network
|
|
83
|
+
curlCommand, wgetCommand,
|
|
84
|
+
// Users
|
|
85
|
+
adduserCommand, passwdCommand, deluserCommand, sudoCommand, suCommand,
|
|
86
|
+
// Misc
|
|
54
87
|
neofetchCommand,
|
|
55
|
-
htopCommand,
|
|
56
|
-
adduserCommand,
|
|
57
|
-
passwdCommand,
|
|
58
|
-
deluserCommand,
|
|
59
|
-
sudoCommand,
|
|
60
|
-
suCommand,
|
|
61
|
-
curlCommand,
|
|
62
|
-
envCommand,
|
|
63
|
-
wgetCommand,
|
|
64
|
-
grepCommand,
|
|
65
|
-
exportCommand,
|
|
66
|
-
setCommand,
|
|
67
|
-
unsetCommand,
|
|
68
|
-
shCommand,
|
|
69
|
-
clearCommand,
|
|
70
|
-
exitCommand,
|
|
71
|
-
cpCommand,
|
|
72
|
-
mvCommand,
|
|
73
|
-
lnCommand,
|
|
74
|
-
findCommand,
|
|
75
|
-
wcCommand,
|
|
76
|
-
headCommand,
|
|
77
|
-
tailCommand,
|
|
78
|
-
chmodCommand,
|
|
79
88
|
];
|
|
80
89
|
const customCommands = [];
|
|
81
|
-
const helpCommand = createHelpCommand(() => getCommandModules().map((cmd) => cmd.name));
|
|
82
90
|
const commandRegistry = new Map();
|
|
83
91
|
let cachedCommandNames = null;
|
|
92
|
+
const helpCommand = createHelpCommand(() => getCommandModules().map((cmd) => cmd.name));
|
|
84
93
|
function buildCache() {
|
|
85
94
|
commandRegistry.clear();
|
|
86
95
|
for (const mod of getCommandModules()) {
|
|
87
96
|
commandRegistry.set(mod.name, mod);
|
|
88
|
-
for (const alias of mod.aliases ?? [])
|
|
97
|
+
for (const alias of mod.aliases ?? [])
|
|
89
98
|
commandRegistry.set(alias, mod);
|
|
90
|
-
}
|
|
91
99
|
}
|
|
92
100
|
cachedCommandNames = Array.from(commandRegistry.keys()).sort();
|
|
93
101
|
}
|
|
@@ -98,11 +106,11 @@ export function registerCommand(module) {
|
|
|
98
106
|
const normalized = {
|
|
99
107
|
...module,
|
|
100
108
|
name: module.name.trim().toLowerCase(),
|
|
101
|
-
aliases: module.aliases?.map((
|
|
109
|
+
aliases: module.aliases?.map((a) => a.trim().toLowerCase()),
|
|
102
110
|
};
|
|
103
111
|
const names = [normalized.name, ...(normalized.aliases ?? [])];
|
|
104
|
-
if (names.some((
|
|
105
|
-
throw new Error("Command names
|
|
112
|
+
if (names.some((n) => n.length === 0 || /\s/.test(n))) {
|
|
113
|
+
throw new Error("Command names must be non-empty and contain no spaces");
|
|
106
114
|
}
|
|
107
115
|
customCommands.push(normalized);
|
|
108
116
|
buildCache();
|
|
@@ -115,6 +123,9 @@ export function getCommandNames() {
|
|
|
115
123
|
buildCache();
|
|
116
124
|
return cachedCommandNames;
|
|
117
125
|
}
|
|
126
|
+
export function getCommandModulesPublic() {
|
|
127
|
+
return getCommandModules();
|
|
128
|
+
}
|
|
118
129
|
export function resolveModule(name) {
|
|
119
130
|
if (!cachedCommandNames)
|
|
120
131
|
buildCache();
|
|
@@ -125,7 +136,7 @@ function splitArgsRespectingQuotes(input) {
|
|
|
125
136
|
let current = "";
|
|
126
137
|
let inQuotes = false;
|
|
127
138
|
let quoteChar = "";
|
|
128
|
-
for (let i = 0; i < input.length; i
|
|
139
|
+
for (let i = 0; i < input.length; i++) {
|
|
129
140
|
const ch = input[i] || "";
|
|
130
141
|
const prev = i > 0 ? input[i - 1] : "";
|
|
131
142
|
if ((ch === '"' || ch === "'") && prev !== "\\") {
|
|
@@ -155,35 +166,51 @@ function splitArgsRespectingQuotes(input) {
|
|
|
155
166
|
}
|
|
156
167
|
function parseInput(rawInput) {
|
|
157
168
|
const parts = splitArgsRespectingQuotes(rawInput.trim());
|
|
169
|
+
return { commandName: parts[0]?.toLowerCase() ?? "", args: parts.slice(1) };
|
|
170
|
+
}
|
|
171
|
+
export function makeDefaultEnv(authUser, hostname) {
|
|
158
172
|
return {
|
|
159
|
-
|
|
160
|
-
|
|
173
|
+
vars: {
|
|
174
|
+
PATH: "/usr/local/bin:/usr/bin:/bin",
|
|
175
|
+
HOME: `/home/${authUser}`,
|
|
176
|
+
USER: authUser,
|
|
177
|
+
LOGNAME: authUser,
|
|
178
|
+
SHELL: "/bin/sh",
|
|
179
|
+
TERM: "xterm-256color",
|
|
180
|
+
HOSTNAME: hostname,
|
|
181
|
+
PS1: "\\u@\\h:\\w\\$ ",
|
|
182
|
+
},
|
|
183
|
+
lastExitCode: 0,
|
|
161
184
|
};
|
|
162
185
|
}
|
|
163
|
-
export async function runCommand(rawInput, authUser, hostname, mode, cwd, shell, stdin) {
|
|
186
|
+
export async function runCommand(rawInput, authUser, hostname, mode, cwd, shell, stdin, env) {
|
|
164
187
|
const trimmed = rawInput.trim();
|
|
165
188
|
if (trimmed.length === 0)
|
|
166
189
|
return { exitCode: 0 };
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
190
|
+
const shellEnv = env ?? makeDefaultEnv(authUser, hostname);
|
|
191
|
+
// Detect shell operators
|
|
192
|
+
if (/(?<![|&])[|](?![|])/.test(trimmed) ||
|
|
193
|
+
trimmed.includes(">") ||
|
|
194
|
+
trimmed.includes("<") ||
|
|
195
|
+
trimmed.includes("&&") ||
|
|
196
|
+
trimmed.includes("||") ||
|
|
197
|
+
trimmed.includes(";")) {
|
|
198
|
+
const { parseScript } = await import("../VirtualShell/shellParser");
|
|
199
|
+
const { executeStatements } = await import("../SSHMimic/executor");
|
|
200
|
+
const script = parseScript(trimmed);
|
|
201
|
+
if (!script.isValid)
|
|
202
|
+
return { stderr: script.error || "Syntax error", exitCode: 1 };
|
|
174
203
|
try {
|
|
175
|
-
return await
|
|
204
|
+
return await executeStatements(script.statements, authUser, hostname, mode, cwd, shell, shellEnv);
|
|
176
205
|
}
|
|
177
206
|
catch (error) {
|
|
178
|
-
|
|
179
|
-
return { stderr: message, exitCode: 1 };
|
|
207
|
+
return { stderr: error instanceof Error ? error.message : "Execution failed", exitCode: 1 };
|
|
180
208
|
}
|
|
181
209
|
}
|
|
182
210
|
const { commandName, args } = parseInput(trimmed);
|
|
183
211
|
const mod = resolveModule(commandName);
|
|
184
|
-
if (!mod)
|
|
185
|
-
return { stderr:
|
|
186
|
-
}
|
|
212
|
+
if (!mod)
|
|
213
|
+
return { stderr: `${commandName}: command not found`, exitCode: 127 };
|
|
187
214
|
try {
|
|
188
215
|
return await mod.run({
|
|
189
216
|
authUser,
|
|
@@ -195,10 +222,10 @@ export async function runCommand(rawInput, authUser, hostname, mode, cwd, shell,
|
|
|
195
222
|
stdin,
|
|
196
223
|
cwd,
|
|
197
224
|
shell,
|
|
225
|
+
env: shellEnv,
|
|
198
226
|
});
|
|
199
227
|
}
|
|
200
228
|
catch (error) {
|
|
201
|
-
|
|
202
|
-
return { stderr: message, exitCode: 1 };
|
|
229
|
+
return { stderr: error instanceof Error ? error.message : "Command failed", exitCode: 1 };
|
|
203
230
|
}
|
|
204
231
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kill.d.ts","sourceRoot":"","sources":["../../src/commands/kill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,WAAW,EAAE,WAWzB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const killCommand = {
|
|
2
|
+
name: "kill",
|
|
3
|
+
description: "Send signal to process",
|
|
4
|
+
category: "system",
|
|
5
|
+
params: ["[-9] <pid>"],
|
|
6
|
+
run: ({ args }) => {
|
|
7
|
+
const pid = args.find((a) => !a.startsWith("-"));
|
|
8
|
+
if (!pid)
|
|
9
|
+
return { stderr: "kill: no pid specified", exitCode: 1 };
|
|
10
|
+
// In virtual env, we just acknowledge the kill
|
|
11
|
+
return { stdout: ``, exitCode: 0 };
|
|
12
|
+
},
|
|
13
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ln.d.ts","sourceRoot":"","sources":["../../src/commands/ln.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"ln.d.ts","sourceRoot":"","sources":["../../src/commands/ln.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,SAAS,EAAE,WA4CvB,CAAC"}
|
package/dist/commands/ln.js
CHANGED
|
@@ -2,6 +2,8 @@ import { ifFlag } from "./command-helpers";
|
|
|
2
2
|
import { assertPathAccess, resolvePath } from "./helpers";
|
|
3
3
|
export const lnCommand = {
|
|
4
4
|
name: "ln",
|
|
5
|
+
description: "Create links",
|
|
6
|
+
category: "files",
|
|
5
7
|
params: ["[-s] <target> <link_name>"],
|
|
6
8
|
run: ({ authUser, shell, cwd, args }) => {
|
|
7
9
|
const symbolic = ifFlag(args, ["-s", "--symbolic"]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA4BrD,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA4BrD,eAAO,MAAM,SAAS,EAAE,WAyBvB,CAAC"}
|
package/dist/commands/ls.js
CHANGED
|
@@ -23,6 +23,8 @@ function formatDate(date) {
|
|
|
23
23
|
}
|
|
24
24
|
export const lsCommand = {
|
|
25
25
|
name: "ls",
|
|
26
|
+
description: "List directory contents",
|
|
27
|
+
category: "navigation",
|
|
26
28
|
params: ["[path]"],
|
|
27
29
|
run: ({ authUser, shell, cwd, args }) => {
|
|
28
30
|
const longFormat = ifFlag(args, ["-l", "--long"]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mkdir.d.ts","sourceRoot":"","sources":["../../src/commands/mkdir.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"mkdir.d.ts","sourceRoot":"","sources":["../../src/commands/mkdir.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,YAAY,EAAE,WAqB1B,CAAC"}
|
package/dist/commands/mkdir.js
CHANGED
|
@@ -2,6 +2,8 @@ import { getArg } from "./command-helpers";
|
|
|
2
2
|
import { assertPathAccess, resolvePath } from "./helpers";
|
|
3
3
|
export const mkdirCommand = {
|
|
4
4
|
name: "mkdir",
|
|
5
|
+
description: "Make directories",
|
|
6
|
+
category: "files",
|
|
5
7
|
params: ["<dir>"],
|
|
6
8
|
run: ({ authUser, shell, cwd, args }) => {
|
|
7
9
|
if (args.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mv.d.ts","sourceRoot":"","sources":["../../src/commands/mv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"mv.d.ts","sourceRoot":"","sources":["../../src/commands/mv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,SAAS,EAAE,WAyCvB,CAAC"}
|
package/dist/commands/mv.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { assertPathAccess, resolvePath } from "./helpers";
|
|
2
2
|
export const mvCommand = {
|
|
3
3
|
name: "mv",
|
|
4
|
+
description: "Move or rename files",
|
|
5
|
+
category: "files",
|
|
4
6
|
params: ["<source> <dest>"],
|
|
5
7
|
run: ({ authUser, shell, cwd, args }) => {
|
|
6
8
|
const positionals = args.filter((a) => !a.startsWith("-"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nano.d.ts","sourceRoot":"","sources":["../../src/commands/nano.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"nano.d.ts","sourceRoot":"","sources":["../../src/commands/nano.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,WAAW,EAAE,WA4BzB,CAAC"}
|
package/dist/commands/nano.js
CHANGED
|
@@ -2,6 +2,8 @@ import * as path from "node:path";
|
|
|
2
2
|
import { assertPathAccess, resolvePath } from "./helpers";
|
|
3
3
|
export const nanoCommand = {
|
|
4
4
|
name: "nano",
|
|
5
|
+
description: "Text editor",
|
|
6
|
+
category: "shell",
|
|
5
7
|
params: ["<file>"],
|
|
6
8
|
run: ({ authUser, shell, cwd, args }) => {
|
|
7
9
|
const fileArg = args[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neofetch.d.ts","sourceRoot":"","sources":["../../src/commands/neofetch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"neofetch.d.ts","sourceRoot":"","sources":["../../src/commands/neofetch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,eAAe,EAAE,WAiC7B,CAAC"}
|
|
@@ -3,6 +3,8 @@ import { ifFlag } from "./command-helpers";
|
|
|
3
3
|
import { getAllEnvVars } from "./set";
|
|
4
4
|
export const neofetchCommand = {
|
|
5
5
|
name: "neofetch",
|
|
6
|
+
description: "System info display",
|
|
7
|
+
category: "misc",
|
|
6
8
|
params: ["[--off]"],
|
|
7
9
|
run: ({ args, authUser, hostname, shell }) => {
|
|
8
10
|
const env = getAllEnvVars(authUser);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passwd.d.ts","sourceRoot":"","sources":["../../src/commands/passwd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"passwd.d.ts","sourceRoot":"","sources":["../../src/commands/passwd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,aAAa,EAAE,WAwB3B,CAAC"}
|
package/dist/commands/passwd.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ping.d.ts","sourceRoot":"","sources":["../../src/commands/ping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,WAAW,EAAE,WAiBzB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const pingCommand = {
|
|
2
|
+
name: "ping",
|
|
3
|
+
description: "Send ICMP ECHO_REQUEST (mock)",
|
|
4
|
+
category: "network",
|
|
5
|
+
params: ["[-c <count>] <host>"],
|
|
6
|
+
run: ({ args }) => {
|
|
7
|
+
const host = args.find((a) => !a.startsWith("-")) ?? "localhost";
|
|
8
|
+
const count = 4;
|
|
9
|
+
const lines = [`PING ${host}: 56 data bytes`];
|
|
10
|
+
for (let i = 0; i < count; i++) {
|
|
11
|
+
const ms = (Math.random() * 10 + 1).toFixed(3);
|
|
12
|
+
lines.push(`64 bytes from ${host}: icmp_seq=${i} ttl=64 time=${ms} ms`);
|
|
13
|
+
}
|
|
14
|
+
lines.push(`--- ${host} ping statistics ---`);
|
|
15
|
+
lines.push(`${count} packets transmitted, ${count} received, 0% packet loss`);
|
|
16
|
+
return { stdout: lines.join("\n"), exitCode: 0 };
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ps.d.ts","sourceRoot":"","sources":["../../src/commands/ps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,SAAS,EAAE,WAgBvB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const psCommand = {
|
|
2
|
+
name: "ps",
|
|
3
|
+
description: "Report process status",
|
|
4
|
+
category: "system",
|
|
5
|
+
params: ["[-a] [-u] [-x]"],
|
|
6
|
+
run: ({ authUser, shell }) => {
|
|
7
|
+
const sessions = shell.users.listActiveSessions();
|
|
8
|
+
const lines = [" PID TTY TIME CMD"];
|
|
9
|
+
let pid = 1000;
|
|
10
|
+
for (const s of sessions) {
|
|
11
|
+
lines.push(`${String(pid).padStart(5)} ${s.tty.padEnd(12)} 00:00:00 ${s.username === authUser ? "bash" : `bash (${s.username})`}`);
|
|
12
|
+
pid++;
|
|
13
|
+
}
|
|
14
|
+
lines.push(`${String(pid).padStart(5)} pts/0 00:00:00 ps`);
|
|
15
|
+
return { stdout: lines.join("\n"), exitCode: 0 };
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwd.d.ts","sourceRoot":"","sources":["../../src/commands/pwd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"pwd.d.ts","sourceRoot":"","sources":["../../src/commands/pwd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,UAAU,EAAE,WAMxB,CAAC"}
|
package/dist/commands/pwd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rm.d.ts","sourceRoot":"","sources":["../../src/commands/rm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"rm.d.ts","sourceRoot":"","sources":["../../src/commands/rm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,SAAS,EAAE,WAgCvB,CAAC"}
|
package/dist/commands/rm.js
CHANGED
|
@@ -2,6 +2,8 @@ import { getArg, ifFlag } from "./command-helpers";
|
|
|
2
2
|
import { assertPathAccess, resolvePath } from "./helpers";
|
|
3
3
|
export const rmCommand = {
|
|
4
4
|
name: "rm",
|
|
5
|
+
description: "Remove files or directories",
|
|
6
|
+
category: "files",
|
|
5
7
|
params: ["[-r|-rf] <path>"],
|
|
6
8
|
run: ({ authUser, shell, cwd, args }) => {
|
|
7
9
|
if (args.length === 0) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sed.d.ts","sourceRoot":"","sources":["../../src/commands/sed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,eAAO,MAAM,UAAU,EAAE,WAwCxB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getFlag, ifFlag } from "./command-helpers";
|
|
2
|
+
import { resolvePath } from "./helpers";
|
|
3
|
+
export const sedCommand = {
|
|
4
|
+
name: "sed",
|
|
5
|
+
description: "Stream editor for filtering and transforming text",
|
|
6
|
+
category: "text",
|
|
7
|
+
params: ["-e <expr> [file]", "s/pattern/replace/[g]"],
|
|
8
|
+
run: ({ authUser, shell, cwd, args, stdin }) => {
|
|
9
|
+
const inPlace = ifFlag(args, ["-i"]);
|
|
10
|
+
const expr = getFlag(args, ["-e"]) ?? args.find((a) => !a.startsWith("-"));
|
|
11
|
+
const fileArg = args.filter((a) => !a.startsWith("-") && a !== expr).pop();
|
|
12
|
+
if (!expr)
|
|
13
|
+
return { stderr: "sed: no expression", exitCode: 1 };
|
|
14
|
+
let content = stdin ?? "";
|
|
15
|
+
if (fileArg) {
|
|
16
|
+
const p = resolvePath(cwd, fileArg);
|
|
17
|
+
try {
|
|
18
|
+
content = shell.vfs.readFile(p);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { stderr: `sed: ${fileArg}: No such file or directory`, exitCode: 1 };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Parse s/from/to/[g]
|
|
25
|
+
const sMatch = expr.match(/^s([^a-zA-Z0-9])(.+?)\1(.*?)\1([gi]*)$/);
|
|
26
|
+
if (!sMatch)
|
|
27
|
+
return { stderr: `sed: unrecognized command: ${expr}`, exitCode: 1 };
|
|
28
|
+
const [, , from, to, flags] = sMatch;
|
|
29
|
+
const regexFlags = (flags ?? "").includes("i") ? "gi" : (flags ?? "").includes("g") ? "g" : "";
|
|
30
|
+
let regex;
|
|
31
|
+
try {
|
|
32
|
+
regex = new RegExp(from, regexFlags || "");
|
|
33
|
+
}
|
|
34
|
+
catch (_e) {
|
|
35
|
+
return { stderr: `sed: invalid regex: ${from}`, exitCode: 1 };
|
|
36
|
+
}
|
|
37
|
+
const result = (flags ?? "").includes("g") || regexFlags.includes("g")
|
|
38
|
+
? content.replace(regex, to ?? "")
|
|
39
|
+
: content.replace(regex, to ?? "");
|
|
40
|
+
if (inPlace && fileArg) {
|
|
41
|
+
const p = resolvePath(cwd, fileArg);
|
|
42
|
+
shell.writeFileAsUser(authUser, p, result);
|
|
43
|
+
return { exitCode: 0 };
|
|
44
|
+
}
|
|
45
|
+
return { stdout: result, exitCode: 0 };
|
|
46
|
+
},
|
|
47
|
+
};
|
package/dist/commands/set.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/** biome-ignore-all lint/style/useNamingConvention: env variables */
|
|
2
2
|
import type { ShellModule } from "../types/commands";
|
|
3
|
+
/** @deprecated use env.vars from CommandContext */
|
|
3
4
|
export declare function getEnvVar(name: string): string | undefined;
|
|
5
|
+
/** @deprecated use env.vars from CommandContext */
|
|
4
6
|
export declare function setEnvVar(name: string, value: string): void;
|
|
7
|
+
/** @deprecated use env.vars from CommandContext */
|
|
5
8
|
export declare function getAllEnvVars(authUser: string): Record<string, string>;
|
|
6
9
|
export declare const setCommand: ShellModule;
|
|
7
10
|
//# sourceMappingURL=set.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWrD,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAA6B;AACxF,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAA8B;AAC1F,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAItE;AAED,eAAO,MAAM,UAAU,EAAE,WAkBxB,CAAC"}
|
package/dist/commands/set.js
CHANGED
|
@@ -1,64 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// In a real implementation, this would be per-session/per-user
|
|
4
|
-
const envVars = {
|
|
1
|
+
// Legacy global store kept for compatibility with older callers
|
|
2
|
+
const _globalEnv = {
|
|
5
3
|
PATH: "/usr/local/bin:/usr/bin:/bin",
|
|
6
4
|
HOME: "/home/user",
|
|
7
5
|
SHELL: "/bin/sh",
|
|
8
6
|
TERM: "xterm-256color",
|
|
9
7
|
USER: "user",
|
|
10
8
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export function setEnvVar(name, value) {
|
|
15
|
-
|
|
16
|
-
}
|
|
9
|
+
/** @deprecated use env.vars from CommandContext */
|
|
10
|
+
export function getEnvVar(name) { return _globalEnv[name]; }
|
|
11
|
+
/** @deprecated use env.vars from CommandContext */
|
|
12
|
+
export function setEnvVar(name, value) { _globalEnv[name] = value; }
|
|
13
|
+
/** @deprecated use env.vars from CommandContext */
|
|
17
14
|
export function getAllEnvVars(authUser) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return { ...
|
|
15
|
+
_globalEnv.USER = authUser;
|
|
16
|
+
_globalEnv.HOME = `/home/${authUser}`;
|
|
17
|
+
return { ..._globalEnv };
|
|
21
18
|
}
|
|
22
19
|
export const setCommand = {
|
|
23
20
|
name: "set",
|
|
21
|
+
description: "Display or set shell variables",
|
|
22
|
+
category: "shell",
|
|
24
23
|
params: ["[VAR=value]"],
|
|
25
|
-
run: ({ args }) => {
|
|
26
|
-
// No arguments: display all environment variables
|
|
24
|
+
run: ({ args, env }) => {
|
|
27
25
|
if (args.length === 0) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
.sort()
|
|
31
|
-
.join("\n");
|
|
32
|
-
return { stdout: output, exitCode: 0 };
|
|
26
|
+
const out = Object.entries(env.vars).map(([k, v]) => `${k}=${v}`).join("\n");
|
|
27
|
+
return { stdout: out, exitCode: 0 };
|
|
33
28
|
}
|
|
34
|
-
|
|
35
|
-
const assignments = [];
|
|
36
|
-
for (let index = 0;; index += 1) {
|
|
37
|
-
const arg = getArg(args, index);
|
|
38
|
-
if (!arg) {
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
29
|
+
for (const arg of args) {
|
|
41
30
|
if (arg.includes("=")) {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
setEnvVar(varName, varValue);
|
|
45
|
-
assignments.push(arg);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
// If no '=' present, display that specific variable
|
|
50
|
-
const value = getEnvVar(arg);
|
|
51
|
-
if (value !== undefined) {
|
|
52
|
-
assignments.push(`${arg}=${value}`);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
assignments.push(`${arg}: not set`);
|
|
56
|
-
}
|
|
31
|
+
const eq = arg.indexOf("=");
|
|
32
|
+
env.vars[arg.slice(0, eq)] = arg.slice(eq + 1);
|
|
57
33
|
}
|
|
58
34
|
}
|
|
59
|
-
return {
|
|
60
|
-
stdout: assignments.length > 0 ? assignments.join("\n") : "",
|
|
61
|
-
exitCode: 0,
|
|
62
|
-
};
|
|
35
|
+
return { exitCode: 0 };
|
|
63
36
|
},
|
|
64
37
|
};
|
package/dist/commands/sh.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sh.d.ts","sourceRoot":"","sources":["../../src/commands/sh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"sh.d.ts","sourceRoot":"","sources":["../../src/commands/sh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiC,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA8KpF,eAAO,MAAM,SAAS,EAAE,WA+BvB,CAAC"}
|