cyclops-clientdevbridge-cli 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/dist/artifacts.d.ts +56 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +58 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +348 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/compare.d.ts +27 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +209 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/context.d.ts +25 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +36 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/doctor.d.ts +31 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +234 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/hotswap.d.ts +7 -0
- package/dist/commands/hotswap.d.ts.map +1 -0
- package/dist/commands/hotswap.js +76 -0
- package/dist/commands/hotswap.js.map +1 -0
- package/dist/commands/input.d.ts +53 -0
- package/dist/commands/input.d.ts.map +1 -0
- package/dist/commands/input.js +204 -0
- package/dist/commands/input.js.map +1 -0
- package/dist/commands/inspect.d.ts +19 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +90 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/lifecycle.d.ts +29 -0
- package/dist/commands/lifecycle.d.ts.map +1 -0
- package/dist/commands/lifecycle.js +201 -0
- package/dist/commands/lifecycle.js.map +1 -0
- package/dist/commands/snapshot.d.ts +37 -0
- package/dist/commands/snapshot.d.ts.map +1 -0
- package/dist/commands/snapshot.js +133 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/commands/world.d.ts +27 -0
- package/dist/commands/world.d.ts.map +1 -0
- package/dist/commands/world.js +203 -0
- package/dist/commands/world.js.map +1 -0
- package/dist/detect.d.ts +58 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +185 -0
- package/dist/detect.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +37 -0
- package/dist/errors.js.map +1 -0
- package/dist/hotswap.d.ts +58 -0
- package/dist/hotswap.d.ts.map +1 -0
- package/dist/hotswap.js +284 -0
- package/dist/hotswap.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/initscript.d.ts +49 -0
- package/dist/initscript.d.ts.map +1 -0
- package/dist/initscript.js +202 -0
- package/dist/initscript.js.map +1 -0
- package/dist/java.d.ts +47 -0
- package/dist/java.d.ts.map +1 -0
- package/dist/java.js +114 -0
- package/dist/java.js.map +1 -0
- package/dist/launcher.d.ts +104 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +609 -0
- package/dist/launcher.js.map +1 -0
- package/dist/loopback.d.ts +17 -0
- package/dist/loopback.d.ts.map +1 -0
- package/dist/loopback.js +19 -0
- package/dist/loopback.js.map +1 -0
- package/dist/output.d.ts +21 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +41 -0
- package/dist/output.js.map +1 -0
- package/dist/paths.d.ts +23 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +47 -0
- package/dist/paths.js.map +1 -0
- package/dist/protocol/client.d.ts +35 -0
- package/dist/protocol/client.d.ts.map +1 -0
- package/dist/protocol/client.js +170 -0
- package/dist/protocol/client.js.map +1 -0
- package/dist/protocol/types.d.ts +114 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +38 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/session.d.ts +77 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +79 -0
- package/dist/session.js.map +1 -0
- package/dist/snapshot/model.d.ts +327 -0
- package/dist/snapshot/model.d.ts.map +1 -0
- package/dist/snapshot/model.js +91 -0
- package/dist/snapshot/model.js.map +1 -0
- package/dist/snapshot/outline.d.ts +35 -0
- package/dist/snapshot/outline.d.ts.map +1 -0
- package/dist/snapshot/outline.js +135 -0
- package/dist/snapshot/outline.js.map +1 -0
- package/dist/xvfb.d.ts +30 -0
- package/dist/xvfb.d.ts.map +1 -0
- package/dist/xvfb.js +66 -0
- package/dist/xvfb.js.map +1 -0
- package/package.json +66 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
<a name="v0.1.0"></a>
|
|
5
|
+
## [v0.1.0] - 2026-08-30
|
|
6
|
+
|
|
7
|
+
First release. Everything below arrived together, so the entries name the feature rather than the
|
|
8
|
+
commit that happened to carry it.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
* [Session lifecycle](https://github.com/CyclopsMC/clientdevbridge-cli/commit/458d17823ea1ee2905a0ce1d34acf89a6096986e):
|
|
12
|
+
`start`, `stop`, `status` and `restart`, with detached process groups, stale-session detection,
|
|
13
|
+
and Xvfb started and reaped around the client.
|
|
14
|
+
* [Gradle init-script injection](https://github.com/CyclopsMC/clientdevbridge-cli/commit/458d17823ea1ee2905a0ce1d34acf89a6096986e),
|
|
15
|
+
so a consumer repository needs no edits to be driven.
|
|
16
|
+
* [`screenshot`](https://github.com/CyclopsMC/clientdevbridge-cli/commit/458d17823ea1ee2905a0ce1d34acf89a6096986e),
|
|
17
|
+
which writes a PNG and prints its path; it never emits base64 to stdout.
|
|
18
|
+
* [`logs`](https://github.com/CyclopsMC/clientdevbridge-cli/commit/458d17823ea1ee2905a0ce1d34acf89a6096986e):
|
|
19
|
+
the in-game log, or `gradle.log` with `--gradle`.
|
|
20
|
+
* [`doctor`](https://github.com/CyclopsMC/clientdevbridge-cli/commit/458d17823ea1ee2905a0ce1d34acf89a6096986e),
|
|
21
|
+
which checks Java, the Gradle wrapper, Xvfb, Mesa, the network allowlist, and whether a
|
|
22
|
+
ClientDevBridge build exists for the project's Minecraft version.
|
|
23
|
+
* [Screen inspection and input](https://github.com/CyclopsMC/clientdevbridge-cli/commit/d8f5252618c256f0dbfe0181dba396f866cb5ff6):
|
|
24
|
+
`snapshot`, `find`, `click`, `type`, `key`, `hold-key`, `mouse-move`, `scroll`, `drag`, `tooltip`,
|
|
25
|
+
`open-gui`, `close-screen`, and the `inspect-gui` composite.
|
|
26
|
+
* [World and player control](https://github.com/CyclopsMC/clientdevbridge-cli/commit/d8f5252618c256f0dbfe0181dba396f866cb5ff6):
|
|
27
|
+
`world-reset`, `world-load`, `world-leave`, `world-list`, `command`, `block`, `setblock`, `give`,
|
|
28
|
+
`teleport`, `look`, `inventory`, `eval` and `wait`.
|
|
29
|
+
* [`resize` and `compare`](https://github.com/CyclopsMC/clientdevbridge-cli/commit/d8f5252618c256f0dbfe0181dba396f866cb5ff6),
|
|
30
|
+
with golden images kept per renderer so software rasterisation and a real GPU can each be
|
|
31
|
+
compared strictly.
|
|
32
|
+
* [`hotswap`](https://github.com/CyclopsMC/clientdevbridge-cli/commit/d8f5252618c256f0dbfe0181dba396f866cb5ff6),
|
|
33
|
+
redefining changed classes in a running client over JDWP.
|
|
34
|
+
* [Compatibility tests](https://github.com/CyclopsMC/clientdevbridge-cli/commit/d8f5252618c256f0dbfe0181dba396f866cb5ff6)
|
|
35
|
+
that replay recorded protocol transcripts from every supported mod branch, so a release is
|
|
36
|
+
verified against all of them without booting Minecraft.
|
|
37
|
+
* [Minecraft 26 support](https://github.com/CyclopsMC/clientdevbridge-cli/commit/4d171c2f72d62a3e1c0cfc8034b9bc455b717e4a),
|
|
38
|
+
including running Gradle on a JDK the project accepts rather than whatever `java` is on `PATH`.
|
|
39
|
+
* [Anonymous artifact resolution](https://github.com/CyclopsMC/clientdevbridge-cli/commit/b8e24514c62e9d3264265f9d340fb9d8f839954e):
|
|
40
|
+
the mod is resolved from the static GitHub Pages Maven, so no credentials are needed to launch a
|
|
41
|
+
client.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Cyclops
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# clientdevbridge-cli
|
|
2
|
+
|
|
3
|
+
Launch and drive a Minecraft **dev client** from the shell — for coding agents.
|
|
4
|
+
|
|
5
|
+
Everything is a bash command, so this works identically in a local terminal, in Claude Code on the
|
|
6
|
+
web, and in CI. There is no MCP server and nothing to configure.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install -g cyclops-clientdevbridge-cli # or use npx
|
|
10
|
+
|
|
11
|
+
cd path/to/your/mod
|
|
12
|
+
clientdevbridge doctor # is this machine able to build and launch a client?
|
|
13
|
+
clientdevbridge start # boots the dev client, headless if there is no $DISPLAY
|
|
14
|
+
clientdevbridge status # what is it showing right now?
|
|
15
|
+
clientdevbridge screenshot # prints a PNG path — open it with your agent's file-reading tool
|
|
16
|
+
clientdevbridge stop
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
You do **not** need to modify your mod project. `start` generates
|
|
20
|
+
`.clientdevbridge/init.gradle` and passes it to `./gradlew runClient`, which injects the matching
|
|
21
|
+
[ClientDevBridge](https://github.com/CyclopsMC/ClientDevBridge) mod build and pins the settings that
|
|
22
|
+
make screenshots reproducible.
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
### It runs a real client, and screenshots show what a player would see
|
|
27
|
+
|
|
28
|
+
Not a stub renderer and not a headless simulation: an actual Minecraft client on a virtual display,
|
|
29
|
+
with software OpenGL. Every image below was produced by the commands beside it, on a machine with
|
|
30
|
+
no GPU and no `$DISPLAY`.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
clientdevbridge world-reset
|
|
34
|
+
clientdevbridge setblock 0 4 2 minecraft:crafting_table
|
|
35
|
+
clientdevbridge setblock 2 4 2 minecraft:chest
|
|
36
|
+
clientdevbridge setblock -2 4 2 minecraft:furnace
|
|
37
|
+
clientdevbridge give minecraft:diamond 5
|
|
38
|
+
clientdevbridge teleport 0 5 6 --yaw 180 --pitch 20
|
|
39
|
+
clientdevbridge screenshot --name scene
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
### It reads a GUI structurally, not just visually
|
|
45
|
+
|
|
46
|
+
`inspect-gui` right-clicks a block, waits for the screen, prints the widget tree, and writes a
|
|
47
|
+
screenshot — one command for the thing you actually want.
|
|
48
|
+
|
|
49
|
+
```console
|
|
50
|
+
$ clientdevbridge inspect-gui 0 4 2
|
|
51
|
+
CraftingScreen "Crafting"
|
|
52
|
+
gui 427x240 @ scale 2, window 854x480px, mouse at 213.5,120
|
|
53
|
+
container CraftingMenu at (125,37) 176x166, 46 slots (1 filled)
|
|
54
|
+
slot 14 (empty) @(205,121) hovered
|
|
55
|
+
slot 37 minecraft:diamond x5 @(133,179)
|
|
56
|
+
ImageButton " button Left click to activate" @(130,71 20x18) /root/children[0]
|
|
57
|
+
RecipeBookComponent @(unknown) /root/children[1]
|
|
58
|
+
|
|
59
|
+
/path/to/mod/.clientdevbridge/screenshots/inspect-gui_....png
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
The two halves answer different questions, and **a bug is usually a disagreement between them**.
|
|
65
|
+
The outline says what the game thinks is there; the screenshot says what is drawn. Check them
|
|
66
|
+
against each other: the container is reported at GUI (125,37) 176x166, which is pixels
|
|
67
|
+
(250,74)–(602,406) at scale 2 — where the panel is. The diamonds are at (133,179), bottom-left of
|
|
68
|
+
the inventory grid. Slot 14 is marked hovered, and it is the visibly lightened one.
|
|
69
|
+
|
|
70
|
+
Coordinates are in GUI space and are what you send back:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
clientdevbridge find "button" # locate a widget by label, type or path
|
|
74
|
+
clientdevbridge click --widget "/root/children[0]"
|
|
75
|
+
clientdevbridge tooltip --at 133,179 # read what hovering there would show
|
|
76
|
+
clientdevbridge snapshot --json # the whole tree, for a program to consume
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### It catches rendering regressions
|
|
80
|
+
|
|
81
|
+
`compare` checks a screenshot against a committed golden image and writes a diff you can look at.
|
|
82
|
+
Golden sets are kept per GL renderer, because llvmpipe and a real GPU do not produce identical
|
|
83
|
+
pixels and one tolerance cannot cover both without hiding regressions.
|
|
84
|
+
|
|
85
|
+
```console
|
|
86
|
+
$ clientdevbridge compare scene --update # record
|
|
87
|
+
$ clientdevbridge compare scene # verify
|
|
88
|
+
scene: matches (0 of 409920 pixels differ, 0.000% <= 0.1%).
|
|
89
|
+
|
|
90
|
+
$ clientdevbridge setblock 2 4 2 minecraft:oak_slab # break something
|
|
91
|
+
$ clientdevbridge compare scene
|
|
92
|
+
scene: DIFFERS — 7811 of 409920 pixels, 1.905% > 0.1%.
|
|
93
|
+
/path/to/mod/.clientdevbridge/diffs/scene_..._-diff.png
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+

|
|
97
|
+
|
|
98
|
+
The unchanged scene is ghosted so the change is the only thing you see. `--region` narrows the
|
|
99
|
+
comparison to a rectangle — applied to the golden as well, so it needs no re-record — and
|
|
100
|
+
`--threshold` sets how much drift still counts as a match.
|
|
101
|
+
|
|
102
|
+
Determinism is not luck: `start` pins the GUI scale, disables clouds, particles, entity shadows,
|
|
103
|
+
view bobbing and vsync, fixes the window size, and the test world is a fixed-seed superflat with
|
|
104
|
+
the daylight cycle and weather off. `world-reset` puts the player at a known position every time.
|
|
105
|
+
|
|
106
|
+
### It drives the client
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
clientdevbridge click --at 205,121 # or --widget by text or path
|
|
110
|
+
clientdevbridge type "hello" # into the focused widget
|
|
111
|
+
clientdevbridge key ESCAPE # or 'E', or 'GLFW_KEY_F3'
|
|
112
|
+
clientdevbridge hold-key W --ticks 20 # movement, held through the real key binding
|
|
113
|
+
clientdevbridge drag --from 133,179 --to 205,121
|
|
114
|
+
clientdevbridge scroll --at 200,120 --dy -3
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Input goes through the game's own handlers, so a mod's click logic runs exactly as it would for a
|
|
118
|
+
player. Off-screen coordinates are refused rather than silently doing nothing.
|
|
119
|
+
|
|
120
|
+
### It sets up the world for you
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
clientdevbridge world-reset # fixed-seed creative superflat, player at 0,4,0
|
|
124
|
+
clientdevbridge world-reset --template my-save # or start from a world committed in your repo
|
|
125
|
+
clientdevbridge command "fill -4 4 -4 4 8 4 minecraft:air"
|
|
126
|
+
clientdevbridge block 0 4 2 --json # block, state, properties, block entity NBT
|
|
127
|
+
clientdevbridge inventory
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### It waits on conditions instead of on sleeps
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
clientdevbridge wait --screen CraftingScreen --timeout 5000
|
|
134
|
+
clientdevbridge wait --ticks 20
|
|
135
|
+
clientdevbridge wait --chunk 0,4,0
|
|
136
|
+
clientdevbridge wait --expr "mc.level != null"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Every wait reports the state it actually observed when it times out, so a failure says what was on
|
|
140
|
+
screen rather than only that something did not happen.
|
|
141
|
+
|
|
142
|
+
### It iterates without restarting
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
clientdevbridge hotswap # recompile and redefine changed classes in the running client
|
|
146
|
+
clientdevbridge eval "player.getY()"
|
|
147
|
+
clientdevbridge logs --lines 20 --level warn
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`hotswap` redefines method bodies through JDWP, so the client has to have been started with a
|
|
151
|
+
debug port: `clientdevbridge start --jdwp-port 5005`. Adding or removing a field, a method or a
|
|
152
|
+
superclass cannot be redefined by any JVM — `hotswap` says so and points at `restart`, rather than
|
|
153
|
+
reporting success and leaving you looking at stale code.
|
|
154
|
+
|
|
155
|
+
`eval` is an escape hatch for what no command covers, with `mc`, `player`, `level`, `screen` and
|
|
156
|
+
`server` bound. It is opt-in and localhost-only, like the whole bridge.
|
|
157
|
+
|
|
158
|
+
## Output conventions
|
|
159
|
+
|
|
160
|
+
These exist so an agent reading stdout can act on it without guessing:
|
|
161
|
+
|
|
162
|
+
- **Images are never printed.** `screenshot` writes a file and prints its absolute path on its own
|
|
163
|
+
line. Open that path with your file-reading tool.
|
|
164
|
+
- Default output is readable text. `--json` prints the raw protocol result instead.
|
|
165
|
+
- Exit codes: `0` success, `1` a protocol-level failure (bad arguments, a method that refused),
|
|
166
|
+
`2` a session or connection failure (nothing running, port taken, client gone).
|
|
167
|
+
|
|
168
|
+
## Session state
|
|
169
|
+
|
|
170
|
+
A session lives in `<project>/.clientdevbridge/`:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
session.json port, pid, loader, Minecraft version, when it started
|
|
174
|
+
gradle.log the client's stdout and stderr
|
|
175
|
+
screenshots/ PNG output
|
|
176
|
+
golden/ committed golden images — this one is meant to be checked in
|
|
177
|
+
init.gradle regenerated on every start
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`start` detaches the client into its own process group, so it outlives the CLI invocation that
|
|
181
|
+
created it; `stop` kills the whole group. Every command detects a stale `session.json` — a
|
|
182
|
+
reclaimed cloud VM, a crash, a reboot — and says "not running" cleanly instead of hanging.
|
|
183
|
+
|
|
184
|
+
## Headless
|
|
185
|
+
|
|
186
|
+
On Linux with no `$DISPLAY`, `start` wraps the launch in `xvfb-run` and forces Mesa's llvmpipe
|
|
187
|
+
software rasteriser. This is a **real client on a virtual display**, not a client that skips
|
|
188
|
+
rendering, so screenshots show exactly what a player would see. Everywhere else, and with
|
|
189
|
+
`--headed`, a normal window opens. Nothing else about the CLI's behaviour differs.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
sudo apt-get install -y xvfb libgl1-mesa-dri
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`clientdevbridge doctor` checks for all of this and prints the exact command to fix whatever is
|
|
196
|
+
missing.
|
|
197
|
+
|
|
198
|
+
## Minecraft versions
|
|
199
|
+
|
|
200
|
+
This package is **version-agnostic and single-branch**. The wire protocol is identical on every
|
|
201
|
+
ClientDevBridge branch, so one CLI release drives every supported Minecraft version. The only
|
|
202
|
+
version knowledge it holds is which branch publishes builds for which Minecraft version, in
|
|
203
|
+
`src/artifacts.ts` — today the 1.21, 26 LTS and 26 lines. That file is the authority rather than
|
|
204
|
+
this paragraph, and `clientdevbridge doctor` prints which branch it picked for the project in
|
|
205
|
+
front of you, so neither has to be trusted from memory.
|
|
206
|
+
|
|
207
|
+
## Development
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npm install
|
|
211
|
+
npm test # unit tests and recorded-transcript replay; no Minecraft needed
|
|
212
|
+
npm run build
|
|
213
|
+
npm run lint
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`scripts/record-fixture.mjs` records a handshake and transcript from a running client into
|
|
217
|
+
`test/fixtures/transcripts/`, which is how a CLI release is verified against every branch without
|
|
218
|
+
booting the game.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's only version-aware logic (plan §4).
|
|
3
|
+
*
|
|
4
|
+
* The wire protocol is identical on every branch, so one CLI release drives every supported
|
|
5
|
+
* Minecraft version. The single thing it has to know is which ClientDevBridge branch publishes
|
|
6
|
+
* artifacts for a given Minecraft version.
|
|
7
|
+
*
|
|
8
|
+
* ClientDevBridge follows the Cyclops artifact convention — `cyclopscore-<mc>-<loader>`,
|
|
9
|
+
* `flopper-<mc>-<loader>` — so artifacts are named `clientdevbridge-<mc>-<loader>`. Each entry
|
|
10
|
+
* below therefore records the exact Minecraft versions a branch builds against.
|
|
11
|
+
*/
|
|
12
|
+
export interface ArtifactLine {
|
|
13
|
+
/** The ClientDevBridge branch that publishes this line. */
|
|
14
|
+
readonly branch: string;
|
|
15
|
+
/** Minecraft versions this branch supports, most-preferred first. */
|
|
16
|
+
readonly minecraftVersions: readonly string[];
|
|
17
|
+
/** Matches Minecraft versions this branch also covers, for point releases published later. */
|
|
18
|
+
readonly matches: RegExp;
|
|
19
|
+
}
|
|
20
|
+
export declare const GROUP = "org.cyclops.clientdevbridge";
|
|
21
|
+
/**
|
|
22
|
+
* Where the mod builds are published.
|
|
23
|
+
*
|
|
24
|
+
* A static Maven repository served by GitHub Pages out of CyclopsMC/ClientDevBridge-Releases. It
|
|
25
|
+
* is deliberately not the CyclopsMC GitHub Packages Maven that the rest of the Cyclops artifacts
|
|
26
|
+
* live in: GitHub Packages requires a token even for public packages, so every mod developer would
|
|
27
|
+
* have to set credentials up before they could launch a client. This one is anonymous, which is
|
|
28
|
+
* what lets a consumer repository need no setup at all.
|
|
29
|
+
*
|
|
30
|
+
* `CLIENTDEVBRIDGE_MAVEN_URL` overrides it, for a fork, a mirror, or a local server.
|
|
31
|
+
*/
|
|
32
|
+
export declare const RELEASES_MAVEN_URL = "https://cyclopsmc.github.io/ClientDevBridge-Releases";
|
|
33
|
+
export declare function releasesMavenUrl(): string;
|
|
34
|
+
export declare const ARTIFACT_LINES: readonly ArtifactLine[];
|
|
35
|
+
export declare function findLine(minecraftVersion: string): ArtifactLine | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The Maven coordinate of the bridge build a consumer on this Minecraft version needs.
|
|
38
|
+
*
|
|
39
|
+
* The artifact id embeds the Minecraft version rather than the branch name, matching how
|
|
40
|
+
* CyclopsCore and Flopper name theirs.
|
|
41
|
+
*/
|
|
42
|
+
export declare function artifactId(minecraftVersion: string, loader: string): string;
|
|
43
|
+
export declare function coordinate(minecraftVersion: string, loader: string, version: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Explains, in the terms the user can act on, that no branch covers their Minecraft version.
|
|
46
|
+
*/
|
|
47
|
+
export declare function unsupportedMessage(minecraftVersion: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* The Groovy engine that powers `eval` and `wait --expr`.
|
|
50
|
+
*
|
|
51
|
+
* The mod reaches it through `javax.script`, so it is genuinely optional — but the Cyclops
|
|
52
|
+
* publishing convention emits artifact-only POMs, so nothing declares it transitively and the
|
|
53
|
+
* init script has to add it alongside the bridge itself.
|
|
54
|
+
*/
|
|
55
|
+
export declare const GROOVY_DEPENDENCY = "org.apache.groovy:groovy-jsr223:4.0.22";
|
|
56
|
+
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../src/artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,KAAK,gCAAgC,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,yDAAyD,CAAC;AAEzF,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAID,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAIjD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAI3E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,UAAU,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAUnE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,2CAA2C,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const GROUP = 'org.cyclops.clientdevbridge';
|
|
2
|
+
/**
|
|
3
|
+
* Where the mod builds are published.
|
|
4
|
+
*
|
|
5
|
+
* A static Maven repository served by GitHub Pages out of CyclopsMC/ClientDevBridge-Releases. It
|
|
6
|
+
* is deliberately not the CyclopsMC GitHub Packages Maven that the rest of the Cyclops artifacts
|
|
7
|
+
* live in: GitHub Packages requires a token even for public packages, so every mod developer would
|
|
8
|
+
* have to set credentials up before they could launch a client. This one is anonymous, which is
|
|
9
|
+
* what lets a consumer repository need no setup at all.
|
|
10
|
+
*
|
|
11
|
+
* `CLIENTDEVBRIDGE_MAVEN_URL` overrides it, for a fork, a mirror, or a local server.
|
|
12
|
+
*/
|
|
13
|
+
export const RELEASES_MAVEN_URL = 'https://cyclopsmc.github.io/ClientDevBridge-Releases';
|
|
14
|
+
export function releasesMavenUrl() {
|
|
15
|
+
const override = process.env['CLIENTDEVBRIDGE_MAVEN_URL'];
|
|
16
|
+
return override === undefined || override.length === 0 ? RELEASES_MAVEN_URL : override;
|
|
17
|
+
}
|
|
18
|
+
// Order matters: the first matching line wins, so the LTS lines are listed before the trunk one.
|
|
19
|
+
// The LTS branch tracks a specific point release (26.1.x); the trunk branch is everything newer.
|
|
20
|
+
export const ARTIFACT_LINES = [
|
|
21
|
+
{ branch: 'master-1.21-lts', minecraftVersions: ['1.21.1'], matches: /^1\.21(\.1)?$/ },
|
|
22
|
+
{ branch: 'master-26-lts', minecraftVersions: ['26.1.2'], matches: /^26\.1(\.\d+)?$/ },
|
|
23
|
+
{ branch: 'master-26', minecraftVersions: ['26.2'], matches: /^26\./ },
|
|
24
|
+
];
|
|
25
|
+
export function findLine(minecraftVersion) {
|
|
26
|
+
return ARTIFACT_LINES.find((line) => line.minecraftVersions.includes(minecraftVersion) || line.matches.test(minecraftVersion));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The Maven coordinate of the bridge build a consumer on this Minecraft version needs.
|
|
30
|
+
*
|
|
31
|
+
* The artifact id embeds the Minecraft version rather than the branch name, matching how
|
|
32
|
+
* CyclopsCore and Flopper name theirs.
|
|
33
|
+
*/
|
|
34
|
+
export function artifactId(minecraftVersion, loader) {
|
|
35
|
+
return `clientdevbridge-${minecraftVersion}-${loader}`;
|
|
36
|
+
}
|
|
37
|
+
export function coordinate(minecraftVersion, loader, version) {
|
|
38
|
+
return `${GROUP}:${artifactId(minecraftVersion, loader)}:${version}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Explains, in the terms the user can act on, that no branch covers their Minecraft version.
|
|
42
|
+
*/
|
|
43
|
+
export function unsupportedMessage(minecraftVersion) {
|
|
44
|
+
const supported = ARTIFACT_LINES.map((line) => `${line.branch} (${line.minecraftVersions.join(', ') || 'no released versions yet'})`).join('\n ');
|
|
45
|
+
return (`No ClientDevBridge build is mapped to Minecraft ${minecraftVersion}.\n` +
|
|
46
|
+
`Known branches:\n ${supported}\n` +
|
|
47
|
+
'Pass --clientdevbridge-version to pin a build explicitly, or publish one with ' +
|
|
48
|
+
"'./gradlew publishToMavenLocal' in a ClientDevBridge checkout on the matching branch.");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The Groovy engine that powers `eval` and `wait --expr`.
|
|
52
|
+
*
|
|
53
|
+
* The mod reaches it through `javax.script`, so it is genuinely optional — but the Cyclops
|
|
54
|
+
* publishing convention emits artifact-only POMs, so nothing declares it transitively and the
|
|
55
|
+
* init script has to add it alongside the bridge itself.
|
|
56
|
+
*/
|
|
57
|
+
export const GROOVY_DEPENDENCY = 'org.apache.groovy:groovy-jsr223:4.0.22';
|
|
58
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../src/artifacts.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,MAAM,KAAK,GAAG,6BAA6B,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,sDAAsD,CAAC;AAEzF,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC1D,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC;AACzF,CAAC;AAED,iGAAiG;AACjG,iGAAiG;AACjG,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE;IACtF,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE;IACtF,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE;CACvE,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,gBAAwB;IAC/C,OAAO,cAAc,CAAC,IAAI,CACxB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CACnG,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,gBAAwB,EAAE,MAAc;IACjE,OAAO,mBAAmB,gBAAgB,IAAI,MAAM,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,gBAAwB,EAAE,MAAc,EAAE,OAAe;IAClF,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,gBAAwB;IACzD,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAClC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,GAAG,CAChG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACf,OAAO,CACL,mDAAmD,gBAAgB,KAAK;QACxE,sBAAsB,SAAS,IAAI;QACnC,gFAAgF;QAChF,uFAAuF,CACxF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,wCAAwC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|