typescript-virtual-container 1.5.11 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -456
- package/dist/.tsbuildinfo +1 -1
- package/dist/Honeypot/index.d.ts +9 -0
- package/dist/Honeypot/index.js +57 -0
- package/dist/SSHMimic/exec.d.ts +4 -0
- package/dist/SSHMimic/exec.js +4 -0
- package/dist/SSHMimic/executor.d.ts +10 -1
- package/dist/SSHMimic/executor.js +18 -8
- package/dist/SSHMimic/hostKey.d.ts +5 -0
- package/dist/SSHMimic/hostKey.js +5 -0
- package/dist/SSHMimic/loginBanner.d.ts +7 -0
- package/dist/SSHMimic/loginBanner.js +4 -0
- package/dist/SSHMimic/loginFormat.d.ts +4 -0
- package/dist/SSHMimic/loginFormat.js +4 -0
- package/dist/SSHMimic/prompt.d.ts +9 -0
- package/dist/SSHMimic/prompt.js +9 -0
- package/dist/SSHMimic/scp.d.ts +18 -0
- package/dist/SSHMimic/scp.js +14 -0
- package/dist/VirtualFileSystem/binaryPack.d.ts +7 -3
- package/dist/VirtualFileSystem/binaryPack.js +32 -10
- package/dist/VirtualFileSystem/index.d.ts +29 -0
- package/dist/VirtualFileSystem/index.js +126 -5
- package/dist/VirtualFileSystem/internalTypes.d.ts +4 -0
- package/dist/VirtualFileSystem/journal.d.ts +10 -4
- package/dist/VirtualFileSystem/journal.js +12 -2
- package/dist/VirtualFileSystem/path.d.ts +23 -1
- package/dist/VirtualFileSystem/path.js +23 -3
- package/dist/VirtualPackageManager/index.js +1 -1
- package/dist/VirtualShell/index.d.ts +3 -0
- package/dist/VirtualShell/index.js +12 -3
- package/dist/VirtualUserManager/index.d.ts +20 -1
- package/dist/VirtualUserManager/index.js +52 -15
- package/dist/commands/bc.d.ts +5 -0
- package/dist/commands/bc.js +5 -0
- package/dist/commands/cat.js +2 -2
- package/dist/commands/chgrp.d.ts +7 -0
- package/dist/commands/chgrp.js +42 -0
- package/dist/commands/chown.d.ts +7 -0
- package/dist/commands/chown.js +79 -0
- package/dist/commands/cp.js +4 -3
- package/dist/commands/dd.d.ts +7 -0
- package/dist/commands/dd.js +60 -0
- package/dist/commands/declare.js +0 -2
- package/dist/commands/expr.d.ts +7 -0
- package/dist/commands/expr.js +63 -0
- package/dist/commands/fun.d.ts +5 -0
- package/dist/commands/fun.js +5 -1
- package/dist/commands/help.d.ts +5 -0
- package/dist/commands/help.js +5 -0
- package/dist/commands/helpers.d.ts +43 -0
- package/dist/commands/helpers.js +61 -0
- package/dist/commands/id.d.ts +5 -0
- package/dist/commands/id.js +5 -0
- package/dist/commands/ip.d.ts +1 -0
- package/dist/commands/ip.js +50 -23
- package/dist/commands/jobs.js +43 -9
- package/dist/commands/kill.d.ts +1 -0
- package/dist/commands/kill.js +13 -5
- package/dist/commands/last.js +1 -1
- package/dist/commands/ln.d.ts +5 -0
- package/dist/commands/ln.js +5 -0
- package/dist/commands/ls.d.ts +5 -0
- package/dist/commands/ls.js +19 -4
- package/dist/commands/lsb-release.js +1 -1
- package/dist/commands/man.d.ts +5 -0
- package/dist/commands/man.js +5 -0
- package/dist/commands/manuals-bundle.js +242 -0
- package/dist/commands/miscutils.d.ts +43 -0
- package/dist/commands/miscutils.js +233 -0
- package/dist/commands/mkdir.js +3 -2
- package/dist/commands/mv.js +4 -3
- package/dist/commands/netcat.d.ts +7 -0
- package/dist/commands/netcat.js +64 -0
- package/dist/commands/nice.d.ts +7 -0
- package/dist/commands/nice.js +22 -0
- package/dist/commands/nohup.d.ts +7 -0
- package/dist/commands/nohup.js +18 -0
- package/dist/commands/ping.d.ts +2 -1
- package/dist/commands/ping.js +46 -8
- package/dist/commands/procUtils.d.ts +13 -0
- package/dist/commands/procUtils.js +72 -0
- package/dist/commands/pwd.d.ts +5 -0
- package/dist/commands/pwd.js +5 -0
- package/dist/commands/python.js +0 -4
- package/dist/commands/read.js +0 -1
- package/dist/commands/registry.d.ts +37 -0
- package/dist/commands/registry.js +73 -0
- package/dist/commands/rm.js +3 -2
- package/dist/commands/runtime.d.ts +47 -1
- package/dist/commands/runtime.js +60 -5
- package/dist/commands/sh.d.ts +5 -0
- package/dist/commands/sh.js +5 -0
- package/dist/commands/stat.js +3 -2
- package/dist/commands/strace.js +0 -1
- package/dist/commands/sysinfo.d.ts +19 -0
- package/dist/commands/sysinfo.js +73 -0
- package/dist/commands/test.d.ts +5 -0
- package/dist/commands/test.js +5 -0
- package/dist/commands/textutils.d.ts +25 -0
- package/dist/commands/textutils.js +171 -0
- package/dist/commands/top.d.ts +7 -0
- package/dist/commands/top.js +54 -0
- package/dist/commands/touch.js +6 -2
- package/dist/commands/tr.d.ts +5 -0
- package/dist/commands/tr.js +5 -0
- package/dist/commands/w.js +1 -1
- package/dist/commands/which.d.ts +5 -0
- package/dist/commands/which.js +5 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.js +4 -0
- package/dist/modules/VirtualNetworkManager.d.ts +123 -0
- package/dist/modules/VirtualNetworkManager.js +201 -0
- package/dist/modules/linuxRootfs.d.ts +4 -3
- package/dist/modules/linuxRootfs.js +115 -74
- package/dist/modules/neofetch.d.ts +2 -0
- package/dist/modules/neofetch.js +3 -2
- package/dist/modules/pacmanGame.d.ts +2 -0
- package/dist/modules/pacmanGame.js +1 -0
- package/dist/modules/shellInteractive.d.ts +2 -0
- package/dist/modules/shellInteractive.js +2 -0
- package/dist/modules/shellRuntime.d.ts +7 -0
- package/dist/modules/shellRuntime.js +6 -0
- package/dist/modules/webTermRenderer.js +0 -7
- package/dist/types/commands.d.ts +1 -1
- package/dist/types/vfs.d.ts +8 -0
- package/dist/utils/argv.d.ts +22 -3
- package/dist/utils/argv.js +22 -3
- package/dist/utils/perfLogger.d.ts +10 -2
- package/dist/utils/perfLogger.js +7 -14
- package/dist/utils/shellSession.d.ts +35 -0
- package/dist/utils/shellSession.js +35 -0
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Netcat network utility
|
|
3
|
+
* @category net
|
|
4
|
+
* @params ["[-l] [-p port] [-v]"]
|
|
5
|
+
*/
|
|
6
|
+
export const ncCommand = {
|
|
7
|
+
name: "nc",
|
|
8
|
+
description: "Netcat network utility",
|
|
9
|
+
category: "net",
|
|
10
|
+
params: ["[-l] [-p port] [-v]"],
|
|
11
|
+
run: async ({ args }) => {
|
|
12
|
+
let mod;
|
|
13
|
+
try {
|
|
14
|
+
mod = await import("node:net");
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return { stderr: "nc: not available in this environment\n", exitCode: 1 };
|
|
18
|
+
}
|
|
19
|
+
const net = mod;
|
|
20
|
+
const isListen = args.includes("-l");
|
|
21
|
+
const pIdx = args.indexOf("-p");
|
|
22
|
+
const port = pIdx !== -1 && args[pIdx + 1] ? parseInt(args[pIdx + 1], 10) : undefined;
|
|
23
|
+
const verbose = args.includes("-v");
|
|
24
|
+
if (isListen && port) {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
const server = net.createServer((socket) => {
|
|
27
|
+
let data = "";
|
|
28
|
+
socket.on("data", (chunk) => { data += chunk.toString(); });
|
|
29
|
+
socket.on("end", () => {
|
|
30
|
+
server.close();
|
|
31
|
+
resolve({ stdout: data, exitCode: 0 });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
server.listen(port, () => {
|
|
35
|
+
if (verbose) {
|
|
36
|
+
resolve({ stdout: `Listening on port ${port}...\n`, exitCode: 0 });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
setTimeout(() => { server.close(); resolve({ exitCode: 0 }); }, 5000);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const nonFlag = args.filter((a) => !a.startsWith("-"));
|
|
43
|
+
const host = nonFlag[0];
|
|
44
|
+
const portNum = nonFlag[1] ? parseInt(nonFlag[1], 10) : NaN;
|
|
45
|
+
if (host && !isNaN(portNum)) {
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
const socket = net.createConnection({ host, port: portNum }, () => {
|
|
48
|
+
if (verbose) {
|
|
49
|
+
resolve({ stdout: `Connected to ${host}:${portNum}\n`, exitCode: 0 });
|
|
50
|
+
}
|
|
51
|
+
setTimeout(() => { socket.end(); resolve({ exitCode: 0 }); }, 3000);
|
|
52
|
+
});
|
|
53
|
+
socket.on("error", () => {
|
|
54
|
+
resolve({ stderr: `nc: connection to ${host}:${portNum} failed\n`, exitCode: 1 });
|
|
55
|
+
});
|
|
56
|
+
setTimeout(() => { socket.destroy(); resolve({ exitCode: 1 }); }, 5000);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
stderr: "nc: missing arguments. Usage: nc [-l] [-p port] [-v] [host] [port]\n",
|
|
61
|
+
exitCode: 1,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { parseArgs } from "./command-helpers";
|
|
2
|
+
import { runCommand } from "./runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Run command with adjusted niceness
|
|
5
|
+
* @category system
|
|
6
|
+
* @params ["[-n adjustment] <command> [args...]"]
|
|
7
|
+
*/
|
|
8
|
+
export const niceCommand = {
|
|
9
|
+
name: "nice",
|
|
10
|
+
description: "Run command with adjusted niceness",
|
|
11
|
+
category: "system",
|
|
12
|
+
params: ["[-n adjustment] <command> [args...]"],
|
|
13
|
+
run: async ({ authUser, hostname, mode, cwd, shell, stdin, env, args }) => {
|
|
14
|
+
const { positionals } = parseArgs(args, {
|
|
15
|
+
flagsWithValue: ["-n"],
|
|
16
|
+
});
|
|
17
|
+
const cmd = positionals.join(" ");
|
|
18
|
+
if (!cmd)
|
|
19
|
+
return { stderr: "nice: missing command\n", exitCode: 1 };
|
|
20
|
+
return runCommand(cmd, authUser, hostname, mode, cwd, shell, stdin, env);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { runCommand } from "./runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Run command immune to hup signals
|
|
4
|
+
* @category system
|
|
5
|
+
* @params ["<command> [args...]"]
|
|
6
|
+
*/
|
|
7
|
+
export const nohupCommand = {
|
|
8
|
+
name: "nohup",
|
|
9
|
+
description: "Run command immune to hup signals",
|
|
10
|
+
category: "system",
|
|
11
|
+
params: ["<command> [args...]"],
|
|
12
|
+
run: async ({ authUser, hostname, mode, cwd, shell, stdin, env, args }) => {
|
|
13
|
+
const cmd = args.join(" ");
|
|
14
|
+
if (!cmd)
|
|
15
|
+
return { stderr: "nohup: missing command\n", exitCode: 1 };
|
|
16
|
+
return runCommand(cmd, authUser, hostname, mode, cwd, shell, stdin, env);
|
|
17
|
+
},
|
|
18
|
+
};
|
package/dist/commands/ping.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ShellModule } from "../types/commands";
|
|
2
2
|
/**
|
|
3
|
-
* Send ICMP ECHO_REQUEST packets
|
|
3
|
+
* Send ICMP ECHO_REQUEST packets — uses the real host ping when available,
|
|
4
|
+
* falls back to VirtualNetworkManager simulation in browser or when system ping is absent.
|
|
4
5
|
* @category network
|
|
5
6
|
* @params ["[-c <count>] <host>"]
|
|
6
7
|
*/
|
package/dist/commands/ping.js
CHANGED
|
@@ -1,28 +1,66 @@
|
|
|
1
1
|
import { parseArgs } from "./command-helpers";
|
|
2
|
+
const isBrowser = typeof process === "undefined" || typeof process.versions?.node === "undefined";
|
|
3
|
+
/** Lazily import execSync — avoids static import that breaks browser polyfills. */
|
|
4
|
+
async function execPing(count, host) {
|
|
5
|
+
try {
|
|
6
|
+
const { execSync } = await import("node:child_process");
|
|
7
|
+
const output = execSync(`ping -c ${count} ${host}`, {
|
|
8
|
+
timeout: 30000,
|
|
9
|
+
encoding: "utf8",
|
|
10
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
11
|
+
});
|
|
12
|
+
return { stdout: output };
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
const stderrMsg = err instanceof Error ? err.stderr : "";
|
|
16
|
+
if (stderrMsg)
|
|
17
|
+
return { stderr: stderrMsg };
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
2
21
|
/**
|
|
3
|
-
* Send ICMP ECHO_REQUEST packets
|
|
22
|
+
* Send ICMP ECHO_REQUEST packets — uses the real host ping when available,
|
|
23
|
+
* falls back to VirtualNetworkManager simulation in browser or when system ping is absent.
|
|
4
24
|
* @category network
|
|
5
25
|
* @params ["[-c <count>] <host>"]
|
|
6
26
|
*/
|
|
7
27
|
export const pingCommand = {
|
|
8
28
|
name: "ping",
|
|
9
|
-
description: "Send ICMP ECHO_REQUEST
|
|
29
|
+
description: "Send ICMP ECHO_REQUEST to network hosts",
|
|
10
30
|
category: "network",
|
|
11
31
|
params: ["[-c <count>] <host>"],
|
|
12
|
-
run: ({ args }) => {
|
|
32
|
+
run: async ({ args, shell }) => {
|
|
13
33
|
const { flagsWithValues, positionals } = parseArgs(args, {
|
|
14
34
|
flagsWithValue: ["-c", "-i", "-W"],
|
|
15
35
|
});
|
|
16
36
|
const host = positionals[0] ?? "localhost";
|
|
17
37
|
const countArg = flagsWithValues.get("-c");
|
|
18
38
|
const count = countArg ? Math.max(1, parseInt(countArg, 10) || 4) : 4;
|
|
19
|
-
|
|
39
|
+
// Try real system ping first (Node.js only)
|
|
40
|
+
if (!isBrowser) {
|
|
41
|
+
const result = await execPing(count, host);
|
|
42
|
+
if (result)
|
|
43
|
+
return { ...result, exitCode: "stdout" in result ? 0 : 1 };
|
|
44
|
+
}
|
|
45
|
+
// Fallback: VirtualNetworkManager simulation
|
|
46
|
+
const lines = [`PING ${host} (${host === "localhost" ? "127.0.0.1" : host}): 56 data bytes`];
|
|
47
|
+
let transmitted = 0;
|
|
48
|
+
let received = 0;
|
|
20
49
|
for (let i = 0; i < count; i++) {
|
|
21
|
-
|
|
22
|
-
|
|
50
|
+
transmitted++;
|
|
51
|
+
const latency = shell.network.ping(host);
|
|
52
|
+
if (latency < 0) {
|
|
53
|
+
lines.push(`From ${host} icmp_seq=${i} Destination Host Unreachable`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
received++;
|
|
57
|
+
lines.push(`64 bytes from ${host}: icmp_seq=${i} ttl=64 time=${latency.toFixed(3)} ms`);
|
|
58
|
+
}
|
|
23
59
|
}
|
|
60
|
+
const lost = transmitted - received;
|
|
61
|
+
const lossPct = ((lost / transmitted) * 100).toFixed(0);
|
|
24
62
|
lines.push(`--- ${host} ping statistics ---`);
|
|
25
|
-
lines.push(`${
|
|
26
|
-
return { stdout: lines.join("\n")
|
|
63
|
+
lines.push(`${transmitted} packets transmitted, ${received} received, ${lossPct}% packet loss`);
|
|
64
|
+
return { stdout: `${lines.join("\n")}\n`, exitCode: 0 };
|
|
27
65
|
},
|
|
28
66
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShellModule } from "../types/commands";
|
|
2
|
+
/**
|
|
3
|
+
* List process IDs matching a pattern
|
|
4
|
+
* @category system
|
|
5
|
+
* @params ["[-f] <pattern>"]
|
|
6
|
+
*/
|
|
7
|
+
export declare const pgrepCommand: ShellModule;
|
|
8
|
+
/**
|
|
9
|
+
* Kill processes matching a pattern
|
|
10
|
+
* @category system
|
|
11
|
+
* @params ["[-f] <pattern>"]
|
|
12
|
+
*/
|
|
13
|
+
export declare const pkillCommand: ShellModule;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List process IDs matching a pattern
|
|
3
|
+
* @category system
|
|
4
|
+
* @params ["[-f] <pattern>"]
|
|
5
|
+
*/
|
|
6
|
+
export const pgrepCommand = {
|
|
7
|
+
name: "pgrep",
|
|
8
|
+
description: "List process IDs matching a pattern",
|
|
9
|
+
category: "system",
|
|
10
|
+
params: ["[-f] <pattern>"],
|
|
11
|
+
run: ({ activeSessions, args }) => {
|
|
12
|
+
const useFull = args.includes("-f");
|
|
13
|
+
const pattern = args.find((a) => !a.startsWith("-"));
|
|
14
|
+
if (!pattern)
|
|
15
|
+
return { stderr: "pgrep: missing pattern\n", exitCode: 1 };
|
|
16
|
+
try {
|
|
17
|
+
const re = new RegExp(pattern);
|
|
18
|
+
const results = [];
|
|
19
|
+
for (let i = 0; i < activeSessions.length; i++) {
|
|
20
|
+
const s = activeSessions[i];
|
|
21
|
+
const target = useFull
|
|
22
|
+
? `${s.username} ${s.tty} ${s.remoteAddress} ${s.id}`
|
|
23
|
+
: s.username;
|
|
24
|
+
if (re.test(target)) {
|
|
25
|
+
results.push(String(1000 + i));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (results.length === 0)
|
|
29
|
+
return { exitCode: 1 };
|
|
30
|
+
return { stdout: results.join("\n") + "\n", exitCode: 0 };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return { stderr: "pgrep: invalid pattern\n", exitCode: 2 };
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Kill processes matching a pattern
|
|
39
|
+
* @category system
|
|
40
|
+
* @params ["[-f] <pattern>"]
|
|
41
|
+
*/
|
|
42
|
+
export const pkillCommand = {
|
|
43
|
+
name: "pkill",
|
|
44
|
+
description: "Kill processes matching a pattern",
|
|
45
|
+
category: "system",
|
|
46
|
+
params: ["[-f] <pattern>"],
|
|
47
|
+
run: ({ activeSessions, shell, args }) => {
|
|
48
|
+
const useFull = args.includes("-f");
|
|
49
|
+
const pattern = args.find((a) => !a.startsWith("-"));
|
|
50
|
+
if (!pattern)
|
|
51
|
+
return { stderr: "pkill: missing pattern\n", exitCode: 1 };
|
|
52
|
+
try {
|
|
53
|
+
const re = new RegExp(pattern);
|
|
54
|
+
let killed = 0;
|
|
55
|
+
for (const s of activeSessions) {
|
|
56
|
+
const target = useFull
|
|
57
|
+
? `${s.username} ${s.tty} ${s.remoteAddress} ${s.id}`
|
|
58
|
+
: s.username;
|
|
59
|
+
if (re.test(target)) {
|
|
60
|
+
shell.users.unregisterSession(s.id);
|
|
61
|
+
killed++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (killed === 0)
|
|
65
|
+
return { exitCode: 1 };
|
|
66
|
+
return { stdout: `killed ${killed} process(es)\n`, exitCode: 0 };
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return { stderr: "pkill: invalid pattern\n", exitCode: 2 };
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
package/dist/commands/pwd.d.ts
CHANGED
package/dist/commands/pwd.js
CHANGED
package/dist/commands/python.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ifFlag } from "./command-helpers";
|
|
2
2
|
import { resolvePath } from "./helpers";
|
|
3
3
|
const VERSION = "Python 3.11.2";
|
|
4
|
-
const _VERSION_SHORT = "3.11.2";
|
|
5
4
|
const VERSION_INFO = "3.11.2 (default, Mar 13 2023, 12:18:29) [GCC 12.2.0]";
|
|
6
5
|
const NONE = { __pytype__: "none" };
|
|
7
6
|
function pyDict(entries = []) {
|
|
@@ -1664,7 +1663,6 @@ class Interpreter {
|
|
|
1664
1663
|
if (line.startsWith("if ") && line.endsWith(":")) {
|
|
1665
1664
|
const cond = line.slice(3, -1).trim();
|
|
1666
1665
|
const body = this.collectBlock(lines, idx + 1, indent);
|
|
1667
|
-
const _skip = body.length + 1;
|
|
1668
1666
|
if (pyBool(this.pyEval(cond, scope))) {
|
|
1669
1667
|
this.execBlock(body, new Map(scope).also?.((s) => {
|
|
1670
1668
|
for (const [k, v] of scope)
|
|
@@ -1814,7 +1812,6 @@ class Interpreter {
|
|
|
1814
1812
|
else
|
|
1815
1813
|
break;
|
|
1816
1814
|
}
|
|
1817
|
-
let _caughtErr = null;
|
|
1818
1815
|
try {
|
|
1819
1816
|
this.runBlockInScope(tryBody, scope);
|
|
1820
1817
|
if (elseBody.length)
|
|
@@ -1822,7 +1819,6 @@ class Interpreter {
|
|
|
1822
1819
|
}
|
|
1823
1820
|
catch (e) {
|
|
1824
1821
|
if (e instanceof PyError) {
|
|
1825
|
-
_caughtErr = e;
|
|
1826
1822
|
let handled = false;
|
|
1827
1823
|
for (const clause of exceptClauses) {
|
|
1828
1824
|
if (clause.exc === null ||
|
package/dist/commands/read.js
CHANGED
|
@@ -10,7 +10,6 @@ export const readCommand = {
|
|
|
10
10
|
category: "shell",
|
|
11
11
|
params: ["[-r] [-p prompt] <var...>"],
|
|
12
12
|
run: ({ args, stdin, env }) => {
|
|
13
|
-
const _promptIdx = args.indexOf("-p");
|
|
14
13
|
const varNames = args.filter((a, i) => a !== "-r" && a !== "-p" && args[i - 1] !== "-p");
|
|
15
14
|
// In non-interactive context, read from stdin pipe
|
|
16
15
|
const input = (stdin ?? "").split("\n")[0] ?? "";
|
|
@@ -1,7 +1,44 @@
|
|
|
1
1
|
/** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */
|
|
2
2
|
import type { CommandContext, CommandResult, ShellModule } from "../types/commands";
|
|
3
|
+
/**
|
|
4
|
+
* Registers a command module so it can be called from the shell.
|
|
5
|
+
* The module's name and aliases are lowercased and trimmed; names must be
|
|
6
|
+
* non-empty and contain no spaces. Updates the registry incrementally and
|
|
7
|
+
* invalidates the sorted-name cache.
|
|
8
|
+
*
|
|
9
|
+
* @param module - The command module to register
|
|
10
|
+
*/
|
|
3
11
|
export declare function registerCommand(module: ShellModule): void;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a custom user-defined command from a shell script or function.
|
|
14
|
+
* The returned module is not automatically registered; call
|
|
15
|
+
* {@link registerCommand} to add it to the registry.
|
|
16
|
+
*
|
|
17
|
+
* @param name - The command name
|
|
18
|
+
* @param params - Parameter names for the command
|
|
19
|
+
* @param run - The handler invoked when the command is executed
|
|
20
|
+
* @returns A command module that can be passed to registerCommand
|
|
21
|
+
*/
|
|
4
22
|
export declare function createCustomCommand(name: string, params: string[], run: (ctx: CommandContext) => CommandResult | Promise<CommandResult>): ShellModule;
|
|
23
|
+
/**
|
|
24
|
+
* Returns a sorted list of all registered command names (including aliases).
|
|
25
|
+
* The list is cached and rebuilt lazily when commands are added or removed.
|
|
26
|
+
*
|
|
27
|
+
* @returns A sorted array of command names
|
|
28
|
+
*/
|
|
5
29
|
export declare function getCommandNames(): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Returns all public command modules — built-in commands, custom commands,
|
|
32
|
+
* and the dynamically generated help command.
|
|
33
|
+
*
|
|
34
|
+
* @returns An array of all registered command modules
|
|
35
|
+
*/
|
|
6
36
|
export declare function getCommandModulesPublic(): ShellModule[];
|
|
37
|
+
/**
|
|
38
|
+
* Resolves a command module by name or alias. The lookup is case-insensitive.
|
|
39
|
+
* Builds the internal cache first if it has not been populated yet.
|
|
40
|
+
*
|
|
41
|
+
* @param name - The command or alias name to look up
|
|
42
|
+
* @returns The matching ShellModule, or undefined if not found
|
|
43
|
+
*/
|
|
7
44
|
export declare function resolveModule(name: string): ShellModule | undefined;
|
|
@@ -13,7 +13,9 @@ import { straceCommand } from "./strace";
|
|
|
13
13
|
import { unzipCommand, zipCommand } from "./zip";
|
|
14
14
|
import { catCommand } from "./cat";
|
|
15
15
|
import { cdCommand } from "./cd";
|
|
16
|
+
import { chgrpCommand } from "./chgrp";
|
|
16
17
|
import { chmodCommand } from "./chmod";
|
|
18
|
+
import { chownCommand } from "./chown";
|
|
17
19
|
import { clearCommand } from "./clear";
|
|
18
20
|
import { cpCommand } from "./cp";
|
|
19
21
|
import { curlCommand } from "./curl";
|
|
@@ -97,6 +99,16 @@ import { whichCommand } from "./which";
|
|
|
97
99
|
import { whoCommand } from "./who";
|
|
98
100
|
import { whoamiCommand } from "./whoami";
|
|
99
101
|
import { xargsCommand } from "./xargs";
|
|
102
|
+
import { ddCommand } from "./dd";
|
|
103
|
+
import { exprCommand } from "./expr";
|
|
104
|
+
import { realpathCommand, md5sumCommand, sha256sumCommand, stringsCommand, foldCommand, expandCommand, fmtCommand } from "./miscutils";
|
|
105
|
+
import { ncCommand } from "./netcat";
|
|
106
|
+
import { niceCommand } from "./nice";
|
|
107
|
+
import { nohupCommand } from "./nohup";
|
|
108
|
+
import { pgrepCommand, pkillCommand } from "./procUtils";
|
|
109
|
+
import { lscpuCommand, lsusbCommand, lspciCommand } from "./sysinfo";
|
|
110
|
+
import { joinCommand, commCommand, splitCommand, csplitCommand } from "./textutils";
|
|
111
|
+
import { topCommand } from "./top";
|
|
100
112
|
const BASE_COMMANDS = [
|
|
101
113
|
// Navigation
|
|
102
114
|
pwdCommand,
|
|
@@ -113,9 +125,13 @@ const BASE_COMMANDS = [
|
|
|
113
125
|
lnCommand,
|
|
114
126
|
readlinkCommand,
|
|
115
127
|
chmodCommand,
|
|
128
|
+
chownCommand,
|
|
129
|
+
chgrpCommand,
|
|
116
130
|
seqCommand,
|
|
117
131
|
statCommand,
|
|
118
132
|
findCommand,
|
|
133
|
+
ddCommand,
|
|
134
|
+
realpathCommand,
|
|
119
135
|
// Text processing
|
|
120
136
|
grepCommand,
|
|
121
137
|
sedCommand,
|
|
@@ -130,6 +146,16 @@ const BASE_COMMANDS = [
|
|
|
130
146
|
teeCommand,
|
|
131
147
|
xargsCommand,
|
|
132
148
|
diffCommand,
|
|
149
|
+
foldCommand,
|
|
150
|
+
expandCommand,
|
|
151
|
+
fmtCommand,
|
|
152
|
+
md5sumCommand,
|
|
153
|
+
sha256sumCommand,
|
|
154
|
+
stringsCommand,
|
|
155
|
+
joinCommand,
|
|
156
|
+
commCommand,
|
|
157
|
+
splitCommand,
|
|
158
|
+
csplitCommand,
|
|
133
159
|
// Archives
|
|
134
160
|
tarCommand,
|
|
135
161
|
gzipCommand,
|
|
@@ -153,6 +179,14 @@ const BASE_COMMANDS = [
|
|
|
153
179
|
dateCommand,
|
|
154
180
|
sleepCommand,
|
|
155
181
|
pingCommand,
|
|
182
|
+
lscpuCommand,
|
|
183
|
+
lsusbCommand,
|
|
184
|
+
lspciCommand,
|
|
185
|
+
pgrepCommand,
|
|
186
|
+
pkillCommand,
|
|
187
|
+
topCommand,
|
|
188
|
+
niceCommand,
|
|
189
|
+
nohupCommand,
|
|
156
190
|
// Shell
|
|
157
191
|
echoCommand,
|
|
158
192
|
envCommand,
|
|
@@ -184,6 +218,7 @@ const BASE_COMMANDS = [
|
|
|
184
218
|
// Network
|
|
185
219
|
curlCommand,
|
|
186
220
|
wgetCommand,
|
|
221
|
+
ncCommand,
|
|
187
222
|
// Users
|
|
188
223
|
adduserCommand,
|
|
189
224
|
passwdCommand,
|
|
@@ -222,6 +257,7 @@ const BASE_COMMANDS = [
|
|
|
222
257
|
npxCommand,
|
|
223
258
|
nodeCommand,
|
|
224
259
|
python3Command,
|
|
260
|
+
exprCommand,
|
|
225
261
|
// System (extended)
|
|
226
262
|
uptimeCommand,
|
|
227
263
|
freeCommand,
|
|
@@ -257,6 +293,14 @@ function buildCache() {
|
|
|
257
293
|
function getCommandModules() {
|
|
258
294
|
return [...BASE_COMMANDS, ...customCommands, helpCommand];
|
|
259
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Registers a command module so it can be called from the shell.
|
|
298
|
+
* The module's name and aliases are lowercased and trimmed; names must be
|
|
299
|
+
* non-empty and contain no spaces. Updates the registry incrementally and
|
|
300
|
+
* invalidates the sorted-name cache.
|
|
301
|
+
*
|
|
302
|
+
* @param module - The command module to register
|
|
303
|
+
*/
|
|
260
304
|
export function registerCommand(module) {
|
|
261
305
|
const normalized = {
|
|
262
306
|
...module,
|
|
@@ -275,17 +319,46 @@ export function registerCommand(module) {
|
|
|
275
319
|
// Invalidate sorted names cache; rebuilt lazily on next getCommandNames()
|
|
276
320
|
cachedCommandNames = null;
|
|
277
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Creates a custom user-defined command from a shell script or function.
|
|
324
|
+
* The returned module is not automatically registered; call
|
|
325
|
+
* {@link registerCommand} to add it to the registry.
|
|
326
|
+
*
|
|
327
|
+
* @param name - The command name
|
|
328
|
+
* @param params - Parameter names for the command
|
|
329
|
+
* @param run - The handler invoked when the command is executed
|
|
330
|
+
* @returns A command module that can be passed to registerCommand
|
|
331
|
+
*/
|
|
278
332
|
export function createCustomCommand(name, params, run) {
|
|
279
333
|
return { name, params, run };
|
|
280
334
|
}
|
|
335
|
+
/**
|
|
336
|
+
* Returns a sorted list of all registered command names (including aliases).
|
|
337
|
+
* The list is cached and rebuilt lazily when commands are added or removed.
|
|
338
|
+
*
|
|
339
|
+
* @returns A sorted array of command names
|
|
340
|
+
*/
|
|
281
341
|
export function getCommandNames() {
|
|
282
342
|
if (!cachedCommandNames)
|
|
283
343
|
buildCache();
|
|
284
344
|
return cachedCommandNames;
|
|
285
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Returns all public command modules — built-in commands, custom commands,
|
|
348
|
+
* and the dynamically generated help command.
|
|
349
|
+
*
|
|
350
|
+
* @returns An array of all registered command modules
|
|
351
|
+
*/
|
|
286
352
|
export function getCommandModulesPublic() {
|
|
287
353
|
return getCommandModules();
|
|
288
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Resolves a command module by name or alias. The lookup is case-insensitive.
|
|
357
|
+
* Builds the internal cache first if it has not been populated yet.
|
|
358
|
+
*
|
|
359
|
+
* @param name - The command or alias name to look up
|
|
360
|
+
* @returns The matching ShellModule, or undefined if not found
|
|
361
|
+
*/
|
|
289
362
|
export function resolveModule(name) {
|
|
290
363
|
if (!cachedCommandNames)
|
|
291
364
|
buildCache();
|
package/dist/commands/rm.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
1
2
|
import { getArg, ifFlag } from "./command-helpers";
|
|
2
|
-
import {
|
|
3
|
+
import { checkFilePermission, resolvePath } from "./helpers";
|
|
3
4
|
const FLAG_RECURSIVE = ["-r", "-R", "-rf", "-fr", "-rF", "-Fr"];
|
|
4
5
|
const FLAG_FORCE = ["-f", "-rf", "-fr", "-rF", "-Fr", "--force"];
|
|
5
6
|
/**
|
|
@@ -31,7 +32,7 @@ export const rmCommand = {
|
|
|
31
32
|
}
|
|
32
33
|
const resolved = targets.map((t) => resolvePath(cwd, t));
|
|
33
34
|
for (const r of resolved)
|
|
34
|
-
|
|
35
|
+
checkFilePermission(shell.vfs, shell.users, authUser, path.posix.dirname(r), 2);
|
|
35
36
|
for (const r of resolved) {
|
|
36
37
|
if (!shell.vfs.exists(r)) {
|
|
37
38
|
if (force)
|
|
@@ -7,6 +7,52 @@ export declare function userHome(authUser: string): string;
|
|
|
7
7
|
* the new user's .bashrc. Call this after setting authUser = newUser.
|
|
8
8
|
*/
|
|
9
9
|
export declare function applyUserSwitch(newUser: string, hostname: string, cwd: string, shellEnv: ShellEnv, shell: VirtualShell): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates the default shell environment variables for a given user and host.
|
|
12
|
+
* Sets PATH, HOME, USER, LOGNAME, SHELL, TERM, HOSTNAME, and a coloured PS1
|
|
13
|
+
* prompt that distinguishes root (red) from ordinary users (magenta).
|
|
14
|
+
*
|
|
15
|
+
* @param authUser - The authenticated username
|
|
16
|
+
* @param hostname - The machine hostname
|
|
17
|
+
* @returns A ShellEnv populated with default variable values
|
|
18
|
+
*/
|
|
10
19
|
export declare function makeDefaultEnv(authUser: string, hostname: string): ShellEnv;
|
|
11
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Runs a command directly by name, bypassing shell parsing and expansion.
|
|
22
|
+
* Handles variable assignments prefixing the command, shell functions
|
|
23
|
+
* (stored as `__func_<name>`), aliases, registered modules, and VFS
|
|
24
|
+
* stub binaries. Includes an anti-loop guard via a module-level call depth
|
|
25
|
+
* counter and registers the process in the user's session table.
|
|
26
|
+
*
|
|
27
|
+
* @param name - The command name to execute
|
|
28
|
+
* @param args - Argument array (does not include the command name)
|
|
29
|
+
* @param authUser - The authenticated user
|
|
30
|
+
* @param hostname - The machine hostname
|
|
31
|
+
* @param mode - The current command mode (shell, pipe, etc.)
|
|
32
|
+
* @param cwd - The current working directory
|
|
33
|
+
* @param shell - The VirtualShell instance
|
|
34
|
+
* @param stdin - Optional stdin string
|
|
35
|
+
* @param env - The current shell environment
|
|
36
|
+
* @param background - Whether the command is run in the background
|
|
37
|
+
* @param abortController - Optional controller to abort a background process
|
|
38
|
+
* @returns The command result
|
|
39
|
+
*/
|
|
40
|
+
export declare function runCommandDirect(name: string, args: string[], authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, stdin: string | undefined, env: ShellEnv, background?: boolean, abortController?: AbortController): Promise<CommandResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Parses and runs a command line string through the full execution pipeline:
|
|
43
|
+
* history expansion (`!!` / `!n`), alias expansion, sh-syntax detection
|
|
44
|
+
* (for/while/if/function/arithmetic), pipe/redirect routing via the shell
|
|
45
|
+
* parser, variable expansion, brace expansion, and glob expansion. Falls
|
|
46
|
+
* back to the `sh` interpreter for compound constructs.
|
|
47
|
+
*
|
|
48
|
+
* @param rawInput - The raw command line string to parse and run
|
|
49
|
+
* @param authUser - The authenticated user
|
|
50
|
+
* @param hostname - The machine hostname
|
|
51
|
+
* @param mode - The current command mode (shell, pipe, etc.)
|
|
52
|
+
* @param cwd - The current working directory
|
|
53
|
+
* @param shell - The VirtualShell instance
|
|
54
|
+
* @param stdin - Optional stdin string
|
|
55
|
+
* @param env - Optional shell environment (created from defaults if omitted)
|
|
56
|
+
* @returns The command result
|
|
57
|
+
*/
|
|
12
58
|
export declare function runCommand(rawInput: string, authUser: string, hostname: string, mode: CommandMode, cwd: string, shell: VirtualShell, stdin?: string, env?: ShellEnv): Promise<CommandResult>;
|