@jtsang/nettune-mcp 0.1.0 → 0.1.2

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 +461 -156
  2. package/package.json +7 -6
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
  import { createRequire } from "node:module";
4
3
  var __create = Object.create;
5
4
  var __getProtoOf = Object.getPrototypeOf;
@@ -70,7 +69,7 @@ var require_argument = __commonJS((exports) => {
70
69
  this._name = name;
71
70
  break;
72
71
  }
73
- if (this._name.length > 3 && this._name.slice(-3) === "...") {
72
+ if (this._name.endsWith("...")) {
74
73
  this.variadic = true;
75
74
  this._name = this._name.slice(0, -3);
76
75
  }
@@ -78,11 +77,12 @@ var require_argument = __commonJS((exports) => {
78
77
  name() {
79
78
  return this._name;
80
79
  }
81
- _concatValue(value, previous) {
80
+ _collectValue(value, previous) {
82
81
  if (previous === this.defaultValue || !Array.isArray(previous)) {
83
82
  return [value];
84
83
  }
85
- return previous.concat(value);
84
+ previous.push(value);
85
+ return previous;
86
86
  }
87
87
  default(value, description) {
88
88
  this.defaultValue = value;
@@ -100,7 +100,7 @@ var require_argument = __commonJS((exports) => {
100
100
  throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
101
101
  }
102
102
  if (this.variadic) {
103
- return this._concatValue(arg, previous);
103
+ return this._collectValue(arg, previous);
104
104
  }
105
105
  return arg;
106
106
  };
@@ -130,10 +130,14 @@ var require_help = __commonJS((exports) => {
130
130
  class Help {
131
131
  constructor() {
132
132
  this.helpWidth = undefined;
133
+ this.minWidthToWrap = 40;
133
134
  this.sortSubcommands = false;
134
135
  this.sortOptions = false;
135
136
  this.showGlobalOptions = false;
136
137
  }
138
+ prepareContext(contextOptions) {
139
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
140
+ }
137
141
  visibleCommands(cmd) {
138
142
  const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
139
143
  const helpCommand = cmd._getHelpCommand();
@@ -208,22 +212,22 @@ var require_help = __commonJS((exports) => {
208
212
  }
209
213
  longestSubcommandTermLength(cmd, helper) {
210
214
  return helper.visibleCommands(cmd).reduce((max, command) => {
211
- return Math.max(max, helper.subcommandTerm(command).length);
215
+ return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
212
216
  }, 0);
213
217
  }
214
218
  longestOptionTermLength(cmd, helper) {
215
219
  return helper.visibleOptions(cmd).reduce((max, option) => {
216
- return Math.max(max, helper.optionTerm(option).length);
220
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
217
221
  }, 0);
218
222
  }
219
223
  longestGlobalOptionTermLength(cmd, helper) {
220
224
  return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
221
- return Math.max(max, helper.optionTerm(option).length);
225
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
222
226
  }, 0);
223
227
  }
224
228
  longestArgumentTermLength(cmd, helper) {
225
229
  return helper.visibleArguments(cmd).reduce((max, argument) => {
226
- return Math.max(max, helper.argumentTerm(argument).length);
230
+ return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
227
231
  }, 0);
228
232
  }
229
233
  commandUsage(cmd) {
@@ -261,7 +265,11 @@ var require_help = __commonJS((exports) => {
261
265
  extraInfo.push(`env: ${option.envVar}`);
262
266
  }
263
267
  if (extraInfo.length > 0) {
264
- return `${option.description} (${extraInfo.join(", ")})`;
268
+ const extraDescription = `(${extraInfo.join(", ")})`;
269
+ if (option.description) {
270
+ return `${option.description} ${extraDescription}`;
271
+ }
272
+ return extraDescription;
265
273
  }
266
274
  return option.description;
267
275
  }
@@ -274,102 +282,202 @@ var require_help = __commonJS((exports) => {
274
282
  extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
275
283
  }
276
284
  if (extraInfo.length > 0) {
277
- const extraDescripton = `(${extraInfo.join(", ")})`;
285
+ const extraDescription = `(${extraInfo.join(", ")})`;
278
286
  if (argument.description) {
279
- return `${argument.description} ${extraDescripton}`;
287
+ return `${argument.description} ${extraDescription}`;
280
288
  }
281
- return extraDescripton;
289
+ return extraDescription;
282
290
  }
283
291
  return argument.description;
284
292
  }
293
+ formatItemList(heading, items, helper) {
294
+ if (items.length === 0)
295
+ return [];
296
+ return [helper.styleTitle(heading), ...items, ""];
297
+ }
298
+ groupItems(unsortedItems, visibleItems, getGroup) {
299
+ const result = new Map;
300
+ unsortedItems.forEach((item) => {
301
+ const group = getGroup(item);
302
+ if (!result.has(group))
303
+ result.set(group, []);
304
+ });
305
+ visibleItems.forEach((item) => {
306
+ const group = getGroup(item);
307
+ if (!result.has(group)) {
308
+ result.set(group, []);
309
+ }
310
+ result.get(group).push(item);
311
+ });
312
+ return result;
313
+ }
285
314
  formatHelp(cmd, helper) {
286
315
  const termWidth = helper.padWidth(cmd, helper);
287
- const helpWidth = helper.helpWidth || 80;
288
- const itemIndentWidth = 2;
289
- const itemSeparatorWidth = 2;
290
- function formatItem(term, description) {
291
- if (description) {
292
- const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
293
- return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
294
- }
295
- return term;
296
- }
297
- function formatList(textArray) {
298
- return textArray.join(`
299
- `).replace(/^/gm, " ".repeat(itemIndentWidth));
300
- }
301
- let output = [`Usage: ${helper.commandUsage(cmd)}`, ""];
316
+ const helpWidth = helper.helpWidth ?? 80;
317
+ function callFormatItem(term, description) {
318
+ return helper.formatItem(term, termWidth, description, helper);
319
+ }
320
+ let output = [
321
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
322
+ ""
323
+ ];
302
324
  const commandDescription = helper.commandDescription(cmd);
303
325
  if (commandDescription.length > 0) {
304
326
  output = output.concat([
305
- helper.wrap(commandDescription, helpWidth, 0),
327
+ helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth),
306
328
  ""
307
329
  ]);
308
330
  }
309
331
  const argumentList = helper.visibleArguments(cmd).map((argument) => {
310
- return formatItem(helper.argumentTerm(argument), helper.argumentDescription(argument));
332
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
311
333
  });
312
- if (argumentList.length > 0) {
313
- output = output.concat(["Arguments:", formatList(argumentList), ""]);
314
- }
315
- const optionList = helper.visibleOptions(cmd).map((option) => {
316
- return formatItem(helper.optionTerm(option), helper.optionDescription(option));
334
+ output = output.concat(this.formatItemList("Arguments:", argumentList, helper));
335
+ const optionGroups = this.groupItems(cmd.options, helper.visibleOptions(cmd), (option) => option.helpGroupHeading ?? "Options:");
336
+ optionGroups.forEach((options, group) => {
337
+ const optionList = options.map((option) => {
338
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
339
+ });
340
+ output = output.concat(this.formatItemList(group, optionList, helper));
317
341
  });
318
- if (optionList.length > 0) {
319
- output = output.concat(["Options:", formatList(optionList), ""]);
320
- }
321
- if (this.showGlobalOptions) {
342
+ if (helper.showGlobalOptions) {
322
343
  const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
323
- return formatItem(helper.optionTerm(option), helper.optionDescription(option));
344
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
324
345
  });
325
- if (globalOptionList.length > 0) {
326
- output = output.concat([
327
- "Global Options:",
328
- formatList(globalOptionList),
329
- ""
330
- ]);
331
- }
346
+ output = output.concat(this.formatItemList("Global Options:", globalOptionList, helper));
332
347
  }
333
- const commandList = helper.visibleCommands(cmd).map((cmd2) => {
334
- return formatItem(helper.subcommandTerm(cmd2), helper.subcommandDescription(cmd2));
348
+ const commandGroups = this.groupItems(cmd.commands, helper.visibleCommands(cmd), (sub) => sub.helpGroup() || "Commands:");
349
+ commandGroups.forEach((commands, group) => {
350
+ const commandList = commands.map((sub) => {
351
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)), helper.styleSubcommandDescription(helper.subcommandDescription(sub)));
352
+ });
353
+ output = output.concat(this.formatItemList(group, commandList, helper));
335
354
  });
336
- if (commandList.length > 0) {
337
- output = output.concat(["Commands:", formatList(commandList), ""]);
338
- }
339
355
  return output.join(`
340
356
  `);
341
357
  }
358
+ displayWidth(str) {
359
+ return stripColor(str).length;
360
+ }
361
+ styleTitle(str) {
362
+ return str;
363
+ }
364
+ styleUsage(str) {
365
+ return str.split(" ").map((word) => {
366
+ if (word === "[options]")
367
+ return this.styleOptionText(word);
368
+ if (word === "[command]")
369
+ return this.styleSubcommandText(word);
370
+ if (word[0] === "[" || word[0] === "<")
371
+ return this.styleArgumentText(word);
372
+ return this.styleCommandText(word);
373
+ }).join(" ");
374
+ }
375
+ styleCommandDescription(str) {
376
+ return this.styleDescriptionText(str);
377
+ }
378
+ styleOptionDescription(str) {
379
+ return this.styleDescriptionText(str);
380
+ }
381
+ styleSubcommandDescription(str) {
382
+ return this.styleDescriptionText(str);
383
+ }
384
+ styleArgumentDescription(str) {
385
+ return this.styleDescriptionText(str);
386
+ }
387
+ styleDescriptionText(str) {
388
+ return str;
389
+ }
390
+ styleOptionTerm(str) {
391
+ return this.styleOptionText(str);
392
+ }
393
+ styleSubcommandTerm(str) {
394
+ return str.split(" ").map((word) => {
395
+ if (word === "[options]")
396
+ return this.styleOptionText(word);
397
+ if (word[0] === "[" || word[0] === "<")
398
+ return this.styleArgumentText(word);
399
+ return this.styleSubcommandText(word);
400
+ }).join(" ");
401
+ }
402
+ styleArgumentTerm(str) {
403
+ return this.styleArgumentText(str);
404
+ }
405
+ styleOptionText(str) {
406
+ return str;
407
+ }
408
+ styleArgumentText(str) {
409
+ return str;
410
+ }
411
+ styleSubcommandText(str) {
412
+ return str;
413
+ }
414
+ styleCommandText(str) {
415
+ return str;
416
+ }
342
417
  padWidth(cmd, helper) {
343
418
  return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
344
419
  }
345
- wrap(str, width, indent, minColumnWidth = 40) {
346
- const indents = " \\f\\t\\v   -    \uFEFF";
347
- const manualIndent = new RegExp(`[\\n][${indents}]+`);
348
- if (str.match(manualIndent))
349
- return str;
350
- const columnWidth = width - indent;
351
- if (columnWidth < minColumnWidth)
420
+ preformatted(str) {
421
+ return /\n[^\S\r\n]/.test(str);
422
+ }
423
+ formatItem(term, termWidth, description, helper) {
424
+ const itemIndent = 2;
425
+ const itemIndentStr = " ".repeat(itemIndent);
426
+ if (!description)
427
+ return itemIndentStr + term;
428
+ const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
429
+ const spacerWidth = 2;
430
+ const helpWidth = this.helpWidth ?? 80;
431
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
432
+ let formattedDescription;
433
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
434
+ formattedDescription = description;
435
+ } else {
436
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
437
+ formattedDescription = wrappedDescription.replace(/\n/g, `
438
+ ` + " ".repeat(termWidth + spacerWidth));
439
+ }
440
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
441
+ ${itemIndentStr}`);
442
+ }
443
+ boxWrap(str, width) {
444
+ if (width < this.minWidthToWrap)
352
445
  return str;
353
- const leadingStr = str.slice(0, indent);
354
- const columnText = str.slice(indent).replace(`\r
355
- `, `
356
- `);
357
- const indentString = " ".repeat(indent);
358
- const zeroWidthSpace = "​";
359
- const breaks = `\\s${zeroWidthSpace}`;
360
- const regex = new RegExp(`
361
- |.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, "g");
362
- const lines = columnText.match(regex) || [];
363
- return leadingStr + lines.map((line, i) => {
364
- if (line === `
365
- `)
366
- return "";
367
- return (i > 0 ? indentString : "") + line.trimEnd();
368
- }).join(`
446
+ const rawLines = str.split(/\r\n|\n/);
447
+ const chunkPattern = /[\s]*[^\s]+/g;
448
+ const wrappedLines = [];
449
+ rawLines.forEach((line) => {
450
+ const chunks = line.match(chunkPattern);
451
+ if (chunks === null) {
452
+ wrappedLines.push("");
453
+ return;
454
+ }
455
+ let sumChunks = [chunks.shift()];
456
+ let sumWidth = this.displayWidth(sumChunks[0]);
457
+ chunks.forEach((chunk) => {
458
+ const visibleWidth = this.displayWidth(chunk);
459
+ if (sumWidth + visibleWidth <= width) {
460
+ sumChunks.push(chunk);
461
+ sumWidth += visibleWidth;
462
+ return;
463
+ }
464
+ wrappedLines.push(sumChunks.join(""));
465
+ const nextChunk = chunk.trimStart();
466
+ sumChunks = [nextChunk];
467
+ sumWidth = this.displayWidth(nextChunk);
468
+ });
469
+ wrappedLines.push(sumChunks.join(""));
470
+ });
471
+ return wrappedLines.join(`
369
472
  `);
370
473
  }
371
474
  }
475
+ function stripColor(str) {
476
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
477
+ return str.replace(sgrPattern, "");
478
+ }
372
479
  exports.Help = Help;
480
+ exports.stripColor = stripColor;
373
481
  });
374
482
 
375
483
  // node_modules/commander/lib/option.js
@@ -400,6 +508,7 @@ var require_option = __commonJS((exports) => {
400
508
  this.argChoices = undefined;
401
509
  this.conflictsWith = [];
402
510
  this.implied = undefined;
511
+ this.helpGroupHeading = undefined;
403
512
  }
404
513
  default(value, description) {
405
514
  this.defaultValue = value;
@@ -438,11 +547,12 @@ var require_option = __commonJS((exports) => {
438
547
  this.hidden = !!hide;
439
548
  return this;
440
549
  }
441
- _concatValue(value, previous) {
550
+ _collectValue(value, previous) {
442
551
  if (previous === this.defaultValue || !Array.isArray(previous)) {
443
552
  return [value];
444
553
  }
445
- return previous.concat(value);
554
+ previous.push(value);
555
+ return previous;
446
556
  }
447
557
  choices(values) {
448
558
  this.argChoices = values.slice();
@@ -451,7 +561,7 @@ var require_option = __commonJS((exports) => {
451
561
  throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
452
562
  }
453
563
  if (this.variadic) {
454
- return this._concatValue(arg, previous);
564
+ return this._collectValue(arg, previous);
455
565
  }
456
566
  return arg;
457
567
  };
@@ -464,7 +574,14 @@ var require_option = __commonJS((exports) => {
464
574
  return this.short.replace(/^-/, "");
465
575
  }
466
576
  attributeName() {
467
- return camelcase(this.name().replace(/^no-/, ""));
577
+ if (this.negate) {
578
+ return camelcase(this.name().replace(/^no-/, ""));
579
+ }
580
+ return camelcase(this.name());
581
+ }
582
+ helpGroup(heading) {
583
+ this.helpGroupHeading = heading;
584
+ return this;
468
585
  }
469
586
  is(arg) {
470
587
  return this.short === arg || this.long === arg;
@@ -509,14 +626,38 @@ var require_option = __commonJS((exports) => {
509
626
  function splitOptionFlags(flags) {
510
627
  let shortFlag;
511
628
  let longFlag;
512
- const flagParts = flags.split(/[ |,]+/);
513
- if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1]))
629
+ const shortFlagExp = /^-[^-]$/;
630
+ const longFlagExp = /^--[^-]/;
631
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
632
+ if (shortFlagExp.test(flagParts[0]))
633
+ shortFlag = flagParts.shift();
634
+ if (longFlagExp.test(flagParts[0]))
635
+ longFlag = flagParts.shift();
636
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
514
637
  shortFlag = flagParts.shift();
515
- longFlag = flagParts.shift();
516
- if (!shortFlag && /^-[^-]$/.test(longFlag)) {
638
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
517
639
  shortFlag = longFlag;
518
- longFlag = undefined;
519
- }
640
+ longFlag = flagParts.shift();
641
+ }
642
+ if (flagParts[0].startsWith("-")) {
643
+ const unsupportedFlag = flagParts[0];
644
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
645
+ if (/^-[^-][^-]/.test(unsupportedFlag))
646
+ throw new Error(`${baseError}
647
+ - a short flag is a single dash and a single character
648
+ - either use a single dash and a single character (for a short flag)
649
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
650
+ if (shortFlagExp.test(unsupportedFlag))
651
+ throw new Error(`${baseError}
652
+ - too many short flags`);
653
+ if (longFlagExp.test(unsupportedFlag))
654
+ throw new Error(`${baseError}
655
+ - too many long flags`);
656
+ throw new Error(`${baseError}
657
+ - unrecognised flag format`);
658
+ }
659
+ if (shortFlag === undefined && longFlag === undefined)
660
+ throw new Error(`option creation failed due to no flags found in '${flags}'.`);
520
661
  return { shortFlag, longFlag };
521
662
  }
522
663
  exports.Option = Option;
@@ -605,7 +746,7 @@ var require_command = __commonJS((exports) => {
605
746
  var process2 = __require("node:process");
606
747
  var { Argument, humanReadableArgName } = require_argument();
607
748
  var { CommanderError } = require_error();
608
- var { Help } = require_help();
749
+ var { Help, stripColor } = require_help();
609
750
  var { Option, DualOptions } = require_option();
610
751
  var { suggestSimilar } = require_suggestSimilar();
611
752
 
@@ -616,7 +757,7 @@ var require_command = __commonJS((exports) => {
616
757
  this.options = [];
617
758
  this.parent = null;
618
759
  this._allowUnknownOption = false;
619
- this._allowExcessArguments = true;
760
+ this._allowExcessArguments = false;
620
761
  this.registeredArguments = [];
621
762
  this._args = this.registeredArguments;
622
763
  this.args = [];
@@ -643,18 +784,25 @@ var require_command = __commonJS((exports) => {
643
784
  this._lifeCycleHooks = {};
644
785
  this._showHelpAfterError = false;
645
786
  this._showSuggestionAfterError = true;
787
+ this._savedState = null;
646
788
  this._outputConfiguration = {
647
789
  writeOut: (str) => process2.stdout.write(str),
648
790
  writeErr: (str) => process2.stderr.write(str),
791
+ outputError: (str, write) => write(str),
649
792
  getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
650
793
  getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
651
- outputError: (str, write) => write(str)
794
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
795
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
796
+ stripColor: (str) => stripColor(str)
652
797
  };
653
798
  this._hidden = false;
654
799
  this._helpOption = undefined;
655
800
  this._addImplicitHelpCommand = undefined;
656
801
  this._helpCommand = undefined;
657
802
  this._helpConfiguration = {};
803
+ this._helpGroupHeading = undefined;
804
+ this._defaultCommandGroup = undefined;
805
+ this._defaultOptionGroup = undefined;
658
806
  }
659
807
  copyInheritedSettings(sourceCommand) {
660
808
  this._outputConfiguration = sourceCommand._outputConfiguration;
@@ -719,7 +867,10 @@ var require_command = __commonJS((exports) => {
719
867
  configureOutput(configuration) {
720
868
  if (configuration === undefined)
721
869
  return this._outputConfiguration;
722
- Object.assign(this._outputConfiguration, configuration);
870
+ this._outputConfiguration = {
871
+ ...this._outputConfiguration,
872
+ ...configuration
873
+ };
723
874
  return this;
724
875
  }
725
876
  showHelpAfterError(displayHelp = true) {
@@ -750,12 +901,12 @@ var require_command = __commonJS((exports) => {
750
901
  createArgument(name, description) {
751
902
  return new Argument(name, description);
752
903
  }
753
- argument(name, description, fn, defaultValue) {
904
+ argument(name, description, parseArg, defaultValue) {
754
905
  const argument = this.createArgument(name, description);
755
- if (typeof fn === "function") {
756
- argument.default(defaultValue).argParser(fn);
906
+ if (typeof parseArg === "function") {
907
+ argument.default(defaultValue).argParser(parseArg);
757
908
  } else {
758
- argument.default(fn);
909
+ argument.default(parseArg);
759
910
  }
760
911
  this.addArgument(argument);
761
912
  return this;
@@ -768,7 +919,7 @@ var require_command = __commonJS((exports) => {
768
919
  }
769
920
  addArgument(argument) {
770
921
  const previousArgument = this.registeredArguments.slice(-1)[0];
771
- if (previousArgument && previousArgument.variadic) {
922
+ if (previousArgument?.variadic) {
772
923
  throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
773
924
  }
774
925
  if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
@@ -780,10 +931,13 @@ var require_command = __commonJS((exports) => {
780
931
  helpCommand(enableOrNameAndArgs, description) {
781
932
  if (typeof enableOrNameAndArgs === "boolean") {
782
933
  this._addImplicitHelpCommand = enableOrNameAndArgs;
934
+ if (enableOrNameAndArgs && this._defaultCommandGroup) {
935
+ this._initCommandGroup(this._getHelpCommand());
936
+ }
783
937
  return this;
784
938
  }
785
- enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
786
- const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
939
+ const nameAndArgs = enableOrNameAndArgs ?? "help [command]";
940
+ const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);
787
941
  const helpDescription = description ?? "display help for command";
788
942
  const helpCommand = this.createCommand(helpName);
789
943
  helpCommand.helpOption(false);
@@ -793,6 +947,8 @@ var require_command = __commonJS((exports) => {
793
947
  helpCommand.description(helpDescription);
794
948
  this._addImplicitHelpCommand = true;
795
949
  this._helpCommand = helpCommand;
950
+ if (enableOrNameAndArgs || description)
951
+ this._initCommandGroup(helpCommand);
796
952
  return this;
797
953
  }
798
954
  addHelpCommand(helpCommand, deprecatedDescription) {
@@ -802,6 +958,7 @@ var require_command = __commonJS((exports) => {
802
958
  }
803
959
  this._addImplicitHelpCommand = true;
804
960
  this._helpCommand = helpCommand;
961
+ this._initCommandGroup(helpCommand);
805
962
  return this;
806
963
  }
807
964
  _getHelpCommand() {
@@ -881,6 +1038,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
881
1038
  throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
882
1039
  - already used by option '${matchingOption.flags}'`);
883
1040
  }
1041
+ this._initOptionGroup(option);
884
1042
  this.options.push(option);
885
1043
  }
886
1044
  _registerCommand(command) {
@@ -893,6 +1051,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
893
1051
  const newCmd = knownBy(command).join("|");
894
1052
  throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
895
1053
  }
1054
+ this._initCommandGroup(command);
896
1055
  this.commands.push(command);
897
1056
  }
898
1057
  addOption(option) {
@@ -915,7 +1074,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
915
1074
  if (val !== null && option.parseArg) {
916
1075
  val = this._callParseArg(option, val, oldValue, invalidValueMessage);
917
1076
  } else if (val !== null && option.variadic) {
918
- val = option._concatValue(val, oldValue);
1077
+ val = option._collectValue(val, oldValue);
919
1078
  }
920
1079
  if (val == null) {
921
1080
  if (option.negate) {
@@ -1080,15 +1239,53 @@ Expecting one of '${allowedValues.join("', '")}'`);
1080
1239
  return userArgs;
1081
1240
  }
1082
1241
  parse(argv, parseOptions) {
1242
+ this._prepareForParse();
1083
1243
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1084
1244
  this._parseCommand([], userArgs);
1085
1245
  return this;
1086
1246
  }
1087
1247
  async parseAsync(argv, parseOptions) {
1248
+ this._prepareForParse();
1088
1249
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1089
1250
  await this._parseCommand([], userArgs);
1090
1251
  return this;
1091
1252
  }
1253
+ _prepareForParse() {
1254
+ if (this._savedState === null) {
1255
+ this.saveStateBeforeParse();
1256
+ } else {
1257
+ this.restoreStateBeforeParse();
1258
+ }
1259
+ }
1260
+ saveStateBeforeParse() {
1261
+ this._savedState = {
1262
+ _name: this._name,
1263
+ _optionValues: { ...this._optionValues },
1264
+ _optionValueSources: { ...this._optionValueSources }
1265
+ };
1266
+ }
1267
+ restoreStateBeforeParse() {
1268
+ if (this._storeOptionsAsProperties)
1269
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
1270
+ - either make a new Command for each call to parse, or stop storing options as properties`);
1271
+ this._name = this._savedState._name;
1272
+ this._scriptPath = null;
1273
+ this.rawArgs = [];
1274
+ this._optionValues = { ...this._savedState._optionValues };
1275
+ this._optionValueSources = { ...this._savedState._optionValueSources };
1276
+ this.args = [];
1277
+ this.processedArgs = [];
1278
+ }
1279
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
1280
+ if (fs.existsSync(executableFile))
1281
+ return;
1282
+ 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";
1283
+ const executableMissing = `'${executableFile}' does not exist
1284
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1285
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1286
+ - ${executableDirMessage}`;
1287
+ throw new Error(executableMissing);
1288
+ }
1092
1289
  _executeSubCommand(subcommand, args) {
1093
1290
  args = args.slice();
1094
1291
  let launchWithNode = false;
@@ -1112,7 +1309,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1112
1309
  let resolvedScriptPath;
1113
1310
  try {
1114
1311
  resolvedScriptPath = fs.realpathSync(this._scriptPath);
1115
- } catch (err) {
1312
+ } catch {
1116
1313
  resolvedScriptPath = this._scriptPath;
1117
1314
  }
1118
1315
  executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
@@ -1138,6 +1335,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1138
1335
  proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1139
1336
  }
1140
1337
  } else {
1338
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1141
1339
  args.unshift(executableFile);
1142
1340
  args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1143
1341
  proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
@@ -1163,12 +1361,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1163
1361
  });
1164
1362
  proc.on("error", (err) => {
1165
1363
  if (err.code === "ENOENT") {
1166
- 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";
1167
- const executableMissing = `'${executableFile}' does not exist
1168
- - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1169
- - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1170
- - ${executableDirMessage}`;
1171
- throw new Error(executableMissing);
1364
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1172
1365
  } else if (err.code === "EACCES") {
1173
1366
  throw new Error(`'${executableFile}' not executable`);
1174
1367
  }
@@ -1186,6 +1379,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1186
1379
  const subCommand = this._findCommand(commandName);
1187
1380
  if (!subCommand)
1188
1381
  this.help({ error: true });
1382
+ subCommand._prepareForParse();
1189
1383
  let promiseChain;
1190
1384
  promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
1191
1385
  promiseChain = this._chainOrCall(promiseChain, () => {
@@ -1255,7 +1449,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1255
1449
  this.processedArgs = processedArgs;
1256
1450
  }
1257
1451
  _chainOrCall(promise, fn) {
1258
- if (promise && promise.then && typeof promise.then === "function") {
1452
+ if (promise?.then && typeof promise.then === "function") {
1259
1453
  return promise.then(() => fn());
1260
1454
  }
1261
1455
  return fn();
@@ -1332,7 +1526,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1332
1526
  promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
1333
1527
  return promiseChain;
1334
1528
  }
1335
- if (this.parent && this.parent.listenerCount(commandEvent)) {
1529
+ if (this.parent?.listenerCount(commandEvent)) {
1336
1530
  checkForUnknownOptions();
1337
1531
  this._processArguments();
1338
1532
  this.parent.emit(commandEvent, operands, unknown);
@@ -1394,24 +1588,31 @@ Expecting one of '${allowedValues.join("', '")}'`);
1394
1588
  cmd._checkForConflictingLocalOptions();
1395
1589
  });
1396
1590
  }
1397
- parseOptions(argv) {
1591
+ parseOptions(args) {
1398
1592
  const operands = [];
1399
1593
  const unknown = [];
1400
1594
  let dest = operands;
1401
- const args = argv.slice();
1402
1595
  function maybeOption(arg) {
1403
1596
  return arg.length > 1 && arg[0] === "-";
1404
1597
  }
1598
+ const negativeNumberArg = (arg) => {
1599
+ if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg))
1600
+ return false;
1601
+ return !this._getCommandAndAncestors().some((cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short)));
1602
+ };
1405
1603
  let activeVariadicOption = null;
1406
- while (args.length) {
1407
- const arg = args.shift();
1604
+ let activeGroup = null;
1605
+ let i = 0;
1606
+ while (i < args.length || activeGroup) {
1607
+ const arg = activeGroup ?? args[i++];
1608
+ activeGroup = null;
1408
1609
  if (arg === "--") {
1409
1610
  if (dest === unknown)
1410
1611
  dest.push(arg);
1411
- dest.push(...args);
1612
+ dest.push(...args.slice(i));
1412
1613
  break;
1413
1614
  }
1414
- if (activeVariadicOption && !maybeOption(arg)) {
1615
+ if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
1415
1616
  this.emit(`option:${activeVariadicOption.name()}`, arg);
1416
1617
  continue;
1417
1618
  }
@@ -1420,14 +1621,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
1420
1621
  const option = this._findOption(arg);
1421
1622
  if (option) {
1422
1623
  if (option.required) {
1423
- const value = args.shift();
1624
+ const value = args[i++];
1424
1625
  if (value === undefined)
1425
1626
  this.optionMissingArgument(option);
1426
1627
  this.emit(`option:${option.name()}`, value);
1427
1628
  } else if (option.optional) {
1428
1629
  let value = null;
1429
- if (args.length > 0 && !maybeOption(args[0])) {
1430
- value = args.shift();
1630
+ if (i < args.length && (!maybeOption(args[i]) || negativeNumberArg(args[i]))) {
1631
+ value = args[i++];
1431
1632
  }
1432
1633
  this.emit(`option:${option.name()}`, value);
1433
1634
  } else {
@@ -1444,7 +1645,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1444
1645
  this.emit(`option:${option.name()}`, arg.slice(2));
1445
1646
  } else {
1446
1647
  this.emit(`option:${option.name()}`);
1447
- args.unshift(`-${arg.slice(2)}`);
1648
+ activeGroup = `-${arg.slice(2)}`;
1448
1649
  }
1449
1650
  continue;
1450
1651
  }
@@ -1457,31 +1658,24 @@ Expecting one of '${allowedValues.join("', '")}'`);
1457
1658
  continue;
1458
1659
  }
1459
1660
  }
1460
- if (maybeOption(arg)) {
1661
+ if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
1461
1662
  dest = unknown;
1462
1663
  }
1463
1664
  if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
1464
1665
  if (this._findCommand(arg)) {
1465
1666
  operands.push(arg);
1466
- if (args.length > 0)
1467
- unknown.push(...args);
1667
+ unknown.push(...args.slice(i));
1468
1668
  break;
1469
1669
  } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
1470
- operands.push(arg);
1471
- if (args.length > 0)
1472
- operands.push(...args);
1670
+ operands.push(arg, ...args.slice(i));
1473
1671
  break;
1474
1672
  } else if (this._defaultCommandName) {
1475
- unknown.push(arg);
1476
- if (args.length > 0)
1477
- unknown.push(...args);
1673
+ unknown.push(arg, ...args.slice(i));
1478
1674
  break;
1479
1675
  }
1480
1676
  }
1481
1677
  if (this._passThroughOptions) {
1482
- dest.push(arg);
1483
- if (args.length > 0)
1484
- dest.push(...args);
1678
+ dest.push(arg, ...args.slice(i));
1485
1679
  break;
1486
1680
  }
1487
1681
  dest.push(arg);
@@ -1692,6 +1886,32 @@ Expecting one of '${allowedValues.join("', '")}'`);
1692
1886
  this._name = str;
1693
1887
  return this;
1694
1888
  }
1889
+ helpGroup(heading) {
1890
+ if (heading === undefined)
1891
+ return this._helpGroupHeading ?? "";
1892
+ this._helpGroupHeading = heading;
1893
+ return this;
1894
+ }
1895
+ commandsGroup(heading) {
1896
+ if (heading === undefined)
1897
+ return this._defaultCommandGroup ?? "";
1898
+ this._defaultCommandGroup = heading;
1899
+ return this;
1900
+ }
1901
+ optionsGroup(heading) {
1902
+ if (heading === undefined)
1903
+ return this._defaultOptionGroup ?? "";
1904
+ this._defaultOptionGroup = heading;
1905
+ return this;
1906
+ }
1907
+ _initOptionGroup(option) {
1908
+ if (this._defaultOptionGroup && !option.helpGroupHeading)
1909
+ option.helpGroup(this._defaultOptionGroup);
1910
+ }
1911
+ _initCommandGroup(cmd) {
1912
+ if (this._defaultCommandGroup && !cmd.helpGroup())
1913
+ cmd.helpGroup(this._defaultCommandGroup);
1914
+ }
1695
1915
  nameFromFilename(filename) {
1696
1916
  this._name = path.basename(filename, path.extname(filename));
1697
1917
  return this;
@@ -1704,23 +1924,38 @@ Expecting one of '${allowedValues.join("', '")}'`);
1704
1924
  }
1705
1925
  helpInformation(contextOptions) {
1706
1926
  const helper = this.createHelp();
1707
- if (helper.helpWidth === undefined) {
1708
- helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
1709
- }
1710
- return helper.formatHelp(this, helper);
1927
+ const context = this._getOutputContext(contextOptions);
1928
+ helper.prepareContext({
1929
+ error: context.error,
1930
+ helpWidth: context.helpWidth,
1931
+ outputHasColors: context.hasColors
1932
+ });
1933
+ const text = helper.formatHelp(this, helper);
1934
+ if (context.hasColors)
1935
+ return text;
1936
+ return this._outputConfiguration.stripColor(text);
1711
1937
  }
1712
- _getHelpContext(contextOptions) {
1938
+ _getOutputContext(contextOptions) {
1713
1939
  contextOptions = contextOptions || {};
1714
- const context = { error: !!contextOptions.error };
1715
- let write;
1716
- if (context.error) {
1717
- write = (arg) => this._outputConfiguration.writeErr(arg);
1940
+ const error = !!contextOptions.error;
1941
+ let baseWrite;
1942
+ let hasColors;
1943
+ let helpWidth;
1944
+ if (error) {
1945
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
1946
+ hasColors = this._outputConfiguration.getErrHasColors();
1947
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
1718
1948
  } else {
1719
- write = (arg) => this._outputConfiguration.writeOut(arg);
1720
- }
1721
- context.write = contextOptions.write || write;
1722
- context.command = this;
1723
- return context;
1949
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
1950
+ hasColors = this._outputConfiguration.getOutHasColors();
1951
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
1952
+ }
1953
+ const write = (str) => {
1954
+ if (!hasColors)
1955
+ str = this._outputConfiguration.stripColor(str);
1956
+ return baseWrite(str);
1957
+ };
1958
+ return { error, write, hasColors, helpWidth };
1724
1959
  }
1725
1960
  outputHelp(contextOptions) {
1726
1961
  let deprecatedCallback;
@@ -1728,35 +1963,44 @@ Expecting one of '${allowedValues.join("', '")}'`);
1728
1963
  deprecatedCallback = contextOptions;
1729
1964
  contextOptions = undefined;
1730
1965
  }
1731
- const context = this._getHelpContext(contextOptions);
1732
- this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", context));
1733
- this.emit("beforeHelp", context);
1734
- let helpInformation = this.helpInformation(context);
1966
+ const outputContext = this._getOutputContext(contextOptions);
1967
+ const eventContext = {
1968
+ error: outputContext.error,
1969
+ write: outputContext.write,
1970
+ command: this
1971
+ };
1972
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
1973
+ this.emit("beforeHelp", eventContext);
1974
+ let helpInformation = this.helpInformation({ error: outputContext.error });
1735
1975
  if (deprecatedCallback) {
1736
1976
  helpInformation = deprecatedCallback(helpInformation);
1737
1977
  if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
1738
1978
  throw new Error("outputHelp callback must return a string or a Buffer");
1739
1979
  }
1740
1980
  }
1741
- context.write(helpInformation);
1981
+ outputContext.write(helpInformation);
1742
1982
  if (this._getHelpOption()?.long) {
1743
1983
  this.emit(this._getHelpOption().long);
1744
1984
  }
1745
- this.emit("afterHelp", context);
1746
- this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", context));
1985
+ this.emit("afterHelp", eventContext);
1986
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
1747
1987
  }
1748
1988
  helpOption(flags, description) {
1749
1989
  if (typeof flags === "boolean") {
1750
1990
  if (flags) {
1751
- this._helpOption = this._helpOption ?? undefined;
1991
+ if (this._helpOption === null)
1992
+ this._helpOption = undefined;
1993
+ if (this._defaultOptionGroup) {
1994
+ this._initOptionGroup(this._getHelpOption());
1995
+ }
1752
1996
  } else {
1753
1997
  this._helpOption = null;
1754
1998
  }
1755
1999
  return this;
1756
2000
  }
1757
- flags = flags ?? "-h, --help";
1758
- description = description ?? "display help for command";
1759
- this._helpOption = this.createOption(flags, description);
2001
+ this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
2002
+ if (flags || description)
2003
+ this._initOptionGroup(this._helpOption);
1760
2004
  return this;
1761
2005
  }
1762
2006
  _getHelpOption() {
@@ -1767,11 +2011,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
1767
2011
  }
1768
2012
  addHelpOption(option) {
1769
2013
  this._helpOption = option;
2014
+ this._initOptionGroup(option);
1770
2015
  return this;
1771
2016
  }
1772
2017
  help(contextOptions) {
1773
2018
  this.outputHelp(contextOptions);
1774
- let exitCode = process2.exitCode || 0;
2019
+ let exitCode = Number(process2.exitCode ?? 0);
1775
2020
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
1776
2021
  exitCode = 1;
1777
2022
  }
@@ -1836,7 +2081,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
1836
2081
  return arg;
1837
2082
  });
1838
2083
  }
2084
+ function useColor() {
2085
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
2086
+ return false;
2087
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
2088
+ return true;
2089
+ return;
2090
+ }
1839
2091
  exports.Command = Command;
2092
+ exports.useColor = useColor;
1840
2093
  });
1841
2094
 
1842
2095
  // node_modules/commander/index.js
@@ -1874,9 +2127,60 @@ var {
1874
2127
  Option,
1875
2128
  Help
1876
2129
  } = import__.default;
2130
+ // package.json
2131
+ var package_default = {
2132
+ name: "@jtsang/nettune-mcp",
2133
+ version: "0.1.2",
2134
+ private: false,
2135
+ description: "MCP stdio wrapper for nettune - TCP network optimization tool",
2136
+ type: "module",
2137
+ main: "./dist/index.js",
2138
+ bin: {
2139
+ "nettune-mcp": "./dist/index.js"
2140
+ },
2141
+ files: [
2142
+ "dist",
2143
+ "README.md"
2144
+ ],
2145
+ scripts: {
2146
+ build: "bunx rimraf dist && bun build src/index.ts --outdir dist --target node --format esm && echo '#!/usr/bin/env node' | cat - dist/index.js > dist/tmp && mv dist/tmp dist/index.js && chmod +x dist/index.js",
2147
+ dev: "bun run src/index.ts",
2148
+ test: "bun test",
2149
+ typecheck: "tsc --noEmit",
2150
+ prepublishOnly: "bun run build"
2151
+ },
2152
+ keywords: [
2153
+ "nettune",
2154
+ "mcp",
2155
+ "tcp",
2156
+ "network",
2157
+ "optimization",
2158
+ "bbr",
2159
+ "cli"
2160
+ ],
2161
+ author: "jtsang4",
2162
+ license: "MIT",
2163
+ repository: {
2164
+ type: "git",
2165
+ url: "https://github.com/jtsang4/nettune.git",
2166
+ directory: "js"
2167
+ },
2168
+ engines: {
2169
+ node: ">=24.0.0"
2170
+ },
2171
+ dependencies: {
2172
+ commander: "^14.0.2"
2173
+ },
2174
+ devDependencies: {
2175
+ "@types/bun": "^1.2.22",
2176
+ "@types/node": "^24.10.1",
2177
+ rimraf: "^6.0.1",
2178
+ typescript: "^5.8.3"
2179
+ }
2180
+ };
1877
2181
 
1878
2182
  // src/cli.ts
1879
- var VERSION = "0.1.0";
2183
+ var VERSION = package_default.version;
1880
2184
  function parseArgs() {
1881
2185
  const program2 = new Command;
1882
2186
  program2.name("nettune-mcp").description("MCP stdio wrapper for nettune TCP network optimization tool").version(VERSION).requiredOption("-k, --api-key <key>", "API key for server authentication (required)").option("-s, --server <url>", "Server URL", "http://127.0.0.1:9876").option("--mcp-name <name>", "MCP server name identifier", "nettune").option("--version-tag <version>", "Specific nettune version to use", "latest").option("-v, --verbose", "Enable verbose logging", false).parse(process.argv);
@@ -1940,8 +2244,9 @@ function detectPlatform() {
1940
2244
  }
1941
2245
  function getBinaryName(platform) {
1942
2246
  const archName = platform.arch === "x64" ? "amd64" : platform.arch;
2247
+ const osName = platform.os === "win32" ? "windows" : platform.os;
1943
2248
  const ext = platform.os === "win32" ? ".exe" : "";
1944
- return `nettune-${platform.os}-${archName}${ext}`;
2249
+ return `nettune-${osName}-${archName}${ext}`;
1945
2250
  }
1946
2251
  function getChecksumsFileName() {
1947
2252
  return "checksums.txt";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jtsang/nettune-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "MCP stdio wrapper for nettune - TCP network optimization tool",
6
6
  "type": "module",
@@ -13,7 +13,7 @@
13
13
  "README.md"
14
14
  ],
15
15
  "scripts": {
16
- "build": "bun build src/index.ts --outdir dist --target node --format esm && echo '#!/usr/bin/env node' | cat - dist/index.js > dist/tmp && mv dist/tmp dist/index.js && chmod +x dist/index.js",
16
+ "build": "bunx rimraf dist && bun build src/index.ts --outdir dist --target node --format esm && echo '#!/usr/bin/env node' | cat - dist/index.js > dist/tmp && mv dist/tmp dist/index.js && chmod +x dist/index.js",
17
17
  "dev": "bun run src/index.ts",
18
18
  "test": "bun test",
19
19
  "typecheck": "tsc --noEmit",
@@ -39,11 +39,12 @@
39
39
  "node": ">=24.0.0"
40
40
  },
41
41
  "dependencies": {
42
- "commander": "^12.1.0"
42
+ "commander": "^14.0.2"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/bun": "^1.3.3",
46
- "@types/node": "^22.10.1",
47
- "typescript": "^5.7.2"
45
+ "@types/bun": "^1.2.22",
46
+ "@types/node": "^24.10.1",
47
+ "rimraf": "^6.0.1",
48
+ "typescript": "^5.8.3"
48
49
  }
49
50
  }