@jtsang/nettune-mcp 0.1.0 → 0.1.1

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