typescript-virtual-container 1.5.3 → 1.5.4
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 +43 -23
- package/dist/.tsbuildinfo +1 -0
- package/dist/SSHMimic/executor.js +23 -5
- package/dist/VirtualPackageManager/index.js +10 -0
- package/dist/commands/basename.d.ts +13 -0
- package/dist/commands/basename.js +45 -0
- package/dist/commands/file.d.ts +8 -0
- package/dist/commands/file.js +57 -0
- package/dist/commands/fun.d.ts +32 -0
- package/dist/commands/fun.js +172 -0
- package/dist/commands/ifconfig.d.ts +7 -0
- package/dist/commands/ifconfig.js +52 -0
- package/dist/commands/last.d.ts +13 -0
- package/dist/commands/last.js +68 -0
- package/dist/commands/manuals-bundle.js +598 -6
- package/dist/commands/registry.js +24 -2
- package/dist/commands/runtime.js +22 -2
- package/dist/commands/sh.js +5 -0
- package/dist/commands/tput.d.ts +13 -0
- package/dist/commands/tput.js +76 -0
- package/dist/commands/w.d.ts +7 -0
- package/dist/commands/w.js +38 -0
- package/dist/utils/expand.d.ts +12 -0
- package/dist/utils/expand.js +84 -0
- package/package.json +9 -3
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -50
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -31
- package/.github/dependabot.yml +0 -27
- package/.github/pull_request_template.md +0 -21
- package/.github/workflows/create-pull-request.yml +0 -85
- package/.github/workflows/publish.yml +0 -25
- package/.github/workflows/test-battery.yml +0 -102
- package/.vscode/settings.json +0 -20
- package/CODE_OF_CONDUCT.md +0 -39
- package/CONTRIBUTING.md +0 -59
- package/HONEYPOT.md +0 -358
- package/SECURITY.md +0 -33
- package/benchmark-results.txt +0 -40
- package/benchmark-virtualshell.ts +0 -88
- package/biome.json +0 -37
- package/build.js +0 -22
- package/builds/fortune-nyx-v1.5.3-directbash-k6.1.0.mjs +0 -1764
- package/builds/fortune-nyx-v1.5.3-ssh-nosftp.js +0 -1764
- package/builds/fortune-nyx-v1.5.3-ssh.cjs +0 -1765
- package/builds/fortune-nyx-v1.5.3-web.min.js +0 -17036
- package/bun.lock +0 -244
- package/docs/.nojekyll +0 -1
- package/docs/app.js +0 -1751
- package/docs/assets/hierarchy.js +0 -1
- package/docs/assets/highlight.css +0 -162
- package/docs/assets/icons.js +0 -18
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -60
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1633
- package/docs/classes/HoneyPot.html +0 -31
- package/docs/classes/IdleManager.html +0 -162
- package/docs/classes/SshClient.html +0 -66
- package/docs/classes/VirtualFileSystem.html +0 -279
- package/docs/classes/VirtualPackageManager.html +0 -63
- package/docs/classes/VirtualSftpServer.html +0 -169
- package/docs/classes/VirtualShell.html +0 -285
- package/docs/classes/VirtualSshServer.html +0 -182
- package/docs/classes/VirtualUserManager.html +0 -276
- package/docs/demo.html +0 -82
- package/docs/functions/assertDiff.html +0 -6
- package/docs/functions/diffSnapshots.html +0 -7
- package/docs/functions/formatDiff.html +0 -6
- package/docs/functions/getArg.html +0 -13
- package/docs/functions/getFlag.html +0 -15
- package/docs/functions/ifFlag.html +0 -11
- package/docs/hierarchy.html +0 -1
- package/docs/index.html +0 -1869
- package/docs/interfaces/AuditLogEntry.html +0 -6
- package/docs/interfaces/CommandContext.html +0 -22
- package/docs/interfaces/CommandResult.html +0 -26
- package/docs/interfaces/ExecStream.html +0 -11
- package/docs/interfaces/HoneyPotStats.html +0 -16
- package/docs/interfaces/IdleManagerOptions.html +0 -7
- package/docs/interfaces/InstalledPackage.html +0 -20
- package/docs/interfaces/NanoEditorSession.html +0 -8
- package/docs/interfaces/PackageDefinition.html +0 -30
- package/docs/interfaces/PackageFile.html +0 -8
- package/docs/interfaces/PasswordChallenge.html +0 -16
- package/docs/interfaces/RemoveOptions.html +0 -4
- package/docs/interfaces/ShellEnv.html +0 -6
- package/docs/interfaces/ShellModule.html +0 -14
- package/docs/interfaces/ShellProperties.html +0 -14
- package/docs/interfaces/ShellStream.html +0 -11
- package/docs/interfaces/SudoChallenge.html +0 -24
- package/docs/interfaces/VfsBaseNode.html +0 -12
- package/docs/interfaces/VfsDiff.html +0 -10
- package/docs/interfaces/VfsDiffEntry.html +0 -6
- package/docs/interfaces/VfsDiffModified.html +0 -10
- package/docs/interfaces/VfsDirectoryNode.html +0 -15
- package/docs/interfaces/VfsFileNode.html +0 -17
- package/docs/interfaces/VfsOptions.html +0 -26
- package/docs/interfaces/VfsSnapshot.html +0 -3
- package/docs/interfaces/VfsSnapshotBaseNode.html +0 -8
- package/docs/interfaces/VfsSnapshotDirectoryNode.html +0 -10
- package/docs/interfaces/VfsSnapshotFileNode.html +0 -12
- package/docs/interfaces/VirtualActiveSession.html +0 -12
- package/docs/interfaces/VirtualSftpServerOptions.html +0 -7
- package/docs/interfaces/VirtualShellVfsLike.html +0 -15
- package/docs/interfaces/VirtualShellVfsOptions.html +0 -3
- package/docs/interfaces/WriteFileOptions.html +0 -6
- package/docs/media/LICENSE +0 -21
- package/docs/modules.html +0 -1
- package/docs/types/ArgParseOptions.html +0 -4
- package/docs/types/CommandMode.html +0 -2
- package/docs/types/CommandOutcome.html +0 -2
- package/docs/types/IdleState.html +0 -1
- package/docs/types/VfsNodeStats.html +0 -2
- package/docs/types/VfsNodeType.html +0 -2
- package/docs/types/VfsPersistenceMode.html +0 -5
- package/docs/types/VfsSnapshotNode.html +0 -2
- package/examples/README.md +0 -288
- package/examples/app.js +0 -1751
- package/examples/app.ts +0 -299
- package/examples/build.js +0 -27
- package/examples/demo.html +0 -33
- package/examples/honeypot-audit.ts +0 -180
- package/examples/honeypot-export.ts +0 -253
- package/examples/honeypot-quickstart.ts +0 -110
- package/examples/index.html +0 -82
- package/examples/server.js +0 -55
- package/polyfills/buffer.js +0 -117
- package/polyfills/node_child_process/index.js +0 -2
- package/polyfills/node_crypto/index.js +0 -167
- package/polyfills/node_events/index.js +0 -9
- package/polyfills/node_fs/index.js +0 -202
- package/polyfills/node_fs/promises.js +0 -4
- package/polyfills/node_os/index.js +0 -9
- package/polyfills/node_path/index.js +0 -28
- package/polyfills/node_vm/index.js +0 -7
- package/polyfills/node_zlib/index.js +0 -3
- package/polyfills/process.js +0 -14
- package/polyfills/ssh2/index.js +0 -75
- package/scripts/build-all.mjs +0 -226
- package/scripts/build-names.mjs +0 -43
- package/scripts/generate-manuals-bundle.mjs +0 -49
- package/scripts/postinstall.js +0 -42
- package/scripts/publish-package.sh +0 -70
- package/src/Honeypot/index.ts +0 -457
- package/src/SSHClient/index.ts +0 -270
- package/src/SSHMimic/exec.ts +0 -49
- package/src/SSHMimic/executor.ts +0 -251
- package/src/SSHMimic/hostKey.ts +0 -21
- package/src/SSHMimic/index.ts +0 -337
- package/src/SSHMimic/loginBanner.ts +0 -36
- package/src/SSHMimic/loginFormat.ts +0 -10
- package/src/SSHMimic/prompt.ts +0 -14
- package/src/SSHMimic/sftp.ts +0 -883
- package/src/VirtualFileSystem/binaryPack.ts +0 -258
- package/src/VirtualFileSystem/index.ts +0 -1193
- package/src/VirtualFileSystem/internalTypes.ts +0 -43
- package/src/VirtualFileSystem/journal.ts +0 -171
- package/src/VirtualFileSystem/path.ts +0 -74
- package/src/VirtualPackageManager/index.ts +0 -996
- package/src/VirtualShell/idleManager.ts +0 -137
- package/src/VirtualShell/index.ts +0 -475
- package/src/VirtualShell/shell.ts +0 -700
- package/src/VirtualShell/shellParser.ts +0 -285
- package/src/VirtualUserManager/index.ts +0 -758
- package/src/bun.d.ts +0 -1
- package/src/commands/adduser.ts +0 -103
- package/src/commands/alias.ts +0 -69
- package/src/commands/apt.ts +0 -233
- package/src/commands/awk.ts +0 -168
- package/src/commands/base64.ts +0 -29
- package/src/commands/cat.ts +0 -52
- package/src/commands/cd.ts +0 -25
- package/src/commands/chmod.ts +0 -85
- package/src/commands/clear.ts +0 -15
- package/src/commands/command-helpers.ts +0 -286
- package/src/commands/cp.ts +0 -83
- package/src/commands/curl.ts +0 -147
- package/src/commands/cut.ts +0 -36
- package/src/commands/date.ts +0 -30
- package/src/commands/declare.ts +0 -49
- package/src/commands/deluser.ts +0 -98
- package/src/commands/df.ts +0 -23
- package/src/commands/diff.ts +0 -43
- package/src/commands/dpkg.ts +0 -180
- package/src/commands/du.ts +0 -56
- package/src/commands/echo.ts +0 -58
- package/src/commands/env.ts +0 -23
- package/src/commands/exit.ts +0 -18
- package/src/commands/export.ts +0 -34
- package/src/commands/find.ts +0 -68
- package/src/commands/free.ts +0 -47
- package/src/commands/grep.ts +0 -116
- package/src/commands/groups.ts +0 -19
- package/src/commands/gzip.ts +0 -88
- package/src/commands/head.ts +0 -52
- package/src/commands/help.ts +0 -152
- package/src/commands/helpers.ts +0 -234
- package/src/commands/history.ts +0 -34
- package/src/commands/hostname.ts +0 -14
- package/src/commands/htop.ts +0 -20
- package/src/commands/id.ts +0 -19
- package/src/commands/index.ts +0 -9
- package/src/commands/kill.ts +0 -19
- package/src/commands/ln.ts +0 -71
- package/src/commands/ls.ts +0 -243
- package/src/commands/lsb-release.ts +0 -63
- package/src/commands/man.ts +0 -31
- package/src/commands/manuals/adduser.txt +0 -11
- package/src/commands/manuals/apt-cache.txt +0 -12
- package/src/commands/manuals/apt.txt +0 -20
- package/src/commands/manuals/awk.txt +0 -13
- package/src/commands/manuals/cat.txt +0 -14
- package/src/commands/manuals/cd.txt +0 -16
- package/src/commands/manuals/chmod.txt +0 -16
- package/src/commands/manuals/clear.txt +0 -10
- package/src/commands/manuals/cp.txt +0 -10
- package/src/commands/manuals/curl.txt +0 -20
- package/src/commands/manuals/date.txt +0 -14
- package/src/commands/manuals/declare.txt +0 -12
- package/src/commands/manuals/deluser.txt +0 -10
- package/src/commands/manuals/df.txt +0 -10
- package/src/commands/manuals/dpkg-query.txt +0 -11
- package/src/commands/manuals/dpkg.txt +0 -14
- package/src/commands/manuals/du.txt +0 -11
- package/src/commands/manuals/echo.txt +0 -11
- package/src/commands/manuals/false.txt +0 -10
- package/src/commands/manuals/find.txt +0 -11
- package/src/commands/manuals/free.txt +0 -12
- package/src/commands/manuals/grep.txt +0 -13
- package/src/commands/manuals/groups.txt +0 -10
- package/src/commands/manuals/gzip.txt +0 -11
- package/src/commands/manuals/head.txt +0 -10
- package/src/commands/manuals/help.txt +0 -11
- package/src/commands/manuals/history.txt +0 -11
- package/src/commands/manuals/hostname.txt +0 -10
- package/src/commands/manuals/id.txt +0 -10
- package/src/commands/manuals/kill.txt +0 -13
- package/src/commands/manuals/ls.txt +0 -20
- package/src/commands/manuals/lsb_release.txt +0 -14
- package/src/commands/manuals/mkdir.txt +0 -10
- package/src/commands/manuals/mv.txt +0 -10
- package/src/commands/manuals/nano.txt +0 -11
- package/src/commands/manuals/neofetch.txt +0 -10
- package/src/commands/manuals/node.txt +0 -13
- package/src/commands/manuals/npm.txt +0 -13
- package/src/commands/manuals/npx.txt +0 -13
- package/src/commands/manuals/passwd.txt +0 -11
- package/src/commands/manuals/ping.txt +0 -10
- package/src/commands/manuals/printf.txt +0 -11
- package/src/commands/manuals/ps.txt +0 -10
- package/src/commands/manuals/pwd.txt +0 -10
- package/src/commands/manuals/python3.txt +0 -13
- package/src/commands/manuals/readlink.txt +0 -10
- package/src/commands/manuals/return.txt +0 -10
- package/src/commands/manuals/rm.txt +0 -10
- package/src/commands/manuals/sed.txt +0 -11
- package/src/commands/manuals/set.txt +0 -11
- package/src/commands/manuals/shift.txt +0 -10
- package/src/commands/manuals/sleep.txt +0 -10
- package/src/commands/manuals/sort.txt +0 -12
- package/src/commands/manuals/source.txt +0 -11
- package/src/commands/manuals/ssh.txt +0 -11
- package/src/commands/manuals/stat.txt +0 -10
- package/src/commands/manuals/su.txt +0 -13
- package/src/commands/manuals/sudo.txt +0 -11
- package/src/commands/manuals/tail.txt +0 -10
- package/src/commands/manuals/tar.txt +0 -19
- package/src/commands/manuals/tee.txt +0 -10
- package/src/commands/manuals/test.txt +0 -11
- package/src/commands/manuals/touch.txt +0 -11
- package/src/commands/manuals/tr.txt +0 -10
- package/src/commands/manuals/trap.txt +0 -10
- package/src/commands/manuals/true.txt +0 -10
- package/src/commands/manuals/type.txt +0 -10
- package/src/commands/manuals/uname.txt +0 -12
- package/src/commands/manuals/uniq.txt +0 -12
- package/src/commands/manuals/unset.txt +0 -10
- package/src/commands/manuals/uptime.txt +0 -11
- package/src/commands/manuals/wc.txt +0 -12
- package/src/commands/manuals/wget.txt +0 -12
- package/src/commands/manuals/which.txt +0 -10
- package/src/commands/manuals/whoami.txt +0 -10
- package/src/commands/manuals/xargs.txt +0 -10
- package/src/commands/manuals-bundle.ts +0 -898
- package/src/commands/mkdir.ts +0 -31
- package/src/commands/mv.ts +0 -50
- package/src/commands/nano.ts +0 -38
- package/src/commands/neofetch.ts +0 -53
- package/src/commands/node.ts +0 -341
- package/src/commands/npm.ts +0 -132
- package/src/commands/passwd.ts +0 -50
- package/src/commands/ping.ts +0 -32
- package/src/commands/printf.ts +0 -129
- package/src/commands/ps.ts +0 -58
- package/src/commands/pwd.ts +0 -9
- package/src/commands/python.ts +0 -2229
- package/src/commands/read.ts +0 -46
- package/src/commands/registry.ts +0 -249
- package/src/commands/rm.ts +0 -42
- package/src/commands/runtime.ts +0 -421
- package/src/commands/sed.ts +0 -68
- package/src/commands/seq.ts +0 -43
- package/src/commands/set.ts +0 -29
- package/src/commands/sh.ts +0 -467
- package/src/commands/shift.ts +0 -63
- package/src/commands/sleep.ts +0 -20
- package/src/commands/sort.ts +0 -46
- package/src/commands/source.ts +0 -52
- package/src/commands/stat.ts +0 -61
- package/src/commands/su.ts +0 -72
- package/src/commands/sudo.ts +0 -76
- package/src/commands/tail.ts +0 -53
- package/src/commands/tar.ts +0 -102
- package/src/commands/tee.ts +0 -36
- package/src/commands/test.ts +0 -137
- package/src/commands/touch.ts +0 -28
- package/src/commands/tr.ts +0 -70
- package/src/commands/tree.ts +0 -20
- package/src/commands/true.ts +0 -27
- package/src/commands/type.ts +0 -48
- package/src/commands/uname.ts +0 -29
- package/src/commands/uniq.ts +0 -39
- package/src/commands/unset.ts +0 -17
- package/src/commands/uptime.ts +0 -54
- package/src/commands/wc.ts +0 -55
- package/src/commands/wget.ts +0 -148
- package/src/commands/which.ts +0 -37
- package/src/commands/who.ts +0 -25
- package/src/commands/whoami.ts +0 -14
- package/src/commands/xargs.ts +0 -31
- package/src/index.ts +0 -67
- package/src/modules/linuxRootfs.ts +0 -1961
- package/src/modules/neofetch.ts +0 -358
- package/src/modules/shellInteractive.ts +0 -57
- package/src/modules/shellRuntime.ts +0 -76
- package/src/self-standalone.ts +0 -542
- package/src/standalone-wo-sftp.ts +0 -38
- package/src/standalone.ts +0 -72
- package/src/types/commands.ts +0 -146
- package/src/types/pipeline.ts +0 -52
- package/src/types/streams.ts +0 -32
- package/src/types/tar-stream.d.ts +0 -38
- package/src/types/vfs.ts +0 -98
- package/src/utils/expand.ts +0 -491
- package/src/utils/perfLogger.ts +0 -72
- package/src/utils/tokenize.ts +0 -98
- package/src/utils/vfsDiff.ts +0 -275
- package/tests/command-helpers.test.ts +0 -116
- package/tests/commands-admin-net.test.ts +0 -441
- package/tests/commands-advanced.test.ts +0 -456
- package/tests/commands-core.test.ts +0 -562
- package/tests/commands-missing.test.ts +0 -570
- package/tests/commands-specific-units.test.ts +0 -327
- package/tests/commands-text-sys.test.ts +0 -445
- package/tests/expand.test.ts +0 -170
- package/tests/helpers.test.ts +0 -97
- package/tests/new-features.test.ts +0 -1036
- package/tests/parser-executor.test.ts +0 -37
- package/tests/sftp.test.ts +0 -323
- package/tests/ssh-exec.test.ts +0 -45
- package/tests/test-helper.ts +0 -79
- package/tests/users.test.ts +0 -86
- package/tsconfig.json +0 -49
- package/typedoc.json +0 -47
|
@@ -3,6 +3,7 @@ import { aliasCommand, unaliasCommand } from "./alias";
|
|
|
3
3
|
import { aptCacheCommand, aptCommand } from "./apt";
|
|
4
4
|
import { awkCommand } from "./awk";
|
|
5
5
|
import { base64Command } from "./base64";
|
|
6
|
+
import { basenameCommand, dirnameCommand } from "./basename";
|
|
6
7
|
import { catCommand } from "./cat";
|
|
7
8
|
import { cdCommand } from "./cd";
|
|
8
9
|
import { chmodCommand } from "./chmod";
|
|
@@ -21,8 +22,10 @@ import { echoCommand } from "./echo";
|
|
|
21
22
|
import { envCommand } from "./env";
|
|
22
23
|
import { exitCommand } from "./exit";
|
|
23
24
|
import { exportCommand } from "./export";
|
|
25
|
+
import { fileCommand } from "./file";
|
|
24
26
|
import { findCommand } from "./find";
|
|
25
27
|
import { freeCommand } from "./free";
|
|
28
|
+
import { cmatrixCommand, cowsayCommand, cowthinkCommand, fortuneCommand, slCommand, yesCommand } from "./fun";
|
|
26
29
|
import { grepCommand } from "./grep";
|
|
27
30
|
import { groupsCommand } from "./groups";
|
|
28
31
|
import { gunzipCommand, gzipCommand } from "./gzip";
|
|
@@ -32,10 +35,10 @@ import { historyCommand } from "./history";
|
|
|
32
35
|
import { hostnameCommand } from "./hostname";
|
|
33
36
|
import { htopCommand } from "./htop";
|
|
34
37
|
import { idCommand } from "./id";
|
|
38
|
+
import { ifconfigCommand } from "./ifconfig";
|
|
35
39
|
import { killCommand } from "./kill";
|
|
40
|
+
import { dmesgCommand, lastCommand } from "./last";
|
|
36
41
|
import { lnCommand, readlinkCommand } from "./ln";
|
|
37
|
-
import { seqCommand } from "./seq";
|
|
38
|
-
import { statCommand } from "./stat";
|
|
39
42
|
import { lsCommand } from "./ls";
|
|
40
43
|
import { lsbReleaseCommand } from "./lsb-release";
|
|
41
44
|
import { manCommand } from "./man";
|
|
@@ -54,12 +57,14 @@ import { python3Command } from "./python";
|
|
|
54
57
|
import { readCommand } from "./read";
|
|
55
58
|
import { rmCommand } from "./rm";
|
|
56
59
|
import { sedCommand } from "./sed";
|
|
60
|
+
import { seqCommand } from "./seq";
|
|
57
61
|
import { setCommand } from "./set";
|
|
58
62
|
import { shCommand } from "./sh";
|
|
59
63
|
import { returnCommand, shiftCommand, trapCommand } from "./shift";
|
|
60
64
|
import { sleepCommand } from "./sleep";
|
|
61
65
|
import { sortCommand } from "./sort";
|
|
62
66
|
import { sourceCommand } from "./source";
|
|
67
|
+
import { statCommand } from "./stat";
|
|
63
68
|
import { suCommand } from "./su";
|
|
64
69
|
import { sudoCommand } from "./sudo";
|
|
65
70
|
import { tailCommand } from "./tail";
|
|
@@ -67,6 +72,7 @@ import { tarCommand } from "./tar";
|
|
|
67
72
|
import { teeCommand } from "./tee";
|
|
68
73
|
import { testCommand } from "./test";
|
|
69
74
|
import { touchCommand } from "./touch";
|
|
75
|
+
import { sttyCommand, tputCommand } from "./tput";
|
|
70
76
|
import { trCommand } from "./tr";
|
|
71
77
|
import { treeCommand } from "./tree";
|
|
72
78
|
import { falseCommand, trueCommand } from "./true";
|
|
@@ -81,6 +87,7 @@ import { whichCommand } from "./which";
|
|
|
81
87
|
import { whoCommand } from "./who";
|
|
82
88
|
import { whoamiCommand } from "./whoami";
|
|
83
89
|
import { xargsCommand } from "./xargs";
|
|
90
|
+
import { wCommand } from "./w";
|
|
84
91
|
const BASE_COMMANDS = [
|
|
85
92
|
// Navigation
|
|
86
93
|
pwdCommand,
|
|
@@ -144,6 +151,21 @@ const BASE_COMMANDS = [
|
|
|
144
151
|
exitCommand,
|
|
145
152
|
// Editors
|
|
146
153
|
nanoCommand,
|
|
154
|
+
wCommand,
|
|
155
|
+
basenameCommand,
|
|
156
|
+
dirnameCommand,
|
|
157
|
+
fileCommand,
|
|
158
|
+
tputCommand,
|
|
159
|
+
sttyCommand,
|
|
160
|
+
lastCommand,
|
|
161
|
+
dmesgCommand,
|
|
162
|
+
ifconfigCommand,
|
|
163
|
+
yesCommand,
|
|
164
|
+
fortuneCommand,
|
|
165
|
+
cowsayCommand,
|
|
166
|
+
cowthinkCommand,
|
|
167
|
+
cmatrixCommand,
|
|
168
|
+
slCommand,
|
|
147
169
|
htopCommand,
|
|
148
170
|
// Network
|
|
149
171
|
curlCommand,
|
package/dist/commands/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */
|
|
2
2
|
import { executeStatements } from "../SSHMimic/executor";
|
|
3
3
|
import { parseScript } from "../VirtualShell/shellParser";
|
|
4
|
-
import { expandAsync, expandBraces } from "../utils/expand";
|
|
4
|
+
import { expandAsync, expandBraces, expandGlob } from "../utils/expand";
|
|
5
5
|
import { tokenizeCommand } from "../utils/tokenize";
|
|
6
6
|
import { resolveModule } from "./registry";
|
|
7
7
|
/** Returns the home directory path for a given user. Root lives at /root. */
|
|
@@ -192,6 +192,26 @@ export async function runCommand(rawInput, authUser, hostname, mode, cwd, shell,
|
|
|
192
192
|
return { stderr: `${trimmed.split(" ")[0]}: maximum call depth (${MAX_CALL_DEPTH}) exceeded`, exitCode: 126 };
|
|
193
193
|
}
|
|
194
194
|
try {
|
|
195
|
+
// History expansion: !! and !n
|
|
196
|
+
if (trimmed === '!!' || /^!-?\d+$/.test(trimmed) || trimmed.startsWith('!! ')) {
|
|
197
|
+
const histPath = `${shellEnv.vars.HOME ?? `/home/${authUser}`}/.bash_history`;
|
|
198
|
+
if (shell.vfs.exists(histPath)) {
|
|
199
|
+
const lines = shell.vfs.readFile(histPath).split('\n').filter(Boolean);
|
|
200
|
+
let cmd;
|
|
201
|
+
if (trimmed === '!!' || trimmed.startsWith('!! ')) {
|
|
202
|
+
cmd = lines[lines.length - 1];
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const n = parseInt(trimmed.slice(1), 10);
|
|
206
|
+
cmd = n > 0 ? lines[n - 1] : lines[lines.length + n];
|
|
207
|
+
}
|
|
208
|
+
if (cmd) {
|
|
209
|
+
const suffix = trimmed.startsWith('!! ') ? trimmed.slice(3) : '';
|
|
210
|
+
return runCommand(`${cmd}${suffix ? ` ${suffix}` : ''}`, authUser, hostname, mode, cwd, shell, stdin, shellEnv);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return { stderr: `${trimmed}: event not found`, exitCode: 1 };
|
|
214
|
+
}
|
|
195
215
|
const rawTokens = tokenizeCommand(trimmed);
|
|
196
216
|
const rawFirstWord = rawTokens[0]?.toLowerCase() ?? "";
|
|
197
217
|
const aliasVal = shellEnv.vars[`__alias_${rawFirstWord}`];
|
|
@@ -252,7 +272,7 @@ export async function runCommand(rawInput, authUser, hostname, mode, cwd, shell,
|
|
|
252
272
|
}
|
|
253
273
|
const commandName = parts[0]?.toLowerCase() ?? "";
|
|
254
274
|
// Apply brace expansion to each arg token
|
|
255
|
-
const args = parts.slice(1).flatMap(expandBraces);
|
|
275
|
+
const args = parts.slice(1).flatMap(expandBraces).flatMap(token => expandGlob(token, cwd, shell.vfs));
|
|
256
276
|
const mod = resolveModule(commandName);
|
|
257
277
|
if (!mod) {
|
|
258
278
|
const vfsBinary = resolveVfsBinary(commandName, shellEnv, shell, authUser);
|
package/dist/commands/sh.js
CHANGED
|
@@ -369,6 +369,11 @@ function splitShScript(script) {
|
|
|
369
369
|
}
|
|
370
370
|
continue;
|
|
371
371
|
}
|
|
372
|
+
// Backslash-newline continuation: join lines
|
|
373
|
+
if (!inSingleQ && ch === '\\' && i + 1 < script.length && script[i + 1] === '\n') {
|
|
374
|
+
i += 2; // skip \ and \n
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
372
377
|
if (depth === 0 && (ch === ";" || ch === "\n")) {
|
|
373
378
|
const t = current.trim();
|
|
374
379
|
if (t && !t.startsWith("#"))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShellModule } from "../types/commands";
|
|
2
|
+
/**
|
|
3
|
+
* Terminal control.
|
|
4
|
+
* @category shell
|
|
5
|
+
* @params ["<cap> [args...]"]
|
|
6
|
+
*/
|
|
7
|
+
export declare const tputCommand: ShellModule;
|
|
8
|
+
/**
|
|
9
|
+
* Print or set terminal line settings.
|
|
10
|
+
* @category shell
|
|
11
|
+
* @params ["[args...]"]
|
|
12
|
+
*/
|
|
13
|
+
export declare const sttyCommand: ShellModule;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const CAPS = {
|
|
2
|
+
cols: 220, lines: 50, colors: 256,
|
|
3
|
+
bold: "\x1b[1m", dim: "\x1b[2m", smul: "\x1b[4m", rmul: "\x1b[24m",
|
|
4
|
+
rev: "\x1b[7m", smso: "\x1b[7m", rmso: "\x1b[27m",
|
|
5
|
+
sgr0: "\x1b[0m", el: "\x1b[K", ed: "\x1b[J",
|
|
6
|
+
clear: "\x1b[2J\x1b[H", cup: "", setaf: "", setab: "",
|
|
7
|
+
};
|
|
8
|
+
const ANSI_COLORS = [
|
|
9
|
+
"30", "31", "32", "33", "34", "35", "36", "37",
|
|
10
|
+
"90", "91", "92", "93", "94", "95", "96", "97",
|
|
11
|
+
];
|
|
12
|
+
/**
|
|
13
|
+
* Terminal control.
|
|
14
|
+
* @category shell
|
|
15
|
+
* @params ["<cap> [args...]"]
|
|
16
|
+
*/
|
|
17
|
+
export const tputCommand = {
|
|
18
|
+
name: "tput",
|
|
19
|
+
description: "Query terminfo database",
|
|
20
|
+
category: "shell",
|
|
21
|
+
params: ["<cap> [args...]"],
|
|
22
|
+
run: ({ args }) => {
|
|
23
|
+
const cap = args[0];
|
|
24
|
+
if (!cap)
|
|
25
|
+
return { stderr: "tput: missing capability", exitCode: 1 };
|
|
26
|
+
if (cap === "setaf" && args[1] !== undefined) {
|
|
27
|
+
const n = parseInt(args[1], 10);
|
|
28
|
+
const code = ANSI_COLORS[n] ?? "39";
|
|
29
|
+
return { stdout: `\x1b[${code}m`, exitCode: 0 };
|
|
30
|
+
}
|
|
31
|
+
if (cap === "setab" && args[1] !== undefined) {
|
|
32
|
+
const n = parseInt(args[1], 10);
|
|
33
|
+
const code = ANSI_COLORS[n]?.replace(/3/, "4").replace(/9/, "10") ?? "49";
|
|
34
|
+
return { stdout: `\x1b[${code}m`, exitCode: 0 };
|
|
35
|
+
}
|
|
36
|
+
if (cap === "cup" && args[1] !== undefined && args[2] !== undefined) {
|
|
37
|
+
return { stdout: `\x1b[${parseInt(args[1], 10) + 1};${parseInt(args[2], 10) + 1}H`, exitCode: 0 };
|
|
38
|
+
}
|
|
39
|
+
const val = CAPS[cap];
|
|
40
|
+
if (val === undefined)
|
|
41
|
+
return { stderr: `tput: unknown terminal capability '${cap}'`, exitCode: 1 };
|
|
42
|
+
return { stdout: String(val), exitCode: 0 };
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Print or set terminal line settings.
|
|
47
|
+
* @category shell
|
|
48
|
+
* @params ["[args...]"]
|
|
49
|
+
*/
|
|
50
|
+
export const sttyCommand = {
|
|
51
|
+
name: "stty",
|
|
52
|
+
description: "Change and print terminal line settings",
|
|
53
|
+
category: "shell",
|
|
54
|
+
params: ["[args...]"],
|
|
55
|
+
run: ({ args }) => {
|
|
56
|
+
if (args.includes("-a") || args.includes("--all")) {
|
|
57
|
+
return {
|
|
58
|
+
stdout: [
|
|
59
|
+
"speed 38400 baud; rows 50; columns 220; line = 0;",
|
|
60
|
+
"intr = ^C; quit = ^\\; erase = ^?; kill = ^U; eof = ^D;",
|
|
61
|
+
"eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S;",
|
|
62
|
+
"-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts",
|
|
63
|
+
"brkint -icrnl ixon -ixoff -iuclc ixany imaxbel -iutf8",
|
|
64
|
+
"opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0",
|
|
65
|
+
"isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke",
|
|
66
|
+
].join("\n"),
|
|
67
|
+
exitCode: 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (args.includes("size")) {
|
|
71
|
+
return { stdout: "50 220", exitCode: 0 };
|
|
72
|
+
}
|
|
73
|
+
// silently accept set operations
|
|
74
|
+
return { exitCode: 0 };
|
|
75
|
+
},
|
|
76
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { userHome } from "./runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Show who is logged on and what they are doing.
|
|
4
|
+
* @category system
|
|
5
|
+
* @params ["[user]"]
|
|
6
|
+
*/
|
|
7
|
+
export const wCommand = {
|
|
8
|
+
name: "w",
|
|
9
|
+
description: "Show who is logged on and what they are doing",
|
|
10
|
+
category: "system",
|
|
11
|
+
params: ["[user]"],
|
|
12
|
+
run: ({ shell, authUser }) => {
|
|
13
|
+
const now = new Date();
|
|
14
|
+
const upSecs = Math.floor(performance.now() / 1000);
|
|
15
|
+
const upMins = Math.floor(upSecs / 60);
|
|
16
|
+
const upHours = Math.floor(upMins / 60);
|
|
17
|
+
const uptimeStr = upHours > 0
|
|
18
|
+
? `${upHours}:${String(upMins % 60).padStart(2, "0")}`
|
|
19
|
+
: `${upMins} min`;
|
|
20
|
+
const timeStr = now.toTimeString().slice(0, 5);
|
|
21
|
+
// Read active sessions
|
|
22
|
+
shell.users.listActiveSessions?.();
|
|
23
|
+
const logPath = `${userHome(authUser)}/.lastlog`;
|
|
24
|
+
let loginTime = timeStr;
|
|
25
|
+
if (shell.vfs.exists(logPath)) {
|
|
26
|
+
try {
|
|
27
|
+
const log = JSON.parse(shell.vfs.readFile(logPath));
|
|
28
|
+
loginTime = new Date(log.at).toTimeString().slice(0, 5);
|
|
29
|
+
}
|
|
30
|
+
catch { }
|
|
31
|
+
}
|
|
32
|
+
const header = ` ${timeStr} up ${uptimeStr}, 1 user, load average: 0.${Math.floor(Math.random() * 30).toString().padStart(2, "0")}, 0.${Math.floor(Math.random() * 15).toString().padStart(2, "0")}, 0.${Math.floor(Math.random() * 10).toString().padStart(2, "0")}`;
|
|
33
|
+
const colHeader = "USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT";
|
|
34
|
+
const idle = "0.00s";
|
|
35
|
+
const row = `${authUser.padEnd(8)} pts/0 browser ${loginTime} ${idle} 0.01s 0.00s -bash`;
|
|
36
|
+
return { stdout: [header, colHeader, row].join("\n"), exitCode: 0 };
|
|
37
|
+
},
|
|
38
|
+
};
|
package/dist/utils/expand.d.ts
CHANGED
|
@@ -56,3 +56,15 @@ export declare function expandSync(input: string, env: Record<string, string>, l
|
|
|
56
56
|
* @param runCmd Async callback to execute a command and return its stdout.
|
|
57
57
|
*/
|
|
58
58
|
export declare function expandAsync(input: string, env: Record<string, string>, lastExit: number, runCmd: (cmd: string) => Promise<string>): Promise<string>;
|
|
59
|
+
/**
|
|
60
|
+
* Expand a glob pattern against a VirtualShell VFS.
|
|
61
|
+
* Supports * (any chars in segment) and ** (any path).
|
|
62
|
+
* Returns the original pattern if no matches found (bash behavior).
|
|
63
|
+
*/
|
|
64
|
+
export declare function expandGlob(pattern: string, cwd: string, vfs: {
|
|
65
|
+
list: (p: string) => string[];
|
|
66
|
+
exists: (p: string) => boolean;
|
|
67
|
+
stat: (p: string) => {
|
|
68
|
+
type: string;
|
|
69
|
+
};
|
|
70
|
+
}): string[];
|
package/dist/utils/expand.js
CHANGED
|
@@ -474,3 +474,87 @@ export async function expandAsync(input, env, lastExit, runCmd) {
|
|
|
474
474
|
env[depthKey] = String(currentDepth);
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
|
+
// ─── Glob expansion ──────────────────────────────────────────────────────────
|
|
478
|
+
/**
|
|
479
|
+
* Expand a glob pattern against a VirtualShell VFS.
|
|
480
|
+
* Supports * (any chars in segment) and ** (any path).
|
|
481
|
+
* Returns the original pattern if no matches found (bash behavior).
|
|
482
|
+
*/
|
|
483
|
+
export function expandGlob(pattern, cwd, vfs) {
|
|
484
|
+
// No glob chars → return as-is
|
|
485
|
+
if (!pattern.includes('*') && !pattern.includes('?'))
|
|
486
|
+
return [pattern];
|
|
487
|
+
const isAbsolute = pattern.startsWith('/');
|
|
488
|
+
const base = isAbsolute ? '/' : cwd;
|
|
489
|
+
const relPattern = isAbsolute ? pattern.slice(1) : pattern;
|
|
490
|
+
const results = matchGlob(base, relPattern.split('/'), vfs);
|
|
491
|
+
if (results.length === 0)
|
|
492
|
+
return [pattern]; // no match → literal
|
|
493
|
+
return results.sort();
|
|
494
|
+
}
|
|
495
|
+
function matchGlob(dir, segments, vfs) {
|
|
496
|
+
if (segments.length === 0)
|
|
497
|
+
return [dir];
|
|
498
|
+
const [seg, ...rest] = segments;
|
|
499
|
+
if (!seg)
|
|
500
|
+
return [dir];
|
|
501
|
+
// ** matches zero or more path segments
|
|
502
|
+
if (seg === '**') {
|
|
503
|
+
const all = walkAll(dir, vfs);
|
|
504
|
+
return rest.length === 0 ? all : all.flatMap(d => {
|
|
505
|
+
try {
|
|
506
|
+
if (vfs.stat(d).type === 'directory')
|
|
507
|
+
return matchGlob(d, rest, vfs);
|
|
508
|
+
}
|
|
509
|
+
catch { }
|
|
510
|
+
return [];
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
let entries = [];
|
|
514
|
+
try {
|
|
515
|
+
entries = vfs.list(dir);
|
|
516
|
+
}
|
|
517
|
+
catch {
|
|
518
|
+
return [];
|
|
519
|
+
}
|
|
520
|
+
const re = globToRegex(seg);
|
|
521
|
+
return entries
|
|
522
|
+
.filter(e => !e.startsWith('.') || seg.startsWith('.'))
|
|
523
|
+
.filter(e => re.test(e))
|
|
524
|
+
.flatMap(e => {
|
|
525
|
+
const full = dir === '/' ? `/${e}` : `${dir}/${e}`;
|
|
526
|
+
if (rest.length === 0)
|
|
527
|
+
return [full];
|
|
528
|
+
try {
|
|
529
|
+
if (vfs.stat(full).type === 'directory')
|
|
530
|
+
return matchGlob(full, rest, vfs);
|
|
531
|
+
}
|
|
532
|
+
catch { }
|
|
533
|
+
return [];
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
function walkAll(dir, vfs) {
|
|
537
|
+
const results = [dir];
|
|
538
|
+
let entries = [];
|
|
539
|
+
try {
|
|
540
|
+
entries = vfs.list(dir);
|
|
541
|
+
}
|
|
542
|
+
catch {
|
|
543
|
+
return results;
|
|
544
|
+
}
|
|
545
|
+
for (const e of entries) {
|
|
546
|
+
const full = dir === '/' ? `/${e}` : `${dir}/${e}`;
|
|
547
|
+
try {
|
|
548
|
+
if (vfs.stat(full).type === 'directory')
|
|
549
|
+
results.push(...walkAll(full, vfs));
|
|
550
|
+
}
|
|
551
|
+
catch { }
|
|
552
|
+
}
|
|
553
|
+
return results;
|
|
554
|
+
}
|
|
555
|
+
function globToRegex(pattern) {
|
|
556
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
557
|
+
.replace(/\*/g, '.*')
|
|
558
|
+
.replace(/\?/g, '.');
|
|
559
|
+
return new RegExp(`^${escaped}$`);
|
|
560
|
+
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "1.5.
|
|
7
|
+
"version": "1.5.4",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist/",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE",
|
|
12
|
+
"CHANGELOG.md"
|
|
13
|
+
],
|
|
8
14
|
"license": "MIT",
|
|
9
15
|
"repository": {
|
|
10
16
|
"type": "git",
|
|
@@ -26,7 +32,7 @@
|
|
|
26
32
|
"lint:write": "bunx --bun @biomejs/biome lint --write ./src",
|
|
27
33
|
"test": "bun run test-salve",
|
|
28
34
|
"test-battery": "bun test tests/",
|
|
29
|
-
"test-salve": "for f in tests/*.test.ts; do echo \"\\n
|
|
35
|
+
"test-salve": "for f in tests/*.test.ts; do echo \"\\n\ud83e\uddea Testing $f...\"; bun test \"$f\" --timeout 10000; sleep 0.25; done",
|
|
30
36
|
"build": "tsc --project tsconfig.json",
|
|
31
37
|
"deploy:npm": "bun publish --access public",
|
|
32
38
|
"bench": "rm -rf .benchmark-shells/ && bun benchmark-virtualshell.ts",
|
|
@@ -59,4 +65,4 @@
|
|
|
59
65
|
"dependencies": {
|
|
60
66
|
"ssh2": "^1.17.0"
|
|
61
67
|
}
|
|
62
|
-
}
|
|
68
|
+
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
name: Bug report
|
|
2
|
-
description: Report a reproducible problem
|
|
3
|
-
labels: [bug]
|
|
4
|
-
body:
|
|
5
|
-
- type: markdown
|
|
6
|
-
attributes:
|
|
7
|
-
value: |
|
|
8
|
-
Thanks for reporting a bug. Please fill out the details below.
|
|
9
|
-
- type: input
|
|
10
|
-
id: version
|
|
11
|
-
attributes:
|
|
12
|
-
label: Package version
|
|
13
|
-
placeholder: 1.0.0
|
|
14
|
-
validations:
|
|
15
|
-
required: true
|
|
16
|
-
- type: input
|
|
17
|
-
id: runtime
|
|
18
|
-
attributes:
|
|
19
|
-
label: Runtime and version
|
|
20
|
-
description: Node or Bun
|
|
21
|
-
placeholder: Node 20.12.0
|
|
22
|
-
validations:
|
|
23
|
-
required: true
|
|
24
|
-
- type: textarea
|
|
25
|
-
id: reproduction
|
|
26
|
-
attributes:
|
|
27
|
-
label: Reproduction steps
|
|
28
|
-
placeholder: |
|
|
29
|
-
1. Start server with ...
|
|
30
|
-
2. Run command ...
|
|
31
|
-
3. Observe error ...
|
|
32
|
-
validations:
|
|
33
|
-
required: true
|
|
34
|
-
- type: textarea
|
|
35
|
-
id: expected
|
|
36
|
-
attributes:
|
|
37
|
-
label: Expected behavior
|
|
38
|
-
validations:
|
|
39
|
-
required: true
|
|
40
|
-
- type: textarea
|
|
41
|
-
id: actual
|
|
42
|
-
attributes:
|
|
43
|
-
label: Actual behavior
|
|
44
|
-
validations:
|
|
45
|
-
required: true
|
|
46
|
-
- type: textarea
|
|
47
|
-
id: logs
|
|
48
|
-
attributes:
|
|
49
|
-
label: Logs or stack trace
|
|
50
|
-
render: shell
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
name: Feature request
|
|
2
|
-
description: Suggest an improvement
|
|
3
|
-
labels: [enhancement]
|
|
4
|
-
body:
|
|
5
|
-
- type: markdown
|
|
6
|
-
attributes:
|
|
7
|
-
value: |
|
|
8
|
-
Thanks for proposing an improvement.
|
|
9
|
-
- type: textarea
|
|
10
|
-
id: problem
|
|
11
|
-
attributes:
|
|
12
|
-
label: Problem statement
|
|
13
|
-
description: What problem are you trying to solve?
|
|
14
|
-
validations:
|
|
15
|
-
required: true
|
|
16
|
-
- type: textarea
|
|
17
|
-
id: proposal
|
|
18
|
-
attributes:
|
|
19
|
-
label: Proposed solution
|
|
20
|
-
description: Describe the API or behavior you want.
|
|
21
|
-
validations:
|
|
22
|
-
required: true
|
|
23
|
-
- type: textarea
|
|
24
|
-
id: alternatives
|
|
25
|
-
attributes:
|
|
26
|
-
label: Alternatives considered
|
|
27
|
-
- type: textarea
|
|
28
|
-
id: impact
|
|
29
|
-
attributes:
|
|
30
|
-
label: Breaking change impact
|
|
31
|
-
description: Does this change public API behavior?
|
package/.github/dependabot.yml
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
updates:
|
|
3
|
-
- package-ecosystem: "npm"
|
|
4
|
-
directory: "/"
|
|
5
|
-
schedule:
|
|
6
|
-
interval: "daily"
|
|
7
|
-
time: "04:00"
|
|
8
|
-
timezone: "Europe/Paris"
|
|
9
|
-
open-pull-requests-limit: 20
|
|
10
|
-
rebase-strategy: "auto"
|
|
11
|
-
versioning-strategy: "increase-if-necessary"
|
|
12
|
-
# Exclude metric/analytics packages from version update PRs.
|
|
13
|
-
ignore:
|
|
14
|
-
- dependency-name: "*metrics*"
|
|
15
|
-
- dependency-name: "*analytics*"
|
|
16
|
-
groups:
|
|
17
|
-
patch-and-minor:
|
|
18
|
-
patterns:
|
|
19
|
-
- "*"
|
|
20
|
-
update-types:
|
|
21
|
-
- "minor"
|
|
22
|
-
- "patch"
|
|
23
|
-
major:
|
|
24
|
-
patterns:
|
|
25
|
-
- "*"
|
|
26
|
-
update-types:
|
|
27
|
-
- "major"
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
## Summary
|
|
2
|
-
|
|
3
|
-
Describe what changed and why.
|
|
4
|
-
|
|
5
|
-
## Type of change
|
|
6
|
-
|
|
7
|
-
- [ ] Bug fix
|
|
8
|
-
- [ ] New feature
|
|
9
|
-
- [ ] Breaking change
|
|
10
|
-
- [ ] Documentation update
|
|
11
|
-
- [ ] Refactor
|
|
12
|
-
|
|
13
|
-
## Validation
|
|
14
|
-
|
|
15
|
-
- [ ] I ran bun format
|
|
16
|
-
- [ ] I ran bun check
|
|
17
|
-
- [ ] I tested the changed behavior locally
|
|
18
|
-
|
|
19
|
-
## Notes for reviewers
|
|
20
|
-
|
|
21
|
-
Include anything reviewers should focus on (tradeoffs, edge cases, risks).
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
name: Auto Create Pull Request
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
create-pull-request:
|
|
9
|
-
if: github.ref != 'refs/heads/main'
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
steps:
|
|
12
|
-
- name: Validate pull request token
|
|
13
|
-
env:
|
|
14
|
-
AUTO_PR_TOKEN: ${{ secrets.AUTO_PR_TOKEN }}
|
|
15
|
-
run: |
|
|
16
|
-
if [ -z "$AUTO_PR_TOKEN" ]; then
|
|
17
|
-
echo "AUTO_PR_TOKEN is required to create pull requests from GitHub Actions. Use a PAT or GitHub App token with contents:write and pull-requests:write."
|
|
18
|
-
exit 1
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
- name: Create pull request if none exists
|
|
22
|
-
uses: actions/github-script@v8
|
|
23
|
-
with:
|
|
24
|
-
github-token: ${{ secrets.AUTO_PR_TOKEN }}
|
|
25
|
-
script: |
|
|
26
|
-
const owner = context.repo.owner;
|
|
27
|
-
const repo = context.repo.repo;
|
|
28
|
-
const sourceBranch = context.ref.startsWith('refs/heads/')
|
|
29
|
-
? context.ref.slice('refs/heads/'.length)
|
|
30
|
-
: context.ref;
|
|
31
|
-
const head = `${owner}:${sourceBranch}`;
|
|
32
|
-
const base = 'main';
|
|
33
|
-
|
|
34
|
-
// Check if there are commits between main and the current branch
|
|
35
|
-
const { data: comparison } = await github.rest.repos.compareCommits({
|
|
36
|
-
owner,
|
|
37
|
-
repo,
|
|
38
|
-
base: 'main',
|
|
39
|
-
head: sourceBranch,
|
|
40
|
-
}).catch(err => {
|
|
41
|
-
if (err.status === 404 && err.message.includes('No commits')) {
|
|
42
|
-
core.info('No commits between main and ' + sourceBranch + ' - skipping PR creation');
|
|
43
|
-
return { data: { ahead_by: 0 } };
|
|
44
|
-
}
|
|
45
|
-
throw err;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
if (comparison.ahead_by === 0) {
|
|
49
|
-
core.info('Branches are identical - no pull request needed');
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const { data: existingPullRequests } = await github.rest.pulls.list({
|
|
54
|
-
owner,
|
|
55
|
-
repo,
|
|
56
|
-
state: 'open',
|
|
57
|
-
head,
|
|
58
|
-
base,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
if (existingPullRequests.length > 0) {
|
|
62
|
-
core.info(`Pull request already exists: #${existingPullRequests[0].number}`);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const { data: pullRequest } = await github.rest.pulls.create({
|
|
67
|
-
owner,
|
|
68
|
-
repo,
|
|
69
|
-
head: sourceBranch,
|
|
70
|
-
base,
|
|
71
|
-
title: `chore: auto PR from ${sourceBranch} to main`,
|
|
72
|
-
body: [
|
|
73
|
-
'This pull request was created automatically by GitHub Actions.',
|
|
74
|
-
'',
|
|
75
|
-
`- source branch: \`${sourceBranch}\``,
|
|
76
|
-
`- target branch: \`main\``,
|
|
77
|
-
`- triggered by commit \`${context.sha}\``,
|
|
78
|
-
].join('\n'),
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
core.info(`Created pull request #${pullRequest.number}: ${pullRequest.html_url}`);
|
|
82
|
-
|
|
83
|
-
permissions:
|
|
84
|
-
contents: write
|
|
85
|
-
pull-requests: write
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
name: Publish Package
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*'
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
id-token: write # Required for OIDC
|
|
11
|
-
contents: read
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
publish:
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
steps:
|
|
17
|
-
- uses: actions/checkout@v6
|
|
18
|
-
|
|
19
|
-
- uses: actions/setup-node@v6
|
|
20
|
-
with:
|
|
21
|
-
node-version: '24'
|
|
22
|
-
registry-url: 'https://registry.npmjs.org'
|
|
23
|
-
- run: npm install
|
|
24
|
-
- run: npm run build --if-present
|
|
25
|
-
- run: npm publish
|