typescript-virtual-container 1.5.7 → 1.5.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 (37) hide show
  1. package/README.md +39 -29
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/SSHMimic/executor.js +9 -0
  4. package/dist/SSHMimic/prompt.d.ts +2 -1
  5. package/dist/SSHMimic/prompt.js +28 -6
  6. package/dist/SSHMimic/sftp.d.ts +1 -1
  7. package/dist/SSHMimic/sftp.js +1 -1
  8. package/dist/VirtualShell/index.d.ts +2 -3
  9. package/dist/VirtualShell/index.js +2 -3
  10. package/dist/VirtualShell/shell.js +108 -134
  11. package/dist/VirtualShell/shellParser.js +35 -3
  12. package/dist/commands/coreutils.d.ts +55 -0
  13. package/dist/commands/coreutils.js +275 -0
  14. package/dist/commands/id.js +8 -1
  15. package/dist/commands/index.d.ts +1 -1
  16. package/dist/commands/index.js +1 -1
  17. package/dist/commands/manuals-bundle.js +237 -1
  18. package/dist/commands/pacman.d.ts +8 -0
  19. package/dist/commands/pacman.js +15 -0
  20. package/dist/commands/registry.js +13 -0
  21. package/dist/commands/rm.d.ts +1 -1
  22. package/dist/commands/rm.js +48 -11
  23. package/dist/commands/runtime.d.ts +5 -0
  24. package/dist/commands/runtime.js +60 -1
  25. package/dist/commands/sh.js +5 -3
  26. package/dist/modules/linuxRootfs.js +7 -3
  27. package/dist/modules/nanoEditor.d.ts +92 -0
  28. package/dist/modules/nanoEditor.js +974 -0
  29. package/dist/modules/pacmanGame.d.ts +59 -0
  30. package/dist/modules/pacmanGame.js +655 -0
  31. package/dist/modules/webTermRenderer.d.ts +50 -0
  32. package/dist/modules/webTermRenderer.js +425 -0
  33. package/dist/types/commands.d.ts +2 -0
  34. package/dist/types/pipeline.d.ts +2 -0
  35. package/dist/utils/shellSession.d.ts +10 -0
  36. package/dist/utils/shellSession.js +56 -0
  37. package/package.json +2 -2
@@ -0,0 +1,275 @@
1
+ /**
2
+ * timeout — run command with time limit (simulated: just runs the command)
3
+ * @category shell
4
+ * @params ["<duration> <command> [args...]"]
5
+ */
6
+ export const timeoutCommand = {
7
+ name: "timeout",
8
+ description: "Run command with time limit",
9
+ category: "shell",
10
+ params: ["<duration>", "<command>", "[args...]"],
11
+ run: async ({ args, authUser, hostname, mode, cwd, shell, env, stdin }) => {
12
+ // First arg is duration (ignored in simulation), rest is the command
13
+ if (args.length < 2)
14
+ return { stderr: "timeout: missing operand", exitCode: 1 };
15
+ const { runCommand } = await import("./runtime");
16
+ const cmd = args.slice(1).join(" ");
17
+ return runCommand(cmd, authUser, hostname, mode, cwd, shell, stdin, env);
18
+ },
19
+ };
20
+ /**
21
+ * mktemp — create a temporary file or directory
22
+ * @category shell
23
+ * @params ["[TEMPLATE]"]
24
+ */
25
+ export const mktempCommand = {
26
+ name: "mktemp",
27
+ description: "Create a temporary file or directory",
28
+ category: "shell",
29
+ params: ["[-d]", "[TEMPLATE]"],
30
+ run: ({ args, shell }) => {
31
+ const isDir = args.includes("-d");
32
+ const templateArg = args.find((a) => !a.startsWith("-")) ?? "tmp.XXXXXXXXXX";
33
+ const suffix = templateArg.replace(/X+$/, "") || "tmp.";
34
+ const rand = Math.random().toString(36).slice(2, 10);
35
+ const name = `${suffix}${rand}`;
36
+ const path = name.startsWith("/") ? name : `/tmp/${name}`;
37
+ try {
38
+ if (!shell.vfs.exists("/tmp"))
39
+ shell.vfs.mkdir("/tmp");
40
+ if (isDir) {
41
+ shell.vfs.mkdir(path);
42
+ }
43
+ else {
44
+ shell.vfs.writeFile(path, "");
45
+ }
46
+ }
47
+ catch {
48
+ return { stderr: `mktemp: failed to create ${isDir ? "directory" : "file"} via template '${templateArg}'`, exitCode: 1 };
49
+ }
50
+ return { stdout: path, exitCode: 0 };
51
+ },
52
+ };
53
+ /**
54
+ * nproc — print number of processing units
55
+ * @category system
56
+ * @params ["[--all]"]
57
+ */
58
+ export const nprocCommand = {
59
+ name: "nproc",
60
+ description: "Print number of processing units",
61
+ category: "system",
62
+ params: ["[--all]"],
63
+ run: () => ({ stdout: "4", exitCode: 0 }),
64
+ };
65
+ /**
66
+ * wait — wait for background jobs (no-op: background jobs are fire-and-forget)
67
+ * @category shell
68
+ * @params ["[job_id...]"]
69
+ */
70
+ export const waitCommand = {
71
+ name: "wait",
72
+ description: "Wait for background jobs to finish",
73
+ category: "shell",
74
+ params: ["[job_id...]"],
75
+ run: () => ({ exitCode: 0 }),
76
+ };
77
+ /**
78
+ * shuf — shuffle lines of input
79
+ * @category text
80
+ * @params ["[-n count] [-i lo-hi] [file]"]
81
+ */
82
+ export const shufCommand = {
83
+ name: "shuf",
84
+ description: "Shuffle lines of input randomly",
85
+ category: "text",
86
+ params: ["[-n count]", "[-i lo-hi]", "[file]"],
87
+ run: ({ args, stdin, shell, cwd }) => {
88
+ const { resolvePath } = require("./helpers");
89
+ // -i lo-hi: generate range
90
+ const iIdx = args.indexOf("-i");
91
+ if (iIdx !== -1) {
92
+ const range = args[iIdx + 1] ?? "";
93
+ const m = range.match(/^(-?\d+)-(-?\d+)$/);
94
+ if (!m)
95
+ return { stderr: "shuf: invalid range", exitCode: 1 };
96
+ const lo = parseInt(m[1], 10);
97
+ const hi = parseInt(m[2], 10);
98
+ const nums = [];
99
+ for (let n = lo; n <= hi; n++)
100
+ nums.push(n);
101
+ for (let i = nums.length - 1; i > 0; i--) {
102
+ const j = Math.floor(Math.random() * (i + 1));
103
+ [nums[i], nums[j]] = [nums[j], nums[i]];
104
+ }
105
+ const nIdx = args.indexOf("-n");
106
+ const count = nIdx !== -1 ? parseInt(args[nIdx + 1] ?? "0", 10) : nums.length;
107
+ return { stdout: nums.slice(0, count).join("\n"), exitCode: 0 };
108
+ }
109
+ // file or stdin
110
+ let input = stdin ?? "";
111
+ const fileArg = args.find((a) => !a.startsWith("-"));
112
+ if (fileArg) {
113
+ const p = resolvePath(cwd ?? "/", fileArg);
114
+ if (!shell.vfs.exists(p))
115
+ return { stderr: `shuf: ${fileArg}: No such file or directory`, exitCode: 1 };
116
+ input = shell.vfs.readFile(p);
117
+ }
118
+ const lines = input.split("\n").filter((l) => l !== "");
119
+ for (let i = lines.length - 1; i > 0; i--) {
120
+ const j = Math.floor(Math.random() * (i + 1));
121
+ [lines[i], lines[j]] = [lines[j], lines[i]];
122
+ }
123
+ const nIdx = args.indexOf("-n");
124
+ const count = nIdx !== -1 ? parseInt(args[nIdx + 1] ?? "0", 10) : lines.length;
125
+ return { stdout: lines.slice(0, count).join("\n"), exitCode: 0 };
126
+ },
127
+ };
128
+ /**
129
+ * paste — merge lines of files side by side
130
+ * @category text
131
+ * @params ["[-d delimiter] file..."]
132
+ */
133
+ export const pasteCommand = {
134
+ name: "paste",
135
+ description: "Merge lines of files",
136
+ category: "text",
137
+ params: ["[-d delimiter]", "file..."],
138
+ run: ({ args, stdin, shell, cwd }) => {
139
+ const { resolvePath } = require("./helpers");
140
+ let delim = "\t";
141
+ const files = [];
142
+ let i = 0;
143
+ while (i < args.length) {
144
+ if (args[i] === "-d" && args[i + 1]) {
145
+ delim = args[i + 1];
146
+ i += 2;
147
+ }
148
+ else {
149
+ files.push(args[i]);
150
+ i++;
151
+ }
152
+ }
153
+ // serial mode (-s not implemented; basic merge)
154
+ let sources;
155
+ if (files.length === 0 || files[0] === "-") {
156
+ sources = [(stdin ?? "").split("\n")];
157
+ }
158
+ else {
159
+ sources = files.map((f) => {
160
+ const p = resolvePath(cwd ?? "/", f);
161
+ if (!shell.vfs.exists(p))
162
+ return [];
163
+ return shell.vfs.readFile(p).split("\n");
164
+ });
165
+ }
166
+ const maxLen = Math.max(...sources.map((s) => s.length));
167
+ const out = [];
168
+ for (let row = 0; row < maxLen; row++) {
169
+ out.push(sources.map((s) => s[row] ?? "").join(delim));
170
+ }
171
+ return { stdout: out.join("\n"), exitCode: 0 };
172
+ },
173
+ };
174
+ /**
175
+ * tac — concatenate files in reverse (line order)
176
+ * @category text
177
+ * @params ["[file...]"]
178
+ */
179
+ export const tacCommand = {
180
+ name: "tac",
181
+ description: "Concatenate files in reverse line order",
182
+ category: "text",
183
+ params: ["[file...]"],
184
+ run: ({ args, stdin, shell, cwd }) => {
185
+ const { resolvePath } = require("./helpers");
186
+ let input = "";
187
+ if (args.length === 0 || (args.length === 1 && args[0] === "-")) {
188
+ input = stdin ?? "";
189
+ }
190
+ else {
191
+ for (const f of args) {
192
+ const p = resolvePath(cwd ?? "/", f);
193
+ if (!shell.vfs.exists(p))
194
+ return { stderr: `tac: ${f}: No such file or directory`, exitCode: 1 };
195
+ input += shell.vfs.readFile(p);
196
+ }
197
+ }
198
+ const lines = input.split("\n");
199
+ // preserve trailing newline behaviour
200
+ if (lines[lines.length - 1] === "")
201
+ lines.pop();
202
+ return { stdout: lines.reverse().join("\n"), exitCode: 0 };
203
+ },
204
+ };
205
+ /**
206
+ * nl — number lines of files
207
+ * @category text
208
+ * @params ["[file]"]
209
+ */
210
+ export const nlCommand = {
211
+ name: "nl",
212
+ description: "Number lines of files",
213
+ category: "text",
214
+ params: ["[-ba] [-nrz] [file]"],
215
+ run: ({ args, stdin, shell, cwd }) => {
216
+ const { resolvePath } = require("./helpers");
217
+ const fileArg = args.find((a) => !a.startsWith("-"));
218
+ let input = stdin ?? "";
219
+ if (fileArg) {
220
+ const p = resolvePath(cwd ?? "/", fileArg);
221
+ if (!shell.vfs.exists(p))
222
+ return { stderr: `nl: ${fileArg}: No such file or directory`, exitCode: 1 };
223
+ input = shell.vfs.readFile(p);
224
+ }
225
+ const lines = input.split("\n");
226
+ if (lines[lines.length - 1] === "")
227
+ lines.pop();
228
+ let n = 1;
229
+ const out = lines.map((l) => {
230
+ if (l.trim() === "")
231
+ return `\t${l}`;
232
+ return `${String(n++).padStart(6)}\t${l}`;
233
+ });
234
+ return { stdout: out.join("\n"), exitCode: 0 };
235
+ },
236
+ };
237
+ /**
238
+ * column — columnate lists
239
+ * @category text
240
+ * @params ["[-t] [-s sep] [file]"]
241
+ */
242
+ export const columnCommand = {
243
+ name: "column",
244
+ description: "Columnate lists",
245
+ category: "text",
246
+ params: ["[-t]", "[-s sep]", "[file]"],
247
+ run: ({ args, stdin, shell, cwd }) => {
248
+ const { resolvePath } = require("./helpers");
249
+ const tableMode = args.includes("-t");
250
+ const sIdx = args.indexOf("-s");
251
+ const sep = sIdx !== -1 ? (args[sIdx + 1] ?? "\t") : /\s+/;
252
+ const fileArg = args.find((a) => !a.startsWith("-") && a !== args[sIdx + 1]);
253
+ let input = stdin ?? "";
254
+ if (fileArg) {
255
+ const p = resolvePath(cwd ?? "/", fileArg);
256
+ if (!shell.vfs.exists(p))
257
+ return { stderr: `column: ${fileArg}: No such file or directory`, exitCode: 1 };
258
+ input = shell.vfs.readFile(p);
259
+ }
260
+ const lines = input.split("\n").filter((l) => l !== "");
261
+ if (tableMode) {
262
+ const rows = lines.map((l) => (typeof sep === "string" ? l.split(sep) : l.split(sep)));
263
+ const colWidths = [];
264
+ for (const row of rows) {
265
+ row.forEach((cell, ci) => {
266
+ colWidths[ci] = Math.max(colWidths[ci] ?? 0, cell.length);
267
+ });
268
+ }
269
+ const out = rows.map((row) => row.map((cell, ci) => cell.padEnd(colWidths[ci] ?? 0)).join(" ").trimEnd());
270
+ return { stdout: out.join("\n"), exitCode: 0 };
271
+ }
272
+ // Default: fill columns (simple: just output as-is)
273
+ return { stdout: lines.join("\n"), exitCode: 0 };
274
+ },
275
+ };
@@ -4,11 +4,18 @@ export const idCommand = {
4
4
  category: "system",
5
5
  params: ["[user]"],
6
6
  run: ({ authUser, shell, args }) => {
7
- const target = args[0] ?? authUser;
7
+ const flagU = args.includes("-u");
8
+ const flagG = args.includes("-g");
9
+ const flagN = args.includes("-n");
10
+ const target = args.find(a => !a.startsWith("-")) ?? authUser;
8
11
  const uid = target === "root" ? 0 : 1000;
9
12
  const gid = uid;
10
13
  const isSudo = shell.users.isSudoer(target);
11
14
  const groups = isSudo ? `${gid}(${target}),0(root)` : `${gid}(${target})`;
15
+ if (flagU)
16
+ return { stdout: flagN ? target : String(uid), exitCode: 0 };
17
+ if (flagG)
18
+ return { stdout: flagN ? target : String(gid), exitCode: 0 };
12
19
  return {
13
20
  stdout: `uid=${uid}(${target}) gid=${gid}(${target}) groups=${groups}`,
14
21
  exitCode: 0,
@@ -1,2 +1,2 @@
1
1
  export { createCustomCommand, getCommandModulesPublic, getCommandNames, registerCommand, resolveModule } from "./registry";
2
- export { makeDefaultEnv, runCommand, runCommandDirect, userHome } from "./runtime";
2
+ export { applyUserSwitch, makeDefaultEnv, runCommand, runCommandDirect, userHome } from "./runtime";
@@ -1,2 +1,2 @@
1
1
  export { createCustomCommand, getCommandModulesPublic, getCommandNames, registerCommand, resolveModule } from "./registry";
2
- export { makeDefaultEnv, runCommand, runCommandDirect, userHome } from "./runtime";
2
+ export { applyUserSwitch, makeDefaultEnv, runCommand, runCommandDirect, userHome } from "./runtime";
@@ -187,6 +187,28 @@ OPTIONS
187
187
 
188
188
  EXAMPLES
189
189
  cmatrix`,
190
+ "column": `COLUMN(1) User Commands COLUMN(1)
191
+
192
+ NAME
193
+ column - columnate lists
194
+
195
+ SYNOPSIS
196
+ column [OPTION]... [FILE]...
197
+
198
+ DESCRIPTION
199
+ The column utility formats its input into multiple columns.
200
+ Rows are filled before columns. Input is taken from FILE or stdin.
201
+
202
+ OPTIONS
203
+ -t determine the number of columns the input contains and create
204
+ a table (useful for pretty-printing)
205
+ -s specify a set of characters to be used to delimit columns
206
+ (default: whitespace)
207
+
208
+ EXAMPLES
209
+ mount | column -t
210
+ cat /etc/passwd | column -t -s:
211
+ column -t file.txt`,
190
212
  "cowsay": `COWSAY(1) User Commands COWSAY(1)
191
213
 
192
214
  NAME
@@ -810,6 +832,31 @@ SYNOPSIS
810
832
 
811
833
  OPTIONS
812
834
  -p no error if existing, make parent directories as needed`,
835
+ "mktemp": `MKTEMP(1) User Commands MKTEMP(1)
836
+
837
+ NAME
838
+ mktemp - create a temporary file or directory
839
+
840
+ SYNOPSIS
841
+ mktemp [OPTION]... [TEMPLATE]
842
+
843
+ DESCRIPTION
844
+ Create a temporary file or directory, safely, and print its name.
845
+ TEMPLATE must contain at least 3 consecutive 'X's in last component.
846
+ If TEMPLATE is not specified, use tmp.XXXXXXXXXX.
847
+ Files are created in /tmp.
848
+
849
+ OPTIONS
850
+ -d create a directory, not a file
851
+
852
+ EXIT STATUS
853
+ 0 on success
854
+ 1 if the file/directory could not be created
855
+
856
+ EXAMPLES
857
+ mktemp
858
+ mktemp -d
859
+ mktemp /tmp/foo.XXXXXX`,
813
860
  "mv": `MV(1) User Commands MV(1)
814
861
 
815
862
  NAME
@@ -841,6 +888,30 @@ SYNOPSIS
841
888
 
842
889
  DESCRIPTION
843
890
  Print OS, kernel, uptime, package count, and related system details.`,
891
+ "nl": `NL(1) User Commands NL(1)
892
+
893
+ NAME
894
+ nl - number lines of files
895
+
896
+ SYNOPSIS
897
+ nl [OPTION]... [FILE]...
898
+
899
+ DESCRIPTION
900
+ Write each FILE to standard output, with line numbers added.
901
+ With no FILE, or when FILE is -, read standard input.
902
+
903
+ OPTIONS
904
+ -b, --body-numbering=STYLE use STYLE for numbering body lines
905
+ a number all lines
906
+ t number only non-empty lines (default)
907
+ -n, --number-format=FORMAT use FORMAT for line numbers
908
+ ln left justified, no leading zeros
909
+ rn right justified, no leading zeros (default)
910
+ rz right justified, leading zeros
911
+
912
+ EXAMPLES
913
+ nl /etc/passwd
914
+ cat file.txt | nl`,
844
915
  "node": `NODE(1) User Commands NODE(1)
845
916
 
846
917
  NAME
@@ -867,6 +938,24 @@ DESCRIPTION
867
938
 
868
939
  NOTES
869
940
  Requires package installation: apt install npm.`,
941
+ "nproc": `NPROC(1) User Commands NPROC(1)
942
+
943
+ NAME
944
+ nproc - print the number of processing units available
945
+
946
+ SYNOPSIS
947
+ nproc [OPTION]...
948
+
949
+ DESCRIPTION
950
+ Print the number of processing units available to the current process.
951
+ In this environment, always returns 4.
952
+
953
+ OPTIONS
954
+ --all print the number of installed processors
955
+
956
+ EXAMPLES
957
+ nproc
958
+ make -j$(nproc)`,
870
959
  "npx": `NPX(1) User Commands NPX(1)
871
960
 
872
961
  NAME
@@ -880,6 +969,41 @@ DESCRIPTION
880
969
 
881
970
  NOTES
882
971
  Requires package installation: apt install npm.`,
972
+ "pacman": `PACMAN(1) User Commands PACMAN(1)
973
+
974
+ NAME
975
+ pacman - play ASCII Pac-Man in the terminal
976
+
977
+ SYNOPSIS
978
+ pacman
979
+
980
+ DESCRIPTION
981
+ pacman launches an interactive ASCII Pac-Man game using myman
982
+ maze graphics. Eat all dots to win. Avoid ghosts or lose a life.
983
+ Eat a power pellet to enter fright mode and eat ghosts for points.
984
+
985
+ CONTROLS
986
+ W, Up move up
987
+ S, Down move down
988
+ A, Left move left
989
+ D, Right move right
990
+ Q, Ctrl+C quit
991
+
992
+ GHOSTS
993
+ Blinky (red) directly chases Pac-Man
994
+ Pinky (pink) targets 4 tiles ahead of Pac-Man
995
+ Inky (cyan) uses Blinky's position to compute target
996
+ Clyde (orange) chases when far, scatters when close
997
+
998
+ SCORING
999
+ Dot 10 points
1000
+ Power pellet 50 points
1001
+ Ghost 200 points (during fright mode)
1002
+
1003
+ NOTES
1004
+ Ghosts slow down during fright mode. Fright mode ends after
1005
+ a few seconds; ghosts flash before returning to normal.
1006
+ Left and right tunnel exits wrap around the maze.`,
883
1007
  "passwd": `PASSWD(1) User Commands PASSWD(1)
884
1008
 
885
1009
  NAME
@@ -891,6 +1015,26 @@ SYNOPSIS
891
1015
  DESCRIPTION
892
1016
  Update the authentication token (password) for USER.
893
1017
  Without USER, change the current user's password.`,
1018
+ "paste": `PASTE(1) User Commands PASTE(1)
1019
+
1020
+ NAME
1021
+ paste - merge lines of files
1022
+
1023
+ SYNOPSIS
1024
+ paste [OPTION]... [FILE]...
1025
+
1026
+ DESCRIPTION
1027
+ Write lines consisting of the sequentially corresponding lines from
1028
+ each FILE, separated by TABs, to standard output.
1029
+
1030
+ OPTIONS
1031
+ -d, --delimiters=LIST use characters from LIST instead of TABs
1032
+ -s, --serial paste one file at a time instead of in parallel
1033
+
1034
+ EXAMPLES
1035
+ paste file1 file2
1036
+ paste -d: /etc/passwd /etc/shadow
1037
+ paste -d, a.txt b.txt c.txt`,
894
1038
  "ping": `PING(8) User Commands PING(8)
895
1039
 
896
1040
  NAME
@@ -993,7 +1137,16 @@ SYNOPSIS
993
1137
  rm [OPTION]... FILE...
994
1138
 
995
1139
  OPTIONS
996
- -r remove directories and their contents recursively`,
1140
+ -r, -R remove directories and their contents recursively
1141
+
1142
+ -f, --force
1143
+ skip confirmation prompt, never prompt
1144
+
1145
+ -rf, -fr
1146
+ recursive and force combined
1147
+
1148
+ Without -f, rm prompts for confirmation before removing each target.
1149
+ Answer y or yes to confirm, anything else cancels.`,
997
1150
  "sed": `SED(1) User Commands SED(1)
998
1151
 
999
1152
  NAME
@@ -1071,6 +1224,28 @@ SYNOPSIS
1071
1224
 
1072
1225
  DESCRIPTION
1073
1226
  Rename positional parameters by discarding the first N arguments.`,
1227
+ "shuf": `SHUF(1) User Commands SHUF(1)
1228
+
1229
+ NAME
1230
+ shuf - generate random permutations
1231
+
1232
+ SYNOPSIS
1233
+ shuf [OPTION]... [FILE]
1234
+ shuf -i LO-HI [OPTION]...
1235
+ shuf -e [OPTION]... [ARG]...
1236
+
1237
+ DESCRIPTION
1238
+ Write a random permutation of the input lines to standard output.
1239
+
1240
+ OPTIONS
1241
+ -i LO-HI treat each number LO through HI as an input line
1242
+ -n COUNT output at most COUNT lines
1243
+ -e treat each ARG as an input line
1244
+
1245
+ EXAMPLES
1246
+ shuf /etc/passwd
1247
+ shuf -i 1-10
1248
+ shuf -n 3 /etc/hosts`,
1074
1249
  "sl": `SL(1) User Commands SL(1)
1075
1250
 
1076
1251
  NAME
@@ -1186,6 +1361,24 @@ SYNOPSIS
1186
1361
  OPTIONS
1187
1362
  -i run login shell as target user
1188
1363
  -u USER run command as USER`,
1364
+ "tac": `TAC(1) User Commands TAC(1)
1365
+
1366
+ NAME
1367
+ tac - concatenate and print files in reverse
1368
+
1369
+ SYNOPSIS
1370
+ tac [OPTION]... [FILE]...
1371
+
1372
+ DESCRIPTION
1373
+ Write each FILE to standard output, last line first.
1374
+ With no FILE, or when FILE is -, read standard input.
1375
+
1376
+ OPTIONS
1377
+ -s, --separator=STRING use STRING as the record separator
1378
+
1379
+ EXAMPLES
1380
+ tac /var/log/syslog
1381
+ echo -e "a\\nb\\nc" | tac`,
1189
1382
  "tail": `TAIL(1) User Commands TAIL(1)
1190
1383
 
1191
1384
  NAME
@@ -1236,6 +1429,29 @@ SYNOPSIS
1236
1429
 
1237
1430
  DESCRIPTION
1238
1431
  Evaluate conditional expressions for scripts and shell logic.`,
1432
+ "timeout": `TIMEOUT(1) User Commands TIMEOUT(1)
1433
+
1434
+ NAME
1435
+ timeout - run a command with a time limit
1436
+
1437
+ SYNOPSIS
1438
+ timeout DURATION COMMAND [ARG]...
1439
+
1440
+ DESCRIPTION
1441
+ Start COMMAND, and kill it if still running after DURATION seconds.
1442
+ In this environment, the time limit is simulated and the command
1443
+ always runs to completion.
1444
+
1445
+ OPTIONS
1446
+ DURATION An integer number of seconds (e.g. 5).
1447
+
1448
+ EXIT STATUS
1449
+ 124 if the command times out
1450
+ Otherwise the exit status of COMMAND.
1451
+
1452
+ EXAMPLES
1453
+ timeout 5 sleep 10
1454
+ timeout 30 curl http://example.com/`,
1239
1455
  "touch": `TOUCH(1) User Commands TOUCH(1)
1240
1456
 
1241
1457
  NAME
@@ -1397,6 +1613,26 @@ DESCRIPTION
1397
1613
  The following entries are displayed for each user: login name,
1398
1614
  the tty name, the remote host, login time, idle time, JCPU, PCPU,
1399
1615
  and the command line of the current process.`,
1616
+ "wait": `WAIT(1) Bash Builtin Commands WAIT(1)
1617
+
1618
+ NAME
1619
+ wait - wait for job completion
1620
+
1621
+ SYNOPSIS
1622
+ wait [jobspec or pid ...]
1623
+
1624
+ DESCRIPTION
1625
+ Wait for each specified process or job and return its termination
1626
+ status. If no arguments are given, wait for all currently active
1627
+ background jobs.
1628
+
1629
+ In this environment, background jobs are fire-and-forget; wait
1630
+ returns immediately with exit code 0.
1631
+
1632
+ EXAMPLES
1633
+ sleep 5 &
1634
+ wait
1635
+ echo "done"`,
1400
1636
  "wc": `WC(1) User Commands WC(1)
1401
1637
 
1402
1638
  NAME
@@ -0,0 +1,8 @@
1
+ import type { ShellModule } from "../types/commands";
2
+ /**
3
+ * Play ASCII Pac-Man in the terminal (myman-wip-2009-10-30 maze graphics).
4
+ * Controls: WASD or arrow keys to move, Q to quit.
5
+ * @category misc
6
+ * @params [""]
7
+ */
8
+ export declare const pacmanCommand: ShellModule;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Play ASCII Pac-Man in the terminal (myman-wip-2009-10-30 maze graphics).
3
+ * Controls: WASD or arrow keys to move, Q to quit.
4
+ * @category misc
5
+ * @params [""]
6
+ */
7
+ export const pacmanCommand = {
8
+ name: "pacman",
9
+ description: "Play ASCII Pac-Man (myman graphics, WASD/arrows)",
10
+ category: "misc",
11
+ params: [],
12
+ run: () => {
13
+ return { openPacman: true, exitCode: 0 };
14
+ },
15
+ };
@@ -5,6 +5,7 @@ import { awkCommand } from "./awk";
5
5
  import { base64Command } from "./base64";
6
6
  import { basenameCommand, dirnameCommand } from "./basename";
7
7
  import { bcCommand } from "./bc";
8
+ import { columnCommand, mktempCommand, nlCommand, nprocCommand, pasteCommand, shufCommand, tacCommand, timeoutCommand, waitCommand } from "./coreutils";
8
9
  import { bunzip2Command, bzip2Command } from "./bzip2";
9
10
  import { lsofCommand } from "./lsof";
10
11
  import { perlCommand } from "./perl";
@@ -32,6 +33,7 @@ import { fileCommand } from "./file";
32
33
  import { findCommand } from "./find";
33
34
  import { freeCommand } from "./free";
34
35
  import { cmatrixCommand, cowsayCommand, cowthinkCommand, fortuneCommand, slCommand, yesCommand } from "./fun";
36
+ import { pacmanCommand } from "./pacman";
35
37
  import { grepCommand } from "./grep";
36
38
  import { groupsCommand } from "./groups";
37
39
  import { gunzipCommand, gzipCommand } from "./gzip";
@@ -177,6 +179,7 @@ const BASE_COMMANDS = [
177
179
  cowthinkCommand,
178
180
  cmatrixCommand,
179
181
  slCommand,
182
+ pacmanCommand,
180
183
  htopCommand,
181
184
  // Network
182
185
  curlCommand,
@@ -227,6 +230,16 @@ const BASE_COMMANDS = [
227
230
  straceCommand,
228
231
  // Scripting
229
232
  perlCommand,
233
+ // Coreutils (extended)
234
+ timeoutCommand,
235
+ mktempCommand,
236
+ nprocCommand,
237
+ waitCommand,
238
+ shufCommand,
239
+ pasteCommand,
240
+ tacCommand,
241
+ nlCommand,
242
+ columnCommand,
230
243
  ];
231
244
  const customCommands = [];
232
245
  const commandRegistry = new Map();
@@ -2,6 +2,6 @@ import type { ShellModule } from "../types/commands";
2
2
  /**
3
3
  * Remove files or directories from the filesystem.
4
4
  * @category files
5
- * @params ["[-r|-rf] <path>"]
5
+ * @params ["[-r|-rf|-f] <path>"]
6
6
  */
7
7
  export declare const rmCommand: ShellModule;