@kzheart_/mc-pilot 0.1.0

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 (99) hide show
  1. package/bin/mct +2 -0
  2. package/data/variants.json +139 -0
  3. package/dist/client/ClientManager.d.ts +82 -0
  4. package/dist/client/ClientManager.js +213 -0
  5. package/dist/client/WebSocketClient.d.ts +15 -0
  6. package/dist/client/WebSocketClient.js +76 -0
  7. package/dist/commands/block.d.ts +2 -0
  8. package/dist/commands/block.js +52 -0
  9. package/dist/commands/book.d.ts +2 -0
  10. package/dist/commands/book.js +21 -0
  11. package/dist/commands/channel.d.ts +2 -0
  12. package/dist/commands/channel.js +24 -0
  13. package/dist/commands/chat.d.ts +2 -0
  14. package/dist/commands/chat.js +31 -0
  15. package/dist/commands/client.d.ts +2 -0
  16. package/dist/commands/client.js +87 -0
  17. package/dist/commands/combat.d.ts +2 -0
  18. package/dist/commands/combat.js +46 -0
  19. package/dist/commands/craft.d.ts +5 -0
  20. package/dist/commands/craft.js +45 -0
  21. package/dist/commands/effects.d.ts +2 -0
  22. package/dist/commands/effects.js +16 -0
  23. package/dist/commands/entity.d.ts +2 -0
  24. package/dist/commands/entity.js +53 -0
  25. package/dist/commands/gui.d.ts +2 -0
  26. package/dist/commands/gui.js +49 -0
  27. package/dist/commands/hud.d.ts +2 -0
  28. package/dist/commands/hud.js +16 -0
  29. package/dist/commands/input.d.ts +2 -0
  30. package/dist/commands/input.js +124 -0
  31. package/dist/commands/inventory.d.ts +2 -0
  32. package/dist/commands/inventory.js +28 -0
  33. package/dist/commands/look.d.ts +2 -0
  34. package/dist/commands/look.js +37 -0
  35. package/dist/commands/move.d.ts +2 -0
  36. package/dist/commands/move.js +50 -0
  37. package/dist/commands/position.d.ts +2 -0
  38. package/dist/commands/position.js +7 -0
  39. package/dist/commands/request-helpers.d.ts +26 -0
  40. package/dist/commands/request-helpers.js +58 -0
  41. package/dist/commands/resourcepack.d.ts +2 -0
  42. package/dist/commands/resourcepack.js +9 -0
  43. package/dist/commands/rotation.d.ts +2 -0
  44. package/dist/commands/rotation.js +7 -0
  45. package/dist/commands/screen.d.ts +2 -0
  46. package/dist/commands/screen.js +7 -0
  47. package/dist/commands/screenshot.d.ts +2 -0
  48. package/dist/commands/screenshot.js +14 -0
  49. package/dist/commands/server.d.ts +2 -0
  50. package/dist/commands/server.js +66 -0
  51. package/dist/commands/sign.d.ts +2 -0
  52. package/dist/commands/sign.js +30 -0
  53. package/dist/commands/status.d.ts +2 -0
  54. package/dist/commands/status.js +17 -0
  55. package/dist/commands/wait.d.ts +2 -0
  56. package/dist/commands/wait.js +23 -0
  57. package/dist/download/CacheManager.d.ts +20 -0
  58. package/dist/download/CacheManager.js +50 -0
  59. package/dist/download/DownloadUtils.d.ts +2 -0
  60. package/dist/download/DownloadUtils.js +23 -0
  61. package/dist/download/JavaDetector.d.ts +7 -0
  62. package/dist/download/JavaDetector.js +31 -0
  63. package/dist/download/ModVariantCatalog.d.ts +10 -0
  64. package/dist/download/ModVariantCatalog.js +52 -0
  65. package/dist/download/SearchCommand.d.ts +29 -0
  66. package/dist/download/SearchCommand.js +37 -0
  67. package/dist/download/VersionMatrix.d.ts +72 -0
  68. package/dist/download/VersionMatrix.js +227 -0
  69. package/dist/download/client/Arm64LwjglPatcher.d.ts +5 -0
  70. package/dist/download/client/Arm64LwjglPatcher.js +153 -0
  71. package/dist/download/client/ClientDownloader.d.ts +42 -0
  72. package/dist/download/client/ClientDownloader.js +233 -0
  73. package/dist/download/client/FabricRuntimeDownloader.d.ts +10 -0
  74. package/dist/download/client/FabricRuntimeDownloader.js +91 -0
  75. package/dist/download/server/ServerDownloader.d.ts +51 -0
  76. package/dist/download/server/ServerDownloader.js +196 -0
  77. package/dist/download/types.d.ts +37 -0
  78. package/dist/download/types.js +1 -0
  79. package/dist/index.d.ts +2 -0
  80. package/dist/index.js +89 -0
  81. package/dist/server/ServerManager.d.ts +63 -0
  82. package/dist/server/ServerManager.js +114 -0
  83. package/dist/util/command.d.ts +10 -0
  84. package/dist/util/command.js +35 -0
  85. package/dist/util/config.d.ts +30 -0
  86. package/dist/util/config.js +59 -0
  87. package/dist/util/context.d.ts +17 -0
  88. package/dist/util/context.js +16 -0
  89. package/dist/util/errors.d.ts +20 -0
  90. package/dist/util/errors.js +37 -0
  91. package/dist/util/net.d.ts +5 -0
  92. package/dist/util/net.js +35 -0
  93. package/dist/util/output.d.ts +4 -0
  94. package/dist/util/output.js +23 -0
  95. package/dist/util/process.d.ts +3 -0
  96. package/dist/util/process.js +32 -0
  97. package/dist/util/state.d.ts +10 -0
  98. package/dist/util/state.js +40 -0
  99. package/package.json +54 -0
@@ -0,0 +1,87 @@
1
+ import { Command } from "commander";
2
+ import { ClientManager } from "../client/ClientManager.js";
3
+ import { downloadClientMod } from "../download/client/ClientDownloader.js";
4
+ import { buildClientSearchResults } from "../download/SearchCommand.js";
5
+ import { createRequestAction } from "./request-helpers.js";
6
+ import { wrapCommand } from "../util/command.js";
7
+ export function createClientCommand() {
8
+ const command = new Command("client").description("Manage Minecraft client");
9
+ command
10
+ .command("search")
11
+ .description("Search available client version and loader combinations")
12
+ .option("--loader <loader>", "Client loader: fabric|forge|neoforge")
13
+ .option("--version <version>", "Minecraft version")
14
+ .action(wrapCommand(async (_context, { options }) => {
15
+ return {
16
+ results: buildClientSearchResults({
17
+ loader: options.loader,
18
+ version: options.version
19
+ })
20
+ };
21
+ }));
22
+ command
23
+ .command("download")
24
+ .description("Download client mod and update config")
25
+ .option("--loader <loader>", "Client loader: fabric|forge|neoforge (default: fabric)")
26
+ .option("--version <version>", "Minecraft version (default: 1.20.4)")
27
+ .option("--dir <path>", "Mod download directory")
28
+ .option("--name <name>", "Client config name (default: \"default\"); use this name with \"client launch\"")
29
+ .option("--ws-port <port>", "WebSocket port for CLI-to-mod communication (default: 25560)", Number)
30
+ .option("--server <address>", "Default server address (e.g. localhost:25565)")
31
+ .option("--instance-dir <path>", "Client instance directory")
32
+ .option("--meta-dir <path>", "Runtime metadata directory")
33
+ .option("--libraries-dir <path>", "Runtime libraries directory")
34
+ .option("--assets-dir <path>", "Runtime assets directory")
35
+ .option("--natives-dir <path>", "Runtime natives directory")
36
+ .action(wrapCommand(async (context, { options }) => {
37
+ return downloadClientMod(context, options);
38
+ }));
39
+ command
40
+ .command("launch")
41
+ .description("Launch a client instance")
42
+ .argument("<name>", "Client name (matches a key in config \"clients\", e.g. \"default\")")
43
+ .option("--version <version>", "Minecraft version")
44
+ .option("--server <address>", "Target server address (e.g. localhost:25565)")
45
+ .option("--account <account>", "Offline username or account identifier")
46
+ .option("--ws-port <port>", "WebSocket port (default: 25560)", Number)
47
+ .option("--headless", "Launch in headless mode (window hidden)")
48
+ .action(wrapCommand(async (context, { args, options }) => {
49
+ const manager = new ClientManager(context);
50
+ return manager.launch({
51
+ name: args[0],
52
+ ...options
53
+ });
54
+ }));
55
+ command
56
+ .command("stop")
57
+ .description("Stop a client instance")
58
+ .argument("<name>", "Client name")
59
+ .action(wrapCommand(async (context, { args }) => {
60
+ const manager = new ClientManager(context);
61
+ return manager.stop(args[0]);
62
+ }));
63
+ command
64
+ .command("list")
65
+ .description("List all client instances and their status")
66
+ .action(wrapCommand(async (context) => {
67
+ const manager = new ClientManager(context);
68
+ return manager.list();
69
+ }));
70
+ command
71
+ .command("wait-ready")
72
+ .description("Wait until client WebSocket is connected")
73
+ .argument("<name>", "Client name")
74
+ .option("--timeout <seconds>", "Timeout in seconds", Number)
75
+ .action(wrapCommand(async (context, { args, options }) => {
76
+ const manager = new ClientManager(context);
77
+ return manager.waitReady(args[0], options.timeout ?? context.config.timeout.clientReady);
78
+ }));
79
+ command
80
+ .command("reconnect")
81
+ .description("Reconnect the client to the server")
82
+ .option("--address <address>", "Target server address (default: from launch config)")
83
+ .action(createRequestAction("client.reconnect", ({ options }) => ({
84
+ address: options.address
85
+ })));
86
+ return command;
87
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createCombatCommand(): Command;
@@ -0,0 +1,46 @@
1
+ import { Command } from "commander";
2
+ import { buildEntityFilter, createRequestAction, withTransportTimeoutBuffer } from "./request-helpers.js";
3
+ export function createCombatCommand() {
4
+ const command = new Command("combat").description("Combat combo operations");
5
+ const combatActionLabels = {
6
+ kill: "Attack target repeatedly until it dies",
7
+ engage: "Approach and attack target once",
8
+ chase: "Chase target without attacking"
9
+ };
10
+ for (const actionName of ["kill", "engage", "chase"]) {
11
+ command
12
+ .command(actionName)
13
+ .description(combatActionLabels[actionName])
14
+ .option("--type <type>", "Entity type (e.g. zombie, skeleton)")
15
+ .option("--name <name>", "Entity custom name")
16
+ .option("--nearest", "Target the nearest matching entity")
17
+ .option("--id <id>", "Entity network ID", Number)
18
+ .option("--max-distance <distance>", "Max search distance in blocks", Number)
19
+ .option("--timeout <seconds>", "Timeout in seconds (default: 30)", Number)
20
+ .action(createRequestAction(`combat.${actionName}`, ({ options }) => ({
21
+ filter: buildEntityFilter(options),
22
+ timeout: options.timeout
23
+ }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : 30, context.config.timeout.default)));
24
+ }
25
+ command
26
+ .command("clear")
27
+ .description("Kill all entities of a type within radius")
28
+ .requiredOption("--type <type>", "Entity type (e.g. zombie)")
29
+ .option("--radius <radius>", "Search radius in blocks (default: 16)", Number)
30
+ .option("--timeout <seconds>", "Timeout in seconds (default: 60)", Number)
31
+ .action(createRequestAction("combat.clear", ({ options }) => ({
32
+ type: options.type,
33
+ radius: options.radius ?? 16,
34
+ timeout: options.timeout
35
+ }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : 60, context.config.timeout.default)));
36
+ command
37
+ .command("pickup")
38
+ .description("Pick up nearby dropped items")
39
+ .option("--radius <radius>", "Pickup radius in blocks (default: 5)", Number)
40
+ .option("--timeout <seconds>", "Timeout in seconds (default: 10)", Number)
41
+ .action(createRequestAction("combat.pickup", ({ options }) => ({
42
+ radius: options.radius ?? 5,
43
+ timeout: options.timeout
44
+ }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : 10, context.config.timeout.default)));
45
+ return command;
46
+ }
@@ -0,0 +1,5 @@
1
+ import { Command } from "commander";
2
+ export declare function createCraftCommand(): Command;
3
+ export declare function createAnvilCommand(): Command;
4
+ export declare function createEnchantCommand(): Command;
5
+ export declare function createTradeCommand(): Command;
@@ -0,0 +1,45 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction, parseJson } from "./request-helpers.js";
3
+ export function createCraftCommand() {
4
+ return new Command("craft")
5
+ .description("Crafting table recipe\n" +
6
+ "Prerequisite: open crafting table with \"block interact <x> <y> <z>\"\n" +
7
+ "Auto-places materials from inventory, crafts, and moves result to inventory.\n" +
8
+ "GUI closes automatically after crafting.")
9
+ .requiredOption("--recipe <json>", "Recipe JSON: 9-slot array in row-major order (top-left to bottom-right).\n" +
10
+ "Use item IDs without namespace (e.g. \"oak_planks\", not \"minecraft:oak_planks\").\n" +
11
+ "Example: '{\"slots\":[\"oak_planks\",\"oak_planks\",null,\"oak_planks\",\"oak_planks\",null,null,null,null]}'")
12
+ .action(createRequestAction("craft.craft", ({ options }) => ({ recipe: parseJson(String(options.recipe), "recipe") })));
13
+ }
14
+ export function createAnvilCommand() {
15
+ return new Command("anvil")
16
+ .description("Anvil rename operation\n" +
17
+ "Prerequisite: open anvil with \"block interact <x> <y> <z>\"\n" +
18
+ "Auto-moves item from inventory slot to anvil, renames it, and moves result back.\n" +
19
+ "GUI closes automatically.")
20
+ .requiredOption("--input-slot <slot>", "Inventory slot of the item to rename (0-8: hotbar, 9-35: main)", Number)
21
+ .requiredOption("--rename <name>", "New item name")
22
+ .action(createRequestAction("craft.anvil", ({ options }) => ({
23
+ inputSlot: options.inputSlot,
24
+ rename: options.rename
25
+ })));
26
+ }
27
+ export function createEnchantCommand() {
28
+ return new Command("enchant")
29
+ .description("Enchanting table operation\n" +
30
+ "Prerequisite: open enchanting table with \"block interact <x> <y> <z>\"\n" +
31
+ "You must first place the item and lapis lazuli manually via \"gui click\".\n" +
32
+ "Use \"gui snapshot\" to inspect slot layout. This command only selects the enchantment option.")
33
+ .requiredOption("--option <index>", "Enchantment option: 0 = top, 1 = middle, 2 = bottom", Number)
34
+ .action(createRequestAction("craft.enchant", ({ options }) => ({ option: options.option })));
35
+ }
36
+ export function createTradeCommand() {
37
+ return new Command("trade")
38
+ .description("Villager trading\n" +
39
+ "Prerequisite: open trade GUI with \"entity interact --nearest --type villager\"\n" +
40
+ "Use \"gui snapshot\" to inspect available trades.\n" +
41
+ "Selects the trade by index, auto-takes the result into inventory.\n" +
42
+ "Requires payment items already in inventory.")
43
+ .requiredOption("--index <index>", "Trade index (0-based)", Number)
44
+ .action(createRequestAction("craft.trade", ({ options }) => ({ index: options.index })));
45
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createEffectsCommand(): Command;
@@ -0,0 +1,16 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction } from "./request-helpers.js";
3
+ export function createEffectsCommand() {
4
+ const command = new Command("effects").description("音效与粒子事件");
5
+ command
6
+ .command("sounds")
7
+ .description("获取音效事件")
8
+ .option("--last <count>", "最近条数", Number)
9
+ .action(createRequestAction("effects.sounds", ({ options }) => ({ last: options.last ?? 10 })));
10
+ command
11
+ .command("particles")
12
+ .description("获取粒子事件")
13
+ .option("--last <count>", "最近条数", Number)
14
+ .action(createRequestAction("effects.particles", ({ options }) => ({ last: options.last ?? 10 })));
15
+ return command;
16
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createEntityCommand(): Command;
@@ -0,0 +1,53 @@
1
+ import { Command } from "commander";
2
+ import { buildEntityFilter, createRequestAction } from "./request-helpers.js";
3
+ export function createEntityCommand() {
4
+ const command = new Command("entity").description("Entity interaction");
5
+ const entityActionLabels = {
6
+ attack: "Attack an entity",
7
+ interact: "Interact with an entity (right-click)",
8
+ mount: "Mount an entity"
9
+ };
10
+ for (const actionName of ["attack", "interact", "mount"]) {
11
+ command
12
+ .command(actionName)
13
+ .description(entityActionLabels[actionName])
14
+ .option("--type <type>", "Entity type (e.g. zombie, villager)")
15
+ .option("--name <name>", "Entity custom name")
16
+ .option("--nearest", "Target the nearest matching entity")
17
+ .option("--id <id>", "Entity network ID", Number)
18
+ .option("--max-distance <distance>", "Max search distance in blocks", Number)
19
+ .action(createRequestAction(`entity.${actionName}`, ({ options }) => ({
20
+ filter: buildEntityFilter(options)
21
+ })));
22
+ }
23
+ command
24
+ .command("list")
25
+ .description("List nearby entities")
26
+ .option("--radius <radius>", "Search radius in blocks (default: 10)", Number)
27
+ .action(createRequestAction("entity.list", ({ options }) => ({ radius: options.radius ?? 10 })));
28
+ command
29
+ .command("info")
30
+ .description("Get detailed entity info")
31
+ .requiredOption("--id <id>", "Entity network ID", Number)
32
+ .action(createRequestAction("entity.info", ({ options }) => ({ id: options.id })));
33
+ command
34
+ .command("dismount")
35
+ .description("Dismount from current vehicle")
36
+ .action(createRequestAction("entity.dismount", () => ({})));
37
+ command
38
+ .command("steer")
39
+ .description("Steer a mounted vehicle (flags can be combined)")
40
+ .option("--forward", "Move forward")
41
+ .option("--back", "Move backward")
42
+ .option("--left", "Turn left")
43
+ .option("--right", "Turn right")
44
+ .option("--jump", "Jump")
45
+ .option("--sneak", "Sneak / dismount")
46
+ .action(createRequestAction("entity.steer", ({ options }) => ({
47
+ forward: options.forward ? 1 : options.back ? -1 : 0,
48
+ sideways: options.left ? 1 : options.right ? -1 : 0,
49
+ jump: Boolean(options.jump),
50
+ sneak: Boolean(options.sneak)
51
+ })));
52
+ return command;
53
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createGuiCommand(): Command;
@@ -0,0 +1,49 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction, parseNumberList, withTransportTimeoutBuffer } from "./request-helpers.js";
3
+ export function createGuiCommand() {
4
+ const command = new Command("gui").description("GUI / container interaction (use \"gui snapshot\" to inspect slot indices and contents)");
5
+ command.command("info").description("Get current GUI info (title, type, slot count)").action(createRequestAction("gui.info", () => ({})));
6
+ command.command("snapshot").description("Get full GUI snapshot with all slot contents").action(createRequestAction("gui.snapshot", () => ({})));
7
+ command
8
+ .command("slot")
9
+ .description("Get a specific GUI slot")
10
+ .argument("<slot>", "Slot index")
11
+ .action(createRequestAction("gui.slot", ({ args }) => ({ slot: Number(args[0]) })));
12
+ command
13
+ .command("click")
14
+ .description("Click a GUI slot")
15
+ .argument("<slot>", "Slot index")
16
+ .option("--button <button>", "Click button: left|right|middle|shift-left|shift-right", "left")
17
+ .option("--key <key>", "Number key 1-9 to quick-move item to that hotbar slot")
18
+ .action(createRequestAction("gui.click", ({ args, options }) => ({
19
+ slot: Number(args[0]),
20
+ button: options.button,
21
+ key: options.key ? Number(options.key) : undefined
22
+ })));
23
+ command
24
+ .command("drag")
25
+ .description("Drag across GUI slots (distribute items)")
26
+ .requiredOption("--slots <slots>", "Comma-separated slot indices, e.g. 1,2,3")
27
+ .requiredOption("--button <button>", "Drag button: left (split evenly) | right (one each)")
28
+ .action(createRequestAction("gui.drag", ({ options }) => ({
29
+ slots: parseNumberList(String(options.slots)),
30
+ button: options.button
31
+ })));
32
+ command.command("close").description("Close the current GUI").action(createRequestAction("gui.close", () => ({})));
33
+ command
34
+ .command("wait-open")
35
+ .description("Wait for a GUI to open")
36
+ .option("--timeout <seconds>", "Timeout in seconds", Number)
37
+ .action(createRequestAction("gui.wait-open", ({ options }) => ({ timeout: options.timeout }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : undefined, context.config.timeout.default)));
38
+ command
39
+ .command("wait-update")
40
+ .description("Wait for the GUI to update")
41
+ .option("--timeout <seconds>", "Timeout in seconds", Number)
42
+ .action(createRequestAction("gui.wait-update", ({ options }) => ({ timeout: options.timeout }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : undefined, context.config.timeout.default)));
43
+ command
44
+ .command("screenshot")
45
+ .description("Take a screenshot of the current GUI")
46
+ .requiredOption("--output <path>", "Output file path")
47
+ .action(createRequestAction("gui.screenshot", ({ options }) => ({ output: options.output })));
48
+ return command;
49
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createHudCommand(): Command;
@@ -0,0 +1,16 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction } from "./request-helpers.js";
3
+ export function createHudCommand() {
4
+ const command = new Command("hud").description("HUD element queries");
5
+ command.command("scoreboard").description("Get sidebar scoreboard").action(createRequestAction("hud.scoreboard", () => ({})));
6
+ command.command("tab").description("Get tab list (player list)").action(createRequestAction("hud.tab", () => ({})));
7
+ command.command("bossbar").description("Get boss bar(s)").action(createRequestAction("hud.bossbar", () => ({})));
8
+ command.command("actionbar").description("Get action bar text").action(createRequestAction("hud.actionbar", () => ({})));
9
+ command.command("title").description("Get current title/subtitle").action(createRequestAction("hud.title", () => ({})));
10
+ command
11
+ .command("nametag")
12
+ .description("Get a player's nametag info")
13
+ .requiredOption("--player <player>", "Player name")
14
+ .action(createRequestAction("hud.nametag", ({ options }) => ({ player: options.player })));
15
+ return command;
16
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createInputCommand(): Command;
@@ -0,0 +1,124 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction, withTransportTimeoutBuffer } from "./request-helpers.js";
3
+ function buildPointerParams(options) {
4
+ const modifiers = options.modifiers
5
+ ? String(options.modifiers)
6
+ .split(",")
7
+ .map((value) => value.trim())
8
+ .filter(Boolean)
9
+ : [];
10
+ return {
11
+ button: options.button ?? "left",
12
+ modifiers
13
+ };
14
+ }
15
+ export function createInputCommand() {
16
+ const command = new Command("input").description("Raw mouse/keyboard input");
17
+ command
18
+ .command("click")
19
+ .description("Click at screen coordinates")
20
+ .argument("<x>", "Screen X", Number)
21
+ .argument("<y>", "Screen Y", Number)
22
+ .option("--button <button>", "Mouse button: left|right|middle", "left")
23
+ .option("--modifiers <modifiers>", "Modifier keys, comma-separated: shift,ctrl,alt")
24
+ .action(createRequestAction("input.click", ({ args, options }) => ({
25
+ x: Number(args[0]),
26
+ y: Number(args[1]),
27
+ ...buildPointerParams(options)
28
+ })));
29
+ command
30
+ .command("double-click")
31
+ .description("Double-click at screen coordinates")
32
+ .argument("<x>", "Screen X", Number)
33
+ .argument("<y>", "Screen Y", Number)
34
+ .option("--button <button>", "Mouse button: left|right|middle", "left")
35
+ .action(createRequestAction("input.double-click", ({ args, options }) => ({
36
+ x: Number(args[0]),
37
+ y: Number(args[1]),
38
+ button: options.button ?? "left"
39
+ })));
40
+ command
41
+ .command("mouse-move")
42
+ .description("Move mouse to screen coordinates")
43
+ .argument("<x>", "Screen X", Number)
44
+ .argument("<y>", "Screen Y", Number)
45
+ .action(createRequestAction("input.mouse-move", ({ args }) => ({
46
+ x: Number(args[0]),
47
+ y: Number(args[1])
48
+ })));
49
+ command
50
+ .command("drag")
51
+ .description("Mouse drag from one position to another")
52
+ .argument("<fromX>", "Start X", Number)
53
+ .argument("<fromY>", "Start Y", Number)
54
+ .argument("<toX>", "End X", Number)
55
+ .argument("<toY>", "End Y", Number)
56
+ .option("--button <button>", "Mouse button: left|right|middle", "left")
57
+ .action(createRequestAction("input.drag", ({ args, options }) => ({
58
+ fromX: Number(args[0]),
59
+ fromY: Number(args[1]),
60
+ toX: Number(args[2]),
61
+ toY: Number(args[3]),
62
+ button: options.button ?? "left"
63
+ })));
64
+ command
65
+ .command("scroll")
66
+ .description("Scroll mouse wheel at coordinates")
67
+ .argument("<x>", "Screen X", Number)
68
+ .argument("<y>", "Screen Y", Number)
69
+ .requiredOption("--delta <delta>", "Scroll amount (positive = up, negative = down)", Number)
70
+ .action(createRequestAction("input.scroll", ({ args, options }) => ({
71
+ x: Number(args[0]),
72
+ y: Number(args[1]),
73
+ delta: Number(options.delta)
74
+ })));
75
+ const keyCommand = command.command("key").description("Keyboard input");
76
+ keyCommand
77
+ .command("press")
78
+ .description("Press and release a key")
79
+ .argument("<key>", "Key name (e.g. w, a, s, d, space, escape, shift, enter, tab, e, f1)")
80
+ .action(createRequestAction("input.key-press", ({ args }) => ({ key: String(args[0]) })));
81
+ keyCommand
82
+ .command("hold")
83
+ .description("Hold a key for a duration")
84
+ .argument("<key>", "Key name")
85
+ .requiredOption("--duration <ms>", "Hold duration in milliseconds", Number)
86
+ .action(createRequestAction("input.key-hold", ({ args, options }) => ({
87
+ key: String(args[0]),
88
+ duration: Number(options.duration)
89
+ }), ({ options }, context) => withTransportTimeoutBuffer(Math.max(Number(options.duration ?? 0) / 1000 + 2, 3), context.config.timeout.default)));
90
+ keyCommand
91
+ .command("down")
92
+ .description("Press a key down (without releasing)")
93
+ .argument("<key>", "Key name")
94
+ .action(createRequestAction("input.key-down", ({ args }) => ({ key: String(args[0]) })));
95
+ keyCommand
96
+ .command("up")
97
+ .description("Release a key")
98
+ .argument("<key>", "Key name")
99
+ .action(createRequestAction("input.key-up", ({ args }) => ({ key: String(args[0]) })));
100
+ keyCommand
101
+ .command("combo")
102
+ .description("Press a key combination in sequence")
103
+ .argument("<keys...>", "Key names")
104
+ .action(createRequestAction("input.key-combo", ({ args }) => ({
105
+ keys: String(args[0])
106
+ .split(",")
107
+ .map((value) => value.trim())
108
+ .filter(Boolean)
109
+ })));
110
+ command
111
+ .command("type")
112
+ .description("Type text into the currently focused field")
113
+ .argument("<text>", "Text to type")
114
+ .action(createRequestAction("input.type", ({ args }) => ({ text: String(args[0]) })));
115
+ command
116
+ .command("mouse-pos")
117
+ .description("Get current mouse position")
118
+ .action(createRequestAction("input.mouse-pos", () => ({})));
119
+ command
120
+ .command("keys-down")
121
+ .description("Get currently held keys")
122
+ .action(createRequestAction("input.keys-down", () => ({})));
123
+ return command;
124
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createInventoryCommand(): Command;
@@ -0,0 +1,28 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction } from "./request-helpers.js";
3
+ export function createInventoryCommand() {
4
+ const command = new Command("inventory").description("Inventory and item operations");
5
+ command.command("get").description("Get full inventory contents").action(createRequestAction("inventory.get", () => ({})));
6
+ command
7
+ .command("slot")
8
+ .description("Get a specific inventory slot")
9
+ .argument("<slot>", "Slot index (0-8: hotbar, 9-35: main inventory)")
10
+ .action(createRequestAction("inventory.slot", ({ args }) => ({ slot: Number(args[0]) })));
11
+ command.command("held").description("Get currently held item").action(createRequestAction("inventory.held", () => ({})));
12
+ command
13
+ .command("hotbar")
14
+ .description("Switch active hotbar slot")
15
+ .argument("<slot>", "Hotbar slot (0-8)")
16
+ .action(createRequestAction("inventory.hotbar", ({ args }) => ({ slot: Number(args[0]) })));
17
+ command
18
+ .command("drop")
19
+ .description("Drop the held item")
20
+ .option("--all", "Drop the entire stack")
21
+ .action(createRequestAction("inventory.drop", ({ options }) => ({ all: Boolean(options.all) })));
22
+ command.command("use").description("Use (right-click) the held item").action(createRequestAction("inventory.use", () => ({})));
23
+ command
24
+ .command("swap-hands")
25
+ .description("Swap main hand and off-hand items")
26
+ .action(createRequestAction("inventory.swap-hands", () => ({})));
27
+ return command;
28
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createLookCommand(): Command;
@@ -0,0 +1,37 @@
1
+ import { Command } from "commander";
2
+ import { buildEntityFilter, createRequestAction } from "./request-helpers.js";
3
+ export function createLookCommand() {
4
+ const command = new Command("look").description("Camera / view direction control");
5
+ command
6
+ .command("at")
7
+ .description("Look at coordinates")
8
+ .argument("<x>", "X coordinate")
9
+ .argument("<y>", "Y coordinate")
10
+ .argument("<z>", "Z coordinate")
11
+ .action(createRequestAction("look.at", ({ args }) => ({
12
+ x: Number(args[0]),
13
+ y: Number(args[1]),
14
+ z: Number(args[2])
15
+ })));
16
+ command
17
+ .command("entity")
18
+ .description("Look at an entity")
19
+ .option("--type <type>", "Entity type (e.g. zombie, villager)")
20
+ .option("--name <name>", "Entity custom name")
21
+ .option("--nearest", "Target the nearest matching entity")
22
+ .option("--id <id>", "Entity network ID", Number)
23
+ .option("--max-distance <distance>", "Max search distance in blocks", Number)
24
+ .action(createRequestAction("look.entity", ({ options }) => ({
25
+ filter: buildEntityFilter(options)
26
+ })));
27
+ command
28
+ .command("set")
29
+ .description("Set camera angle directly")
30
+ .requiredOption("--yaw <yaw>", "Horizontal angle (-180 to 180: 0=south, -90=east, 90=west, ±180=north)", Number)
31
+ .requiredOption("--pitch <pitch>", "Vertical angle (-90=up, 0=horizon, 90=down)", Number)
32
+ .action(createRequestAction("look.set", ({ options }) => ({
33
+ yaw: options.yaw,
34
+ pitch: options.pitch
35
+ })));
36
+ return command;
37
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createMoveCommand(): Command;
@@ -0,0 +1,50 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction, withTransportTimeoutBuffer } from "./request-helpers.js";
3
+ export function createMoveCommand() {
4
+ const command = new Command("move").description("Movement control");
5
+ command
6
+ .command("to")
7
+ .description("Move to coordinates (straight-line walk, may get stuck on obstacles; times out after 30s)")
8
+ .argument("<x>", "X coordinate")
9
+ .argument("<y>", "Y coordinate")
10
+ .argument("<z>", "Z coordinate")
11
+ .action(createRequestAction("move.to", ({ args }) => ({
12
+ x: Number(args[0]),
13
+ y: Number(args[1]),
14
+ z: Number(args[2])
15
+ }), (_payload, context) => withTransportTimeoutBuffer(30, context.config.timeout.default)));
16
+ const directionLabels = { forward: "Move forward", back: "Move backward", left: "Move left", right: "Move right" };
17
+ for (const direction of ["forward", "back", "left", "right"]) {
18
+ command
19
+ .command(direction)
20
+ .description(directionLabels[direction])
21
+ .argument("<blocks>", "Distance in blocks (supports decimals)")
22
+ .action(createRequestAction("move.direction", ({ args }) => ({
23
+ direction,
24
+ blocks: Number(args[0])
25
+ }), ({ args }, context) => {
26
+ const blocks = Math.abs(Number(args[0]));
27
+ const timeout = Math.max(1.5, blocks * 2.0);
28
+ return withTransportTimeoutBuffer(timeout, context.config.timeout.default);
29
+ }));
30
+ }
31
+ command
32
+ .command("jump")
33
+ .description("Jump once")
34
+ .action(createRequestAction("move.jump", () => ({})));
35
+ command
36
+ .command("sneak")
37
+ .description("Toggle sneaking")
38
+ .argument("<state>", "on/off")
39
+ .action(createRequestAction("move.sneak", ({ args }) => ({
40
+ enabled: args[0] === "on"
41
+ })));
42
+ command
43
+ .command("sprint")
44
+ .description("Toggle sprinting")
45
+ .argument("<state>", "on/off")
46
+ .action(createRequestAction("move.sprint", ({ args }) => ({
47
+ enabled: args[0] === "on"
48
+ })));
49
+ return command;
50
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createPositionCommand(): Command;
@@ -0,0 +1,7 @@
1
+ import { Command } from "commander";
2
+ import { createRequestAction } from "./request-helpers.js";
3
+ export function createPositionCommand() {
4
+ const command = new Command("position").description("Position query");
5
+ command.command("get").description("Get current player position (x, y, z)").action(createRequestAction("position.get", () => ({})));
6
+ return command;
7
+ }