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.
Files changed (112) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.md +218 -0
  4. package/dist/artifacts.d.ts +56 -0
  5. package/dist/artifacts.d.ts.map +1 -0
  6. package/dist/artifacts.js +58 -0
  7. package/dist/artifacts.js.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +348 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/compare.d.ts +27 -0
  13. package/dist/commands/compare.d.ts.map +1 -0
  14. package/dist/commands/compare.js +209 -0
  15. package/dist/commands/compare.js.map +1 -0
  16. package/dist/commands/context.d.ts +25 -0
  17. package/dist/commands/context.d.ts.map +1 -0
  18. package/dist/commands/context.js +36 -0
  19. package/dist/commands/context.js.map +1 -0
  20. package/dist/commands/doctor.d.ts +31 -0
  21. package/dist/commands/doctor.d.ts.map +1 -0
  22. package/dist/commands/doctor.js +234 -0
  23. package/dist/commands/doctor.js.map +1 -0
  24. package/dist/commands/hotswap.d.ts +7 -0
  25. package/dist/commands/hotswap.d.ts.map +1 -0
  26. package/dist/commands/hotswap.js +76 -0
  27. package/dist/commands/hotswap.js.map +1 -0
  28. package/dist/commands/input.d.ts +53 -0
  29. package/dist/commands/input.d.ts.map +1 -0
  30. package/dist/commands/input.js +204 -0
  31. package/dist/commands/input.js.map +1 -0
  32. package/dist/commands/inspect.d.ts +19 -0
  33. package/dist/commands/inspect.d.ts.map +1 -0
  34. package/dist/commands/inspect.js +90 -0
  35. package/dist/commands/inspect.js.map +1 -0
  36. package/dist/commands/lifecycle.d.ts +29 -0
  37. package/dist/commands/lifecycle.d.ts.map +1 -0
  38. package/dist/commands/lifecycle.js +201 -0
  39. package/dist/commands/lifecycle.js.map +1 -0
  40. package/dist/commands/snapshot.d.ts +37 -0
  41. package/dist/commands/snapshot.d.ts.map +1 -0
  42. package/dist/commands/snapshot.js +133 -0
  43. package/dist/commands/snapshot.js.map +1 -0
  44. package/dist/commands/world.d.ts +27 -0
  45. package/dist/commands/world.d.ts.map +1 -0
  46. package/dist/commands/world.js +203 -0
  47. package/dist/commands/world.js.map +1 -0
  48. package/dist/detect.d.ts +58 -0
  49. package/dist/detect.d.ts.map +1 -0
  50. package/dist/detect.js +185 -0
  51. package/dist/detect.js.map +1 -0
  52. package/dist/errors.d.ts +24 -0
  53. package/dist/errors.d.ts.map +1 -0
  54. package/dist/errors.js +37 -0
  55. package/dist/errors.js.map +1 -0
  56. package/dist/hotswap.d.ts +58 -0
  57. package/dist/hotswap.d.ts.map +1 -0
  58. package/dist/hotswap.js +284 -0
  59. package/dist/hotswap.js.map +1 -0
  60. package/dist/index.d.ts +11 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +11 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/initscript.d.ts +49 -0
  65. package/dist/initscript.d.ts.map +1 -0
  66. package/dist/initscript.js +202 -0
  67. package/dist/initscript.js.map +1 -0
  68. package/dist/java.d.ts +47 -0
  69. package/dist/java.d.ts.map +1 -0
  70. package/dist/java.js +114 -0
  71. package/dist/java.js.map +1 -0
  72. package/dist/launcher.d.ts +104 -0
  73. package/dist/launcher.d.ts.map +1 -0
  74. package/dist/launcher.js +609 -0
  75. package/dist/launcher.js.map +1 -0
  76. package/dist/loopback.d.ts +17 -0
  77. package/dist/loopback.d.ts.map +1 -0
  78. package/dist/loopback.js +19 -0
  79. package/dist/loopback.js.map +1 -0
  80. package/dist/output.d.ts +21 -0
  81. package/dist/output.d.ts.map +1 -0
  82. package/dist/output.js +41 -0
  83. package/dist/output.js.map +1 -0
  84. package/dist/paths.d.ts +23 -0
  85. package/dist/paths.d.ts.map +1 -0
  86. package/dist/paths.js +47 -0
  87. package/dist/paths.js.map +1 -0
  88. package/dist/protocol/client.d.ts +35 -0
  89. package/dist/protocol/client.d.ts.map +1 -0
  90. package/dist/protocol/client.js +170 -0
  91. package/dist/protocol/client.js.map +1 -0
  92. package/dist/protocol/types.d.ts +114 -0
  93. package/dist/protocol/types.d.ts.map +1 -0
  94. package/dist/protocol/types.js +38 -0
  95. package/dist/protocol/types.js.map +1 -0
  96. package/dist/session.d.ts +77 -0
  97. package/dist/session.d.ts.map +1 -0
  98. package/dist/session.js +79 -0
  99. package/dist/session.js.map +1 -0
  100. package/dist/snapshot/model.d.ts +327 -0
  101. package/dist/snapshot/model.d.ts.map +1 -0
  102. package/dist/snapshot/model.js +91 -0
  103. package/dist/snapshot/model.js.map +1 -0
  104. package/dist/snapshot/outline.d.ts +35 -0
  105. package/dist/snapshot/outline.d.ts.map +1 -0
  106. package/dist/snapshot/outline.js +135 -0
  107. package/dist/snapshot/outline.js.map +1 -0
  108. package/dist/xvfb.d.ts +30 -0
  109. package/dist/xvfb.d.ts.map +1 -0
  110. package/dist/xvfb.js +66 -0
  111. package/dist/xvfb.js.map +1 -0
  112. package/package.json +66 -0
package/dist/cli.js ADDED
@@ -0,0 +1,348 @@
1
+ #!/usr/bin/env node
2
+ import * as fs from 'node:fs';
3
+ import { Command } from 'commander';
4
+ import { CliError, EXIT_OK, EXIT_PROTOCOL, EXIT_SESSION, ProtocolError } from './errors.js';
5
+ import { runRestart, runStart, runStatus, runStop, START_DEFAULTS } from './commands/lifecycle.js';
6
+ import { runLogs, runScreenshot } from './commands/inspect.js';
7
+ import { runDoctor } from './commands/doctor.js';
8
+ import { runBlock, runCommand, runGive, runInventory, runLook, runSetblock, runTeleport, runWorldLeave, runWorldList, runWorldLoad, runWorldReset, } from './commands/world.js';
9
+ import { runClick, runCloseScreen, runDrag, runEval, runHoldKey, runKey, runMouseMove, runOpenGui, runScroll, runType, runWaitFor, } from './commands/input.js';
10
+ import { runFind, runInspectGui, runSnapshot, runTooltip } from './commands/snapshot.js';
11
+ import { runCompare, runResize } from './commands/compare.js';
12
+ import { runHotswap } from './commands/hotswap.js';
13
+ const program = new Command();
14
+ program
15
+ .name('clientdevbridge')
16
+ .description('Launch and drive a Minecraft dev client from the shell, for coding agents.\n' +
17
+ 'Screenshots are written to files and their paths printed; open them with your agent\'s file-reading tool.')
18
+ .version('0.1.0')
19
+ .option('-p, --project <dir>', 'the mod project to drive', process.cwd())
20
+ .option('--json', 'print the raw protocol result instead of readable text', false)
21
+ .option('-q, --quiet', 'print only the essential output', false)
22
+ .showHelpAfterError();
23
+ function globals() {
24
+ const options = program.opts();
25
+ const project = String(options['project']);
26
+ // Checked once, here, rather than in each command: a --project that does not exist otherwise
27
+ // reads as "Not running (no session recorded) in /typo", which is true and useless.
28
+ if (!fs.existsSync(project)) {
29
+ throw new CliError(`No such directory: ${project}`, 2, 'Check the path passed to --project.');
30
+ }
31
+ if (!fs.statSync(project).isDirectory()) {
32
+ throw new CliError(`--project must be a directory, but ${project} is a file.`, 2);
33
+ }
34
+ return { project, json: options['json'], quiet: options['quiet'] };
35
+ }
36
+ program
37
+ .command('start')
38
+ .description('launch the dev client and wait until it answers')
39
+ .option('--loader <loader>', 'fabric or neoforge (default: detected from the applied Gradle plugins)')
40
+ .option('--mc-version <version>', "Minecraft version (default: gradle.properties 'minecraft_version')")
41
+ .option('--clientdevbridge-version <version>', 'pin a specific ClientDevBridge mod build')
42
+ .option('--world <name>', 'join this singleplayer world on startup, via --quickPlaySingleplayer')
43
+ .option('--headed', 'use a real window even when $DISPLAY is unset', false)
44
+ .option('--port <port>', 'localhost port for the bridge', START_DEFAULTS.port)
45
+ .option('--timeout <seconds>', 'how long to wait for the client to come up', START_DEFAULTS.timeout)
46
+ .option('--width <px>', 'client window width', START_DEFAULTS.width)
47
+ .option('--height <px>', 'client window height', START_DEFAULTS.height)
48
+ .option('--jdwp-port <port>', 'also open a JDWP debug port, required by hotswap')
49
+ .option('--gradle-args <args>', 'extra arguments to pass to Gradle, space separated')
50
+ .option('--no-eval', 'do not enable the eval escape hatch')
51
+ .option('--no-pin-options', 'do not pin the determinism settings in options.txt')
52
+ .action(async (options) => runStart(globals(), options));
53
+ program
54
+ .command('stop')
55
+ .description('kill the dev client and its whole process group')
56
+ .option('--port <port>', 'the bridge port to check for an orphaned client', START_DEFAULTS.port)
57
+ .action(async (options) => runStop(globals(), options));
58
+ program
59
+ .command('status')
60
+ .description('report whether a client is running, and what it is showing')
61
+ .action(async () => runStatus(globals()));
62
+ program
63
+ .command('restart')
64
+ .description('stop, then start again with the same options')
65
+ .option('--loader <loader>', 'fabric or neoforge')
66
+ .option('--mc-version <version>', 'Minecraft version')
67
+ .option('--clientdevbridge-version <version>', 'pin a specific ClientDevBridge mod build')
68
+ .option('--world <name>', 'join this singleplayer world on startup')
69
+ .option('--headed', 'use a real window even when $DISPLAY is unset', false)
70
+ .option('--port <port>', 'localhost port for the bridge', START_DEFAULTS.port)
71
+ .option('--timeout <seconds>', 'how long to wait for the client to come up', START_DEFAULTS.timeout)
72
+ .option('--width <px>', 'client window width', START_DEFAULTS.width)
73
+ .option('--height <px>', 'client window height', START_DEFAULTS.height)
74
+ .option('--jdwp-port <port>', 'also open a JDWP debug port, required by hotswap')
75
+ .option('--gradle-args <args>', 'extra arguments to pass to Gradle, space separated')
76
+ .option('--no-eval', 'do not enable the eval escape hatch')
77
+ .option('--no-pin-options', 'do not pin the determinism settings in options.txt')
78
+ .action(async (options) => runRestart(globals(), options));
79
+ program
80
+ .command('screenshot')
81
+ .description('capture the framebuffer to a PNG and print its path')
82
+ .option('--name <name>', 'file name to write (default: a timestamp)')
83
+ .option('--region <x,y,w,h>', 'capture only this rectangle')
84
+ .option('--space <space>', 'coordinate space for --region: gui or pixel', 'gui')
85
+ .option('--scale <factor>', 'rescale the captured image')
86
+ .option('--after-ticks <n>', 'wait this many client ticks before capturing')
87
+ .action(async (options) => runScreenshot(globals(), options));
88
+ program
89
+ .command('logs')
90
+ .description("show the game's recent log lines, or Gradle's with --gradle")
91
+ .option('-n, --lines <n>', 'how many lines to show', '200')
92
+ .option('--filter <regex>', 'only lines matching this regular expression')
93
+ .option('--level <level>', 'lowest severity to show: trace, debug, info, warn, error, fatal', 'info')
94
+ .option('--gradle', 'read .clientdevbridge/gradle.log instead of the in-game log', false)
95
+ .action(async (options) => runLogs(globals(), options));
96
+ program
97
+ .command('wait')
98
+ .description('wait for ticks to pass, or for the game to reach a state')
99
+ .option('--ticks <n>', 'wait this many client ticks')
100
+ .option('--screen <name>', 'wait until this screen is open (simple or fully-qualified class name)')
101
+ .option('--expr <groovy>', 'wait until this expression is true')
102
+ .option('--chunk <x,y,z>', 'wait until the chunk containing this block is loaded')
103
+ .option('--in-world', 'wait until a world is joined', false)
104
+ .option('--timeout <ms>', 'give up after this many milliseconds', '10000')
105
+ .action(async (options) => runWaitFor(globals(), options));
106
+ program
107
+ .command('snapshot')
108
+ .description('print the widget tree of the open screen as an outline')
109
+ .option('--include-hidden', 'also list invisible widgets and pure decorations', false)
110
+ .option('--max-depth <n>', 'stop descending past this depth')
111
+ .action(async (options) => runSnapshot(globals(), options));
112
+ program
113
+ .command('find <text>')
114
+ .description('find widgets by label, type or path, and print where to click them')
115
+ .option('--type <type>', 'only widgets whose class name contains this')
116
+ .action(async (text, options) => runFind(globals(), text, options));
117
+ program
118
+ .command('click')
119
+ .description('click a point or a widget')
120
+ .option('--at <x,y>', 'click this point')
121
+ .option('--widget <text-or-path>', 'click the centre of the matching widget')
122
+ .option('--button <n>', '0 left, 1 right, 2 middle', '0')
123
+ .option('--space <space>', 'coordinate space for --at: gui or pixel', 'gui')
124
+ .action(async (options) => runClick(globals(), options));
125
+ program
126
+ .command('type <text>')
127
+ .description('type text into the focused widget')
128
+ .action(async (text) => runType(globals(), text));
129
+ program
130
+ .command('key <key>')
131
+ .description("press a key, e.g. 'E', 'ESCAPE' or 'GLFW_KEY_F3'")
132
+ .option('--action <action>', 'tap, press or release', 'tap')
133
+ .option('--modifiers <bits>', 'GLFW modifier bits: 1 shift, 2 ctrl, 4 alt')
134
+ .action(async (key, options) => runKey(globals(), key, options));
135
+ program
136
+ .command('hold-key <key>')
137
+ .description('hold a bound key down for a number of ticks, for movement')
138
+ .requiredOption('--ticks <n>', 'how many client ticks to hold it')
139
+ .action(async (key, options) => runHoldKey(globals(), key, options));
140
+ program
141
+ .command('mouse-move <at>')
142
+ .description("move the mouse to 'x,y'")
143
+ .option('--space <space>', 'gui or pixel', 'gui')
144
+ .action(async (at, options) => runMouseMove(globals(), at, options));
145
+ program
146
+ .command('scroll')
147
+ .description('scroll at a point')
148
+ .requiredOption('--at <x,y>', 'where to scroll')
149
+ .requiredOption('--dy <amount>', 'vertical scroll amount')
150
+ .option('--dx <amount>', 'horizontal scroll amount', '0')
151
+ .option('--space <space>', 'gui or pixel', 'gui')
152
+ .action(async (options) => runScroll(globals(), options));
153
+ program
154
+ .command('drag')
155
+ .description('press, move and release, for sliders and item dragging')
156
+ .requiredOption('--from <x,y>', 'where the drag starts')
157
+ .requiredOption('--to <x,y>', 'where it ends')
158
+ .option('--button <n>', '0 left, 1 right', '0')
159
+ .option('--steps <n>', 'how many intermediate move events to send', '8')
160
+ .option('--space <space>', 'gui or pixel', 'gui')
161
+ .action(async (options) => runDrag(globals(), options));
162
+ program
163
+ .command('tooltip')
164
+ .description('read the tooltip shown at a point or over a widget')
165
+ .option('--at <x,y>', 'where to hover')
166
+ .option('--widget <text-or-path>', 'hover the matching widget')
167
+ .action(async (options) => runTooltip(globals(), options));
168
+ program
169
+ .command('open-gui <x> <y> <z>')
170
+ .description("right-click a block to open its GUI")
171
+ .option('--no-approach', 'do not teleport the player within reach first')
172
+ .action(async (x, y, z, options) => runOpenGui(globals(), x, y, z, options));
173
+ program
174
+ .command('close-screen')
175
+ .description('close the open screen')
176
+ .action(async () => runCloseScreen(globals()));
177
+ program
178
+ .command('inspect-gui <x> <y> <z>')
179
+ .description('open a block GUI, print its outline, and write a screenshot — the usual starting point')
180
+ .option('--no-approach', 'do not teleport the player within reach first')
181
+ .option('--name <name>', 'screenshot file name')
182
+ .action(async (x, y, z, options) => runInspectGui(globals(), x, y, z, options));
183
+ program
184
+ .command('world-reset')
185
+ .description('delete and recreate the test world: creative superflat, no daylight cycle, no mobs')
186
+ .option('--name <name>', 'world folder name')
187
+ .option('--template <name>', 'copy clientdevbridge/templates/<name> instead of generating one')
188
+ .option('--setup <command>', 'run this command once the world is ready')
189
+ .action(async (options) => runWorldReset(globals(), options));
190
+ program
191
+ .command('world-load <name>')
192
+ .description('load an existing singleplayer world')
193
+ .action(async (name) => runWorldLoad(globals(), name));
194
+ program
195
+ .command('world-leave')
196
+ .description('leave the current world')
197
+ .action(async () => runWorldLeave(globals()));
198
+ program
199
+ .command('world-list')
200
+ .description('list the singleplayer worlds in the run directory')
201
+ .action(async () => runWorldList(globals()));
202
+ program
203
+ .command('command <command>')
204
+ .description('run a Minecraft command on the integrated server and print its output')
205
+ .action(async (command) => runCommand(globals(), command));
206
+ program
207
+ .command('block <x> <y> <z>')
208
+ .description('describe the block at a position')
209
+ .option('--nbt', 'include the block entity NBT the client knows about', false)
210
+ .action(async (x, y, z, options) => runBlock(globals(), x, y, z, options));
211
+ program
212
+ .command('setblock <x> <y> <z> <block>')
213
+ .description('place a block')
214
+ .action(async (x, y, z, block) => runSetblock(globals(), x, y, z, block));
215
+ program
216
+ .command('give <item> [count]')
217
+ .description('give the player an item')
218
+ .action(async (item, count) => runGive(globals(), item, count ?? '1'));
219
+ program
220
+ .command('teleport <x> <y> <z>')
221
+ .description('teleport the player')
222
+ .option('--yaw <degrees>', 'facing yaw')
223
+ .option('--pitch <degrees>', 'facing pitch')
224
+ .action(async (x, y, z, options) => runTeleport(globals(), x, y, z, options));
225
+ program
226
+ .command('look')
227
+ .description('point the camera')
228
+ .option('--at <x,y,z>', 'look at this block position')
229
+ .option('--yaw <degrees>', 'set yaw')
230
+ .option('--pitch <degrees>', 'set pitch')
231
+ .action(async (options) => runLook(globals(), options));
232
+ program
233
+ .command('inventory')
234
+ .description("list the player's inventory")
235
+ .action(async () => runInventory(globals()));
236
+ program
237
+ .command('compare <name>')
238
+ .description('compare a screenshot against a committed golden image')
239
+ .option('--region <x,y,w,h>', 'compare only this rectangle; applied to the golden too, so it needs no re-record')
240
+ .option('--space <space>', 'coordinate space for --region: gui or pixel', 'gui')
241
+ .option('--threshold <pct>', 'percentage of differing pixels still counted as a match', '0.1')
242
+ .option('--pixel-threshold <0-1>', 'per-pixel colour tolerance passed to pixelmatch', '0.1')
243
+ .option('--after-ticks <n>', 'wait this many ticks before capturing')
244
+ .option('--renderer <name>', 'golden set to use, instead of detecting it from GL_RENDERER')
245
+ .option('--update', 'write the current screenshot as the golden image instead of comparing', false)
246
+ .action(async (name, options) => runCompare(globals(), name, options));
247
+ program
248
+ .command('resize')
249
+ .description('set the window size and GUI scale, for reproducible screenshots')
250
+ .requiredOption('--width <px>', 'window width (required)')
251
+ .requiredOption('--height <px>', 'window height (required)')
252
+ .option('--gui-scale <n>', 'fixed GUI scale, or 0 for automatic; --width and --height are still required')
253
+ .action(async (options) => runResize(globals(), options));
254
+ program
255
+ .command('eval <code>')
256
+ .description('evaluate a Groovy expression with mc, player, level, screen and server bound')
257
+ .action(async (code) => runEval(globals(), code));
258
+ program
259
+ .command('hotswap')
260
+ .description('recompile the project and redefine the changed classes in the running client')
261
+ .option('--no-compile', 'skip the Gradle compile and swap whatever is already built')
262
+ .option('--baseline', 'record the current classes as the baseline without swapping', false)
263
+ .action(async (options) => runHotswap(globals(), options));
264
+ program
265
+ .command('doctor')
266
+ .description('check that this machine can build and launch a dev client')
267
+ .option('--loader <loader>', 'check for this loader specifically: fabric or neoforge')
268
+ .option('--no-network', 'skip the network reachability probes')
269
+ .action(async (options) => {
270
+ const code = await runDoctor(globals(), options);
271
+ process.exitCode = code;
272
+ });
273
+ /**
274
+ * Piping into `head` or `grep -q` closes stdout while the CLI is still writing, and Node turns
275
+ * that into a fatal EPIPE. Since piping is exactly how an agent reads this output, a broken pipe
276
+ * has to mean "the reader has what it needs", not a crash.
277
+ */
278
+ function ignoreBrokenPipe() {
279
+ for (const stream of [process.stdout, process.stderr]) {
280
+ stream.on('error', (error) => {
281
+ if (error.code === 'EPIPE') {
282
+ process.exit(process.exitCode ?? EXIT_OK);
283
+ }
284
+ throw error;
285
+ });
286
+ }
287
+ }
288
+ /**
289
+ * Marker that hides a negative number from commander's option parser.
290
+ *
291
+ * Minecraft coordinates are routinely negative, and `teleport -10 5 -10` was rejected with
292
+ * "unknown option '-10'". `--` is not a usable answer: it has to come before every operand, so it
293
+ * would swallow the command's own flags too, and no reasonable caller thinks to write it. Nothing
294
+ * in this CLI takes a numeric option name, so a token that looks like a negative number is one.
295
+ */
296
+ const NEGATIVE_NUMBER_MARKER = '\u0000';
297
+ function hideNegativeNumbers(argv) {
298
+ return argv.map((arg) => (/^-\d+(\.\d+)?$/.test(arg) ? `${NEGATIVE_NUMBER_MARKER}${arg}` : arg));
299
+ }
300
+ function reveal(value) {
301
+ if (typeof value === 'string' && value.startsWith(NEGATIVE_NUMBER_MARKER)) {
302
+ return value.slice(NEGATIVE_NUMBER_MARKER.length);
303
+ }
304
+ if (Array.isArray(value)) {
305
+ return value.map(reveal);
306
+ }
307
+ return value;
308
+ }
309
+ // Undone in one place, after commander has finished parsing and before any command sees its
310
+ // arguments, so no individual command has to know this happened.
311
+ program.hook('preAction', (_parent, command) => {
312
+ const withArgs = command;
313
+ withArgs.processedArgs = withArgs.processedArgs.map(reveal);
314
+ const options = command.opts();
315
+ for (const [key, value] of Object.entries(options)) {
316
+ options[key] = reveal(value);
317
+ }
318
+ });
319
+ async function main() {
320
+ ignoreBrokenPipe();
321
+ try {
322
+ await program.parseAsync(hideNegativeNumbers(process.argv));
323
+ }
324
+ catch (error) {
325
+ if (error instanceof ProtocolError) {
326
+ process.stderr.write(`error: ${error.message}\n`);
327
+ if (error.hint !== undefined) {
328
+ process.stderr.write(`${error.hint}\n`);
329
+ }
330
+ process.exitCode = EXIT_PROTOCOL;
331
+ return;
332
+ }
333
+ if (error instanceof CliError) {
334
+ process.stderr.write(`error: ${error.message}\n`);
335
+ if (error.hint !== undefined) {
336
+ process.stderr.write(`${error.hint}\n`);
337
+ }
338
+ process.exitCode = error.exitCode;
339
+ return;
340
+ }
341
+ process.stderr.write(`error: ${error.message}\n`);
342
+ process.exitCode = EXIT_SESSION;
343
+ return;
344
+ }
345
+ process.exitCode = process.exitCode ?? EXIT_OK;
346
+ }
347
+ void main();
348
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5F,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EACL,QAAQ,EACR,UAAU,EACV,OAAO,EACP,YAAY,EACZ,OAAO,EACP,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,QAAQ,EACR,cAAc,EACd,OAAO,EACP,OAAO,EACP,UAAU,EACV,MAAM,EACN,YAAY,EACZ,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,iBAAiB,CAAC;KACvB,WAAW,CACV,8EAA8E;IAC5E,2GAA2G,CAC9G;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,qBAAqB,EAAE,0BAA0B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KACxE,MAAM,CAAC,QAAQ,EAAE,wDAAwD,EAAE,KAAK,CAAC;KACjF,MAAM,CAAC,aAAa,EAAE,iCAAiC,EAAE,KAAK,CAAC;KAC/D,kBAAkB,EAAE,CAAC;AAExB,SAAS,OAAO;IACd,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3C,6FAA6F;IAC7F,oFAAoF;IACpF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,QAAQ,CAAC,sBAAsB,OAAO,EAAE,EAAE,CAAC,EAAE,qCAAqC,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,QAAQ,CAAC,sCAAsC,OAAO,aAAa,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;AACrE,CAAC;AAED,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,mBAAmB,EAAE,wEAAwE,CAAC;KACrG,MAAM,CAAC,wBAAwB,EAAE,oEAAoE,CAAC;KACtG,MAAM,CAAC,qCAAqC,EAAE,0CAA0C,CAAC;KACzF,MAAM,CAAC,gBAAgB,EAAE,sEAAsE,CAAC;KAChG,MAAM,CAAC,UAAU,EAAE,+CAA+C,EAAE,KAAK,CAAC;KAC1E,MAAM,CAAC,eAAe,EAAE,+BAA+B,EAAE,cAAc,CAAC,IAAI,CAAC;KAC7E,MAAM,CAAC,qBAAqB,EAAE,4CAA4C,EAAE,cAAc,CAAC,OAAO,CAAC;KACnG,MAAM,CAAC,cAAc,EAAE,qBAAqB,EAAE,cAAc,CAAC,KAAK,CAAC;KACnE,MAAM,CAAC,eAAe,EAAE,sBAAsB,EAAE,cAAc,CAAC,MAAM,CAAC;KACtE,MAAM,CAAC,oBAAoB,EAAE,kDAAkD,CAAC;KAChF,MAAM,CAAC,sBAAsB,EAAE,oDAAoD,CAAC;KACpF,MAAM,CAAC,WAAW,EAAE,qCAAqC,CAAC;KAC1D,MAAM,CAAC,kBAAkB,EAAE,oDAAoD,CAAC;KAChF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,eAAe,EAAE,iDAAiD,EAAE,cAAc,CAAC,IAAI,CAAC;KAC/F,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1D,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAE5C,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACjD,MAAM,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;KACrD,MAAM,CAAC,qCAAqC,EAAE,0CAA0C,CAAC;KACzF,MAAM,CAAC,gBAAgB,EAAE,yCAAyC,CAAC;KACnE,MAAM,CAAC,UAAU,EAAE,+CAA+C,EAAE,KAAK,CAAC;KAC1E,MAAM,CAAC,eAAe,EAAE,+BAA+B,EAAE,cAAc,CAAC,IAAI,CAAC;KAC7E,MAAM,CAAC,qBAAqB,EAAE,4CAA4C,EAAE,cAAc,CAAC,OAAO,CAAC;KACnG,MAAM,CAAC,cAAc,EAAE,qBAAqB,EAAE,cAAc,CAAC,KAAK,CAAC;KACnE,MAAM,CAAC,eAAe,EAAE,sBAAsB,EAAE,cAAc,CAAC,MAAM,CAAC;KACtE,MAAM,CAAC,oBAAoB,EAAE,kDAAkD,CAAC;KAChF,MAAM,CAAC,sBAAsB,EAAE,oDAAoD,CAAC;KACpF,MAAM,CAAC,WAAW,EAAE,qCAAqC,CAAC;KAC1D,MAAM,CAAC,kBAAkB,EAAE,oDAAoD,CAAC;KAChF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7D,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,qDAAqD,CAAC;KAClE,MAAM,CAAC,eAAe,EAAE,2CAA2C,CAAC;KACpE,MAAM,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;KAC3D,MAAM,CAAC,iBAAiB,EAAE,6CAA6C,EAAE,KAAK,CAAC;KAC/E,MAAM,CAAC,kBAAkB,EAAE,4BAA4B,CAAC;KACxD,MAAM,CAAC,mBAAmB,EAAE,8CAA8C,CAAC;KAC3E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhE,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,KAAK,CAAC;KAC1D,MAAM,CAAC,kBAAkB,EAAE,6CAA6C,CAAC;KACzE,MAAM,CAAC,iBAAiB,EAAE,iEAAiE,EAAE,MAAM,CAAC;KACpG,MAAM,CAAC,UAAU,EAAE,6DAA6D,EAAE,KAAK,CAAC;KACxF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1D,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,aAAa,EAAE,6BAA6B,CAAC;KACpD,MAAM,CAAC,iBAAiB,EAAE,uEAAuE,CAAC;KAClG,MAAM,CAAC,iBAAiB,EAAE,oCAAoC,CAAC;KAC/D,MAAM,CAAC,iBAAiB,EAAE,sDAAsD,CAAC;KACjF,MAAM,CAAC,YAAY,EAAE,8BAA8B,EAAE,KAAK,CAAC;KAC3D,MAAM,CAAC,gBAAgB,EAAE,sCAAsC,EAAE,OAAO,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7D,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,kBAAkB,EAAE,kDAAkD,EAAE,KAAK,CAAC;KACrF,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,oEAAoE,CAAC;KACjF,MAAM,CAAC,eAAe,EAAE,6CAA6C,CAAC;KACtE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AAEtE,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC;KACxC,MAAM,CAAC,yBAAyB,EAAE,yCAAyC,CAAC;KAC5E,MAAM,CAAC,cAAc,EAAE,2BAA2B,EAAE,GAAG,CAAC;KACxD,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,EAAE,KAAK,CAAC;KAC3E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;AAEpD,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,KAAK,CAAC;KAC3D,MAAM,CAAC,oBAAoB,EAAE,4CAA4C,CAAC;KAC1E,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnE,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,2DAA2D,CAAC;KACxE,cAAc,CAAC,aAAa,EAAE,kCAAkC,CAAC;KACjE,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvE,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,iBAAiB,EAAE,cAAc,EAAE,KAAK,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvE,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mBAAmB,CAAC;KAChC,cAAc,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC/C,cAAc,CAAC,eAAe,EAAE,wBAAwB,CAAC;KACzD,MAAM,CAAC,eAAe,EAAE,0BAA0B,EAAE,GAAG,CAAC;KACxD,MAAM,CAAC,iBAAiB,EAAE,cAAc,EAAE,KAAK,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5D,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wDAAwD,CAAC;KACrE,cAAc,CAAC,cAAc,EAAE,uBAAuB,CAAC;KACvD,cAAc,CAAC,YAAY,EAAE,eAAe,CAAC;KAC7C,MAAM,CAAC,cAAc,EAAE,iBAAiB,EAAE,GAAG,CAAC;KAC9C,MAAM,CAAC,aAAa,EAAE,2CAA2C,EAAE,GAAG,CAAC;KACvE,MAAM,CAAC,iBAAiB,EAAE,cAAc,EAAE,KAAK,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1D,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC;KACtC,MAAM,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;KAC9D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7D,OAAO;KACJ,OAAO,CAAC,sBAAsB,CAAC;KAC/B,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,eAAe,EAAE,+CAA+C,CAAC;KACxE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAE/E,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAEjD,OAAO;KACJ,OAAO,CAAC,yBAAyB,CAAC;KAClC,WAAW,CAAC,wFAAwF,CAAC;KACrG,MAAM,CAAC,eAAe,EAAE,+CAA+C,CAAC;KACxE,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC;KAC/C,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAElF,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,oFAAoF,CAAC;KACjG,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC;KAC5C,MAAM,CAAC,mBAAmB,EAAE,iEAAiE,CAAC;KAC9F,MAAM,CAAC,mBAAmB,EAAE,0CAA0C,CAAC;KACvE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhE,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;AAEzD,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAEhD,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAE/C,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,uEAAuE,CAAC;KACpF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7D,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,OAAO,EAAE,qDAAqD,EAAE,KAAK,CAAC;KAC7E,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7E,OAAO;KACJ,OAAO,CAAC,8BAA8B,CAAC;KACvC,WAAW,CAAC,eAAe,CAAC;KAC5B,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AAE5E,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC;AAEzE,OAAO;KACJ,OAAO,CAAC,sBAAsB,CAAC;KAC/B,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,iBAAiB,EAAE,YAAY,CAAC;KACvC,MAAM,CAAC,mBAAmB,EAAE,cAAc,CAAC;KAC3C,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kBAAkB,CAAC;KAC/B,MAAM,CAAC,cAAc,EAAE,6BAA6B,CAAC;KACrD,MAAM,CAAC,iBAAiB,EAAE,SAAS,CAAC;KACpC,MAAM,CAAC,mBAAmB,EAAE,WAAW,CAAC;KACxC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1D,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAE/C,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,oBAAoB,EAAE,kFAAkF,CAAC;KAChH,MAAM,CAAC,iBAAiB,EAAE,6CAA6C,EAAE,KAAK,CAAC;KAC/E,MAAM,CAAC,mBAAmB,EAAE,yDAAyD,EAAE,KAAK,CAAC;KAC7F,MAAM,CAAC,yBAAyB,EAAE,iDAAiD,EAAE,KAAK,CAAC;KAC3F,MAAM,CAAC,mBAAmB,EAAE,uCAAuC,CAAC;KACpE,MAAM,CAAC,mBAAmB,EAAE,6DAA6D,CAAC;KAC1F,MAAM,CAAC,UAAU,EAAE,uEAAuE,EAAE,KAAK,CAAC;KAClG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AAEzE,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iEAAiE,CAAC;KAC9E,cAAc,CAAC,cAAc,EAAE,yBAAyB,CAAC;KACzD,cAAc,CAAC,eAAe,EAAE,0BAA0B,CAAC;KAC3D,MAAM,CAAC,iBAAiB,EAAE,8EAA8E,CAAC;KACzG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5D,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,8EAA8E,CAAC;KAC3F,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;AAEpD,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,8EAA8E,CAAC;KAC3F,MAAM,CAAC,cAAc,EAAE,4DAA4D,CAAC;KACpF,MAAM,CAAC,YAAY,EAAE,6DAA6D,EAAE,KAAK,CAAC;KAC1F,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7D,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2DAA2D,CAAC;KACxE,MAAM,CAAC,mBAAmB,EAAE,wDAAwD,CAAC;KACrF,MAAM,CAAC,cAAc,EAAE,sCAAsC,CAAC;KAC9D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL;;;;GAIG;AACH,SAAS,gBAAgB;IACvB,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;YAClD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC3B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,sBAAsB,GAAG,QAAQ,CAAC;AAExC,SAAS,mBAAmB,CAAC,IAAuB;IAClD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,sBAAsB,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4FAA4F;AAC5F,iEAAiE;AACjE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;IAC7C,MAAM,QAAQ,GAAG,OAAkD,CAAC;IACpE,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAA6B,CAAC;IAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI;IACjB,gBAAgB,EAAE,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;YACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YAClD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;YAC1C,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,aAAa,CAAC;YACjC,OAAO;QACT,CAAC;QACD,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YAClD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;YAC1C,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAClC,OAAO;QACT,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAW,KAAe,CAAC,OAAO,IAAI,CAAC,CAAC;QAC7D,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC;QAChC,OAAO;IACT,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC;AACjD,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type GlobalOptions } from './context.js';
2
+ export interface CompareOptions {
3
+ readonly region?: string | undefined;
4
+ readonly space: string;
5
+ readonly threshold: string;
6
+ readonly pixelThreshold: string;
7
+ readonly update: boolean;
8
+ readonly afterTicks?: string | undefined;
9
+ readonly renderer?: string | undefined;
10
+ }
11
+ /**
12
+ * Golden images are keyed by renderer.
13
+ *
14
+ * Software rasterisation and a real GPU do not produce identical pixels — different texture
15
+ * filtering, different rounding — and no single tolerance covers both without also hiding real
16
+ * regressions. Keeping a set per renderer means each one can be compared strictly.
17
+ */
18
+ export declare function goldenPathFor(goldenDir: string, name: string, renderer: string): string;
19
+ /** Normalises a GL_RENDERER string into a short, stable directory name. */
20
+ export declare function rendererKey(raw: string | null | undefined): string;
21
+ export declare function runCompare(global: GlobalOptions, name: string, options: CompareOptions): Promise<void>;
22
+ export declare function runResize(global: GlobalOptions, options: {
23
+ width: string;
24
+ height: string;
25
+ guiScale?: string | undefined;
26
+ }): Promise<void>;
27
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/commands/compare.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,aAAa,EAAc,MAAM,cAAc,CAAC;AAG9D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CASlE;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA0I5G;AAgBD,wBAAsB,SAAS,CAC7B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CAgBf"}
@@ -0,0 +1,209 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { PNG } from 'pngjs';
4
+ import pixelmatch from 'pixelmatch';
5
+ import { CliError } from '../errors.js';
6
+ import { line, printJson, printPath } from '../output.js';
7
+ import { withClient } from './context.js';
8
+ import { parseRegion } from './inspect.js';
9
+ /**
10
+ * Golden images are keyed by renderer.
11
+ *
12
+ * Software rasterisation and a real GPU do not produce identical pixels — different texture
13
+ * filtering, different rounding — and no single tolerance covers both without also hiding real
14
+ * regressions. Keeping a set per renderer means each one can be compared strictly.
15
+ */
16
+ export function goldenPathFor(goldenDir, name, renderer) {
17
+ return path.join(goldenDir, renderer, `${name}.png`);
18
+ }
19
+ /** Normalises a GL_RENDERER string into a short, stable directory name. */
20
+ export function rendererKey(raw) {
21
+ if (raw === null || raw === undefined || raw.length === 0) {
22
+ return 'unknown';
23
+ }
24
+ const lowered = raw.toLowerCase();
25
+ if (lowered.includes('llvmpipe') || lowered.includes('softpipe') || lowered.includes('swrast')) {
26
+ return 'llvmpipe';
27
+ }
28
+ return 'gpu';
29
+ }
30
+ export async function runCompare(global, name, options) {
31
+ await withClient(global, async ({ client, paths }) => {
32
+ // --region deliberately does not reach the screenshot call. It is a comparison-time filter --
33
+ // "ignore everything outside this rectangle" -- and cropping the capture but not the golden is
34
+ // what made it unusable: it always failed with a size mismatch that blamed the window size.
35
+ // Both images are cropped, below, by the same rectangle.
36
+ const params = {};
37
+ const rawRegion = options.region === undefined ? null : parseRegion(options.region, options.space);
38
+ if (options.afterTicks !== undefined) {
39
+ params['afterTicks'] = Number(options.afterTicks);
40
+ }
41
+ const shot = await client.call('screenshot', params);
42
+ const actualPng = Buffer.from(String(shot['png']), 'base64');
43
+ const renderer = options.renderer ?? rendererKey(await readRenderer(client));
44
+ const goldenPath = goldenPathFor(paths.golden, name, renderer);
45
+ if (options.update) {
46
+ // The golden is stored whole even when --region is given, so the same golden can later be
47
+ // compared under any region, or none.
48
+ fs.mkdirSync(path.dirname(goldenPath), { recursive: true });
49
+ fs.writeFileSync(goldenPath, actualPng);
50
+ if (global.json) {
51
+ printJson({ updated: true, golden: goldenPath, renderer });
52
+ return;
53
+ }
54
+ line(`Wrote the golden image for '${name}' (renderer ${renderer}).`);
55
+ printPath(path.resolve(goldenPath));
56
+ return;
57
+ }
58
+ if (!fs.existsSync(goldenPath)) {
59
+ throw new CliError(`There is no golden image for '${name}' at ${goldenPath}.`, 1, `Create it with: clientdevbridge compare ${name} --update`);
60
+ }
61
+ const wholeGolden = PNG.sync.read(fs.readFileSync(goldenPath));
62
+ const wholeActual = PNG.sync.read(actualPng);
63
+ // Both images are in pixels; a region given in GUI space has to be scaled to match, using the
64
+ // scale the client reported with this very screenshot rather than a remembered one.
65
+ const region = rawRegion === null ? null : toPixelRegion(rawRegion, Number(shot['guiScale'] ?? 1));
66
+ if (region !== null) {
67
+ const tooBig = [
68
+ { label: 'golden image', image: wholeGolden },
69
+ { label: 'screenshot', image: wholeActual },
70
+ ].find(({ image }) => region.x + region.width > image.width || region.y + region.height > image.height);
71
+ if (tooBig !== undefined) {
72
+ throw new CliError(`--region ${region.x},${region.y},${region.width},${region.height} does not fit inside the ` +
73
+ `${tooBig.label}, which is ${tooBig.image.width}x${tooBig.image.height}.`, 1, 'Regions are in pixel space unless --space gui is given.');
74
+ }
75
+ }
76
+ const golden = region === null ? wholeGolden : crop(wholeGolden, region);
77
+ const actual = region === null ? wholeActual : crop(wholeActual, region);
78
+ if (golden.width !== actual.width || golden.height !== actual.height) {
79
+ const actualPath = path.join(paths.diffs, `${name}-actual.png`);
80
+ fs.mkdirSync(paths.diffs, { recursive: true });
81
+ fs.writeFileSync(actualPath, actualPng);
82
+ if (global.json) {
83
+ printJson({
84
+ match: false,
85
+ reason: 'size',
86
+ golden: { width: golden.width, height: golden.height },
87
+ actual: { width: actual.width, height: actual.height },
88
+ actualPath,
89
+ });
90
+ }
91
+ else {
92
+ line(`Size mismatch: the golden image is ${golden.width}x${golden.height} but the screenshot is ` +
93
+ `${actual.width}x${actual.height}.`);
94
+ line('Pin the window with `clientdevbridge resize` before comparing, or re-record with --update.');
95
+ line('(--region is applied to both images, so it is never the cause of a size mismatch.)');
96
+ line('The screenshot that did not match was written to:');
97
+ printPath(path.resolve(actualPath));
98
+ }
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+ const diff = new PNG({ width: golden.width, height: golden.height });
103
+ const pixelsDiff = pixelmatch(golden.data, actual.data, diff.data, golden.width, golden.height, {
104
+ threshold: Number(options.pixelThreshold),
105
+ });
106
+ const total = golden.width * golden.height;
107
+ const percentage = (pixelsDiff / total) * 100;
108
+ const allowed = Number(options.threshold);
109
+ const match = percentage <= allowed;
110
+ let diffPath = null;
111
+ if (!match) {
112
+ fs.mkdirSync(paths.diffs, { recursive: true });
113
+ // Timestamped, so comparing twice does not throw away the first failure. Chasing a
114
+ // regression usually means running compare several times, and the run before last is
115
+ // exactly the one worth looking at again.
116
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-').replace('T', '_').replace('Z', '');
117
+ diffPath = path.join(paths.diffs, `${name}_${stamp}-diff.png`);
118
+ fs.writeFileSync(diffPath, PNG.sync.write(diff));
119
+ fs.writeFileSync(path.join(paths.diffs, `${name}_${stamp}-actual.png`), actualPng);
120
+ pruneDiffs(paths.diffs, name);
121
+ }
122
+ if (global.json) {
123
+ printJson({ match, pixelsDiff, pct: percentage, threshold: allowed, renderer, golden: goldenPath, diffPath });
124
+ }
125
+ else if (match) {
126
+ line(`${name}: matches (${pixelsDiff} of ${total} pixels differ, ${percentage.toFixed(3)}% <= ${allowed}%).`);
127
+ }
128
+ else {
129
+ line(`${name}: DIFFERS — ${pixelsDiff} of ${total} pixels, ${percentage.toFixed(3)}% > ${allowed}%.` +
130
+ ` Golden: ${goldenPath}`);
131
+ printPath(path.resolve(diffPath));
132
+ if (!global.quiet) {
133
+ line(`The screenshot itself is beside it, as ${path.basename(diffPath).replace(/-diff\.png$/, '-actual.png')}`);
134
+ }
135
+ if (!global.quiet) {
136
+ line('If the diff is concentrated on an animated block (lava, fire, water, a portal), on a ' +
137
+ 'toast popup, or on the chat lines that commands like give and setblock leave on ' +
138
+ 'screen for ten seconds, that is animation rather than a regression: wait it out, ' +
139
+ 'raise --threshold, or pass --region to compare only the part that should hold still.');
140
+ }
141
+ }
142
+ if (!match) {
143
+ process.exitCode = 1;
144
+ }
145
+ });
146
+ }
147
+ /**
148
+ * Asks the game which GL renderer it is on, so golden sets can be kept apart.
149
+ * Falls back to 'unknown' rather than failing: a missing renderer name is not worth an error.
150
+ */
151
+ async function readRenderer(client) {
152
+ try {
153
+ const result = await client.call('status');
154
+ const renderer = result['glRenderer'];
155
+ return typeof renderer === 'string' ? renderer : null;
156
+ }
157
+ catch {
158
+ return null;
159
+ }
160
+ }
161
+ export async function runResize(global, options) {
162
+ await withClient(global, async ({ client }) => {
163
+ const params = { width: Number(options.width), height: Number(options.height) };
164
+ if (options.guiScale !== undefined) {
165
+ params['guiScale'] = Number(options.guiScale);
166
+ }
167
+ const result = await client.call('window.resize', params);
168
+ if (global.json) {
169
+ printJson(result);
170
+ return;
171
+ }
172
+ line(`window ${result['pixelWidth']}x${result['pixelHeight']}px, ` +
173
+ `gui ${result['guiWidth']}x${result['guiHeight']} @ scale ${result['guiScale']}`);
174
+ });
175
+ }
176
+ /** Keeps the newest few diffs per golden, so the directory does not grow without limit. */
177
+ function pruneDiffs(directory, name, keep = 10) {
178
+ const suffixes = ['-diff.png', '-actual.png'];
179
+ for (const suffix of suffixes) {
180
+ const files = fs
181
+ .readdirSync(directory)
182
+ .filter((entry) => entry.startsWith(`${name}_`) && entry.endsWith(suffix))
183
+ .sort();
184
+ for (const stale of files.slice(0, Math.max(0, files.length - keep))) {
185
+ try {
186
+ fs.unlinkSync(path.join(directory, stale));
187
+ }
188
+ catch {
189
+ // Someone else removed it, or it is open elsewhere; either way not worth failing a compare.
190
+ }
191
+ }
192
+ }
193
+ }
194
+ function toPixelRegion(raw, guiScale) {
195
+ const factor = raw['space'] === 'pixel' ? 1 : guiScale;
196
+ return {
197
+ x: Math.round(Number(raw['x']) * factor),
198
+ y: Math.round(Number(raw['y']) * factor),
199
+ width: Math.round(Number(raw['w']) * factor),
200
+ height: Math.round(Number(raw['h']) * factor),
201
+ };
202
+ }
203
+ /** Cuts a rectangle out of a decoded PNG, so both sides of a comparison can be narrowed alike. */
204
+ function crop(image, region) {
205
+ const out = new PNG({ width: region.width, height: region.height });
206
+ PNG.bitblt(image, out, region.x, region.y, region.width, region.height, 0, 0);
207
+ return out;
208
+ }
209
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/commands/compare.ts"],"names":[],"mappings":"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"}