@v5x/cli 0.0.11 → 0.0.14

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 (2) hide show
  1. package/dist/index.js +3296 -1162
  2. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -46,866 +46,2268 @@ var __export = (target, all) => {
46
46
  };
47
47
  var __require = import.meta.require;
48
48
 
49
- // ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
50
- var require_picocolors = __commonJS((exports, module) => {
51
- var p = process || {};
52
- var argv = p.argv || [];
53
- var env = p.env || {};
54
- var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
55
- var formatter = (open, close, replace = open) => (input) => {
56
- let string = "" + input, index = string.indexOf(close, open.length);
57
- return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
58
- };
59
- var replaceClose = (string, close, replace, index) => {
60
- let result = "", cursor = 0;
61
- do {
62
- result += string.substring(cursor, index) + replace;
63
- cursor = index + close.length;
64
- index = string.indexOf(close, cursor);
65
- } while (~index);
66
- return result + string.substring(cursor);
67
- };
68
- var createColors = (enabled = isColorSupported) => {
69
- let f = enabled ? formatter : () => String;
70
- return {
71
- isColorSupported: enabled,
72
- reset: f("\x1B[0m", "\x1B[0m"),
73
- bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
74
- dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
75
- italic: f("\x1B[3m", "\x1B[23m"),
76
- underline: f("\x1B[4m", "\x1B[24m"),
77
- inverse: f("\x1B[7m", "\x1B[27m"),
78
- hidden: f("\x1B[8m", "\x1B[28m"),
79
- strikethrough: f("\x1B[9m", "\x1B[29m"),
80
- black: f("\x1B[30m", "\x1B[39m"),
81
- red: f("\x1B[31m", "\x1B[39m"),
82
- green: f("\x1B[32m", "\x1B[39m"),
83
- yellow: f("\x1B[33m", "\x1B[39m"),
84
- blue: f("\x1B[34m", "\x1B[39m"),
85
- magenta: f("\x1B[35m", "\x1B[39m"),
86
- cyan: f("\x1B[36m", "\x1B[39m"),
87
- white: f("\x1B[37m", "\x1B[39m"),
88
- gray: f("\x1B[90m", "\x1B[39m"),
89
- bgBlack: f("\x1B[40m", "\x1B[49m"),
90
- bgRed: f("\x1B[41m", "\x1B[49m"),
91
- bgGreen: f("\x1B[42m", "\x1B[49m"),
92
- bgYellow: f("\x1B[43m", "\x1B[49m"),
93
- bgBlue: f("\x1B[44m", "\x1B[49m"),
94
- bgMagenta: f("\x1B[45m", "\x1B[49m"),
95
- bgCyan: f("\x1B[46m", "\x1B[49m"),
96
- bgWhite: f("\x1B[47m", "\x1B[49m"),
97
- blackBright: f("\x1B[90m", "\x1B[39m"),
98
- redBright: f("\x1B[91m", "\x1B[39m"),
99
- greenBright: f("\x1B[92m", "\x1B[39m"),
100
- yellowBright: f("\x1B[93m", "\x1B[39m"),
101
- blueBright: f("\x1B[94m", "\x1B[39m"),
102
- magentaBright: f("\x1B[95m", "\x1B[39m"),
103
- cyanBright: f("\x1B[96m", "\x1B[39m"),
104
- whiteBright: f("\x1B[97m", "\x1B[39m"),
105
- bgBlackBright: f("\x1B[100m", "\x1B[49m"),
106
- bgRedBright: f("\x1B[101m", "\x1B[49m"),
107
- bgGreenBright: f("\x1B[102m", "\x1B[49m"),
108
- bgYellowBright: f("\x1B[103m", "\x1B[49m"),
109
- bgBlueBright: f("\x1B[104m", "\x1B[49m"),
110
- bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
111
- bgCyanBright: f("\x1B[106m", "\x1B[49m"),
112
- bgWhiteBright: f("\x1B[107m", "\x1B[49m")
113
- };
114
- };
115
- module.exports = createColors();
116
- module.exports.createColors = createColors;
117
- });
118
- // package.json
119
- var package_default = {
120
- name: "@v5x/cli",
121
- version: "0.0.11",
122
- description: "Command line interface for v5x.",
123
- license: "MIT",
124
- type: "module",
125
- bin: {
126
- v5x: "dist/index.js"
127
- },
128
- files: [
129
- "dist",
130
- "README.md"
131
- ],
132
- repository: {
133
- type: "git",
134
- url: "git+https://github.com/beanarchystudios/v5x.git",
135
- directory: "packages/cli"
136
- },
137
- bugs: {
138
- url: "https://github.com/beanarchystudios/v5x/issues"
139
- },
140
- homepage: "https://github.com/beanarchystudios/v5x#readme",
141
- publishConfig: {
142
- access: "public"
143
- },
144
- scripts: {
145
- build: "bun build ./src/index.ts --target bun --external unzipit --outfile ./dist/index.js && chmod +x ./dist/index.js",
146
- dev: "bun run ./src/index.ts",
147
- lint: "bunx tsc --noEmit",
148
- prepublishOnly: "bun run typecheck && bun run build",
149
- typecheck: "bunx tsc --noEmit"
150
- },
151
- engines: {
152
- bun: ">=1.3.14"
153
- },
154
- devDependencies: {
155
- "@types/bun": "^1.3.1"
156
- },
157
- dependencies: {
158
- "bun-serialport": "^0.1.1",
159
- picocolors: "^1.1.1",
160
- unzipit: "^1.4.0"
49
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/error.js
50
+ var require_error = __commonJS((exports) => {
51
+ class CommanderError extends Error {
52
+ constructor(exitCode, code, message) {
53
+ super(message);
54
+ Error.captureStackTrace(this, this.constructor);
55
+ this.name = this.constructor.name;
56
+ this.code = code;
57
+ this.exitCode = exitCode;
58
+ this.nestedError = undefined;
59
+ }
161
60
  }
162
- };
163
61
 
164
- // src/index.ts
165
- var import_picocolors = __toESM(require_picocolors(), 1);
166
-
167
- // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/serialport.js
168
- import { EventEmitter } from "events";
62
+ class InvalidArgumentError extends CommanderError {
63
+ constructor(message) {
64
+ super(1, "commander.invalidArgument", message);
65
+ Error.captureStackTrace(this, this.constructor);
66
+ this.name = this.constructor.name;
67
+ }
68
+ }
69
+ exports.CommanderError = CommanderError;
70
+ exports.InvalidArgumentError = InvalidArgumentError;
71
+ });
169
72
 
170
- // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/posix.js
171
- import { dlopen, FFIType, ptr, toArrayBuffer, CString } from "bun:ffi";
73
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/argument.js
74
+ var require_argument = __commonJS((exports) => {
75
+ var { InvalidArgumentError } = require_error();
172
76
 
173
- // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/constants.js
174
- import { platform } from "os";
175
- var IS_LINUX = platform() === "linux";
176
- var IS_DARWIN = platform() === "darwin";
177
- if (!IS_LINUX && !IS_DARWIN) {
178
- throw new Error(`bun-serialport: unsupported platform "${platform()}"`);
179
- }
180
- var O_RDWR = 2;
181
- var O_NOCTTY = IS_LINUX ? 256 : 131072;
182
- var O_NONBLOCK = IS_LINUX ? 2048 : 4;
183
- var TCSADRAIN = 1;
184
- var TCSAFLUSH = 2;
185
- var TCIOFLUSH = IS_LINUX ? 2 : 3;
186
- var CSIZE = IS_LINUX ? 48 : 768;
187
- var CS5 = IS_LINUX ? 0 : 0;
188
- var CS6 = IS_LINUX ? 16 : 256;
189
- var CS7 = IS_LINUX ? 32 : 512;
190
- var CS8 = IS_LINUX ? 48 : 768;
191
- var CSTOPB = IS_LINUX ? 64 : 1024;
192
- var CREAD = IS_LINUX ? 128 : 2048;
193
- var PARENB = IS_LINUX ? 256 : 4096;
194
- var PARODD = IS_LINUX ? 512 : 8192;
195
- var CLOCAL = IS_LINUX ? 2048 : 32768;
196
- var CRTSCTS = IS_LINUX ? 2147483648 : 196608;
197
- var INPCK = IS_LINUX ? 16 : 16;
198
- var IXON = IS_LINUX ? 1024 : 512;
199
- var IXOFF = IS_LINUX ? 4096 : 1024;
200
- var VMIN = IS_LINUX ? 6 : 16;
201
- var VTIME = IS_LINUX ? 5 : 17;
202
- var NCCS = IS_LINUX ? 32 : 20;
203
- var TIOCMGET = IS_LINUX ? 21525 : 1074033770;
204
- var TIOCMBIS = IS_LINUX ? 21526 : 2147775596;
205
- var TIOCMBIC = IS_LINUX ? 21527 : 2147775595;
206
- var TIOCM_DTR = 2;
207
- var TIOCM_RTS = 4;
208
- var TIOCM_CTS = 32;
209
- var TIOCM_DSR = 256;
210
- var TIOCM_CD = 64;
211
- var TIOCM_RI = 128;
212
- var TERMIOS_SIZE = IS_LINUX ? 60 : 72;
213
- var TCFLAG_SIZE = IS_LINUX ? 4 : 8;
214
- var TERMIOS_OFFSETS = IS_LINUX ? { c_iflag: 0, c_oflag: 4, c_cflag: 8, c_lflag: 12, c_line: 16, c_cc: 17, c_ispeed: 52, c_ospeed: 56 } : { c_iflag: 0, c_oflag: 8, c_cflag: 16, c_lflag: 24, c_cc: 32, c_ispeed: 56, c_ospeed: 64 };
215
- var LINUX_BAUD_MAP = {
216
- 0: 0,
217
- 110: 3,
218
- 300: 7,
219
- 600: 8,
220
- 1200: 9,
221
- 2400: 11,
222
- 4800: 12,
223
- 9600: 13,
224
- 19200: 14,
225
- 38400: 15,
226
- 57600: 4097,
227
- 115200: 4098,
228
- 230400: 4099,
229
- 460800: 4100,
230
- 500000: 4101,
231
- 576000: 4102,
232
- 921600: 4103,
233
- 1e6: 4104,
234
- 1152000: 4105,
235
- 1500000: 4106,
236
- 2000000: 4107,
237
- 2500000: 4108,
238
- 3000000: 4109,
239
- 3500000: 4110,
240
- 4000000: 4111
241
- };
242
- function encodeBaudRate(rate) {
243
- if (IS_DARWIN)
244
- return rate;
245
- const encoded = LINUX_BAUD_MAP[rate];
246
- if (encoded === undefined)
247
- throw new Error(`Unsupported baud rate: ${rate}`);
248
- return encoded;
249
- }
250
- function dataBitsFlag(bits) {
251
- switch (bits) {
252
- case 5:
253
- return CS5;
254
- case 6:
255
- return CS6;
256
- case 7:
257
- return CS7;
258
- case 8:
259
- return CS8;
260
- default:
261
- throw new Error(`Invalid data bits: ${bits}`);
77
+ class Argument {
78
+ constructor(name, description) {
79
+ this.description = description || "";
80
+ this.variadic = false;
81
+ this.parseArg = undefined;
82
+ this.defaultValue = undefined;
83
+ this.defaultValueDescription = undefined;
84
+ this.argChoices = undefined;
85
+ switch (name[0]) {
86
+ case "<":
87
+ this.required = true;
88
+ this._name = name.slice(1, -1);
89
+ break;
90
+ case "[":
91
+ this.required = false;
92
+ this._name = name.slice(1, -1);
93
+ break;
94
+ default:
95
+ this.required = true;
96
+ this._name = name;
97
+ break;
98
+ }
99
+ if (this._name.endsWith("...")) {
100
+ this.variadic = true;
101
+ this._name = this._name.slice(0, -3);
102
+ }
103
+ }
104
+ name() {
105
+ return this._name;
106
+ }
107
+ _collectValue(value, previous) {
108
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
109
+ return [value];
110
+ }
111
+ previous.push(value);
112
+ return previous;
113
+ }
114
+ default(value, description) {
115
+ this.defaultValue = value;
116
+ this.defaultValueDescription = description;
117
+ return this;
118
+ }
119
+ argParser(fn) {
120
+ this.parseArg = fn;
121
+ return this;
122
+ }
123
+ choices(values) {
124
+ this.argChoices = values.slice();
125
+ this.parseArg = (arg, previous) => {
126
+ if (!this.argChoices.includes(arg)) {
127
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
128
+ }
129
+ if (this.variadic) {
130
+ return this._collectValue(arg, previous);
131
+ }
132
+ return arg;
133
+ };
134
+ return this;
135
+ }
136
+ argRequired() {
137
+ this.required = true;
138
+ return this;
139
+ }
140
+ argOptional() {
141
+ this.required = false;
142
+ return this;
143
+ }
262
144
  }
263
- }
264
-
265
- // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/posix.js
266
- import { platform as platform2 } from "os";
267
- var IS_LINUX2 = platform2() === "linux";
268
- var IS_DARWIN2 = platform2() === "darwin";
269
- var LIBC_PATH = IS_LINUX2 ? "libc.so.6" : "libSystem.B.dylib";
270
- var libc = dlopen(LIBC_PATH, {
271
- open: { args: [FFIType.cstring, FFIType.i32], returns: FFIType.i32 },
272
- close: { args: [FFIType.i32], returns: FFIType.i32 },
273
- read: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
274
- write: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
275
- tcgetattr: { args: [FFIType.i32, FFIType.ptr], returns: FFIType.i32 },
276
- tcsetattr: { args: [FFIType.i32, FFIType.i32, FFIType.ptr], returns: FFIType.i32 },
277
- tcflush: { args: [FFIType.i32, FFIType.i32], returns: FFIType.i32 },
278
- tcdrain: { args: [FFIType.i32], returns: FFIType.i32 },
279
- cfsetispeed: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
280
- cfsetospeed: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
281
- fcntl: { args: [FFIType.i32, FFIType.i32, FFIType.i32], returns: FFIType.i32 },
282
- ioctl: { args: [FFIType.i32, FFIType.u64, FFIType.ptr], returns: FFIType.i32 },
283
- strerror: { args: [FFIType.i32], returns: FFIType.ptr }
145
+ function humanReadableArgName(arg) {
146
+ const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
147
+ return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
148
+ }
149
+ exports.Argument = Argument;
150
+ exports.humanReadableArgName = humanReadableArgName;
284
151
  });
285
- var errnoLib = dlopen(LIBC_PATH, IS_LINUX2 ? { __errno_location: { args: [], returns: FFIType.ptr } } : { __error: { args: [], returns: FFIType.ptr } });
286
- function getErrno() {
287
- const errPtr = IS_LINUX2 ? errnoLib.symbols.__errno_location() : errnoLib.symbols.__error();
288
- const view = new DataView(toArrayBuffer(errPtr, 0, 4));
289
- return view.getInt32(0, true);
290
- }
291
- function errnoError(syscall) {
292
- const code = getErrno();
293
- const msgPtr = libc.symbols.strerror(code);
294
- const msg = msgPtr ? new CString(msgPtr) : `errno ${code}`;
295
- const err = new Error(`${syscall}: ${msg}`);
296
- err.code = code;
297
- err.syscall = syscall;
298
- return err;
299
- }
300
- function readFlag(buf, offset) {
301
- if (TCFLAG_SIZE === 4) {
302
- return buf.getUint32(offset, true);
303
- }
304
- return Number(buf.getBigUint64(offset, true));
305
- }
306
- function writeFlag(buf, offset, value) {
307
- if (TCFLAG_SIZE === 4) {
308
- buf.setUint32(offset, value >>> 0, true);
309
- } else {
310
- buf.setBigUint64(offset, BigInt(value >>> 0), true);
311
- }
312
- }
313
- function writeSpeed(buf, offset, value) {
314
- if (TCFLAG_SIZE === 4) {
315
- buf.setUint32(offset, value >>> 0, true);
316
- } else {
317
- buf.setBigUint64(offset, BigInt(value), true);
318
- }
319
- }
320
- function openPort(path, options) {
321
- const {
322
- baudRate = 9600,
323
- dataBits = 8,
324
- stopBits = 1,
325
- parity = "none",
326
- rtscts = false,
327
- xon = false,
328
- xoff = false
329
- } = options;
330
- const pathBuf = Buffer.from(path + "\x00", "utf-8");
331
- const fd = libc.symbols.open(ptr(pathBuf), O_RDWR | O_NOCTTY | O_NONBLOCK);
332
- if (fd < 0)
333
- throw errnoError("open");
334
- const termiosBuf = new ArrayBuffer(TERMIOS_SIZE);
335
- const termiosBytes = new Uint8Array(termiosBuf);
336
- const termiosView = new DataView(termiosBuf);
337
- const termiosPtr = ptr(termiosBytes);
338
- if (libc.symbols.tcgetattr(fd, termiosPtr) < 0) {
339
- libc.symbols.close(fd);
340
- throw errnoError("tcgetattr");
152
+
153
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/help.js
154
+ var require_help = __commonJS((exports) => {
155
+ var { humanReadableArgName } = require_argument();
156
+
157
+ class Help {
158
+ constructor() {
159
+ this.helpWidth = undefined;
160
+ this.minWidthToWrap = 40;
161
+ this.sortSubcommands = false;
162
+ this.sortOptions = false;
163
+ this.showGlobalOptions = false;
164
+ }
165
+ prepareContext(contextOptions) {
166
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
167
+ }
168
+ visibleCommands(cmd) {
169
+ const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
170
+ const helpCommand = cmd._getHelpCommand();
171
+ if (helpCommand && !helpCommand._hidden) {
172
+ visibleCommands.push(helpCommand);
173
+ }
174
+ if (this.sortSubcommands) {
175
+ visibleCommands.sort((a, b) => {
176
+ return a.name().localeCompare(b.name());
177
+ });
178
+ }
179
+ return visibleCommands;
180
+ }
181
+ compareOptions(a, b) {
182
+ const getSortKey = (option) => {
183
+ return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
184
+ };
185
+ return getSortKey(a).localeCompare(getSortKey(b));
186
+ }
187
+ visibleOptions(cmd) {
188
+ const visibleOptions = cmd.options.filter((option) => !option.hidden);
189
+ const helpOption = cmd._getHelpOption();
190
+ if (helpOption && !helpOption.hidden) {
191
+ const removeShort = helpOption.short && cmd._findOption(helpOption.short);
192
+ const removeLong = helpOption.long && cmd._findOption(helpOption.long);
193
+ if (!removeShort && !removeLong) {
194
+ visibleOptions.push(helpOption);
195
+ } else if (helpOption.long && !removeLong) {
196
+ visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
197
+ } else if (helpOption.short && !removeShort) {
198
+ visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
199
+ }
200
+ }
201
+ if (this.sortOptions) {
202
+ visibleOptions.sort(this.compareOptions);
203
+ }
204
+ return visibleOptions;
205
+ }
206
+ visibleGlobalOptions(cmd) {
207
+ if (!this.showGlobalOptions)
208
+ return [];
209
+ const globalOptions = [];
210
+ for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
211
+ const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
212
+ globalOptions.push(...visibleOptions);
213
+ }
214
+ if (this.sortOptions) {
215
+ globalOptions.sort(this.compareOptions);
216
+ }
217
+ return globalOptions;
218
+ }
219
+ visibleArguments(cmd) {
220
+ if (cmd._argsDescription) {
221
+ cmd.registeredArguments.forEach((argument) => {
222
+ argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
223
+ });
224
+ }
225
+ if (cmd.registeredArguments.find((argument) => argument.description)) {
226
+ return cmd.registeredArguments;
227
+ }
228
+ return [];
229
+ }
230
+ subcommandTerm(cmd) {
231
+ const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
232
+ return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
233
+ }
234
+ optionTerm(option) {
235
+ return option.flags;
236
+ }
237
+ argumentTerm(argument) {
238
+ return argument.name();
239
+ }
240
+ longestSubcommandTermLength(cmd, helper) {
241
+ return helper.visibleCommands(cmd).reduce((max, command) => {
242
+ return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
243
+ }, 0);
244
+ }
245
+ longestOptionTermLength(cmd, helper) {
246
+ return helper.visibleOptions(cmd).reduce((max, option) => {
247
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
248
+ }, 0);
249
+ }
250
+ longestGlobalOptionTermLength(cmd, helper) {
251
+ return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
252
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
253
+ }, 0);
254
+ }
255
+ longestArgumentTermLength(cmd, helper) {
256
+ return helper.visibleArguments(cmd).reduce((max, argument) => {
257
+ return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
258
+ }, 0);
259
+ }
260
+ commandUsage(cmd) {
261
+ let cmdName = cmd._name;
262
+ if (cmd._aliases[0]) {
263
+ cmdName = cmdName + "|" + cmd._aliases[0];
264
+ }
265
+ let ancestorCmdNames = "";
266
+ for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
267
+ ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
268
+ }
269
+ return ancestorCmdNames + cmdName + " " + cmd.usage();
270
+ }
271
+ commandDescription(cmd) {
272
+ return cmd.description();
273
+ }
274
+ subcommandDescription(cmd) {
275
+ return cmd.summary() || cmd.description();
276
+ }
277
+ optionDescription(option) {
278
+ const extraInfo = [];
279
+ if (option.argChoices) {
280
+ extraInfo.push(`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
281
+ }
282
+ if (option.defaultValue !== undefined) {
283
+ const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean";
284
+ if (showDefault) {
285
+ extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
286
+ }
287
+ }
288
+ if (option.presetArg !== undefined && option.optional) {
289
+ extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
290
+ }
291
+ if (option.envVar !== undefined) {
292
+ extraInfo.push(`env: ${option.envVar}`);
293
+ }
294
+ if (extraInfo.length > 0) {
295
+ const extraDescription = `(${extraInfo.join(", ")})`;
296
+ if (option.description) {
297
+ return `${option.description} ${extraDescription}`;
298
+ }
299
+ return extraDescription;
300
+ }
301
+ return option.description;
302
+ }
303
+ argumentDescription(argument) {
304
+ const extraInfo = [];
305
+ if (argument.argChoices) {
306
+ extraInfo.push(`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
307
+ }
308
+ if (argument.defaultValue !== undefined) {
309
+ extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
310
+ }
311
+ if (extraInfo.length > 0) {
312
+ const extraDescription = `(${extraInfo.join(", ")})`;
313
+ if (argument.description) {
314
+ return `${argument.description} ${extraDescription}`;
315
+ }
316
+ return extraDescription;
317
+ }
318
+ return argument.description;
319
+ }
320
+ formatItemList(heading, items, helper) {
321
+ if (items.length === 0)
322
+ return [];
323
+ return [helper.styleTitle(heading), ...items, ""];
324
+ }
325
+ groupItems(unsortedItems, visibleItems, getGroup) {
326
+ const result = new Map;
327
+ unsortedItems.forEach((item) => {
328
+ const group = getGroup(item);
329
+ if (!result.has(group))
330
+ result.set(group, []);
331
+ });
332
+ visibleItems.forEach((item) => {
333
+ const group = getGroup(item);
334
+ if (!result.has(group)) {
335
+ result.set(group, []);
336
+ }
337
+ result.get(group).push(item);
338
+ });
339
+ return result;
340
+ }
341
+ formatHelp(cmd, helper) {
342
+ const termWidth = helper.padWidth(cmd, helper);
343
+ const helpWidth = helper.helpWidth ?? 80;
344
+ function callFormatItem(term, description) {
345
+ return helper.formatItem(term, termWidth, description, helper);
346
+ }
347
+ let output = [
348
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
349
+ ""
350
+ ];
351
+ const commandDescription = helper.commandDescription(cmd);
352
+ if (commandDescription.length > 0) {
353
+ output = output.concat([
354
+ helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth),
355
+ ""
356
+ ]);
357
+ }
358
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
359
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
360
+ });
361
+ output = output.concat(this.formatItemList("Arguments:", argumentList, helper));
362
+ const optionGroups = this.groupItems(cmd.options, helper.visibleOptions(cmd), (option) => option.helpGroupHeading ?? "Options:");
363
+ optionGroups.forEach((options, group) => {
364
+ const optionList = options.map((option) => {
365
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
366
+ });
367
+ output = output.concat(this.formatItemList(group, optionList, helper));
368
+ });
369
+ if (helper.showGlobalOptions) {
370
+ const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
371
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
372
+ });
373
+ output = output.concat(this.formatItemList("Global Options:", globalOptionList, helper));
374
+ }
375
+ const commandGroups = this.groupItems(cmd.commands, helper.visibleCommands(cmd), (sub) => sub.helpGroup() || "Commands:");
376
+ commandGroups.forEach((commands, group) => {
377
+ const commandList = commands.map((sub) => {
378
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)), helper.styleSubcommandDescription(helper.subcommandDescription(sub)));
379
+ });
380
+ output = output.concat(this.formatItemList(group, commandList, helper));
381
+ });
382
+ return output.join(`
383
+ `);
384
+ }
385
+ displayWidth(str) {
386
+ return stripColor(str).length;
387
+ }
388
+ styleTitle(str) {
389
+ return str;
390
+ }
391
+ styleUsage(str) {
392
+ return str.split(" ").map((word) => {
393
+ if (word === "[options]")
394
+ return this.styleOptionText(word);
395
+ if (word === "[command]")
396
+ return this.styleSubcommandText(word);
397
+ if (word[0] === "[" || word[0] === "<")
398
+ return this.styleArgumentText(word);
399
+ return this.styleCommandText(word);
400
+ }).join(" ");
401
+ }
402
+ styleCommandDescription(str) {
403
+ return this.styleDescriptionText(str);
404
+ }
405
+ styleOptionDescription(str) {
406
+ return this.styleDescriptionText(str);
407
+ }
408
+ styleSubcommandDescription(str) {
409
+ return this.styleDescriptionText(str);
410
+ }
411
+ styleArgumentDescription(str) {
412
+ return this.styleDescriptionText(str);
413
+ }
414
+ styleDescriptionText(str) {
415
+ return str;
416
+ }
417
+ styleOptionTerm(str) {
418
+ return this.styleOptionText(str);
419
+ }
420
+ styleSubcommandTerm(str) {
421
+ return str.split(" ").map((word) => {
422
+ if (word === "[options]")
423
+ return this.styleOptionText(word);
424
+ if (word[0] === "[" || word[0] === "<")
425
+ return this.styleArgumentText(word);
426
+ return this.styleSubcommandText(word);
427
+ }).join(" ");
428
+ }
429
+ styleArgumentTerm(str) {
430
+ return this.styleArgumentText(str);
431
+ }
432
+ styleOptionText(str) {
433
+ return str;
434
+ }
435
+ styleArgumentText(str) {
436
+ return str;
437
+ }
438
+ styleSubcommandText(str) {
439
+ return str;
440
+ }
441
+ styleCommandText(str) {
442
+ return str;
443
+ }
444
+ padWidth(cmd, helper) {
445
+ return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
446
+ }
447
+ preformatted(str) {
448
+ return /\n[^\S\r\n]/.test(str);
449
+ }
450
+ formatItem(term, termWidth, description, helper) {
451
+ const itemIndent = 2;
452
+ const itemIndentStr = " ".repeat(itemIndent);
453
+ if (!description)
454
+ return itemIndentStr + term;
455
+ const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
456
+ const spacerWidth = 2;
457
+ const helpWidth = this.helpWidth ?? 80;
458
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
459
+ let formattedDescription;
460
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
461
+ formattedDescription = description;
462
+ } else {
463
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
464
+ formattedDescription = wrappedDescription.replace(/\n/g, `
465
+ ` + " ".repeat(termWidth + spacerWidth));
466
+ }
467
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
468
+ ${itemIndentStr}`);
469
+ }
470
+ boxWrap(str, width) {
471
+ if (width < this.minWidthToWrap)
472
+ return str;
473
+ const rawLines = str.split(/\r\n|\n/);
474
+ const chunkPattern = /[\s]*[^\s]+/g;
475
+ const wrappedLines = [];
476
+ rawLines.forEach((line) => {
477
+ const chunks = line.match(chunkPattern);
478
+ if (chunks === null) {
479
+ wrappedLines.push("");
480
+ return;
481
+ }
482
+ let sumChunks = [chunks.shift()];
483
+ let sumWidth = this.displayWidth(sumChunks[0]);
484
+ chunks.forEach((chunk) => {
485
+ const visibleWidth = this.displayWidth(chunk);
486
+ if (sumWidth + visibleWidth <= width) {
487
+ sumChunks.push(chunk);
488
+ sumWidth += visibleWidth;
489
+ return;
490
+ }
491
+ wrappedLines.push(sumChunks.join(""));
492
+ const nextChunk = chunk.trimStart();
493
+ sumChunks = [nextChunk];
494
+ sumWidth = this.displayWidth(nextChunk);
495
+ });
496
+ wrappedLines.push(sumChunks.join(""));
497
+ });
498
+ return wrappedLines.join(`
499
+ `);
500
+ }
341
501
  }
342
- const off = TERMIOS_OFFSETS;
343
- let cflag = readFlag(termiosView, off.c_cflag);
344
- cflag &= ~CSIZE;
345
- cflag |= dataBitsFlag(dataBits);
346
- cflag |= CREAD | CLOCAL;
347
- if (stopBits === 2)
348
- cflag |= CSTOPB;
349
- else
350
- cflag &= ~CSTOPB;
351
- if (parity === "none") {
352
- cflag &= ~(PARENB | PARODD);
353
- } else if (parity === "even") {
354
- cflag |= PARENB;
355
- cflag &= ~PARODD;
356
- } else if (parity === "odd") {
357
- cflag |= PARENB | PARODD;
502
+ function stripColor(str) {
503
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
504
+ return str.replace(sgrPattern, "");
358
505
  }
359
- if (rtscts)
360
- cflag |= CRTSCTS;
361
- else
362
- cflag &= ~CRTSCTS;
363
- writeFlag(termiosView, off.c_cflag, cflag);
364
- let iflag = 0;
365
- if (parity !== "none")
366
- iflag |= INPCK;
367
- if (xon)
368
- iflag |= IXON;
369
- if (xoff)
370
- iflag |= IXOFF;
371
- writeFlag(termiosView, off.c_iflag, iflag);
372
- writeFlag(termiosView, off.c_oflag, 0);
373
- writeFlag(termiosView, off.c_lflag, 0);
374
- const ccOffset = off.c_cc;
375
- for (let i = 0;i < NCCS; i++)
376
- termiosBytes[ccOffset + i] = 0;
377
- termiosBytes[ccOffset + VMIN] = 1;
378
- termiosBytes[ccOffset + VTIME] = 0;
379
- const baudCode = encodeBaudRate(baudRate);
380
- if (IS_LINUX2) {
381
- writeSpeed(termiosView, off.c_ispeed, baudCode);
382
- writeSpeed(termiosView, off.c_ospeed, baudCode);
506
+ exports.Help = Help;
507
+ exports.stripColor = stripColor;
508
+ });
509
+
510
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/option.js
511
+ var require_option = __commonJS((exports) => {
512
+ var { InvalidArgumentError } = require_error();
513
+
514
+ class Option {
515
+ constructor(flags, description) {
516
+ this.flags = flags;
517
+ this.description = description || "";
518
+ this.required = flags.includes("<");
519
+ this.optional = flags.includes("[");
520
+ this.variadic = /\w\.\.\.[>\]]$/.test(flags);
521
+ this.mandatory = false;
522
+ const optionFlags = splitOptionFlags(flags);
523
+ this.short = optionFlags.shortFlag;
524
+ this.long = optionFlags.longFlag;
525
+ this.negate = false;
526
+ if (this.long) {
527
+ this.negate = this.long.startsWith("--no-");
528
+ }
529
+ this.defaultValue = undefined;
530
+ this.defaultValueDescription = undefined;
531
+ this.presetArg = undefined;
532
+ this.envVar = undefined;
533
+ this.parseArg = undefined;
534
+ this.hidden = false;
535
+ this.argChoices = undefined;
536
+ this.conflictsWith = [];
537
+ this.implied = undefined;
538
+ this.helpGroupHeading = undefined;
539
+ }
540
+ default(value, description) {
541
+ this.defaultValue = value;
542
+ this.defaultValueDescription = description;
543
+ return this;
544
+ }
545
+ preset(arg) {
546
+ this.presetArg = arg;
547
+ return this;
548
+ }
549
+ conflicts(names) {
550
+ this.conflictsWith = this.conflictsWith.concat(names);
551
+ return this;
552
+ }
553
+ implies(impliedOptionValues) {
554
+ let newImplied = impliedOptionValues;
555
+ if (typeof impliedOptionValues === "string") {
556
+ newImplied = { [impliedOptionValues]: true };
557
+ }
558
+ this.implied = Object.assign(this.implied || {}, newImplied);
559
+ return this;
560
+ }
561
+ env(name) {
562
+ this.envVar = name;
563
+ return this;
564
+ }
565
+ argParser(fn) {
566
+ this.parseArg = fn;
567
+ return this;
568
+ }
569
+ makeOptionMandatory(mandatory = true) {
570
+ this.mandatory = !!mandatory;
571
+ return this;
572
+ }
573
+ hideHelp(hide = true) {
574
+ this.hidden = !!hide;
575
+ return this;
576
+ }
577
+ _collectValue(value, previous) {
578
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
579
+ return [value];
580
+ }
581
+ previous.push(value);
582
+ return previous;
583
+ }
584
+ choices(values) {
585
+ this.argChoices = values.slice();
586
+ this.parseArg = (arg, previous) => {
587
+ if (!this.argChoices.includes(arg)) {
588
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
589
+ }
590
+ if (this.variadic) {
591
+ return this._collectValue(arg, previous);
592
+ }
593
+ return arg;
594
+ };
595
+ return this;
596
+ }
597
+ name() {
598
+ if (this.long) {
599
+ return this.long.replace(/^--/, "");
600
+ }
601
+ return this.short.replace(/^-/, "");
602
+ }
603
+ attributeName() {
604
+ if (this.negate) {
605
+ return camelcase(this.name().replace(/^no-/, ""));
606
+ }
607
+ return camelcase(this.name());
608
+ }
609
+ helpGroup(heading) {
610
+ this.helpGroupHeading = heading;
611
+ return this;
612
+ }
613
+ is(arg) {
614
+ return this.short === arg || this.long === arg;
615
+ }
616
+ isBoolean() {
617
+ return !this.required && !this.optional && !this.negate;
618
+ }
383
619
  }
384
- if (libc.symbols.cfsetispeed(termiosPtr, baudCode) < 0) {
385
- libc.symbols.close(fd);
386
- throw errnoError("cfsetispeed");
620
+
621
+ class DualOptions {
622
+ constructor(options) {
623
+ this.positiveOptions = new Map;
624
+ this.negativeOptions = new Map;
625
+ this.dualOptions = new Set;
626
+ options.forEach((option) => {
627
+ if (option.negate) {
628
+ this.negativeOptions.set(option.attributeName(), option);
629
+ } else {
630
+ this.positiveOptions.set(option.attributeName(), option);
631
+ }
632
+ });
633
+ this.negativeOptions.forEach((value, key) => {
634
+ if (this.positiveOptions.has(key)) {
635
+ this.dualOptions.add(key);
636
+ }
637
+ });
638
+ }
639
+ valueFromOption(value, option) {
640
+ const optionKey = option.attributeName();
641
+ if (!this.dualOptions.has(optionKey))
642
+ return true;
643
+ const preset = this.negativeOptions.get(optionKey).presetArg;
644
+ const negativeValue = preset !== undefined ? preset : false;
645
+ return option.negate === (negativeValue === value);
646
+ }
387
647
  }
388
- if (libc.symbols.cfsetospeed(termiosPtr, baudCode) < 0) {
389
- libc.symbols.close(fd);
390
- throw errnoError("cfsetospeed");
648
+ function camelcase(str) {
649
+ return str.split("-").reduce((str2, word) => {
650
+ return str2 + word[0].toUpperCase() + word.slice(1);
651
+ });
391
652
  }
392
- if (libc.symbols.tcsetattr(fd, TCSAFLUSH, termiosPtr) < 0) {
393
- libc.symbols.close(fd);
394
- throw errnoError("tcsetattr");
653
+ function splitOptionFlags(flags) {
654
+ let shortFlag;
655
+ let longFlag;
656
+ const shortFlagExp = /^-[^-]$/;
657
+ const longFlagExp = /^--[^-]/;
658
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
659
+ if (shortFlagExp.test(flagParts[0]))
660
+ shortFlag = flagParts.shift();
661
+ if (longFlagExp.test(flagParts[0]))
662
+ longFlag = flagParts.shift();
663
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
664
+ shortFlag = flagParts.shift();
665
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
666
+ shortFlag = longFlag;
667
+ longFlag = flagParts.shift();
668
+ }
669
+ if (flagParts[0].startsWith("-")) {
670
+ const unsupportedFlag = flagParts[0];
671
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
672
+ if (/^-[^-][^-]/.test(unsupportedFlag))
673
+ throw new Error(`${baseError}
674
+ - a short flag is a single dash and a single character
675
+ - either use a single dash and a single character (for a short flag)
676
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
677
+ if (shortFlagExp.test(unsupportedFlag))
678
+ throw new Error(`${baseError}
679
+ - too many short flags`);
680
+ if (longFlagExp.test(unsupportedFlag))
681
+ throw new Error(`${baseError}
682
+ - too many long flags`);
683
+ throw new Error(`${baseError}
684
+ - unrecognised flag format`);
685
+ }
686
+ if (shortFlag === undefined && longFlag === undefined)
687
+ throw new Error(`option creation failed due to no flags found in '${flags}'.`);
688
+ return { shortFlag, longFlag };
395
689
  }
396
- libc.symbols.tcflush(fd, TCIOFLUSH);
397
- return fd;
398
- }
399
- function closePort(fd) {
400
- if (libc.symbols.close(fd) < 0)
401
- throw errnoError("close");
402
- }
403
- var MAX_EAGAIN_RETRIES = 1000;
404
- function writePort(fd, data) {
405
- const buf = data instanceof Uint8Array ? data : Buffer.from(data, "utf-8");
406
- let offset = 0;
407
- let eagainCount = 0;
408
- while (offset < buf.length) {
409
- const slice = buf.subarray(offset);
410
- const written = Number(libc.symbols.write(fd, ptr(slice), BigInt(slice.length)));
411
- if (written < 0) {
412
- const code = getErrno();
413
- if (code === 11 || code === 35) {
414
- if (++eagainCount > MAX_EAGAIN_RETRIES) {
415
- throw new Error("write: device not accepting data (EAGAIN limit exceeded)");
690
+ exports.Option = Option;
691
+ exports.DualOptions = DualOptions;
692
+ });
693
+
694
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/suggestSimilar.js
695
+ var require_suggestSimilar = __commonJS((exports) => {
696
+ var maxDistance = 3;
697
+ function editDistance(a, b) {
698
+ if (Math.abs(a.length - b.length) > maxDistance)
699
+ return Math.max(a.length, b.length);
700
+ const d = [];
701
+ for (let i = 0;i <= a.length; i++) {
702
+ d[i] = [i];
703
+ }
704
+ for (let j = 0;j <= b.length; j++) {
705
+ d[0][j] = j;
706
+ }
707
+ for (let j = 1;j <= b.length; j++) {
708
+ for (let i = 1;i <= a.length; i++) {
709
+ let cost = 1;
710
+ if (a[i - 1] === b[j - 1]) {
711
+ cost = 0;
712
+ } else {
713
+ cost = 1;
714
+ }
715
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
716
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
717
+ d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
416
718
  }
417
- continue;
418
719
  }
419
- throw errnoError("write");
420
720
  }
421
- eagainCount = 0;
422
- offset += written;
423
- }
424
- return offset;
425
- }
426
- function readPort(fd, buffer) {
427
- const n = Number(libc.symbols.read(fd, ptr(buffer), BigInt(buffer.length)));
428
- if (n < 0) {
429
- const code = getErrno();
430
- if (code === 11 || code === 35)
431
- return 0;
432
- throw errnoError("read");
433
- }
434
- return n;
435
- }
436
- function updateBaudRate(fd, baudRate) {
437
- const termiosBuf = new ArrayBuffer(TERMIOS_SIZE);
438
- const termiosPtr = ptr(new Uint8Array(termiosBuf));
439
- if (libc.symbols.tcgetattr(fd, termiosPtr) < 0)
440
- throw errnoError("tcgetattr");
441
- const baudCode = encodeBaudRate(baudRate);
442
- if (libc.symbols.cfsetispeed(termiosPtr, baudCode) < 0)
443
- throw errnoError("cfsetispeed");
444
- if (libc.symbols.cfsetospeed(termiosPtr, baudCode) < 0)
445
- throw errnoError("cfsetospeed");
446
- if (IS_LINUX2) {
447
- const view = new DataView(termiosBuf);
448
- writeSpeed(view, TERMIOS_OFFSETS.c_ispeed, baudCode);
449
- writeSpeed(view, TERMIOS_OFFSETS.c_ospeed, baudCode);
450
- }
451
- if (libc.symbols.tcsetattr(fd, TCSADRAIN, termiosPtr) < 0)
452
- throw errnoError("tcsetattr");
453
- }
454
- function setModemLines(fd, flags) {
455
- const { dtr, rts, brk } = flags;
456
- const intBuf = new ArrayBuffer(4);
457
- const intView = new DataView(intBuf);
458
- const intPtr = ptr(new Uint8Array(intBuf));
459
- let bitsToSet = 0;
460
- let bitsToClear = 0;
461
- if (dtr === true)
462
- bitsToSet |= TIOCM_DTR;
463
- if (dtr === false)
464
- bitsToClear |= TIOCM_DTR;
465
- if (rts === true)
466
- bitsToSet |= TIOCM_RTS;
467
- if (rts === false)
468
- bitsToClear |= TIOCM_RTS;
469
- if (bitsToSet) {
470
- intView.setInt32(0, bitsToSet, true);
471
- if (libc.symbols.ioctl(fd, TIOCMBIS, intPtr) < 0)
472
- throw errnoError("ioctl TIOCMBIS");
473
- }
474
- if (bitsToClear) {
475
- intView.setInt32(0, bitsToClear, true);
476
- if (libc.symbols.ioctl(fd, TIOCMBIC, intPtr) < 0)
477
- throw errnoError("ioctl TIOCMBIC");
721
+ return d[a.length][b.length];
722
+ }
723
+ function suggestSimilar(word, candidates) {
724
+ if (!candidates || candidates.length === 0)
725
+ return "";
726
+ candidates = Array.from(new Set(candidates));
727
+ const searchingOptions = word.startsWith("--");
728
+ if (searchingOptions) {
729
+ word = word.slice(2);
730
+ candidates = candidates.map((candidate) => candidate.slice(2));
731
+ }
732
+ let similar = [];
733
+ let bestDistance = maxDistance;
734
+ const minSimilarity = 0.4;
735
+ candidates.forEach((candidate) => {
736
+ if (candidate.length <= 1)
737
+ return;
738
+ const distance = editDistance(word, candidate);
739
+ const length = Math.max(word.length, candidate.length);
740
+ const similarity = (length - distance) / length;
741
+ if (similarity > minSimilarity) {
742
+ if (distance < bestDistance) {
743
+ bestDistance = distance;
744
+ similar = [candidate];
745
+ } else if (distance === bestDistance) {
746
+ similar.push(candidate);
747
+ }
748
+ }
749
+ });
750
+ similar.sort((a, b) => a.localeCompare(b));
751
+ if (searchingOptions) {
752
+ similar = similar.map((candidate) => `--${candidate}`);
753
+ }
754
+ if (similar.length > 1) {
755
+ return `
756
+ (Did you mean one of ${similar.join(", ")}?)`;
757
+ }
758
+ if (similar.length === 1) {
759
+ return `
760
+ (Did you mean ${similar[0]}?)`;
761
+ }
762
+ return "";
478
763
  }
479
- }
480
- function getModemLines(fd) {
481
- const intBuf = new ArrayBuffer(4);
482
- const intView = new DataView(intBuf);
483
- const intPtr = ptr(new Uint8Array(intBuf));
484
- if (libc.symbols.ioctl(fd, TIOCMGET, intPtr) < 0)
485
- throw errnoError("ioctl TIOCMGET");
486
- const bits = intView.getInt32(0, true);
487
- return {
488
- cts: !!(bits & TIOCM_CTS),
489
- dsr: !!(bits & TIOCM_DSR),
490
- dcd: !!(bits & TIOCM_CD),
491
- ri: !!(bits & TIOCM_RI)
492
- };
493
- }
494
- function flushPort(fd) {
495
- if (libc.symbols.tcflush(fd, TCIOFLUSH) < 0)
496
- throw errnoError("tcflush");
497
- }
498
- function drainPort(fd) {
499
- if (libc.symbols.tcdrain(fd) < 0)
500
- throw errnoError("tcdrain");
501
- }
764
+ exports.suggestSimilar = suggestSimilar;
765
+ });
502
766
 
503
- // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/serialport.js
504
- var DEFAULT_READ_BUFFER_SIZE = 65536;
505
- var DEFAULT_READ_INTERVAL_MS = 1;
767
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/lib/command.js
768
+ var require_command = __commonJS((exports) => {
769
+ var EventEmitter = __require("events").EventEmitter;
770
+ var childProcess = __require("child_process");
771
+ var path = __require("path");
772
+ var fs = __require("fs");
773
+ var process2 = __require("process");
774
+ var { Argument, humanReadableArgName } = require_argument();
775
+ var { CommanderError } = require_error();
776
+ var { Help, stripColor } = require_help();
777
+ var { Option, DualOptions } = require_option();
778
+ var { suggestSimilar } = require_suggestSimilar();
506
779
 
507
- class SerialPort extends EventEmitter {
508
- #fd = -1;
509
- #path;
510
- #baudRate;
511
- #options;
512
- #isOpen = false;
513
- #isClosing = false;
514
- #readBuf;
515
- #readInterval;
516
- #readTimer = null;
517
- constructor(options) {
518
- super();
519
- if (!options || !options.path)
520
- throw new Error("options.path is required");
521
- if (!options.baudRate)
522
- throw new Error("options.baudRate is required");
523
- this.#path = options.path;
524
- this.#baudRate = options.baudRate;
525
- this.#options = { ...options };
526
- this.#readBuf = new Uint8Array(options.readBufferSize || DEFAULT_READ_BUFFER_SIZE);
527
- this.#readInterval = options.readInterval || DEFAULT_READ_INTERVAL_MS;
528
- if (options.autoOpen !== false) {
529
- queueMicrotask(() => this.open().catch((err) => this.emit("error", err)));
780
+ class Command extends EventEmitter {
781
+ constructor(name) {
782
+ super();
783
+ this.commands = [];
784
+ this.options = [];
785
+ this.parent = null;
786
+ this._allowUnknownOption = false;
787
+ this._allowExcessArguments = false;
788
+ this.registeredArguments = [];
789
+ this._args = this.registeredArguments;
790
+ this.args = [];
791
+ this.rawArgs = [];
792
+ this.processedArgs = [];
793
+ this._scriptPath = null;
794
+ this._name = name || "";
795
+ this._optionValues = {};
796
+ this._optionValueSources = {};
797
+ this._storeOptionsAsProperties = false;
798
+ this._actionHandler = null;
799
+ this._executableHandler = false;
800
+ this._executableFile = null;
801
+ this._executableDir = null;
802
+ this._defaultCommandName = null;
803
+ this._exitCallback = null;
804
+ this._aliases = [];
805
+ this._combineFlagAndOptionalValue = true;
806
+ this._description = "";
807
+ this._summary = "";
808
+ this._argsDescription = undefined;
809
+ this._enablePositionalOptions = false;
810
+ this._passThroughOptions = false;
811
+ this._lifeCycleHooks = {};
812
+ this._showHelpAfterError = false;
813
+ this._showSuggestionAfterError = true;
814
+ this._savedState = null;
815
+ this._outputConfiguration = {
816
+ writeOut: (str) => process2.stdout.write(str),
817
+ writeErr: (str) => process2.stderr.write(str),
818
+ outputError: (str, write) => write(str),
819
+ getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
820
+ getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
821
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
822
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
823
+ stripColor: (str) => stripColor(str)
824
+ };
825
+ this._hidden = false;
826
+ this._helpOption = undefined;
827
+ this._addImplicitHelpCommand = undefined;
828
+ this._helpCommand = undefined;
829
+ this._helpConfiguration = {};
830
+ this._helpGroupHeading = undefined;
831
+ this._defaultCommandGroup = undefined;
832
+ this._defaultOptionGroup = undefined;
530
833
  }
531
- }
532
- get path() {
533
- return this.#path;
534
- }
535
- get baudRate() {
536
- return this.#baudRate;
537
- }
538
- get isOpen() {
539
- return this.#isOpen && !this.#isClosing;
540
- }
541
- async open() {
542
- if (this.#isOpen)
543
- throw new Error("Port is already open");
544
- try {
545
- this.#fd = openPort(this.#path, this.#options);
546
- this.#isOpen = true;
547
- this.#isClosing = false;
548
- this.#startReading();
549
- this.emit("open");
550
- } catch (err) {
551
- this.#isOpen = false;
552
- throw err;
834
+ copyInheritedSettings(sourceCommand) {
835
+ this._outputConfiguration = sourceCommand._outputConfiguration;
836
+ this._helpOption = sourceCommand._helpOption;
837
+ this._helpCommand = sourceCommand._helpCommand;
838
+ this._helpConfiguration = sourceCommand._helpConfiguration;
839
+ this._exitCallback = sourceCommand._exitCallback;
840
+ this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
841
+ this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
842
+ this._allowExcessArguments = sourceCommand._allowExcessArguments;
843
+ this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
844
+ this._showHelpAfterError = sourceCommand._showHelpAfterError;
845
+ this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
846
+ return this;
553
847
  }
554
- }
555
- async close() {
556
- if (!this.#isOpen)
557
- throw new Error("Port is not open");
558
- if (this.#isClosing)
559
- return;
560
- this.#isClosing = true;
561
- this.#stopReading();
562
- try {
563
- closePort(this.#fd);
564
- } catch (err) {
565
- this.#isClosing = false;
566
- throw err;
848
+ _getCommandAndAncestors() {
849
+ const result = [];
850
+ for (let command = this;command; command = command.parent) {
851
+ result.push(command);
852
+ }
853
+ return result;
567
854
  }
568
- this.#fd = -1;
569
- this.#isOpen = false;
570
- this.#isClosing = false;
571
- this.emit("close");
572
- }
573
- async write(data) {
574
- if (!this.#isOpen || this.#isClosing) {
575
- throw new Error("Port is not open");
855
+ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
856
+ let desc = actionOptsOrExecDesc;
857
+ let opts = execOpts;
858
+ if (typeof desc === "object" && desc !== null) {
859
+ opts = desc;
860
+ desc = null;
861
+ }
862
+ opts = opts || {};
863
+ const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
864
+ const cmd = this.createCommand(name);
865
+ if (desc) {
866
+ cmd.description(desc);
867
+ cmd._executableHandler = true;
868
+ }
869
+ if (opts.isDefault)
870
+ this._defaultCommandName = cmd._name;
871
+ cmd._hidden = !!(opts.noHelp || opts.hidden);
872
+ cmd._executableFile = opts.executableFile || null;
873
+ if (args)
874
+ cmd.arguments(args);
875
+ this._registerCommand(cmd);
876
+ cmd.parent = this;
877
+ cmd.copyInheritedSettings(this);
878
+ if (desc)
879
+ return this;
880
+ return cmd;
576
881
  }
577
- const buf = typeof data === "string" ? Buffer.from(data, "utf-8") : data;
578
- return writePort(this.#fd, buf);
579
- }
580
- async update(options) {
581
- if (!this.#isOpen)
582
- throw new Error("Port is not open");
583
- if (options.baudRate !== undefined) {
584
- updateBaudRate(this.#fd, options.baudRate);
585
- this.#baudRate = options.baudRate;
882
+ createCommand(name) {
883
+ return new Command(name);
586
884
  }
587
- }
588
- async set(flags) {
589
- if (!this.#isOpen)
590
- throw new Error("Port is not open");
591
- setModemLines(this.#fd, flags);
592
- }
593
- async get() {
594
- if (!this.#isOpen)
595
- throw new Error("Port is not open");
596
- return getModemLines(this.#fd);
597
- }
598
- async flush() {
599
- if (!this.#isOpen)
600
- throw new Error("Port is not open");
601
- flushPort(this.#fd);
602
- }
603
- async drain() {
604
- if (!this.#isOpen)
605
- throw new Error("Port is not open");
606
- drainPort(this.#fd);
607
- }
608
- pipe(parser) {
609
- const handler = (chunk) => parser.push(chunk);
610
- this.on("data", handler);
611
- parser._unpipe = () => this.off("data", handler);
612
- return parser;
613
- }
614
- unpipe(parser) {
615
- if (parser && typeof parser._unpipe === "function") {
616
- parser._unpipe();
617
- parser._unpipe = undefined;
885
+ createHelp() {
886
+ return Object.assign(new Help, this.configureHelp());
618
887
  }
619
- }
620
- #startReading() {
621
- this.#readTimer = setInterval(() => {
622
- if (!this.#isOpen || this.#isClosing)
623
- return;
624
- try {
625
- const n = readPort(this.#fd, this.#readBuf);
626
- if (n > 0) {
627
- const data = this.#readBuf.slice(0, n);
628
- this.emit("data", data);
888
+ configureHelp(configuration) {
889
+ if (configuration === undefined)
890
+ return this._helpConfiguration;
891
+ this._helpConfiguration = configuration;
892
+ return this;
893
+ }
894
+ configureOutput(configuration) {
895
+ if (configuration === undefined)
896
+ return this._outputConfiguration;
897
+ this._outputConfiguration = {
898
+ ...this._outputConfiguration,
899
+ ...configuration
900
+ };
901
+ return this;
902
+ }
903
+ showHelpAfterError(displayHelp = true) {
904
+ if (typeof displayHelp !== "string")
905
+ displayHelp = !!displayHelp;
906
+ this._showHelpAfterError = displayHelp;
907
+ return this;
908
+ }
909
+ showSuggestionAfterError(displaySuggestion = true) {
910
+ this._showSuggestionAfterError = !!displaySuggestion;
911
+ return this;
912
+ }
913
+ addCommand(cmd, opts) {
914
+ if (!cmd._name) {
915
+ throw new Error(`Command passed to .addCommand() must have a name
916
+ - specify the name in Command constructor or using .name()`);
917
+ }
918
+ opts = opts || {};
919
+ if (opts.isDefault)
920
+ this._defaultCommandName = cmd._name;
921
+ if (opts.noHelp || opts.hidden)
922
+ cmd._hidden = true;
923
+ this._registerCommand(cmd);
924
+ cmd.parent = this;
925
+ cmd._checkForBrokenPassThrough();
926
+ return this;
927
+ }
928
+ createArgument(name, description) {
929
+ return new Argument(name, description);
930
+ }
931
+ argument(name, description, parseArg, defaultValue) {
932
+ const argument = this.createArgument(name, description);
933
+ if (typeof parseArg === "function") {
934
+ argument.default(defaultValue).argParser(parseArg);
935
+ } else {
936
+ argument.default(parseArg);
937
+ }
938
+ this.addArgument(argument);
939
+ return this;
940
+ }
941
+ arguments(names) {
942
+ names.trim().split(/ +/).forEach((detail) => {
943
+ this.argument(detail);
944
+ });
945
+ return this;
946
+ }
947
+ addArgument(argument) {
948
+ const previousArgument = this.registeredArguments.slice(-1)[0];
949
+ if (previousArgument?.variadic) {
950
+ throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
951
+ }
952
+ if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
953
+ throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
954
+ }
955
+ this.registeredArguments.push(argument);
956
+ return this;
957
+ }
958
+ helpCommand(enableOrNameAndArgs, description) {
959
+ if (typeof enableOrNameAndArgs === "boolean") {
960
+ this._addImplicitHelpCommand = enableOrNameAndArgs;
961
+ if (enableOrNameAndArgs && this._defaultCommandGroup) {
962
+ this._initCommandGroup(this._getHelpCommand());
629
963
  }
630
- } catch (err) {
631
- err.disconnected = true;
632
- this.emit("error", err);
633
- this.close().catch(() => {});
964
+ return this;
634
965
  }
635
- }, this.#readInterval);
636
- }
637
- #stopReading() {
638
- if (this.#readTimer !== null) {
639
- clearInterval(this.#readTimer);
640
- this.#readTimer = null;
966
+ const nameAndArgs = enableOrNameAndArgs ?? "help [command]";
967
+ const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);
968
+ const helpDescription = description ?? "display help for command";
969
+ const helpCommand = this.createCommand(helpName);
970
+ helpCommand.helpOption(false);
971
+ if (helpArgs)
972
+ helpCommand.arguments(helpArgs);
973
+ if (helpDescription)
974
+ helpCommand.description(helpDescription);
975
+ this._addImplicitHelpCommand = true;
976
+ this._helpCommand = helpCommand;
977
+ if (enableOrNameAndArgs || description)
978
+ this._initCommandGroup(helpCommand);
979
+ return this;
641
980
  }
642
- }
643
- }
644
- // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/list.js
645
- import { platform as platform3 } from "os";
646
- import { readdir, readlink, access } from "fs/promises";
647
- import { join } from "path";
648
- var IS_LINUX3 = platform3() === "linux";
649
- async function exists(path) {
650
- try {
651
- await access(path);
652
- return true;
653
- } catch {
654
- return false;
655
- }
656
- }
657
- async function readFileQuiet(path) {
658
- try {
659
- return (await Bun.file(path).text()).trim();
660
- } catch {
661
- return "";
662
- }
663
- }
664
- async function listLinux() {
665
- const ttys = await readdir("/sys/class/tty").catch(() => []);
666
- const checks = ttys.map(async (name) => {
667
- const sysPath = `/sys/class/tty/${name}`;
668
- const devicePath = join(sysPath, "device");
669
- if (!await exists(devicePath))
670
- return null;
671
- const devPath = `/dev/${name}`;
672
- if (!await exists(devPath))
981
+ addHelpCommand(helpCommand, deprecatedDescription) {
982
+ if (typeof helpCommand !== "object") {
983
+ this.helpCommand(helpCommand, deprecatedDescription);
984
+ return this;
985
+ }
986
+ this._addImplicitHelpCommand = true;
987
+ this._helpCommand = helpCommand;
988
+ this._initCommandGroup(helpCommand);
989
+ return this;
990
+ }
991
+ _getHelpCommand() {
992
+ const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
993
+ if (hasImplicitHelpCommand) {
994
+ if (this._helpCommand === undefined) {
995
+ this.helpCommand(undefined, undefined);
996
+ }
997
+ return this._helpCommand;
998
+ }
673
999
  return null;
674
- return { name, devPath, devicePath };
675
- });
676
- const valid = (await Promise.all(checks)).filter(Boolean);
677
- const ports = await Promise.all(valid.map(async ({ devPath, devicePath }) => {
678
- const info = { path: devPath };
679
- const subsystem = await readlink(join(devicePath, "subsystem")).catch(() => "");
680
- if (subsystem.includes("usb-serial") || subsystem.includes("usb")) {
681
- const usbDevice = await findUsbParent(devicePath);
682
- if (usbDevice) {
683
- const [manufacturer, serialNumber, vendorId, productId, product] = await Promise.all([
684
- readFileQuiet(join(usbDevice, "manufacturer")),
685
- readFileQuiet(join(usbDevice, "serial")),
686
- readFileQuiet(join(usbDevice, "idVendor")),
687
- readFileQuiet(join(usbDevice, "idProduct")),
688
- readFileQuiet(join(usbDevice, "product"))
689
- ]);
690
- info.manufacturer = manufacturer;
691
- info.serialNumber = serialNumber;
692
- info.vendorId = vendorId;
693
- info.productId = productId;
694
- info.product = product;
1000
+ }
1001
+ hook(event, listener) {
1002
+ const allowedValues = ["preSubcommand", "preAction", "postAction"];
1003
+ if (!allowedValues.includes(event)) {
1004
+ throw new Error(`Unexpected value for event passed to hook : '${event}'.
1005
+ Expecting one of '${allowedValues.join("', '")}'`);
1006
+ }
1007
+ if (this._lifeCycleHooks[event]) {
1008
+ this._lifeCycleHooks[event].push(listener);
1009
+ } else {
1010
+ this._lifeCycleHooks[event] = [listener];
695
1011
  }
1012
+ return this;
696
1013
  }
697
- return info;
698
- }));
699
- return ports;
700
- }
701
- async function findUsbParent(devicePath) {
702
- let current = devicePath;
703
- for (let i = 0;i < 10; i++) {
704
- current = join(current, "..");
705
- if (await exists(join(current, "idVendor")))
706
- return current;
707
- }
708
- return null;
709
- }
710
- async function listDarwin() {
711
- const devFiles = await readdir("/dev").catch(() => []);
712
- const seen = new Map;
713
- for (const name of devFiles) {
714
- if (!name.startsWith("cu.") && !name.startsWith("tty."))
715
- continue;
716
- if (name === "tty")
717
- continue;
718
- const isCu = name.startsWith("cu.");
719
- const suffix = name.slice(isCu ? 3 : 4);
720
- if (seen.has(suffix) && !isCu)
721
- continue;
722
- seen.set(suffix, { path: `/dev/${name}` });
723
- }
724
- return [...seen.values()];
725
- }
726
- async function list() {
727
- return IS_LINUX3 ? listLinux() : listDarwin();
728
- }
729
- // src/adapter.ts
730
- import { readdir as readdir2, realpath, readlink as readlink2 } from "fs/promises";
731
- import { join as join2 } from "path";
732
- import { platform as platform4 } from "os";
733
-
734
- class WebSerialPortAdapter extends EventTarget {
735
- onconnect = () => {};
736
- ondisconnect = () => {};
737
- _port = null;
738
- _path;
739
- _info;
740
- _readable = null;
741
- _writable = null;
742
- _readerController = null;
743
- constructor(path, info) {
744
- super();
745
- this._path = path;
746
- this._info = info;
747
- }
748
- get readable() {
749
- return this._readable;
750
- }
751
- get writable() {
752
- return this._writable;
753
- }
754
- getInfo() {
755
- return this._info;
756
- }
757
- async open(options) {
758
- if (this._port)
759
- throw new Error("Port already open");
760
- this._port = new SerialPort({
761
- path: this._path,
762
- baudRate: options.baudRate,
763
- autoOpen: false
764
- });
765
- await this._port.open();
766
- this._readable = new ReadableStream({
767
- start: (controller) => {
768
- this._readerController = controller;
769
- this._port?.on("data", (data) => {
770
- controller.enqueue(data);
771
- });
772
- this._port?.on("error", (err) => {
773
- controller.error(err);
774
- this.close().catch(() => {});
775
- });
776
- },
777
- cancel: () => {
778
- this.close();
1014
+ exitOverride(fn) {
1015
+ if (fn) {
1016
+ this._exitCallback = fn;
1017
+ } else {
1018
+ this._exitCallback = (err) => {
1019
+ if (err.code !== "commander.executeSubCommandAsync") {
1020
+ throw err;
1021
+ }
1022
+ };
779
1023
  }
780
- });
781
- this._writable = new WritableStream({
782
- write: async (chunk) => {
783
- if (!this._port)
784
- throw new Error("Port closed");
785
- await this._port.write(chunk);
786
- },
787
- close: async () => {
788
- await this.close();
1024
+ return this;
1025
+ }
1026
+ _exit(exitCode, code, message) {
1027
+ if (this._exitCallback) {
1028
+ this._exitCallback(new CommanderError(exitCode, code, message));
789
1029
  }
790
- });
791
- }
792
- async close() {
793
- if (!this._port)
794
- return;
795
- const port = this._port;
796
- this._port = null;
797
- if (this._readerController) {
798
- try {
799
- this._readerController.close();
800
- } catch (e) {}
801
- this._readerController = null;
1030
+ process2.exit(exitCode);
802
1031
  }
803
- await port.close();
804
- try {
805
- port.removeAllListeners?.();
806
- } catch (e) {}
807
- this._readable = null;
808
- this._writable = null;
809
- this.dispatchEvent(new Event("disconnect"));
810
- }
811
- async forget() {
812
- await this.close();
813
- }
814
- }
815
-
816
- class WebSerialAdapter extends EventTarget {
817
- onconnect = () => {};
818
- ondisconnect = () => {};
819
- async _listPortsLinux() {
820
- const ttys = await readdir2("/sys/class/tty").catch(() => []);
821
- const ports = [];
822
- for (const name of ttys) {
823
- const sysPath = `/sys/class/tty/${name}`;
824
- const devicePath = join2(sysPath, "device");
1032
+ action(fn) {
1033
+ const listener = (args) => {
1034
+ const expectedArgsCount = this.registeredArguments.length;
1035
+ const actionArgs = args.slice(0, expectedArgsCount);
1036
+ if (this._storeOptionsAsProperties) {
1037
+ actionArgs[expectedArgsCount] = this;
1038
+ } else {
1039
+ actionArgs[expectedArgsCount] = this.opts();
1040
+ }
1041
+ actionArgs.push(this);
1042
+ return fn.apply(this, actionArgs);
1043
+ };
1044
+ this._actionHandler = listener;
1045
+ return this;
1046
+ }
1047
+ createOption(flags, description) {
1048
+ return new Option(flags, description);
1049
+ }
1050
+ _callParseArg(target, value, previous, invalidArgumentMessage) {
825
1051
  try {
826
- const realDevicePath = await realpath(devicePath);
827
- const subsystem = await readlink2(join2(realDevicePath, "subsystem")).catch(() => "");
828
- const info = { path: `/dev/${name}` };
829
- if (subsystem.includes("usb")) {
830
- let current = realDevicePath;
831
- for (let i = 0;i < 5; i++) {
832
- try {
833
- const vendorId = await Bun.file(join2(current, "idVendor")).text().then((t) => t.trim());
834
- const productId = await Bun.file(join2(current, "idProduct")).text().then((t) => t.trim());
835
- info.vendorId = vendorId;
836
- info.productId = productId;
837
- break;
838
- } catch (e) {
839
- current = join2(current, "..");
840
- }
1052
+ return target.parseArg(value, previous);
1053
+ } catch (err) {
1054
+ if (err.code === "commander.invalidArgument") {
1055
+ const message = `${invalidArgumentMessage} ${err.message}`;
1056
+ this.error(message, { exitCode: err.exitCode, code: err.code });
1057
+ }
1058
+ throw err;
1059
+ }
1060
+ }
1061
+ _registerOption(option) {
1062
+ const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
1063
+ if (matchingOption) {
1064
+ const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
1065
+ throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
1066
+ - already used by option '${matchingOption.flags}'`);
1067
+ }
1068
+ this._initOptionGroup(option);
1069
+ this.options.push(option);
1070
+ }
1071
+ _registerCommand(command) {
1072
+ const knownBy = (cmd) => {
1073
+ return [cmd.name()].concat(cmd.aliases());
1074
+ };
1075
+ const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
1076
+ if (alreadyUsed) {
1077
+ const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
1078
+ const newCmd = knownBy(command).join("|");
1079
+ throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
1080
+ }
1081
+ this._initCommandGroup(command);
1082
+ this.commands.push(command);
1083
+ }
1084
+ addOption(option) {
1085
+ this._registerOption(option);
1086
+ const oname = option.name();
1087
+ const name = option.attributeName();
1088
+ if (option.negate) {
1089
+ const positiveLongFlag = option.long.replace(/^--no-/, "--");
1090
+ if (!this._findOption(positiveLongFlag)) {
1091
+ this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, "default");
1092
+ }
1093
+ } else if (option.defaultValue !== undefined) {
1094
+ this.setOptionValueWithSource(name, option.defaultValue, "default");
1095
+ }
1096
+ const handleOptionValue = (val, invalidValueMessage, valueSource) => {
1097
+ if (val == null && option.presetArg !== undefined) {
1098
+ val = option.presetArg;
1099
+ }
1100
+ const oldValue = this.getOptionValue(name);
1101
+ if (val !== null && option.parseArg) {
1102
+ val = this._callParseArg(option, val, oldValue, invalidValueMessage);
1103
+ } else if (val !== null && option.variadic) {
1104
+ val = option._collectValue(val, oldValue);
1105
+ }
1106
+ if (val == null) {
1107
+ if (option.negate) {
1108
+ val = false;
1109
+ } else if (option.isBoolean() || option.optional) {
1110
+ val = true;
1111
+ } else {
1112
+ val = "";
841
1113
  }
842
1114
  }
843
- ports.push(info);
844
- } catch (e) {}
1115
+ this.setOptionValueWithSource(name, val, valueSource);
1116
+ };
1117
+ this.on("option:" + oname, (val) => {
1118
+ const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
1119
+ handleOptionValue(val, invalidValueMessage, "cli");
1120
+ });
1121
+ if (option.envVar) {
1122
+ this.on("optionEnv:" + oname, (val) => {
1123
+ const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
1124
+ handleOptionValue(val, invalidValueMessage, "env");
1125
+ });
1126
+ }
1127
+ return this;
845
1128
  }
846
- return ports;
847
- }
848
- async getPorts() {
849
- const ports = platform4() === "linux" ? await this._listPortsLinux() : await list();
850
- return ports.map((p) => new WebSerialPortAdapter(p.path, {
851
- usbVendorId: p.vendorId ? parseInt(p.vendorId, 16) : undefined,
852
- usbProductId: p.productId ? parseInt(p.productId, 16) : undefined
853
- }));
854
- }
855
- async requestPort(options) {
856
- const ports = await this.getPorts();
857
- if (options?.filters && options.filters.length > 0) {
858
- const filtered = ports.filter((p) => {
859
- const info = p.getInfo();
860
- return options.filters?.some((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
1129
+ _optionEx(config, flags, description, fn, defaultValue) {
1130
+ if (typeof flags === "object" && flags instanceof Option) {
1131
+ throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
1132
+ }
1133
+ const option = this.createOption(flags, description);
1134
+ option.makeOptionMandatory(!!config.mandatory);
1135
+ if (typeof fn === "function") {
1136
+ option.default(defaultValue).argParser(fn);
1137
+ } else if (fn instanceof RegExp) {
1138
+ const regex = fn;
1139
+ fn = (val, def) => {
1140
+ const m = regex.exec(val);
1141
+ return m ? m[0] : def;
1142
+ };
1143
+ option.default(defaultValue).argParser(fn);
1144
+ } else {
1145
+ option.default(fn);
1146
+ }
1147
+ return this.addOption(option);
1148
+ }
1149
+ option(flags, description, parseArg, defaultValue) {
1150
+ return this._optionEx({}, flags, description, parseArg, defaultValue);
1151
+ }
1152
+ requiredOption(flags, description, parseArg, defaultValue) {
1153
+ return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
1154
+ }
1155
+ combineFlagAndOptionalValue(combine = true) {
1156
+ this._combineFlagAndOptionalValue = !!combine;
1157
+ return this;
1158
+ }
1159
+ allowUnknownOption(allowUnknown = true) {
1160
+ this._allowUnknownOption = !!allowUnknown;
1161
+ return this;
1162
+ }
1163
+ allowExcessArguments(allowExcess = true) {
1164
+ this._allowExcessArguments = !!allowExcess;
1165
+ return this;
1166
+ }
1167
+ enablePositionalOptions(positional = true) {
1168
+ this._enablePositionalOptions = !!positional;
1169
+ return this;
1170
+ }
1171
+ passThroughOptions(passThrough = true) {
1172
+ this._passThroughOptions = !!passThrough;
1173
+ this._checkForBrokenPassThrough();
1174
+ return this;
1175
+ }
1176
+ _checkForBrokenPassThrough() {
1177
+ if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
1178
+ throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
1179
+ }
1180
+ }
1181
+ storeOptionsAsProperties(storeAsProperties = true) {
1182
+ if (this.options.length) {
1183
+ throw new Error("call .storeOptionsAsProperties() before adding options");
1184
+ }
1185
+ if (Object.keys(this._optionValues).length) {
1186
+ throw new Error("call .storeOptionsAsProperties() before setting option values");
1187
+ }
1188
+ this._storeOptionsAsProperties = !!storeAsProperties;
1189
+ return this;
1190
+ }
1191
+ getOptionValue(key) {
1192
+ if (this._storeOptionsAsProperties) {
1193
+ return this[key];
1194
+ }
1195
+ return this._optionValues[key];
1196
+ }
1197
+ setOptionValue(key, value) {
1198
+ return this.setOptionValueWithSource(key, value, undefined);
1199
+ }
1200
+ setOptionValueWithSource(key, value, source) {
1201
+ if (this._storeOptionsAsProperties) {
1202
+ this[key] = value;
1203
+ } else {
1204
+ this._optionValues[key] = value;
1205
+ }
1206
+ this._optionValueSources[key] = source;
1207
+ return this;
1208
+ }
1209
+ getOptionValueSource(key) {
1210
+ return this._optionValueSources[key];
1211
+ }
1212
+ getOptionValueSourceWithGlobals(key) {
1213
+ let source;
1214
+ this._getCommandAndAncestors().forEach((cmd) => {
1215
+ if (cmd.getOptionValueSource(key) !== undefined) {
1216
+ source = cmd.getOptionValueSource(key);
1217
+ }
861
1218
  });
862
- if (filtered.length > 0)
863
- return filtered[0];
864
- throw new Error("No port found matching filters");
1219
+ return source;
865
1220
  }
866
- if (ports.length > 0)
867
- return ports[0];
868
- throw new Error("No port found");
869
- }
870
- }
871
- var serial = new WebSerialAdapter;
872
-
873
- // ../serial/src/Vex.ts
874
- var USER_PROG_CHUNK_SIZE = 4096;
875
- var USER_FLASH_USR_CODE_START = 58720256;
876
- // ../serial/src/VexEvent.ts
877
- class VexEventEmitter {
878
- handlerMap;
879
- constructor() {
880
- this.handlerMap = new Map;
881
- }
882
- on(eventName, listener) {
883
- let listeners = this.handlerMap.get(eventName);
884
- listeners ??= [];
885
- listeners.push(listener);
886
- this.handlerMap.set(eventName, listeners);
887
- }
888
- remove(eventName, listener) {
889
- let listeners = this.handlerMap.get(eventName);
890
- listeners ??= [];
891
- const index = listeners.indexOf(listener);
892
- if (index > -1) {
893
- listeners.splice(index, 1);
1221
+ _prepareUserArgs(argv, parseOptions) {
1222
+ if (argv !== undefined && !Array.isArray(argv)) {
1223
+ throw new Error("first parameter to parse must be array or undefined");
1224
+ }
1225
+ parseOptions = parseOptions || {};
1226
+ if (argv === undefined && parseOptions.from === undefined) {
1227
+ if (process2.versions?.electron) {
1228
+ parseOptions.from = "electron";
1229
+ }
1230
+ const execArgv = process2.execArgv ?? [];
1231
+ if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
1232
+ parseOptions.from = "eval";
1233
+ }
1234
+ }
1235
+ if (argv === undefined) {
1236
+ argv = process2.argv;
1237
+ }
1238
+ this.rawArgs = argv.slice();
1239
+ let userArgs;
1240
+ switch (parseOptions.from) {
1241
+ case undefined:
1242
+ case "node":
1243
+ this._scriptPath = argv[1];
1244
+ userArgs = argv.slice(2);
1245
+ break;
1246
+ case "electron":
1247
+ if (process2.defaultApp) {
1248
+ this._scriptPath = argv[1];
1249
+ userArgs = argv.slice(2);
1250
+ } else {
1251
+ userArgs = argv.slice(1);
1252
+ }
1253
+ break;
1254
+ case "user":
1255
+ userArgs = argv.slice(0);
1256
+ break;
1257
+ case "eval":
1258
+ userArgs = argv.slice(1);
1259
+ break;
1260
+ default:
1261
+ throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
1262
+ }
1263
+ if (!this._name && this._scriptPath)
1264
+ this.nameFromFilename(this._scriptPath);
1265
+ this._name = this._name || "program";
1266
+ return userArgs;
1267
+ }
1268
+ parse(argv, parseOptions) {
1269
+ this._prepareForParse();
1270
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
1271
+ this._parseCommand([], userArgs);
1272
+ return this;
1273
+ }
1274
+ async parseAsync(argv, parseOptions) {
1275
+ this._prepareForParse();
1276
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
1277
+ await this._parseCommand([], userArgs);
1278
+ return this;
1279
+ }
1280
+ _prepareForParse() {
1281
+ if (this._savedState === null) {
1282
+ this.saveStateBeforeParse();
1283
+ } else {
1284
+ this.restoreStateBeforeParse();
1285
+ }
1286
+ }
1287
+ saveStateBeforeParse() {
1288
+ this._savedState = {
1289
+ _name: this._name,
1290
+ _optionValues: { ...this._optionValues },
1291
+ _optionValueSources: { ...this._optionValueSources }
1292
+ };
1293
+ }
1294
+ restoreStateBeforeParse() {
1295
+ if (this._storeOptionsAsProperties)
1296
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
1297
+ - either make a new Command for each call to parse, or stop storing options as properties`);
1298
+ this._name = this._savedState._name;
1299
+ this._scriptPath = null;
1300
+ this.rawArgs = [];
1301
+ this._optionValues = { ...this._savedState._optionValues };
1302
+ this._optionValueSources = { ...this._savedState._optionValueSources };
1303
+ this.args = [];
1304
+ this.processedArgs = [];
1305
+ }
1306
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
1307
+ if (fs.existsSync(executableFile))
1308
+ return;
1309
+ const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
1310
+ const executableMissing = `'${executableFile}' does not exist
1311
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1312
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1313
+ - ${executableDirMessage}`;
1314
+ throw new Error(executableMissing);
1315
+ }
1316
+ _executeSubCommand(subcommand, args) {
1317
+ args = args.slice();
1318
+ let launchWithNode = false;
1319
+ const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1320
+ function findFile(baseDir, baseName) {
1321
+ const localBin = path.resolve(baseDir, baseName);
1322
+ if (fs.existsSync(localBin))
1323
+ return localBin;
1324
+ if (sourceExt.includes(path.extname(baseName)))
1325
+ return;
1326
+ const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
1327
+ if (foundExt)
1328
+ return `${localBin}${foundExt}`;
1329
+ return;
1330
+ }
1331
+ this._checkForMissingMandatoryOptions();
1332
+ this._checkForConflictingOptions();
1333
+ let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
1334
+ let executableDir = this._executableDir || "";
1335
+ if (this._scriptPath) {
1336
+ let resolvedScriptPath;
1337
+ try {
1338
+ resolvedScriptPath = fs.realpathSync(this._scriptPath);
1339
+ } catch {
1340
+ resolvedScriptPath = this._scriptPath;
1341
+ }
1342
+ executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
1343
+ }
1344
+ if (executableDir) {
1345
+ let localFile = findFile(executableDir, executableFile);
1346
+ if (!localFile && !subcommand._executableFile && this._scriptPath) {
1347
+ const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
1348
+ if (legacyName !== this._name) {
1349
+ localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
1350
+ }
1351
+ }
1352
+ executableFile = localFile || executableFile;
1353
+ }
1354
+ launchWithNode = sourceExt.includes(path.extname(executableFile));
1355
+ let proc;
1356
+ if (process2.platform !== "win32") {
1357
+ if (launchWithNode) {
1358
+ args.unshift(executableFile);
1359
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1360
+ proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
1361
+ } else {
1362
+ proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1363
+ }
1364
+ } else {
1365
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1366
+ args.unshift(executableFile);
1367
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1368
+ proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
1369
+ }
1370
+ if (!proc.killed) {
1371
+ const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
1372
+ signals.forEach((signal) => {
1373
+ process2.on(signal, () => {
1374
+ if (proc.killed === false && proc.exitCode === null) {
1375
+ proc.kill(signal);
1376
+ }
1377
+ });
1378
+ });
1379
+ }
1380
+ const exitCallback = this._exitCallback;
1381
+ proc.on("close", (code) => {
1382
+ code = code ?? 1;
1383
+ if (!exitCallback) {
1384
+ process2.exit(code);
1385
+ } else {
1386
+ exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
1387
+ }
1388
+ });
1389
+ proc.on("error", (err) => {
1390
+ if (err.code === "ENOENT") {
1391
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1392
+ } else if (err.code === "EACCES") {
1393
+ throw new Error(`'${executableFile}' not executable`);
1394
+ }
1395
+ if (!exitCallback) {
1396
+ process2.exit(1);
1397
+ } else {
1398
+ const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
1399
+ wrappedError.nestedError = err;
1400
+ exitCallback(wrappedError);
1401
+ }
1402
+ });
1403
+ this.runningCommand = proc;
1404
+ }
1405
+ _dispatchSubcommand(commandName, operands, unknown) {
1406
+ const subCommand = this._findCommand(commandName);
1407
+ if (!subCommand)
1408
+ this.help({ error: true });
1409
+ subCommand._prepareForParse();
1410
+ let promiseChain;
1411
+ promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
1412
+ promiseChain = this._chainOrCall(promiseChain, () => {
1413
+ if (subCommand._executableHandler) {
1414
+ this._executeSubCommand(subCommand, operands.concat(unknown));
1415
+ } else {
1416
+ return subCommand._parseCommand(operands, unknown);
1417
+ }
1418
+ });
1419
+ return promiseChain;
1420
+ }
1421
+ _dispatchHelpCommand(subcommandName) {
1422
+ if (!subcommandName) {
1423
+ this.help();
1424
+ }
1425
+ const subCommand = this._findCommand(subcommandName);
1426
+ if (subCommand && !subCommand._executableHandler) {
1427
+ subCommand.help();
1428
+ }
1429
+ return this._dispatchSubcommand(subcommandName, [], [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]);
1430
+ }
1431
+ _checkNumberOfArguments() {
1432
+ this.registeredArguments.forEach((arg, i) => {
1433
+ if (arg.required && this.args[i] == null) {
1434
+ this.missingArgument(arg.name());
1435
+ }
1436
+ });
1437
+ if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
1438
+ return;
1439
+ }
1440
+ if (this.args.length > this.registeredArguments.length) {
1441
+ this._excessArguments(this.args);
1442
+ }
1443
+ }
1444
+ _processArguments() {
1445
+ const myParseArg = (argument, value, previous) => {
1446
+ let parsedValue = value;
1447
+ if (value !== null && argument.parseArg) {
1448
+ const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
1449
+ parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
1450
+ }
1451
+ return parsedValue;
1452
+ };
1453
+ this._checkNumberOfArguments();
1454
+ const processedArgs = [];
1455
+ this.registeredArguments.forEach((declaredArg, index) => {
1456
+ let value = declaredArg.defaultValue;
1457
+ if (declaredArg.variadic) {
1458
+ if (index < this.args.length) {
1459
+ value = this.args.slice(index);
1460
+ if (declaredArg.parseArg) {
1461
+ value = value.reduce((processed, v) => {
1462
+ return myParseArg(declaredArg, v, processed);
1463
+ }, declaredArg.defaultValue);
1464
+ }
1465
+ } else if (value === undefined) {
1466
+ value = [];
1467
+ }
1468
+ } else if (index < this.args.length) {
1469
+ value = this.args[index];
1470
+ if (declaredArg.parseArg) {
1471
+ value = myParseArg(declaredArg, value, declaredArg.defaultValue);
1472
+ }
1473
+ }
1474
+ processedArgs[index] = value;
1475
+ });
1476
+ this.processedArgs = processedArgs;
1477
+ }
1478
+ _chainOrCall(promise, fn) {
1479
+ if (promise?.then && typeof promise.then === "function") {
1480
+ return promise.then(() => fn());
1481
+ }
1482
+ return fn();
1483
+ }
1484
+ _chainOrCallHooks(promise, event) {
1485
+ let result = promise;
1486
+ const hooks = [];
1487
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== undefined).forEach((hookedCommand) => {
1488
+ hookedCommand._lifeCycleHooks[event].forEach((callback) => {
1489
+ hooks.push({ hookedCommand, callback });
1490
+ });
1491
+ });
1492
+ if (event === "postAction") {
1493
+ hooks.reverse();
1494
+ }
1495
+ hooks.forEach((hookDetail) => {
1496
+ result = this._chainOrCall(result, () => {
1497
+ return hookDetail.callback(hookDetail.hookedCommand, this);
1498
+ });
1499
+ });
1500
+ return result;
1501
+ }
1502
+ _chainOrCallSubCommandHook(promise, subCommand, event) {
1503
+ let result = promise;
1504
+ if (this._lifeCycleHooks[event] !== undefined) {
1505
+ this._lifeCycleHooks[event].forEach((hook) => {
1506
+ result = this._chainOrCall(result, () => {
1507
+ return hook(this, subCommand);
1508
+ });
1509
+ });
1510
+ }
1511
+ return result;
1512
+ }
1513
+ _parseCommand(operands, unknown) {
1514
+ const parsed = this.parseOptions(unknown);
1515
+ this._parseOptionsEnv();
1516
+ this._parseOptionsImplied();
1517
+ operands = operands.concat(parsed.operands);
1518
+ unknown = parsed.unknown;
1519
+ this.args = operands.concat(unknown);
1520
+ if (operands && this._findCommand(operands[0])) {
1521
+ return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
1522
+ }
1523
+ if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
1524
+ return this._dispatchHelpCommand(operands[1]);
1525
+ }
1526
+ if (this._defaultCommandName) {
1527
+ this._outputHelpIfRequested(unknown);
1528
+ return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
1529
+ }
1530
+ if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
1531
+ this.help({ error: true });
1532
+ }
1533
+ this._outputHelpIfRequested(parsed.unknown);
1534
+ this._checkForMissingMandatoryOptions();
1535
+ this._checkForConflictingOptions();
1536
+ const checkForUnknownOptions = () => {
1537
+ if (parsed.unknown.length > 0) {
1538
+ this.unknownOption(parsed.unknown[0]);
1539
+ }
1540
+ };
1541
+ const commandEvent = `command:${this.name()}`;
1542
+ if (this._actionHandler) {
1543
+ checkForUnknownOptions();
1544
+ this._processArguments();
1545
+ let promiseChain;
1546
+ promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
1547
+ promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
1548
+ if (this.parent) {
1549
+ promiseChain = this._chainOrCall(promiseChain, () => {
1550
+ this.parent.emit(commandEvent, operands, unknown);
1551
+ });
1552
+ }
1553
+ promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
1554
+ return promiseChain;
1555
+ }
1556
+ if (this.parent?.listenerCount(commandEvent)) {
1557
+ checkForUnknownOptions();
1558
+ this._processArguments();
1559
+ this.parent.emit(commandEvent, operands, unknown);
1560
+ } else if (operands.length) {
1561
+ if (this._findCommand("*")) {
1562
+ return this._dispatchSubcommand("*", operands, unknown);
1563
+ }
1564
+ if (this.listenerCount("command:*")) {
1565
+ this.emit("command:*", operands, unknown);
1566
+ } else if (this.commands.length) {
1567
+ this.unknownCommand();
1568
+ } else {
1569
+ checkForUnknownOptions();
1570
+ this._processArguments();
1571
+ }
1572
+ } else if (this.commands.length) {
1573
+ checkForUnknownOptions();
1574
+ this.help({ error: true });
1575
+ } else {
1576
+ checkForUnknownOptions();
1577
+ this._processArguments();
1578
+ }
1579
+ }
1580
+ _findCommand(name) {
1581
+ if (!name)
1582
+ return;
1583
+ return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
1584
+ }
1585
+ _findOption(arg) {
1586
+ return this.options.find((option) => option.is(arg));
1587
+ }
1588
+ _checkForMissingMandatoryOptions() {
1589
+ this._getCommandAndAncestors().forEach((cmd) => {
1590
+ cmd.options.forEach((anOption) => {
1591
+ if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === undefined) {
1592
+ cmd.missingMandatoryOptionValue(anOption);
1593
+ }
1594
+ });
1595
+ });
1596
+ }
1597
+ _checkForConflictingLocalOptions() {
1598
+ const definedNonDefaultOptions = this.options.filter((option) => {
1599
+ const optionKey = option.attributeName();
1600
+ if (this.getOptionValue(optionKey) === undefined) {
1601
+ return false;
1602
+ }
1603
+ return this.getOptionValueSource(optionKey) !== "default";
1604
+ });
1605
+ const optionsWithConflicting = definedNonDefaultOptions.filter((option) => option.conflictsWith.length > 0);
1606
+ optionsWithConflicting.forEach((option) => {
1607
+ const conflictingAndDefined = definedNonDefaultOptions.find((defined) => option.conflictsWith.includes(defined.attributeName()));
1608
+ if (conflictingAndDefined) {
1609
+ this._conflictingOption(option, conflictingAndDefined);
1610
+ }
1611
+ });
1612
+ }
1613
+ _checkForConflictingOptions() {
1614
+ this._getCommandAndAncestors().forEach((cmd) => {
1615
+ cmd._checkForConflictingLocalOptions();
1616
+ });
1617
+ }
1618
+ parseOptions(args) {
1619
+ const operands = [];
1620
+ const unknown = [];
1621
+ let dest = operands;
1622
+ function maybeOption(arg) {
1623
+ return arg.length > 1 && arg[0] === "-";
1624
+ }
1625
+ const negativeNumberArg = (arg) => {
1626
+ if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg))
1627
+ return false;
1628
+ return !this._getCommandAndAncestors().some((cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short)));
1629
+ };
1630
+ let activeVariadicOption = null;
1631
+ let activeGroup = null;
1632
+ let i = 0;
1633
+ while (i < args.length || activeGroup) {
1634
+ const arg = activeGroup ?? args[i++];
1635
+ activeGroup = null;
1636
+ if (arg === "--") {
1637
+ if (dest === unknown)
1638
+ dest.push(arg);
1639
+ dest.push(...args.slice(i));
1640
+ break;
1641
+ }
1642
+ if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
1643
+ this.emit(`option:${activeVariadicOption.name()}`, arg);
1644
+ continue;
1645
+ }
1646
+ activeVariadicOption = null;
1647
+ if (maybeOption(arg)) {
1648
+ const option = this._findOption(arg);
1649
+ if (option) {
1650
+ if (option.required) {
1651
+ const value = args[i++];
1652
+ if (value === undefined)
1653
+ this.optionMissingArgument(option);
1654
+ this.emit(`option:${option.name()}`, value);
1655
+ } else if (option.optional) {
1656
+ let value = null;
1657
+ if (i < args.length && (!maybeOption(args[i]) || negativeNumberArg(args[i]))) {
1658
+ value = args[i++];
1659
+ }
1660
+ this.emit(`option:${option.name()}`, value);
1661
+ } else {
1662
+ this.emit(`option:${option.name()}`);
1663
+ }
1664
+ activeVariadicOption = option.variadic ? option : null;
1665
+ continue;
1666
+ }
1667
+ }
1668
+ if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
1669
+ const option = this._findOption(`-${arg[1]}`);
1670
+ if (option) {
1671
+ if (option.required || option.optional && this._combineFlagAndOptionalValue) {
1672
+ this.emit(`option:${option.name()}`, arg.slice(2));
1673
+ } else {
1674
+ this.emit(`option:${option.name()}`);
1675
+ activeGroup = `-${arg.slice(2)}`;
1676
+ }
1677
+ continue;
1678
+ }
1679
+ }
1680
+ if (/^--[^=]+=/.test(arg)) {
1681
+ const index = arg.indexOf("=");
1682
+ const option = this._findOption(arg.slice(0, index));
1683
+ if (option && (option.required || option.optional)) {
1684
+ this.emit(`option:${option.name()}`, arg.slice(index + 1));
1685
+ continue;
1686
+ }
1687
+ }
1688
+ if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
1689
+ dest = unknown;
1690
+ }
1691
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
1692
+ if (this._findCommand(arg)) {
1693
+ operands.push(arg);
1694
+ unknown.push(...args.slice(i));
1695
+ break;
1696
+ } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
1697
+ operands.push(arg, ...args.slice(i));
1698
+ break;
1699
+ } else if (this._defaultCommandName) {
1700
+ unknown.push(arg, ...args.slice(i));
1701
+ break;
1702
+ }
1703
+ }
1704
+ if (this._passThroughOptions) {
1705
+ dest.push(arg, ...args.slice(i));
1706
+ break;
1707
+ }
1708
+ dest.push(arg);
1709
+ }
1710
+ return { operands, unknown };
1711
+ }
1712
+ opts() {
1713
+ if (this._storeOptionsAsProperties) {
1714
+ const result = {};
1715
+ const len = this.options.length;
1716
+ for (let i = 0;i < len; i++) {
1717
+ const key = this.options[i].attributeName();
1718
+ result[key] = key === this._versionOptionName ? this._version : this[key];
1719
+ }
1720
+ return result;
1721
+ }
1722
+ return this._optionValues;
1723
+ }
1724
+ optsWithGlobals() {
1725
+ return this._getCommandAndAncestors().reduce((combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()), {});
1726
+ }
1727
+ error(message, errorOptions) {
1728
+ this._outputConfiguration.outputError(`${message}
1729
+ `, this._outputConfiguration.writeErr);
1730
+ if (typeof this._showHelpAfterError === "string") {
1731
+ this._outputConfiguration.writeErr(`${this._showHelpAfterError}
1732
+ `);
1733
+ } else if (this._showHelpAfterError) {
1734
+ this._outputConfiguration.writeErr(`
1735
+ `);
1736
+ this.outputHelp({ error: true });
1737
+ }
1738
+ const config = errorOptions || {};
1739
+ const exitCode = config.exitCode || 1;
1740
+ const code = config.code || "commander.error";
1741
+ this._exit(exitCode, code, message);
1742
+ }
1743
+ _parseOptionsEnv() {
1744
+ this.options.forEach((option) => {
1745
+ if (option.envVar && option.envVar in process2.env) {
1746
+ const optionKey = option.attributeName();
1747
+ if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
1748
+ if (option.required || option.optional) {
1749
+ this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
1750
+ } else {
1751
+ this.emit(`optionEnv:${option.name()}`);
1752
+ }
1753
+ }
1754
+ }
1755
+ });
1756
+ }
1757
+ _parseOptionsImplied() {
1758
+ const dualHelper = new DualOptions(this.options);
1759
+ const hasCustomOptionValue = (optionKey) => {
1760
+ return this.getOptionValue(optionKey) !== undefined && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
1761
+ };
1762
+ this.options.filter((option) => option.implied !== undefined && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
1763
+ Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
1764
+ this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
1765
+ });
1766
+ });
1767
+ }
1768
+ missingArgument(name) {
1769
+ const message = `error: missing required argument '${name}'`;
1770
+ this.error(message, { code: "commander.missingArgument" });
1771
+ }
1772
+ optionMissingArgument(option) {
1773
+ const message = `error: option '${option.flags}' argument missing`;
1774
+ this.error(message, { code: "commander.optionMissingArgument" });
1775
+ }
1776
+ missingMandatoryOptionValue(option) {
1777
+ const message = `error: required option '${option.flags}' not specified`;
1778
+ this.error(message, { code: "commander.missingMandatoryOptionValue" });
1779
+ }
1780
+ _conflictingOption(option, conflictingOption) {
1781
+ const findBestOptionFromValue = (option2) => {
1782
+ const optionKey = option2.attributeName();
1783
+ const optionValue = this.getOptionValue(optionKey);
1784
+ const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
1785
+ const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
1786
+ if (negativeOption && (negativeOption.presetArg === undefined && optionValue === false || negativeOption.presetArg !== undefined && optionValue === negativeOption.presetArg)) {
1787
+ return negativeOption;
1788
+ }
1789
+ return positiveOption || option2;
1790
+ };
1791
+ const getErrorMessage = (option2) => {
1792
+ const bestOption = findBestOptionFromValue(option2);
1793
+ const optionKey = bestOption.attributeName();
1794
+ const source = this.getOptionValueSource(optionKey);
1795
+ if (source === "env") {
1796
+ return `environment variable '${bestOption.envVar}'`;
1797
+ }
1798
+ return `option '${bestOption.flags}'`;
1799
+ };
1800
+ const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
1801
+ this.error(message, { code: "commander.conflictingOption" });
1802
+ }
1803
+ unknownOption(flag) {
1804
+ if (this._allowUnknownOption)
1805
+ return;
1806
+ let suggestion = "";
1807
+ if (flag.startsWith("--") && this._showSuggestionAfterError) {
1808
+ let candidateFlags = [];
1809
+ let command = this;
1810
+ do {
1811
+ const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
1812
+ candidateFlags = candidateFlags.concat(moreFlags);
1813
+ command = command.parent;
1814
+ } while (command && !command._enablePositionalOptions);
1815
+ suggestion = suggestSimilar(flag, candidateFlags);
1816
+ }
1817
+ const message = `error: unknown option '${flag}'${suggestion}`;
1818
+ this.error(message, { code: "commander.unknownOption" });
1819
+ }
1820
+ _excessArguments(receivedArgs) {
1821
+ if (this._allowExcessArguments)
1822
+ return;
1823
+ const expected = this.registeredArguments.length;
1824
+ const s = expected === 1 ? "" : "s";
1825
+ const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
1826
+ const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
1827
+ this.error(message, { code: "commander.excessArguments" });
1828
+ }
1829
+ unknownCommand() {
1830
+ const unknownName = this.args[0];
1831
+ let suggestion = "";
1832
+ if (this._showSuggestionAfterError) {
1833
+ const candidateNames = [];
1834
+ this.createHelp().visibleCommands(this).forEach((command) => {
1835
+ candidateNames.push(command.name());
1836
+ if (command.alias())
1837
+ candidateNames.push(command.alias());
1838
+ });
1839
+ suggestion = suggestSimilar(unknownName, candidateNames);
1840
+ }
1841
+ const message = `error: unknown command '${unknownName}'${suggestion}`;
1842
+ this.error(message, { code: "commander.unknownCommand" });
1843
+ }
1844
+ version(str, flags, description) {
1845
+ if (str === undefined)
1846
+ return this._version;
1847
+ this._version = str;
1848
+ flags = flags || "-V, --version";
1849
+ description = description || "output the version number";
1850
+ const versionOption = this.createOption(flags, description);
1851
+ this._versionOptionName = versionOption.attributeName();
1852
+ this._registerOption(versionOption);
1853
+ this.on("option:" + versionOption.name(), () => {
1854
+ this._outputConfiguration.writeOut(`${str}
1855
+ `);
1856
+ this._exit(0, "commander.version", str);
1857
+ });
1858
+ return this;
1859
+ }
1860
+ description(str, argsDescription) {
1861
+ if (str === undefined && argsDescription === undefined)
1862
+ return this._description;
1863
+ this._description = str;
1864
+ if (argsDescription) {
1865
+ this._argsDescription = argsDescription;
1866
+ }
1867
+ return this;
1868
+ }
1869
+ summary(str) {
1870
+ if (str === undefined)
1871
+ return this._summary;
1872
+ this._summary = str;
1873
+ return this;
1874
+ }
1875
+ alias(alias) {
1876
+ if (alias === undefined)
1877
+ return this._aliases[0];
1878
+ let command = this;
1879
+ if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
1880
+ command = this.commands[this.commands.length - 1];
1881
+ }
1882
+ if (alias === command._name)
1883
+ throw new Error("Command alias can't be the same as its name");
1884
+ const matchingCommand = this.parent?._findCommand(alias);
1885
+ if (matchingCommand) {
1886
+ const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
1887
+ throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
1888
+ }
1889
+ command._aliases.push(alias);
1890
+ return this;
1891
+ }
1892
+ aliases(aliases) {
1893
+ if (aliases === undefined)
1894
+ return this._aliases;
1895
+ aliases.forEach((alias) => this.alias(alias));
1896
+ return this;
1897
+ }
1898
+ usage(str) {
1899
+ if (str === undefined) {
1900
+ if (this._usage)
1901
+ return this._usage;
1902
+ const args = this.registeredArguments.map((arg) => {
1903
+ return humanReadableArgName(arg);
1904
+ });
1905
+ return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
1906
+ }
1907
+ this._usage = str;
1908
+ return this;
1909
+ }
1910
+ name(str) {
1911
+ if (str === undefined)
1912
+ return this._name;
1913
+ this._name = str;
1914
+ return this;
1915
+ }
1916
+ helpGroup(heading) {
1917
+ if (heading === undefined)
1918
+ return this._helpGroupHeading ?? "";
1919
+ this._helpGroupHeading = heading;
1920
+ return this;
1921
+ }
1922
+ commandsGroup(heading) {
1923
+ if (heading === undefined)
1924
+ return this._defaultCommandGroup ?? "";
1925
+ this._defaultCommandGroup = heading;
1926
+ return this;
1927
+ }
1928
+ optionsGroup(heading) {
1929
+ if (heading === undefined)
1930
+ return this._defaultOptionGroup ?? "";
1931
+ this._defaultOptionGroup = heading;
1932
+ return this;
1933
+ }
1934
+ _initOptionGroup(option) {
1935
+ if (this._defaultOptionGroup && !option.helpGroupHeading)
1936
+ option.helpGroup(this._defaultOptionGroup);
1937
+ }
1938
+ _initCommandGroup(cmd) {
1939
+ if (this._defaultCommandGroup && !cmd.helpGroup())
1940
+ cmd.helpGroup(this._defaultCommandGroup);
1941
+ }
1942
+ nameFromFilename(filename) {
1943
+ this._name = path.basename(filename, path.extname(filename));
1944
+ return this;
1945
+ }
1946
+ executableDir(path2) {
1947
+ if (path2 === undefined)
1948
+ return this._executableDir;
1949
+ this._executableDir = path2;
1950
+ return this;
1951
+ }
1952
+ helpInformation(contextOptions) {
1953
+ const helper = this.createHelp();
1954
+ const context = this._getOutputContext(contextOptions);
1955
+ helper.prepareContext({
1956
+ error: context.error,
1957
+ helpWidth: context.helpWidth,
1958
+ outputHasColors: context.hasColors
1959
+ });
1960
+ const text = helper.formatHelp(this, helper);
1961
+ if (context.hasColors)
1962
+ return text;
1963
+ return this._outputConfiguration.stripColor(text);
1964
+ }
1965
+ _getOutputContext(contextOptions) {
1966
+ contextOptions = contextOptions || {};
1967
+ const error = !!contextOptions.error;
1968
+ let baseWrite;
1969
+ let hasColors;
1970
+ let helpWidth;
1971
+ if (error) {
1972
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
1973
+ hasColors = this._outputConfiguration.getErrHasColors();
1974
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
1975
+ } else {
1976
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
1977
+ hasColors = this._outputConfiguration.getOutHasColors();
1978
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
1979
+ }
1980
+ const write = (str) => {
1981
+ if (!hasColors)
1982
+ str = this._outputConfiguration.stripColor(str);
1983
+ return baseWrite(str);
1984
+ };
1985
+ return { error, write, hasColors, helpWidth };
1986
+ }
1987
+ outputHelp(contextOptions) {
1988
+ let deprecatedCallback;
1989
+ if (typeof contextOptions === "function") {
1990
+ deprecatedCallback = contextOptions;
1991
+ contextOptions = undefined;
1992
+ }
1993
+ const outputContext = this._getOutputContext(contextOptions);
1994
+ const eventContext = {
1995
+ error: outputContext.error,
1996
+ write: outputContext.write,
1997
+ command: this
1998
+ };
1999
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
2000
+ this.emit("beforeHelp", eventContext);
2001
+ let helpInformation = this.helpInformation({ error: outputContext.error });
2002
+ if (deprecatedCallback) {
2003
+ helpInformation = deprecatedCallback(helpInformation);
2004
+ if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
2005
+ throw new Error("outputHelp callback must return a string or a Buffer");
2006
+ }
2007
+ }
2008
+ outputContext.write(helpInformation);
2009
+ if (this._getHelpOption()?.long) {
2010
+ this.emit(this._getHelpOption().long);
2011
+ }
2012
+ this.emit("afterHelp", eventContext);
2013
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
2014
+ }
2015
+ helpOption(flags, description) {
2016
+ if (typeof flags === "boolean") {
2017
+ if (flags) {
2018
+ if (this._helpOption === null)
2019
+ this._helpOption = undefined;
2020
+ if (this._defaultOptionGroup) {
2021
+ this._initOptionGroup(this._getHelpOption());
2022
+ }
2023
+ } else {
2024
+ this._helpOption = null;
2025
+ }
2026
+ return this;
2027
+ }
2028
+ this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
2029
+ if (flags || description)
2030
+ this._initOptionGroup(this._helpOption);
2031
+ return this;
2032
+ }
2033
+ _getHelpOption() {
2034
+ if (this._helpOption === undefined) {
2035
+ this.helpOption(undefined, undefined);
2036
+ }
2037
+ return this._helpOption;
2038
+ }
2039
+ addHelpOption(option) {
2040
+ this._helpOption = option;
2041
+ this._initOptionGroup(option);
2042
+ return this;
2043
+ }
2044
+ help(contextOptions) {
2045
+ this.outputHelp(contextOptions);
2046
+ let exitCode = Number(process2.exitCode ?? 0);
2047
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
2048
+ exitCode = 1;
2049
+ }
2050
+ this._exit(exitCode, "commander.help", "(outputHelp)");
2051
+ }
2052
+ addHelpText(position, text) {
2053
+ const allowedValues = ["beforeAll", "before", "after", "afterAll"];
2054
+ if (!allowedValues.includes(position)) {
2055
+ throw new Error(`Unexpected value for position to addHelpText.
2056
+ Expecting one of '${allowedValues.join("', '")}'`);
2057
+ }
2058
+ const helpEvent = `${position}Help`;
2059
+ this.on(helpEvent, (context) => {
2060
+ let helpStr;
2061
+ if (typeof text === "function") {
2062
+ helpStr = text({ error: context.error, command: context.command });
2063
+ } else {
2064
+ helpStr = text;
2065
+ }
2066
+ if (helpStr) {
2067
+ context.write(`${helpStr}
2068
+ `);
2069
+ }
2070
+ });
2071
+ return this;
2072
+ }
2073
+ _outputHelpIfRequested(args) {
2074
+ const helpOption = this._getHelpOption();
2075
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
2076
+ if (helpRequested) {
2077
+ this.outputHelp();
2078
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
2079
+ }
894
2080
  }
895
- this.handlerMap.set(eventName, listeners);
896
2081
  }
897
- emit(eventName, data) {
898
- (this.handlerMap.get(eventName) ?? []).forEach((callback) => {
899
- callback(data);
2082
+ function incrementNodeInspectorPort(args) {
2083
+ return args.map((arg) => {
2084
+ if (!arg.startsWith("--inspect")) {
2085
+ return arg;
2086
+ }
2087
+ let debugOption;
2088
+ let debugHost = "127.0.0.1";
2089
+ let debugPort = "9229";
2090
+ let match;
2091
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
2092
+ debugOption = match[1];
2093
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
2094
+ debugOption = match[1];
2095
+ if (/^\d+$/.test(match[3])) {
2096
+ debugPort = match[3];
2097
+ } else {
2098
+ debugHost = match[3];
2099
+ }
2100
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
2101
+ debugOption = match[1];
2102
+ debugHost = match[3];
2103
+ debugPort = match[4];
2104
+ }
2105
+ if (debugOption && debugPort !== "0") {
2106
+ return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
2107
+ }
2108
+ return arg;
900
2109
  });
901
2110
  }
902
- clearListeners() {
903
- this.handlerMap.clear();
2111
+ function useColor() {
2112
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
2113
+ return false;
2114
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
2115
+ return true;
2116
+ return;
904
2117
  }
905
- }
2118
+ exports.Command = Command;
2119
+ exports.useColor = useColor;
2120
+ });
906
2121
 
907
- class VexEventTarget {
908
- emitter;
2122
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/index.js
2123
+ var require_commander = __commonJS((exports) => {
2124
+ var { Argument } = require_argument();
2125
+ var { Command } = require_command();
2126
+ var { CommanderError, InvalidArgumentError } = require_error();
2127
+ var { Help } = require_help();
2128
+ var { Option } = require_option();
2129
+ exports.program = new Command;
2130
+ exports.createCommand = (name) => new Command(name);
2131
+ exports.createOption = (flags, description) => new Option(flags, description);
2132
+ exports.createArgument = (name, description) => new Argument(name, description);
2133
+ exports.Command = Command;
2134
+ exports.Option = Option;
2135
+ exports.Argument = Argument;
2136
+ exports.Help = Help;
2137
+ exports.CommanderError = CommanderError;
2138
+ exports.InvalidArgumentError = InvalidArgumentError;
2139
+ exports.InvalidOptionArgumentError = InvalidArgumentError;
2140
+ });
2141
+
2142
+ // ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
2143
+ var require_picocolors = __commonJS((exports, module) => {
2144
+ var p = process || {};
2145
+ var argv = p.argv || [];
2146
+ var env = p.env || {};
2147
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
2148
+ var formatter = (open, close, replace = open) => (input) => {
2149
+ let string = "" + input, index = string.indexOf(close, open.length);
2150
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
2151
+ };
2152
+ var replaceClose = (string, close, replace, index) => {
2153
+ let result = "", cursor = 0;
2154
+ do {
2155
+ result += string.substring(cursor, index) + replace;
2156
+ cursor = index + close.length;
2157
+ index = string.indexOf(close, cursor);
2158
+ } while (~index);
2159
+ return result + string.substring(cursor);
2160
+ };
2161
+ var createColors = (enabled = isColorSupported) => {
2162
+ let f = enabled ? formatter : () => String;
2163
+ return {
2164
+ isColorSupported: enabled,
2165
+ reset: f("\x1B[0m", "\x1B[0m"),
2166
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
2167
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
2168
+ italic: f("\x1B[3m", "\x1B[23m"),
2169
+ underline: f("\x1B[4m", "\x1B[24m"),
2170
+ inverse: f("\x1B[7m", "\x1B[27m"),
2171
+ hidden: f("\x1B[8m", "\x1B[28m"),
2172
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
2173
+ black: f("\x1B[30m", "\x1B[39m"),
2174
+ red: f("\x1B[31m", "\x1B[39m"),
2175
+ green: f("\x1B[32m", "\x1B[39m"),
2176
+ yellow: f("\x1B[33m", "\x1B[39m"),
2177
+ blue: f("\x1B[34m", "\x1B[39m"),
2178
+ magenta: f("\x1B[35m", "\x1B[39m"),
2179
+ cyan: f("\x1B[36m", "\x1B[39m"),
2180
+ white: f("\x1B[37m", "\x1B[39m"),
2181
+ gray: f("\x1B[90m", "\x1B[39m"),
2182
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
2183
+ bgRed: f("\x1B[41m", "\x1B[49m"),
2184
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
2185
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
2186
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
2187
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
2188
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
2189
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
2190
+ blackBright: f("\x1B[90m", "\x1B[39m"),
2191
+ redBright: f("\x1B[91m", "\x1B[39m"),
2192
+ greenBright: f("\x1B[92m", "\x1B[39m"),
2193
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
2194
+ blueBright: f("\x1B[94m", "\x1B[39m"),
2195
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
2196
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
2197
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
2198
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
2199
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
2200
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
2201
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
2202
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
2203
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
2204
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
2205
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
2206
+ };
2207
+ };
2208
+ module.exports = createColors();
2209
+ module.exports.createColors = createColors;
2210
+ });
2211
+
2212
+ // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/esm.mjs
2213
+ var import__ = __toESM(require_commander(), 1);
2214
+ var {
2215
+ program,
2216
+ createCommand,
2217
+ createArgument,
2218
+ createOption,
2219
+ CommanderError,
2220
+ InvalidArgumentError,
2221
+ InvalidOptionArgumentError,
2222
+ Command,
2223
+ Argument,
2224
+ Option,
2225
+ Help
2226
+ } = import__.default;
2227
+ // package.json
2228
+ var package_default = {
2229
+ name: "@v5x/cli",
2230
+ version: "0.0.14",
2231
+ description: "Command line interface for v5x.",
2232
+ license: "MIT",
2233
+ type: "module",
2234
+ bin: {
2235
+ v5x: "dist/index.js"
2236
+ },
2237
+ files: [
2238
+ "dist",
2239
+ "README.md"
2240
+ ],
2241
+ repository: {
2242
+ type: "git",
2243
+ url: "git+https://github.com/beanarchystudios/v5x.git",
2244
+ directory: "packages/cli"
2245
+ },
2246
+ bugs: {
2247
+ url: "https://github.com/beanarchystudios/v5x/issues"
2248
+ },
2249
+ homepage: "https://github.com/beanarchystudios/v5x#readme",
2250
+ publishConfig: {
2251
+ access: "public"
2252
+ },
2253
+ scripts: {
2254
+ build: "bun build ./src/index.ts --target bun --external unzipit --outfile ./dist/index.js && chmod +x ./dist/index.js",
2255
+ dev: "bun --silent ./src/index.ts",
2256
+ lint: "bunx tsc --noEmit",
2257
+ prepublishOnly: "bun run typecheck && bun run build",
2258
+ typecheck: "bunx tsc --noEmit"
2259
+ },
2260
+ engines: {
2261
+ bun: ">=1.3.14"
2262
+ },
2263
+ devDependencies: {
2264
+ "@types/bun": "^1.3.1"
2265
+ },
2266
+ dependencies: {
2267
+ boxen: "^8.0.1",
2268
+ "bun-serialport": "^0.1.1",
2269
+ commander: "^14.0.3",
2270
+ picocolors: "^1.1.1",
2271
+ unzipit: "^1.4.0"
2272
+ }
2273
+ };
2274
+
2275
+ // ../serial/src/Vex.ts
2276
+ var USER_PROG_CHUNK_SIZE = 4096;
2277
+ var USER_FLASH_USR_CODE_START = 58720256;
2278
+ // ../serial/src/VexEvent.ts
2279
+ class VexEventEmitter {
2280
+ handlerMap;
2281
+ constructor() {
2282
+ this.handlerMap = new Map;
2283
+ }
2284
+ on(eventName, listener) {
2285
+ let listeners = this.handlerMap.get(eventName);
2286
+ listeners ??= [];
2287
+ listeners.push(listener);
2288
+ this.handlerMap.set(eventName, listeners);
2289
+ }
2290
+ remove(eventName, listener) {
2291
+ let listeners = this.handlerMap.get(eventName);
2292
+ listeners ??= [];
2293
+ const index = listeners.indexOf(listener);
2294
+ if (index > -1) {
2295
+ listeners.splice(index, 1);
2296
+ }
2297
+ this.handlerMap.set(eventName, listeners);
2298
+ }
2299
+ emit(eventName, data) {
2300
+ (this.handlerMap.get(eventName) ?? []).forEach((callback) => {
2301
+ callback(data);
2302
+ });
2303
+ }
2304
+ clearListeners() {
2305
+ this.handlerMap.clear();
2306
+ }
2307
+ }
2308
+
2309
+ class VexEventTarget {
2310
+ emitter;
909
2311
  constructor() {
910
2312
  this.emitter = new VexEventEmitter;
911
2313
  }
@@ -2594,9 +3996,9 @@ class VexSerialConnection extends VexEventTarget {
2594
3996
  get isConnected() {
2595
3997
  return this.port !== undefined && this.reader !== undefined && this.writer !== undefined;
2596
3998
  }
2597
- constructor(serial2) {
3999
+ constructor(serial) {
2598
4000
  super();
2599
- this.serial = serial2;
4001
+ this.serial = serial;
2600
4002
  }
2601
4003
  async close() {
2602
4004
  if (!this.isConnected)
@@ -3186,7 +4588,7 @@ class V5Brain {
3186
4588
  continue;
3187
4589
  const n = new Date;
3188
4590
  n.setTime(1000 * bin.timestamp);
3189
- const program = {
4591
+ const program2 = {
3190
4592
  name: programName,
3191
4593
  binfile: bin.filename,
3192
4594
  size: ini.size + bin.size,
@@ -3194,12 +4596,12 @@ class V5Brain {
3194
4596
  time: n,
3195
4597
  requestedSlot: -1
3196
4598
  };
3197
- const result2 = await conn?.writeDataAsync(new GetProgramSlotInfoH2DPacket(1 /* USER */, program.binfile));
4599
+ const result2 = await conn?.writeDataAsync(new GetProgramSlotInfoH2DPacket(1 /* USER */, program2.binfile));
3198
4600
  if (result2 instanceof GetProgramSlotInfoReplyD2HPacket) {
3199
- program.slot = result2.slot;
3200
- program.requestedSlot = result2.requestedSlot;
4601
+ program2.slot = result2.slot;
4602
+ program2.requestedSlot = result2.requestedSlot;
3201
4603
  }
3202
- programList.push(program);
4604
+ programList.push(program2);
3203
4605
  }
3204
4606
  return programList;
3205
4607
  }
@@ -3409,397 +4811,1129 @@ class V5Brain {
3409
4811
  throw e;
3410
4812
  }
3411
4813
  }
3412
- async writeFile(request, progressCallback) {
3413
- this.state._isFileTransferring = true;
3414
- const conn = this.state._instance.connection;
3415
- if (conn == null || !conn.isConnected)
3416
- return;
3417
- try {
3418
- return await conn.uploadFileToDevice(request, progressCallback);
3419
- } catch (e) {
3420
- this.state._isFileTransferring = false;
3421
- throw e;
3422
- }
4814
+ async writeFile(request, progressCallback) {
4815
+ this.state._isFileTransferring = true;
4816
+ const conn = this.state._instance.connection;
4817
+ if (conn == null || !conn.isConnected)
4818
+ return;
4819
+ try {
4820
+ return await conn.uploadFileToDevice(request, progressCallback);
4821
+ } catch (e) {
4822
+ this.state._isFileTransferring = false;
4823
+ throw e;
4824
+ }
4825
+ }
4826
+ async captureScreen(progressCallback) {
4827
+ const conn = this.state._instance.connection;
4828
+ if (conn == null || !conn.isConnected)
4829
+ return;
4830
+ await new Promise((resolve) => {
4831
+ conn.writeData(new ScreenCaptureH2DPacket(0), resolve);
4832
+ });
4833
+ const height = 272;
4834
+ const width = 480;
4835
+ const channels = 3;
4836
+ const messageWidth = 512;
4837
+ const messageChannels = 4;
4838
+ let buf = await conn?.downloadFileToHost({
4839
+ filename: "screen",
4840
+ vendor: 15 /* SYS */,
4841
+ loadAddress: 0,
4842
+ size: messageWidth * height * messageChannels
4843
+ }, 2 /* FILE_TARGET_CBUF */, progressCallback);
4844
+ if (buf == null)
4845
+ return;
4846
+ buf = buf.filter((_byte, i) => i % (messageWidth * messageChannels) < width * messageChannels).filter((_byte, i) => (i + 1) % messageChannels !== 0);
4847
+ for (let i = 0;i < buf.length; i += channels) {
4848
+ const px = buf.slice(i, i + channels).reverse();
4849
+ for (let j = 0;j < px.length; j++) {
4850
+ buf[i + j] = px[j];
4851
+ }
4852
+ }
4853
+ return buf;
4854
+ }
4855
+ }
4856
+
4857
+ class V5Battery {
4858
+ state;
4859
+ constructor(state) {
4860
+ this.state = state;
4861
+ }
4862
+ get batteryPercent() {
4863
+ return this.state.brain.battery.batteryPercent;
4864
+ }
4865
+ get isCharging() {
4866
+ return this.state.brain.battery.isCharging;
4867
+ }
4868
+ }
4869
+
4870
+ class V5BrainButton {
4871
+ state;
4872
+ constructor(state) {
4873
+ this.state = state;
4874
+ }
4875
+ get isPressed() {
4876
+ return this.state.brain.button.isPressed;
4877
+ }
4878
+ get isDoublePressed() {
4879
+ return this.state.brain.button.isDoublePressed;
4880
+ }
4881
+ }
4882
+
4883
+ class V5BrainSettings {
4884
+ state;
4885
+ constructor(state) {
4886
+ this.state = state;
4887
+ }
4888
+ get isScreenReversed() {
4889
+ return this.state.brain.settings.isScreenReversed;
4890
+ }
4891
+ get isWhiteTheme() {
4892
+ return this.state.brain.settings.isWhiteTheme;
4893
+ }
4894
+ get usingLanguage() {
4895
+ return this.state.brain.settings.usingLanguage;
4896
+ }
4897
+ }
4898
+
4899
+ class V5Controller {
4900
+ state;
4901
+ controllerIndex;
4902
+ constructor(state, controllerIndex) {
4903
+ this.state = state;
4904
+ this.controllerIndex = controllerIndex;
4905
+ }
4906
+ get batteryPercent() {
4907
+ return this.state.controllers[this.controllerIndex].battery;
4908
+ }
4909
+ get isMasterController() {
4910
+ return this.controllerIndex === 0;
4911
+ }
4912
+ get isAvailable() {
4913
+ return this.state.controllers[this.controllerIndex].isAvailable;
4914
+ }
4915
+ get isCharging() {
4916
+ return this.state.controllers[this.controllerIndex].isCharging;
4917
+ }
4918
+ }
4919
+
4920
+ class V5SmartDevice {
4921
+ state;
4922
+ deviceIndex;
4923
+ constructor(state, index) {
4924
+ this.state = state;
4925
+ this.deviceIndex = index;
4926
+ }
4927
+ getDeviceInfo() {
4928
+ return this.state.devices[this.deviceIndex];
4929
+ }
4930
+ get isAvailable() {
4931
+ return this.getDeviceInfo() !== undefined;
4932
+ }
4933
+ get port() {
4934
+ return this.deviceIndex;
4935
+ }
4936
+ get type() {
4937
+ return this.getDeviceInfo()?.type ?? 0 /* EMPTY */;
4938
+ }
4939
+ get version() {
4940
+ return this.getDeviceInfo()?.version ?? 0;
4941
+ }
4942
+ }
4943
+
4944
+ class V5Radio {
4945
+ state;
4946
+ constructor(state) {
4947
+ this.state = state;
4948
+ }
4949
+ get channel() {
4950
+ return this.state.radio.channel;
4951
+ }
4952
+ get isAvailable() {
4953
+ return this.state.radio.isAvailable;
4954
+ }
4955
+ get isConnected() {
4956
+ return this.state.radio.isConnected;
4957
+ }
4958
+ get isVexNet() {
4959
+ return this.state.radio.isVexNet;
4960
+ }
4961
+ get isRadioData() {
4962
+ return this.state.radio.isRadioData;
4963
+ }
4964
+ get latency() {
4965
+ return this.state.radio.latency;
4966
+ }
4967
+ async changeChannel(channel) {
4968
+ const result = await this.state._instance.connection?.writeDataAsync(new FileControlH2DPacket(1, channel));
4969
+ return result instanceof FileControlReplyD2HPacket;
4970
+ }
4971
+ }
4972
+
4973
+ class V5SerialDevice extends VexSerialDevice {
4974
+ autoReconnect = true;
4975
+ autoRefresh = true;
4976
+ pauseRefreshOnFileTransfer = true;
4977
+ _isReconnecting = false;
4978
+ _refreshInterval;
4979
+ state = new V5SerialDeviceState(this);
4980
+ constructor(defaultSerial) {
4981
+ super(defaultSerial);
4982
+ let isLastRefreshComplete = true;
4983
+ this._refreshInterval = setInterval(() => {
4984
+ if (this.autoRefresh && isLastRefreshComplete) {
4985
+ if (!this.isConnected) {
4986
+ this.state.brain.isAvailable = false;
4987
+ return;
4988
+ }
4989
+ if (this.pauseRefreshOnFileTransfer && !this.state._isFileTransferring) {
4990
+ isLastRefreshComplete = false;
4991
+ this.refresh().finally(() => isLastRefreshComplete = true);
4992
+ }
4993
+ }
4994
+ }, 200);
4995
+ }
4996
+ get isV5Controller() {
4997
+ return this.deviceType === 1283 /* V5_CONTROLLER */;
4998
+ }
4999
+ get brain() {
5000
+ return new V5Brain(this.state);
5001
+ }
5002
+ get controllers() {
5003
+ return [new V5Controller(this.state, 0), new V5Controller(this.state, 1)];
5004
+ }
5005
+ get devices() {
5006
+ const rtn = [];
5007
+ for (let i = 1;i <= this.state.devices.length; i++) {
5008
+ if (this.state.devices[i] != null)
5009
+ rtn.push(new V5SmartDevice(this.state, i));
5010
+ }
5011
+ return rtn;
5012
+ }
5013
+ get isFieldControllerConnected() {
5014
+ return this.state.isFieldControllerConnected;
5015
+ }
5016
+ get matchMode() {
5017
+ return this.state.matchMode;
5018
+ }
5019
+ set matchMode(value) {
5020
+ (async () => {
5021
+ if (await this.connection?.setMatchMode(value) != null)
5022
+ this.state.matchMode = value;
5023
+ })();
5024
+ }
5025
+ get radio() {
5026
+ return new V5Radio(this.state);
5027
+ }
5028
+ async mockTouch(x, y, press) {
5029
+ return !(await this.connection?.mockTouch(x, y, press) == null);
5030
+ }
5031
+ async connect(conn) {
5032
+ if (this.isConnected)
5033
+ return true;
5034
+ if (conn != null && !conn.isConnected) {
5035
+ if (await conn.query1() === null)
5036
+ return false;
5037
+ this.connection = conn;
5038
+ } else {
5039
+ let tryIdx = 0;
5040
+ while (true) {
5041
+ const c = new V5SerialConnection(this.defaultSerial);
5042
+ const result = await c.open(tryIdx++, true);
5043
+ if (result === undefined)
5044
+ return false;
5045
+ if (!result) {
5046
+ await c.close();
5047
+ continue;
5048
+ }
5049
+ if (await c.query1() === null) {
5050
+ await c.close();
5051
+ continue;
5052
+ }
5053
+ this.connection = c;
5054
+ break;
5055
+ }
5056
+ }
5057
+ if (!this.isConnected)
5058
+ return false;
5059
+ await this.doAfterConnect();
5060
+ return true;
5061
+ }
5062
+ async disconnect() {
5063
+ await this.connection?.close();
5064
+ this.connection = undefined;
5065
+ }
5066
+ async dispose() {
5067
+ this.autoReconnect = false;
5068
+ this.autoRefresh = false;
5069
+ clearInterval(this._refreshInterval);
5070
+ await this.disconnect();
5071
+ }
5072
+ async reconnect(timeout = 0) {
5073
+ if (this.isConnected)
5074
+ return true;
5075
+ if (timeout < 0)
5076
+ return false;
5077
+ const endTime = new Date().getTime() + timeout;
5078
+ if (this._isReconnecting) {
5079
+ let successBeforeTimeout;
5080
+ do {
5081
+ successBeforeTimeout = await sleepUntil(() => !this._isReconnecting, timeout === 0 ? 1000 : timeout);
5082
+ } while (timeout === 0 && !successBeforeTimeout);
5083
+ if (this.isConnected)
5084
+ return true;
5085
+ if (!successBeforeTimeout)
5086
+ return false;
5087
+ }
5088
+ this._isReconnecting = true;
5089
+ while (timeout === 0 || new Date().getTime() < endTime) {
5090
+ let tryIdx = 0;
5091
+ while (true) {
5092
+ const c = new V5SerialConnection(this.defaultSerial);
5093
+ const result = await c.open(tryIdx++, false);
5094
+ if (result === undefined)
5095
+ break;
5096
+ if (!result) {
5097
+ await c.close();
5098
+ continue;
5099
+ }
5100
+ const result2 = await c.getSystemStatus(200);
5101
+ if (result2 === null) {
5102
+ await c.close();
5103
+ continue;
5104
+ }
5105
+ if (this.brain.uniqueId !== 0 && result2.uniqueId !== this.brain.uniqueId) {
5106
+ await c.close();
5107
+ continue;
5108
+ }
5109
+ this.connection = c;
5110
+ break;
5111
+ }
5112
+ if (this.isConnected)
5113
+ break;
5114
+ const getPortCount = async () => (await this.defaultSerial.getPorts()).length;
5115
+ const portsCount = await getPortCount();
5116
+ await sleepUntilAsync(async () => await getPortCount() !== portsCount, 1000);
5117
+ }
5118
+ this._isReconnecting = false;
5119
+ if (!this.isConnected)
5120
+ return false;
5121
+ this.doAfterConnect();
5122
+ return true;
5123
+ }
5124
+ async doAfterConnect() {
5125
+ if (this.connection == null)
5126
+ return;
5127
+ this.connection.on("disconnected", (_data) => {
5128
+ if (this.autoReconnect)
5129
+ this.reconnect();
5130
+ });
5131
+ await this.refresh();
5132
+ }
5133
+ async refresh() {
5134
+ const ssPacket = await this.connection?.getSystemStatus();
5135
+ if (ssPacket == null) {
5136
+ this.state.brain.isAvailable = false;
5137
+ return false;
5138
+ }
5139
+ this.state.brain.cpu0Version = ssPacket.cpu0Version;
5140
+ this.state.brain.cpu1Version = ssPacket.cpu1Version;
5141
+ this.state.brain.systemVersion = ssPacket.systemVersion;
5142
+ const flags2 = ssPacket.sysflags[2];
5143
+ this.state.controllers[0].isCharging = (flags2 & 128) !== 0;
5144
+ this.state.matchMode = (flags2 & 32) !== 0 ? "disabled" : (flags2 & 64) !== 0 ? "autonomous" : "driver";
5145
+ this.state.isFieldControllerConnected = (flags2 & 16) !== 0;
5146
+ const flags4 = ssPacket.sysflags[4];
5147
+ this.state.brain.settings.usingLanguage = (flags4 & 240) >> 4;
5148
+ this.state.brain.settings.isWhiteTheme = (flags4 & 4) !== 0;
5149
+ this.state.brain.settings.isScreenReversed = (flags4 & 1) === 0;
5150
+ this.state.brain.uniqueId = ssPacket.uniqueId;
5151
+ const sfPacket = await this.connection?.getSystemFlags();
5152
+ if (sfPacket == null)
5153
+ return false;
5154
+ const flags5 = sfPacket.flags;
5155
+ this.state.radio.isRadioData = (flags5 & Math.pow(2, 20)) !== 0;
5156
+ this.state.brain.button.isDoublePressed = (flags5 & Math.pow(2, 18)) !== 0;
5157
+ this.state.brain.battery.isCharging = (flags5 & Math.pow(2, 17)) !== 0;
5158
+ this.state.brain.button.isPressed = (flags5 & Math.pow(2, 15)) !== 0;
5159
+ this.state.radio.isVexNet = (flags5 & Math.pow(2, 14)) !== 0;
5160
+ this.state.controllers[1].isAvailable = (flags5 & Math.pow(2, 13)) !== 0;
5161
+ this.state.radio.isConnected = (flags5 & Math.pow(2, 10)) !== 0;
5162
+ this.state.radio.isAvailable = (flags5 & Math.pow(2, 9)) !== 0;
5163
+ this.state.brain.battery.batteryPercent = sfPacket.battery ?? 0;
5164
+ this.state.controllers[0].isAvailable = this.state.radio.isConnected || this.state.controllers[0].isCharging;
5165
+ this.state.controllers[0].battery = sfPacket.controllerBatteryPercent ?? 0;
5166
+ this.state.controllers[1].battery = sfPacket.partnerControllerBatteryPercent ?? 0;
5167
+ this.state.brain.activeProgram = sfPacket.currentProgram;
5168
+ this.state.brain.isAvailable = !this.isV5Controller || this.state.radio.isConnected;
5169
+ const rdPacket = await this.connection?.getRadioStatus();
5170
+ if (rdPacket == null)
5171
+ return false;
5172
+ this.state.radio.channel = rdPacket.channel;
5173
+ this.state.radio.latency = rdPacket.timeslot;
5174
+ this.state.radio.signalQuality = rdPacket.quality;
5175
+ this.state.radio.signalStrength = rdPacket.strength;
5176
+ const dsPacket = await this.connection?.getDeviceStatus();
5177
+ if (dsPacket == null)
5178
+ return false;
5179
+ let missingPorts = this.state.devices.map((d) => d?.port).filter((p) => p !== undefined);
5180
+ for (let i = 0;i < dsPacket.devices.length; i++) {
5181
+ const device = dsPacket.devices[i];
5182
+ this.state.devices[device.port] = device;
5183
+ missingPorts = missingPorts.filter((p) => p !== device.port);
5184
+ }
5185
+ missingPorts.forEach((port) => {
5186
+ this.state.devices[port] = undefined;
5187
+ });
5188
+ return true;
5189
+ }
5190
+ }
5191
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/serialport.js
5192
+ import { EventEmitter } from "events";
5193
+
5194
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/posix.js
5195
+ import { dlopen, FFIType, ptr, toArrayBuffer, CString } from "bun:ffi";
5196
+
5197
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/constants.js
5198
+ import { platform } from "os";
5199
+ var IS_LINUX = platform() === "linux";
5200
+ var IS_DARWIN = platform() === "darwin";
5201
+ if (!IS_LINUX && !IS_DARWIN) {
5202
+ throw new Error(`bun-serialport: unsupported platform "${platform()}"`);
5203
+ }
5204
+ var O_RDWR = 2;
5205
+ var O_NOCTTY = IS_LINUX ? 256 : 131072;
5206
+ var O_NONBLOCK = IS_LINUX ? 2048 : 4;
5207
+ var TCSADRAIN = 1;
5208
+ var TCSAFLUSH = 2;
5209
+ var TCIOFLUSH = IS_LINUX ? 2 : 3;
5210
+ var CSIZE = IS_LINUX ? 48 : 768;
5211
+ var CS5 = IS_LINUX ? 0 : 0;
5212
+ var CS6 = IS_LINUX ? 16 : 256;
5213
+ var CS7 = IS_LINUX ? 32 : 512;
5214
+ var CS8 = IS_LINUX ? 48 : 768;
5215
+ var CSTOPB = IS_LINUX ? 64 : 1024;
5216
+ var CREAD = IS_LINUX ? 128 : 2048;
5217
+ var PARENB = IS_LINUX ? 256 : 4096;
5218
+ var PARODD = IS_LINUX ? 512 : 8192;
5219
+ var CLOCAL = IS_LINUX ? 2048 : 32768;
5220
+ var CRTSCTS = IS_LINUX ? 2147483648 : 196608;
5221
+ var INPCK = IS_LINUX ? 16 : 16;
5222
+ var IXON = IS_LINUX ? 1024 : 512;
5223
+ var IXOFF = IS_LINUX ? 4096 : 1024;
5224
+ var VMIN = IS_LINUX ? 6 : 16;
5225
+ var VTIME = IS_LINUX ? 5 : 17;
5226
+ var NCCS = IS_LINUX ? 32 : 20;
5227
+ var TIOCMGET = IS_LINUX ? 21525 : 1074033770;
5228
+ var TIOCMBIS = IS_LINUX ? 21526 : 2147775596;
5229
+ var TIOCMBIC = IS_LINUX ? 21527 : 2147775595;
5230
+ var TIOCM_DTR = 2;
5231
+ var TIOCM_RTS = 4;
5232
+ var TIOCM_CTS = 32;
5233
+ var TIOCM_DSR = 256;
5234
+ var TIOCM_CD = 64;
5235
+ var TIOCM_RI = 128;
5236
+ var TERMIOS_SIZE = IS_LINUX ? 60 : 72;
5237
+ var TCFLAG_SIZE = IS_LINUX ? 4 : 8;
5238
+ var TERMIOS_OFFSETS = IS_LINUX ? { c_iflag: 0, c_oflag: 4, c_cflag: 8, c_lflag: 12, c_line: 16, c_cc: 17, c_ispeed: 52, c_ospeed: 56 } : { c_iflag: 0, c_oflag: 8, c_cflag: 16, c_lflag: 24, c_cc: 32, c_ispeed: 56, c_ospeed: 64 };
5239
+ var LINUX_BAUD_MAP = {
5240
+ 0: 0,
5241
+ 110: 3,
5242
+ 300: 7,
5243
+ 600: 8,
5244
+ 1200: 9,
5245
+ 2400: 11,
5246
+ 4800: 12,
5247
+ 9600: 13,
5248
+ 19200: 14,
5249
+ 38400: 15,
5250
+ 57600: 4097,
5251
+ 115200: 4098,
5252
+ 230400: 4099,
5253
+ 460800: 4100,
5254
+ 500000: 4101,
5255
+ 576000: 4102,
5256
+ 921600: 4103,
5257
+ 1e6: 4104,
5258
+ 1152000: 4105,
5259
+ 1500000: 4106,
5260
+ 2000000: 4107,
5261
+ 2500000: 4108,
5262
+ 3000000: 4109,
5263
+ 3500000: 4110,
5264
+ 4000000: 4111
5265
+ };
5266
+ function encodeBaudRate(rate) {
5267
+ if (IS_DARWIN)
5268
+ return rate;
5269
+ const encoded = LINUX_BAUD_MAP[rate];
5270
+ if (encoded === undefined)
5271
+ throw new Error(`Unsupported baud rate: ${rate}`);
5272
+ return encoded;
5273
+ }
5274
+ function dataBitsFlag(bits) {
5275
+ switch (bits) {
5276
+ case 5:
5277
+ return CS5;
5278
+ case 6:
5279
+ return CS6;
5280
+ case 7:
5281
+ return CS7;
5282
+ case 8:
5283
+ return CS8;
5284
+ default:
5285
+ throw new Error(`Invalid data bits: ${bits}`);
5286
+ }
5287
+ }
5288
+
5289
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/posix.js
5290
+ import { platform as platform2 } from "os";
5291
+ var IS_LINUX2 = platform2() === "linux";
5292
+ var IS_DARWIN2 = platform2() === "darwin";
5293
+ var LIBC_PATH = IS_LINUX2 ? "libc.so.6" : "libSystem.B.dylib";
5294
+ var libc = dlopen(LIBC_PATH, {
5295
+ open: { args: [FFIType.cstring, FFIType.i32], returns: FFIType.i32 },
5296
+ close: { args: [FFIType.i32], returns: FFIType.i32 },
5297
+ read: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
5298
+ write: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
5299
+ tcgetattr: { args: [FFIType.i32, FFIType.ptr], returns: FFIType.i32 },
5300
+ tcsetattr: { args: [FFIType.i32, FFIType.i32, FFIType.ptr], returns: FFIType.i32 },
5301
+ tcflush: { args: [FFIType.i32, FFIType.i32], returns: FFIType.i32 },
5302
+ tcdrain: { args: [FFIType.i32], returns: FFIType.i32 },
5303
+ cfsetispeed: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
5304
+ cfsetospeed: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
5305
+ fcntl: { args: [FFIType.i32, FFIType.i32, FFIType.i32], returns: FFIType.i32 },
5306
+ ioctl: { args: [FFIType.i32, FFIType.u64, FFIType.ptr], returns: FFIType.i32 },
5307
+ strerror: { args: [FFIType.i32], returns: FFIType.ptr }
5308
+ });
5309
+ var errnoLib = dlopen(LIBC_PATH, IS_LINUX2 ? { __errno_location: { args: [], returns: FFIType.ptr } } : { __error: { args: [], returns: FFIType.ptr } });
5310
+ function getErrno() {
5311
+ const errPtr = IS_LINUX2 ? errnoLib.symbols.__errno_location() : errnoLib.symbols.__error();
5312
+ const view = new DataView(toArrayBuffer(errPtr, 0, 4));
5313
+ return view.getInt32(0, true);
5314
+ }
5315
+ function errnoError(syscall) {
5316
+ const code = getErrno();
5317
+ const msgPtr = libc.symbols.strerror(code);
5318
+ const msg = msgPtr ? new CString(msgPtr) : `errno ${code}`;
5319
+ const err = new Error(`${syscall}: ${msg}`);
5320
+ err.code = code;
5321
+ err.syscall = syscall;
5322
+ return err;
5323
+ }
5324
+ function readFlag(buf, offset) {
5325
+ if (TCFLAG_SIZE === 4) {
5326
+ return buf.getUint32(offset, true);
5327
+ }
5328
+ return Number(buf.getBigUint64(offset, true));
5329
+ }
5330
+ function writeFlag(buf, offset, value) {
5331
+ if (TCFLAG_SIZE === 4) {
5332
+ buf.setUint32(offset, value >>> 0, true);
5333
+ } else {
5334
+ buf.setBigUint64(offset, BigInt(value >>> 0), true);
5335
+ }
5336
+ }
5337
+ function writeSpeed(buf, offset, value) {
5338
+ if (TCFLAG_SIZE === 4) {
5339
+ buf.setUint32(offset, value >>> 0, true);
5340
+ } else {
5341
+ buf.setBigUint64(offset, BigInt(value), true);
5342
+ }
5343
+ }
5344
+ function openPort(path, options) {
5345
+ const {
5346
+ baudRate = 9600,
5347
+ dataBits = 8,
5348
+ stopBits = 1,
5349
+ parity = "none",
5350
+ rtscts = false,
5351
+ xon = false,
5352
+ xoff = false
5353
+ } = options;
5354
+ const pathBuf = Buffer.from(path + "\x00", "utf-8");
5355
+ const fd = libc.symbols.open(ptr(pathBuf), O_RDWR | O_NOCTTY | O_NONBLOCK);
5356
+ if (fd < 0)
5357
+ throw errnoError("open");
5358
+ const termiosBuf = new ArrayBuffer(TERMIOS_SIZE);
5359
+ const termiosBytes = new Uint8Array(termiosBuf);
5360
+ const termiosView = new DataView(termiosBuf);
5361
+ const termiosPtr = ptr(termiosBytes);
5362
+ if (libc.symbols.tcgetattr(fd, termiosPtr) < 0) {
5363
+ libc.symbols.close(fd);
5364
+ throw errnoError("tcgetattr");
5365
+ }
5366
+ const off = TERMIOS_OFFSETS;
5367
+ let cflag = readFlag(termiosView, off.c_cflag);
5368
+ cflag &= ~CSIZE;
5369
+ cflag |= dataBitsFlag(dataBits);
5370
+ cflag |= CREAD | CLOCAL;
5371
+ if (stopBits === 2)
5372
+ cflag |= CSTOPB;
5373
+ else
5374
+ cflag &= ~CSTOPB;
5375
+ if (parity === "none") {
5376
+ cflag &= ~(PARENB | PARODD);
5377
+ } else if (parity === "even") {
5378
+ cflag |= PARENB;
5379
+ cflag &= ~PARODD;
5380
+ } else if (parity === "odd") {
5381
+ cflag |= PARENB | PARODD;
5382
+ }
5383
+ if (rtscts)
5384
+ cflag |= CRTSCTS;
5385
+ else
5386
+ cflag &= ~CRTSCTS;
5387
+ writeFlag(termiosView, off.c_cflag, cflag);
5388
+ let iflag = 0;
5389
+ if (parity !== "none")
5390
+ iflag |= INPCK;
5391
+ if (xon)
5392
+ iflag |= IXON;
5393
+ if (xoff)
5394
+ iflag |= IXOFF;
5395
+ writeFlag(termiosView, off.c_iflag, iflag);
5396
+ writeFlag(termiosView, off.c_oflag, 0);
5397
+ writeFlag(termiosView, off.c_lflag, 0);
5398
+ const ccOffset = off.c_cc;
5399
+ for (let i = 0;i < NCCS; i++)
5400
+ termiosBytes[ccOffset + i] = 0;
5401
+ termiosBytes[ccOffset + VMIN] = 1;
5402
+ termiosBytes[ccOffset + VTIME] = 0;
5403
+ const baudCode = encodeBaudRate(baudRate);
5404
+ if (IS_LINUX2) {
5405
+ writeSpeed(termiosView, off.c_ispeed, baudCode);
5406
+ writeSpeed(termiosView, off.c_ospeed, baudCode);
5407
+ }
5408
+ if (libc.symbols.cfsetispeed(termiosPtr, baudCode) < 0) {
5409
+ libc.symbols.close(fd);
5410
+ throw errnoError("cfsetispeed");
5411
+ }
5412
+ if (libc.symbols.cfsetospeed(termiosPtr, baudCode) < 0) {
5413
+ libc.symbols.close(fd);
5414
+ throw errnoError("cfsetospeed");
5415
+ }
5416
+ if (libc.symbols.tcsetattr(fd, TCSAFLUSH, termiosPtr) < 0) {
5417
+ libc.symbols.close(fd);
5418
+ throw errnoError("tcsetattr");
3423
5419
  }
3424
- async captureScreen(progressCallback) {
3425
- const conn = this.state._instance.connection;
3426
- if (conn == null || !conn.isConnected)
3427
- return;
3428
- await new Promise((resolve) => {
3429
- conn.writeData(new ScreenCaptureH2DPacket(0), resolve);
3430
- });
3431
- const height = 272;
3432
- const width = 480;
3433
- const channels = 3;
3434
- const messageWidth = 512;
3435
- const messageChannels = 4;
3436
- let buf = await conn?.downloadFileToHost({
3437
- filename: "screen",
3438
- vendor: 15 /* SYS */,
3439
- loadAddress: 0,
3440
- size: messageWidth * height * messageChannels
3441
- }, 2 /* FILE_TARGET_CBUF */, progressCallback);
3442
- if (buf == null)
3443
- return;
3444
- buf = buf.filter((_byte, i) => i % (messageWidth * messageChannels) < width * messageChannels).filter((_byte, i) => (i + 1) % messageChannels !== 0);
3445
- for (let i = 0;i < buf.length; i += channels) {
3446
- const px = buf.slice(i, i + channels).reverse();
3447
- for (let j = 0;j < px.length; j++) {
3448
- buf[i + j] = px[j];
5420
+ libc.symbols.tcflush(fd, TCIOFLUSH);
5421
+ return fd;
5422
+ }
5423
+ function closePort(fd) {
5424
+ if (libc.symbols.close(fd) < 0)
5425
+ throw errnoError("close");
5426
+ }
5427
+ var MAX_EAGAIN_RETRIES = 1000;
5428
+ function writePort(fd, data) {
5429
+ const buf = data instanceof Uint8Array ? data : Buffer.from(data, "utf-8");
5430
+ let offset = 0;
5431
+ let eagainCount = 0;
5432
+ while (offset < buf.length) {
5433
+ const slice = buf.subarray(offset);
5434
+ const written = Number(libc.symbols.write(fd, ptr(slice), BigInt(slice.length)));
5435
+ if (written < 0) {
5436
+ const code = getErrno();
5437
+ if (code === 11 || code === 35) {
5438
+ if (++eagainCount > MAX_EAGAIN_RETRIES) {
5439
+ throw new Error("write: device not accepting data (EAGAIN limit exceeded)");
5440
+ }
5441
+ continue;
3449
5442
  }
5443
+ throw errnoError("write");
3450
5444
  }
3451
- return buf;
5445
+ eagainCount = 0;
5446
+ offset += written;
3452
5447
  }
5448
+ return offset;
3453
5449
  }
3454
-
3455
- class V5Battery {
3456
- state;
3457
- constructor(state) {
3458
- this.state = state;
3459
- }
3460
- get batteryPercent() {
3461
- return this.state.brain.battery.batteryPercent;
3462
- }
3463
- get isCharging() {
3464
- return this.state.brain.battery.isCharging;
5450
+ function readPort(fd, buffer) {
5451
+ const n = Number(libc.symbols.read(fd, ptr(buffer), BigInt(buffer.length)));
5452
+ if (n < 0) {
5453
+ const code = getErrno();
5454
+ if (code === 11 || code === 35)
5455
+ return 0;
5456
+ throw errnoError("read");
3465
5457
  }
5458
+ return n;
3466
5459
  }
3467
-
3468
- class V5BrainButton {
3469
- state;
3470
- constructor(state) {
3471
- this.state = state;
3472
- }
3473
- get isPressed() {
3474
- return this.state.brain.button.isPressed;
3475
- }
3476
- get isDoublePressed() {
3477
- return this.state.brain.button.isDoublePressed;
5460
+ function updateBaudRate(fd, baudRate) {
5461
+ const termiosBuf = new ArrayBuffer(TERMIOS_SIZE);
5462
+ const termiosPtr = ptr(new Uint8Array(termiosBuf));
5463
+ if (libc.symbols.tcgetattr(fd, termiosPtr) < 0)
5464
+ throw errnoError("tcgetattr");
5465
+ const baudCode = encodeBaudRate(baudRate);
5466
+ if (libc.symbols.cfsetispeed(termiosPtr, baudCode) < 0)
5467
+ throw errnoError("cfsetispeed");
5468
+ if (libc.symbols.cfsetospeed(termiosPtr, baudCode) < 0)
5469
+ throw errnoError("cfsetospeed");
5470
+ if (IS_LINUX2) {
5471
+ const view = new DataView(termiosBuf);
5472
+ writeSpeed(view, TERMIOS_OFFSETS.c_ispeed, baudCode);
5473
+ writeSpeed(view, TERMIOS_OFFSETS.c_ospeed, baudCode);
3478
5474
  }
5475
+ if (libc.symbols.tcsetattr(fd, TCSADRAIN, termiosPtr) < 0)
5476
+ throw errnoError("tcsetattr");
3479
5477
  }
3480
-
3481
- class V5BrainSettings {
3482
- state;
3483
- constructor(state) {
3484
- this.state = state;
3485
- }
3486
- get isScreenReversed() {
3487
- return this.state.brain.settings.isScreenReversed;
3488
- }
3489
- get isWhiteTheme() {
3490
- return this.state.brain.settings.isWhiteTheme;
5478
+ function setModemLines(fd, flags) {
5479
+ const { dtr, rts, brk } = flags;
5480
+ const intBuf = new ArrayBuffer(4);
5481
+ const intView = new DataView(intBuf);
5482
+ const intPtr = ptr(new Uint8Array(intBuf));
5483
+ let bitsToSet = 0;
5484
+ let bitsToClear = 0;
5485
+ if (dtr === true)
5486
+ bitsToSet |= TIOCM_DTR;
5487
+ if (dtr === false)
5488
+ bitsToClear |= TIOCM_DTR;
5489
+ if (rts === true)
5490
+ bitsToSet |= TIOCM_RTS;
5491
+ if (rts === false)
5492
+ bitsToClear |= TIOCM_RTS;
5493
+ if (bitsToSet) {
5494
+ intView.setInt32(0, bitsToSet, true);
5495
+ if (libc.symbols.ioctl(fd, TIOCMBIS, intPtr) < 0)
5496
+ throw errnoError("ioctl TIOCMBIS");
3491
5497
  }
3492
- get usingLanguage() {
3493
- return this.state.brain.settings.usingLanguage;
5498
+ if (bitsToClear) {
5499
+ intView.setInt32(0, bitsToClear, true);
5500
+ if (libc.symbols.ioctl(fd, TIOCMBIC, intPtr) < 0)
5501
+ throw errnoError("ioctl TIOCMBIC");
3494
5502
  }
3495
5503
  }
3496
-
3497
- class V5Controller {
3498
- state;
3499
- controllerIndex;
3500
- constructor(state, controllerIndex) {
3501
- this.state = state;
3502
- this.controllerIndex = controllerIndex;
3503
- }
3504
- get batteryPercent() {
3505
- return this.state.controllers[this.controllerIndex].battery;
3506
- }
3507
- get isMasterController() {
3508
- return this.controllerIndex === 0;
3509
- }
3510
- get isAvailable() {
3511
- return this.state.controllers[this.controllerIndex].isAvailable;
3512
- }
3513
- get isCharging() {
3514
- return this.state.controllers[this.controllerIndex].isCharging;
3515
- }
5504
+ function getModemLines(fd) {
5505
+ const intBuf = new ArrayBuffer(4);
5506
+ const intView = new DataView(intBuf);
5507
+ const intPtr = ptr(new Uint8Array(intBuf));
5508
+ if (libc.symbols.ioctl(fd, TIOCMGET, intPtr) < 0)
5509
+ throw errnoError("ioctl TIOCMGET");
5510
+ const bits = intView.getInt32(0, true);
5511
+ return {
5512
+ cts: !!(bits & TIOCM_CTS),
5513
+ dsr: !!(bits & TIOCM_DSR),
5514
+ dcd: !!(bits & TIOCM_CD),
5515
+ ri: !!(bits & TIOCM_RI)
5516
+ };
5517
+ }
5518
+ function flushPort(fd) {
5519
+ if (libc.symbols.tcflush(fd, TCIOFLUSH) < 0)
5520
+ throw errnoError("tcflush");
5521
+ }
5522
+ function drainPort(fd) {
5523
+ if (libc.symbols.tcdrain(fd) < 0)
5524
+ throw errnoError("tcdrain");
3516
5525
  }
3517
5526
 
3518
- class V5SmartDevice {
3519
- state;
3520
- deviceIndex;
3521
- constructor(state, index) {
3522
- this.state = state;
3523
- this.deviceIndex = index;
5527
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/serialport.js
5528
+ var DEFAULT_READ_BUFFER_SIZE = 65536;
5529
+ var DEFAULT_READ_INTERVAL_MS = 1;
5530
+
5531
+ class SerialPort extends EventEmitter {
5532
+ #fd = -1;
5533
+ #path;
5534
+ #baudRate;
5535
+ #options;
5536
+ #isOpen = false;
5537
+ #isClosing = false;
5538
+ #readBuf;
5539
+ #readInterval;
5540
+ #readTimer = null;
5541
+ constructor(options) {
5542
+ super();
5543
+ if (!options || !options.path)
5544
+ throw new Error("options.path is required");
5545
+ if (!options.baudRate)
5546
+ throw new Error("options.baudRate is required");
5547
+ this.#path = options.path;
5548
+ this.#baudRate = options.baudRate;
5549
+ this.#options = { ...options };
5550
+ this.#readBuf = new Uint8Array(options.readBufferSize || DEFAULT_READ_BUFFER_SIZE);
5551
+ this.#readInterval = options.readInterval || DEFAULT_READ_INTERVAL_MS;
5552
+ if (options.autoOpen !== false) {
5553
+ queueMicrotask(() => this.open().catch((err) => this.emit("error", err)));
5554
+ }
3524
5555
  }
3525
- getDeviceInfo() {
3526
- return this.state.devices[this.deviceIndex];
5556
+ get path() {
5557
+ return this.#path;
3527
5558
  }
3528
- get isAvailable() {
3529
- return this.getDeviceInfo() !== undefined;
5559
+ get baudRate() {
5560
+ return this.#baudRate;
3530
5561
  }
3531
- get port() {
3532
- return this.deviceIndex;
5562
+ get isOpen() {
5563
+ return this.#isOpen && !this.#isClosing;
3533
5564
  }
3534
- get type() {
3535
- return this.getDeviceInfo()?.type ?? 0 /* EMPTY */;
5565
+ async open() {
5566
+ if (this.#isOpen)
5567
+ throw new Error("Port is already open");
5568
+ try {
5569
+ this.#fd = openPort(this.#path, this.#options);
5570
+ this.#isOpen = true;
5571
+ this.#isClosing = false;
5572
+ this.#startReading();
5573
+ this.emit("open");
5574
+ } catch (err) {
5575
+ this.#isOpen = false;
5576
+ throw err;
5577
+ }
3536
5578
  }
3537
- get version() {
3538
- return this.getDeviceInfo()?.version ?? 0;
5579
+ async close() {
5580
+ if (!this.#isOpen)
5581
+ throw new Error("Port is not open");
5582
+ if (this.#isClosing)
5583
+ return;
5584
+ this.#isClosing = true;
5585
+ this.#stopReading();
5586
+ try {
5587
+ closePort(this.#fd);
5588
+ } catch (err) {
5589
+ this.#isClosing = false;
5590
+ throw err;
5591
+ }
5592
+ this.#fd = -1;
5593
+ this.#isOpen = false;
5594
+ this.#isClosing = false;
5595
+ this.emit("close");
3539
5596
  }
3540
- }
3541
-
3542
- class V5Radio {
3543
- state;
3544
- constructor(state) {
3545
- this.state = state;
5597
+ async write(data) {
5598
+ if (!this.#isOpen || this.#isClosing) {
5599
+ throw new Error("Port is not open");
5600
+ }
5601
+ const buf = typeof data === "string" ? Buffer.from(data, "utf-8") : data;
5602
+ return writePort(this.#fd, buf);
3546
5603
  }
3547
- get channel() {
3548
- return this.state.radio.channel;
5604
+ async update(options) {
5605
+ if (!this.#isOpen)
5606
+ throw new Error("Port is not open");
5607
+ if (options.baudRate !== undefined) {
5608
+ updateBaudRate(this.#fd, options.baudRate);
5609
+ this.#baudRate = options.baudRate;
5610
+ }
3549
5611
  }
3550
- get isAvailable() {
3551
- return this.state.radio.isAvailable;
5612
+ async set(flags) {
5613
+ if (!this.#isOpen)
5614
+ throw new Error("Port is not open");
5615
+ setModemLines(this.#fd, flags);
3552
5616
  }
3553
- get isConnected() {
3554
- return this.state.radio.isConnected;
5617
+ async get() {
5618
+ if (!this.#isOpen)
5619
+ throw new Error("Port is not open");
5620
+ return getModemLines(this.#fd);
3555
5621
  }
3556
- get isVexNet() {
3557
- return this.state.radio.isVexNet;
5622
+ async flush() {
5623
+ if (!this.#isOpen)
5624
+ throw new Error("Port is not open");
5625
+ flushPort(this.#fd);
3558
5626
  }
3559
- get isRadioData() {
3560
- return this.state.radio.isRadioData;
5627
+ async drain() {
5628
+ if (!this.#isOpen)
5629
+ throw new Error("Port is not open");
5630
+ drainPort(this.#fd);
3561
5631
  }
3562
- get latency() {
3563
- return this.state.radio.latency;
5632
+ pipe(parser) {
5633
+ const handler = (chunk) => parser.push(chunk);
5634
+ this.on("data", handler);
5635
+ parser._unpipe = () => this.off("data", handler);
5636
+ return parser;
3564
5637
  }
3565
- async changeChannel(channel) {
3566
- const result = await this.state._instance.connection?.writeDataAsync(new FileControlH2DPacket(1, channel));
3567
- return result instanceof FileControlReplyD2HPacket;
5638
+ unpipe(parser) {
5639
+ if (parser && typeof parser._unpipe === "function") {
5640
+ parser._unpipe();
5641
+ parser._unpipe = undefined;
5642
+ }
3568
5643
  }
3569
- }
3570
-
3571
- class V5SerialDevice extends VexSerialDevice {
3572
- autoReconnect = true;
3573
- autoRefresh = true;
3574
- pauseRefreshOnFileTransfer = true;
3575
- _isReconnecting = false;
3576
- state = new V5SerialDeviceState(this);
3577
- constructor(defaultSerial) {
3578
- super(defaultSerial);
3579
- let isLastRefreshComplete = true;
3580
- setInterval(() => {
3581
- if (this.autoRefresh && isLastRefreshComplete) {
3582
- if (!this.isConnected) {
3583
- this.state.brain.isAvailable = false;
3584
- return;
3585
- }
3586
- if (this.pauseRefreshOnFileTransfer && !this.state._isFileTransferring) {
3587
- isLastRefreshComplete = false;
3588
- this.refresh().finally(() => isLastRefreshComplete = true);
5644
+ #startReading() {
5645
+ this.#readTimer = setInterval(() => {
5646
+ if (!this.#isOpen || this.#isClosing)
5647
+ return;
5648
+ try {
5649
+ const n = readPort(this.#fd, this.#readBuf);
5650
+ if (n > 0) {
5651
+ const data = this.#readBuf.slice(0, n);
5652
+ this.emit("data", data);
3589
5653
  }
5654
+ } catch (err) {
5655
+ err.disconnected = true;
5656
+ this.emit("error", err);
5657
+ this.close().catch(() => {});
3590
5658
  }
3591
- }, 200);
3592
- }
3593
- get isV5Controller() {
3594
- return this.deviceType === 1283 /* V5_CONTROLLER */;
3595
- }
3596
- get brain() {
3597
- return new V5Brain(this.state);
3598
- }
3599
- get controllers() {
3600
- return [new V5Controller(this.state, 0), new V5Controller(this.state, 1)];
5659
+ }, this.#readInterval);
3601
5660
  }
3602
- get devices() {
3603
- const rtn = [];
3604
- for (let i = 1;i <= this.state.devices.length; i++) {
3605
- if (this.state.devices[i] != null)
3606
- rtn.push(new V5SmartDevice(this.state, i));
5661
+ #stopReading() {
5662
+ if (this.#readTimer !== null) {
5663
+ clearInterval(this.#readTimer);
5664
+ this.#readTimer = null;
3607
5665
  }
3608
- return rtn;
3609
- }
3610
- get isFieldControllerConnected() {
3611
- return this.state.isFieldControllerConnected;
3612
5666
  }
3613
- get matchMode() {
3614
- return this.state.matchMode;
5667
+ }
5668
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/list.js
5669
+ import { platform as platform3 } from "os";
5670
+ import { readdir, readlink, access } from "fs/promises";
5671
+ import { join } from "path";
5672
+ var IS_LINUX3 = platform3() === "linux";
5673
+ async function exists(path) {
5674
+ try {
5675
+ await access(path);
5676
+ return true;
5677
+ } catch {
5678
+ return false;
3615
5679
  }
3616
- set matchMode(value) {
3617
- (async () => {
3618
- if (await this.connection?.setMatchMode(value) != null)
3619
- this.state.matchMode = value;
3620
- })();
5680
+ }
5681
+ async function readFileQuiet(path) {
5682
+ try {
5683
+ return (await Bun.file(path).text()).trim();
5684
+ } catch {
5685
+ return "";
3621
5686
  }
3622
- get radio() {
3623
- return new V5Radio(this.state);
5687
+ }
5688
+ async function listLinux() {
5689
+ const ttys = await readdir("/sys/class/tty").catch(() => []);
5690
+ const checks = ttys.map(async (name) => {
5691
+ const sysPath = `/sys/class/tty/${name}`;
5692
+ const devicePath = join(sysPath, "device");
5693
+ if (!await exists(devicePath))
5694
+ return null;
5695
+ const devPath = `/dev/${name}`;
5696
+ if (!await exists(devPath))
5697
+ return null;
5698
+ return { name, devPath, devicePath };
5699
+ });
5700
+ const valid = (await Promise.all(checks)).filter(Boolean);
5701
+ const ports = await Promise.all(valid.map(async ({ devPath, devicePath }) => {
5702
+ const info = { path: devPath };
5703
+ const subsystem = await readlink(join(devicePath, "subsystem")).catch(() => "");
5704
+ if (subsystem.includes("usb-serial") || subsystem.includes("usb")) {
5705
+ const usbDevice = await findUsbParent(devicePath);
5706
+ if (usbDevice) {
5707
+ const [manufacturer, serialNumber, vendorId, productId, product] = await Promise.all([
5708
+ readFileQuiet(join(usbDevice, "manufacturer")),
5709
+ readFileQuiet(join(usbDevice, "serial")),
5710
+ readFileQuiet(join(usbDevice, "idVendor")),
5711
+ readFileQuiet(join(usbDevice, "idProduct")),
5712
+ readFileQuiet(join(usbDevice, "product"))
5713
+ ]);
5714
+ info.manufacturer = manufacturer;
5715
+ info.serialNumber = serialNumber;
5716
+ info.vendorId = vendorId;
5717
+ info.productId = productId;
5718
+ info.product = product;
5719
+ }
5720
+ }
5721
+ return info;
5722
+ }));
5723
+ return ports;
5724
+ }
5725
+ async function findUsbParent(devicePath) {
5726
+ let current = devicePath;
5727
+ for (let i = 0;i < 10; i++) {
5728
+ current = join(current, "..");
5729
+ if (await exists(join(current, "idVendor")))
5730
+ return current;
3624
5731
  }
3625
- async mockTouch(x, y, press) {
3626
- return !(await this.connection?.mockTouch(x, y, press) == null);
5732
+ return null;
5733
+ }
5734
+ async function listDarwin() {
5735
+ const devFiles = await readdir("/dev").catch(() => []);
5736
+ const seen = new Map;
5737
+ for (const name of devFiles) {
5738
+ if (!name.startsWith("cu.") && !name.startsWith("tty."))
5739
+ continue;
5740
+ if (name === "tty")
5741
+ continue;
5742
+ const isCu = name.startsWith("cu.");
5743
+ const suffix = name.slice(isCu ? 3 : 4);
5744
+ if (seen.has(suffix) && !isCu)
5745
+ continue;
5746
+ seen.set(suffix, { path: `/dev/${name}` });
3627
5747
  }
3628
- async connect(conn) {
3629
- if (this.isConnected)
3630
- return true;
3631
- if (conn != null && !conn.isConnected) {
3632
- if (await conn.query1() === null)
3633
- return false;
3634
- this.connection = conn;
3635
- } else {
3636
- let tryIdx = 0;
3637
- while (true) {
3638
- const c = new V5SerialConnection(this.defaultSerial);
3639
- const result = await c.open(tryIdx++, true);
3640
- if (result === undefined)
3641
- return false;
3642
- if (!result) {
3643
- await c.close();
3644
- continue;
3645
- }
3646
- if (await c.query1() === null) {
3647
- await c.close();
3648
- continue;
3649
- }
3650
- this.connection = c;
3651
- break;
5748
+ return [...seen.values()];
5749
+ }
5750
+ async function list() {
5751
+ return IS_LINUX3 ? listLinux() : listDarwin();
5752
+ }
5753
+ // src/adapter.ts
5754
+ import { readdir as readdir2, realpath, readlink as readlink2 } from "fs/promises";
5755
+ import { join as join2 } from "path";
5756
+ import { platform as platform4 } from "os";
5757
+
5758
+ class WebSerialPortAdapter extends EventTarget {
5759
+ onconnect = () => {};
5760
+ ondisconnect = () => {};
5761
+ _port = null;
5762
+ _path;
5763
+ _info;
5764
+ _readable = null;
5765
+ _writable = null;
5766
+ _readerController = null;
5767
+ constructor(path, info) {
5768
+ super();
5769
+ this._path = path;
5770
+ this._info = info;
5771
+ }
5772
+ get readable() {
5773
+ return this._readable;
5774
+ }
5775
+ get writable() {
5776
+ return this._writable;
5777
+ }
5778
+ getInfo() {
5779
+ return this._info;
5780
+ }
5781
+ async open(options) {
5782
+ if (this._port)
5783
+ throw new Error("Port already open");
5784
+ this._port = new SerialPort({
5785
+ path: this._path,
5786
+ baudRate: options.baudRate,
5787
+ autoOpen: false
5788
+ });
5789
+ await this._port.open();
5790
+ this._readable = new ReadableStream({
5791
+ start: (controller) => {
5792
+ this._readerController = controller;
5793
+ this._port?.on("data", (data) => {
5794
+ controller.enqueue(data);
5795
+ });
5796
+ this._port?.on("error", (err) => {
5797
+ controller.error(err);
5798
+ this.close().catch(() => {});
5799
+ });
5800
+ },
5801
+ cancel: () => {
5802
+ this.close();
5803
+ }
5804
+ });
5805
+ this._writable = new WritableStream({
5806
+ write: async (chunk) => {
5807
+ if (!this._port)
5808
+ throw new Error("Port closed");
5809
+ await this._port.write(chunk);
5810
+ },
5811
+ close: async () => {
5812
+ await this.close();
3652
5813
  }
5814
+ });
5815
+ }
5816
+ async close() {
5817
+ if (!this._port)
5818
+ return;
5819
+ const port = this._port;
5820
+ this._port = null;
5821
+ if (this._readerController) {
5822
+ try {
5823
+ this._readerController.close();
5824
+ } catch (e) {}
5825
+ this._readerController = null;
3653
5826
  }
3654
- if (!this.isConnected)
3655
- return false;
3656
- await this.doAfterConnect();
3657
- return true;
5827
+ await port.close();
5828
+ try {
5829
+ port.removeAllListeners?.();
5830
+ } catch (e) {}
5831
+ this._readable = null;
5832
+ this._writable = null;
5833
+ this.dispatchEvent(new Event("disconnect"));
3658
5834
  }
3659
- async disconnect() {
3660
- await this.connection?.close();
3661
- this.connection = undefined;
5835
+ async forget() {
5836
+ await this.close();
3662
5837
  }
3663
- async reconnect(timeout = 0) {
3664
- if (this.isConnected)
3665
- return true;
3666
- if (timeout < 0)
3667
- return false;
3668
- const endTime = new Date().getTime() + timeout;
3669
- if (this._isReconnecting) {
3670
- let successBeforeTimeout;
3671
- do {
3672
- successBeforeTimeout = await sleepUntil(() => !this._isReconnecting, timeout === 0 ? 1000 : timeout);
3673
- } while (timeout === 0 && !successBeforeTimeout);
3674
- if (this.isConnected)
3675
- return true;
3676
- if (!successBeforeTimeout)
3677
- return false;
3678
- }
3679
- this._isReconnecting = true;
3680
- while (timeout === 0 || new Date().getTime() < endTime) {
3681
- let tryIdx = 0;
3682
- while (true) {
3683
- const c = new V5SerialConnection(this.defaultSerial);
3684
- const result = await c.open(tryIdx++, false);
3685
- if (result === undefined)
3686
- break;
3687
- if (!result) {
3688
- await c.close();
3689
- continue;
3690
- }
3691
- const result2 = await c.getSystemStatus(200);
3692
- if (result2 === null) {
3693
- await c.close();
3694
- continue;
3695
- }
3696
- if (this.brain.uniqueId !== 0 && result2.uniqueId !== this.brain.uniqueId) {
3697
- await c.close();
3698
- continue;
5838
+ }
5839
+
5840
+ class WebSerialAdapter extends EventTarget {
5841
+ onconnect = () => {};
5842
+ ondisconnect = () => {};
5843
+ async _listPortsLinux() {
5844
+ const ttys = await readdir2("/sys/class/tty").catch(() => []);
5845
+ const ports = [];
5846
+ for (const name of ttys) {
5847
+ const sysPath = `/sys/class/tty/${name}`;
5848
+ const devicePath = join2(sysPath, "device");
5849
+ try {
5850
+ const realDevicePath = await realpath(devicePath);
5851
+ const subsystem = await readlink2(join2(realDevicePath, "subsystem")).catch(() => "");
5852
+ const info = { path: `/dev/${name}` };
5853
+ if (subsystem.includes("usb")) {
5854
+ let current = realDevicePath;
5855
+ for (let i = 0;i < 5; i++) {
5856
+ try {
5857
+ const vendorId = await Bun.file(join2(current, "idVendor")).text().then((t) => t.trim());
5858
+ const productId = await Bun.file(join2(current, "idProduct")).text().then((t) => t.trim());
5859
+ info.vendorId = vendorId;
5860
+ info.productId = productId;
5861
+ break;
5862
+ } catch (e) {
5863
+ current = join2(current, "..");
5864
+ }
5865
+ }
3699
5866
  }
3700
- this.connection = c;
3701
- break;
3702
- }
3703
- if (this.isConnected)
3704
- break;
3705
- const getPortCount = async () => (await this.defaultSerial.getPorts()).length;
3706
- const portsCount = await getPortCount();
3707
- await sleepUntilAsync(async () => await getPortCount() !== portsCount, 1000);
5867
+ ports.push(info);
5868
+ } catch (e) {}
3708
5869
  }
3709
- this._isReconnecting = false;
3710
- if (!this.isConnected)
3711
- return false;
3712
- this.doAfterConnect();
3713
- return true;
5870
+ return ports;
3714
5871
  }
3715
- async doAfterConnect() {
3716
- if (this.connection == null)
3717
- return;
3718
- this.connection.on("disconnected", (_data) => {
3719
- if (this.autoReconnect)
3720
- this.reconnect();
3721
- });
3722
- await this.refresh();
5872
+ async getPorts() {
5873
+ const ports = platform4() === "linux" ? await this._listPortsLinux() : await list();
5874
+ return ports.map((p) => new WebSerialPortAdapter(p.path, {
5875
+ usbVendorId: p.vendorId ? parseInt(p.vendorId, 16) : undefined,
5876
+ usbProductId: p.productId ? parseInt(p.productId, 16) : undefined
5877
+ }));
3723
5878
  }
3724
- async refresh() {
3725
- const ssPacket = await this.connection?.getSystemStatus();
3726
- if (ssPacket == null) {
3727
- this.state.brain.isAvailable = false;
3728
- return false;
3729
- }
3730
- this.state.brain.cpu0Version = ssPacket.cpu0Version;
3731
- this.state.brain.cpu1Version = ssPacket.cpu1Version;
3732
- this.state.brain.systemVersion = ssPacket.systemVersion;
3733
- const flags2 = ssPacket.sysflags[2];
3734
- this.state.controllers[0].isCharging = (flags2 & 128) !== 0;
3735
- this.state.matchMode = (flags2 & 32) !== 0 ? "disabled" : (flags2 & 64) !== 0 ? "autonomous" : "driver";
3736
- this.state.isFieldControllerConnected = (flags2 & 16) !== 0;
3737
- const flags4 = ssPacket.sysflags[4];
3738
- this.state.brain.settings.usingLanguage = (flags4 & 240) >> 4;
3739
- this.state.brain.settings.isWhiteTheme = (flags4 & 4) !== 0;
3740
- this.state.brain.settings.isScreenReversed = (flags4 & 1) === 0;
3741
- this.state.brain.uniqueId = ssPacket.uniqueId;
3742
- const sfPacket = await this.connection?.getSystemFlags();
3743
- if (sfPacket == null)
3744
- return false;
3745
- const flags5 = sfPacket.flags;
3746
- this.state.radio.isRadioData = (flags5 & Math.pow(2, 20)) !== 0;
3747
- this.state.brain.button.isDoublePressed = (flags5 & Math.pow(2, 18)) !== 0;
3748
- this.state.brain.battery.isCharging = (flags5 & Math.pow(2, 17)) !== 0;
3749
- this.state.brain.button.isPressed = (flags5 & Math.pow(2, 15)) !== 0;
3750
- this.state.radio.isVexNet = (flags5 & Math.pow(2, 14)) !== 0;
3751
- this.state.controllers[1].isAvailable = (flags5 & Math.pow(2, 13)) !== 0;
3752
- this.state.radio.isConnected = (flags5 & Math.pow(2, 10)) !== 0;
3753
- this.state.radio.isAvailable = (flags5 & Math.pow(2, 9)) !== 0;
3754
- this.state.brain.battery.batteryPercent = sfPacket.battery ?? 0;
3755
- this.state.controllers[0].isAvailable = this.state.radio.isConnected || this.state.controllers[0].isCharging;
3756
- this.state.controllers[0].battery = sfPacket.controllerBatteryPercent ?? 0;
3757
- this.state.controllers[1].battery = sfPacket.partnerControllerBatteryPercent ?? 0;
3758
- this.state.brain.activeProgram = sfPacket.currentProgram;
3759
- this.state.brain.isAvailable = !this.isV5Controller || this.state.radio.isConnected;
3760
- const rdPacket = await this.connection?.getRadioStatus();
3761
- if (rdPacket == null)
3762
- return false;
3763
- this.state.radio.channel = rdPacket.channel;
3764
- this.state.radio.latency = rdPacket.timeslot;
3765
- this.state.radio.signalQuality = rdPacket.quality;
3766
- this.state.radio.signalStrength = rdPacket.strength;
3767
- const dsPacket = await this.connection?.getDeviceStatus();
3768
- if (dsPacket == null)
3769
- return false;
3770
- let missingPorts = this.state.devices.map((d) => d?.port).filter((p) => p !== undefined);
3771
- for (let i = 0;i < dsPacket.devices.length; i++) {
3772
- const device = dsPacket.devices[i];
3773
- this.state.devices[device.port] = device;
3774
- missingPorts = missingPorts.filter((p) => p !== device.port);
5879
+ async requestPort(options) {
5880
+ const ports = await this.getPorts();
5881
+ if (options?.filters && options.filters.length > 0) {
5882
+ const filtered = ports.filter((p) => {
5883
+ const info = p.getInfo();
5884
+ return options.filters?.some((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
5885
+ });
5886
+ if (filtered.length > 0)
5887
+ return filtered[0];
5888
+ throw new Error("No port found matching filters");
3775
5889
  }
3776
- missingPorts.forEach((port) => {
3777
- this.state.devices[port] = undefined;
3778
- });
3779
- return true;
5890
+ if (ports.length > 0)
5891
+ return ports[0];
5892
+ throw new Error("No port found");
3780
5893
  }
3781
5894
  }
3782
- // src/index.ts
3783
- var brand = (str) => `\x1B[0;38;2;129;140;248;49m${str}\x1B[0m`;
3784
- console.log(brand(`v5x ${package_default.version}`));
3785
- console.log("modern cli for v5 development");
3786
- async function main() {
5895
+ var serial = new WebSerialAdapter;
5896
+
5897
+ // src/commands/kv.ts
5898
+ var import_picocolors = __toESM(require_picocolors(), 1);
5899
+ var kv = new Command("kv").description("interact with the v5 brain key-value store");
5900
+ kv.command("get").description("read a value from the KV store").argument("<key>", "kv key").action(async (key) => {
3787
5901
  const device = new V5SerialDevice(serial);
5902
+ device.autoReconnect = false;
5903
+ device.autoRefresh = false;
3788
5904
  try {
3789
5905
  await device.connect();
3790
- if (device.isConnected) {
3791
- console.log("os:", device.brain.systemVersion.toUserString());
3792
- console.log("name:", await device.brain.getValue("robotname"));
3793
- console.log("team:", await device.brain.getValue("teamnumber"));
3794
- console.log("id:", device.brain.uniqueId.toString());
3795
- }
3796
- } catch {
3797
- console.warn(import_picocolors.default.yellow("v5 device not found"));
5906
+ const value = await device.brain.getValue(key);
5907
+ console.log(value);
5908
+ } catch (e) {
5909
+ if (e.message === "No valid port selected.")
5910
+ console.log(import_picocolors.default.redBright("no valid device found"));
3798
5911
  } finally {
3799
- await device.disconnect();
5912
+ await device.dispose();
3800
5913
  }
3801
- }
3802
- main().then(() => process.exit(0), (error) => {
3803
- console.error(error);
3804
- process.exit(1);
3805
5914
  });
5915
+ kv.command("set").description("write a value to the KV store").argument("<key>", "kv key").argument("<value>", "value").action(async (key, value) => {
5916
+ const device = new V5SerialDevice(serial);
5917
+ device.autoReconnect = false;
5918
+ device.autoRefresh = false;
5919
+ try {
5920
+ await device.connect();
5921
+ const ok = await device.brain.setValue(key, value);
5922
+ if (ok)
5923
+ console.log(`set ${key} to ${value}`);
5924
+ else
5925
+ console.log(`failed to set ${key} to ${value}`);
5926
+ } catch (e) {
5927
+ console.log(e.message);
5928
+ if (e.message === "No valid port selected.")
5929
+ console.log(import_picocolors.default.redBright("no valid device found"));
5930
+ } finally {
5931
+ await device.dispose();
5932
+ }
5933
+ });
5934
+
5935
+ // src/index.ts
5936
+ var program2 = new Command;
5937
+ program2.name("v5x").description("modern v5 development").version(package_default.version);
5938
+ program2.addCommand(kv);
5939
+ program2.parse();