@tscircuit/cli 0.1.130 → 0.1.132

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 (3) hide show
  1. package/README.md +3 -3
  2. package/dist/main.js +504 -169
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -39,9 +39,9 @@ Options:
39
39
  -h, --help display help for command
40
40
 
41
41
  Commands:
42
- init [directory] Initialize a new TSCircuit project in the
43
- specified directory (or current directory if none
44
- is provided)
42
+ init [directory] Initialize a new TSCircuit project in the specified
43
+ directory (or current directory if none is
44
+ provided)
45
45
  dev [options] [file] Start development server for a package
46
46
  clone [options] <package> Clone a package from the registry
47
47
  push [options] [file] Save snippet code to Registry API
package/dist/main.js CHANGED
@@ -139,10 +139,14 @@ var require_help = __commonJS((exports2) => {
139
139
  class Help {
140
140
  constructor() {
141
141
  this.helpWidth = undefined;
142
+ this.minWidthToWrap = 40;
142
143
  this.sortSubcommands = false;
143
144
  this.sortOptions = false;
144
145
  this.showGlobalOptions = false;
145
146
  }
147
+ prepareContext(contextOptions) {
148
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
149
+ }
146
150
  visibleCommands(cmd) {
147
151
  const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
148
152
  const helpCommand = cmd._getHelpCommand();
@@ -217,22 +221,22 @@ var require_help = __commonJS((exports2) => {
217
221
  }
218
222
  longestSubcommandTermLength(cmd, helper) {
219
223
  return helper.visibleCommands(cmd).reduce((max, command) => {
220
- return Math.max(max, helper.subcommandTerm(command).length);
224
+ return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
221
225
  }, 0);
222
226
  }
223
227
  longestOptionTermLength(cmd, helper) {
224
228
  return helper.visibleOptions(cmd).reduce((max, option) => {
225
- return Math.max(max, helper.optionTerm(option).length);
229
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
226
230
  }, 0);
227
231
  }
228
232
  longestGlobalOptionTermLength(cmd, helper) {
229
233
  return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
230
- return Math.max(max, helper.optionTerm(option).length);
234
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
231
235
  }, 0);
232
236
  }
233
237
  longestArgumentTermLength(cmd, helper) {
234
238
  return helper.visibleArguments(cmd).reduce((max, argument) => {
235
- return Math.max(max, helper.argumentTerm(argument).length);
239
+ return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
236
240
  }, 0);
237
241
  }
238
242
  commandUsage(cmd) {
@@ -270,7 +274,11 @@ var require_help = __commonJS((exports2) => {
270
274
  extraInfo.push(`env: ${option.envVar}`);
271
275
  }
272
276
  if (extraInfo.length > 0) {
273
- return `${option.description} (${extraInfo.join(", ")})`;
277
+ const extraDescription = `(${extraInfo.join(", ")})`;
278
+ if (option.description) {
279
+ return `${option.description} ${extraDescription}`;
280
+ }
281
+ return extraDescription;
274
282
  }
275
283
  return option.description;
276
284
  }
@@ -283,102 +291,202 @@ var require_help = __commonJS((exports2) => {
283
291
  extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
284
292
  }
285
293
  if (extraInfo.length > 0) {
286
- const extraDescripton = `(${extraInfo.join(", ")})`;
294
+ const extraDescription = `(${extraInfo.join(", ")})`;
287
295
  if (argument.description) {
288
- return `${argument.description} ${extraDescripton}`;
296
+ return `${argument.description} ${extraDescription}`;
289
297
  }
290
- return extraDescripton;
298
+ return extraDescription;
291
299
  }
292
300
  return argument.description;
293
301
  }
302
+ formatItemList(heading, items, helper) {
303
+ if (items.length === 0)
304
+ return [];
305
+ return [helper.styleTitle(heading), ...items, ""];
306
+ }
307
+ groupItems(unsortedItems, visibleItems, getGroup) {
308
+ const result = new Map;
309
+ unsortedItems.forEach((item) => {
310
+ const group = getGroup(item);
311
+ if (!result.has(group))
312
+ result.set(group, []);
313
+ });
314
+ visibleItems.forEach((item) => {
315
+ const group = getGroup(item);
316
+ if (!result.has(group)) {
317
+ result.set(group, []);
318
+ }
319
+ result.get(group).push(item);
320
+ });
321
+ return result;
322
+ }
294
323
  formatHelp(cmd, helper) {
295
324
  const termWidth = helper.padWidth(cmd, helper);
296
- const helpWidth = helper.helpWidth || 80;
297
- const itemIndentWidth = 2;
298
- const itemSeparatorWidth = 2;
299
- function formatItem(term, description) {
300
- if (description) {
301
- const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
302
- return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
303
- }
304
- return term;
325
+ const helpWidth = helper.helpWidth ?? 80;
326
+ function callFormatItem(term, description) {
327
+ return helper.formatItem(term, termWidth, description, helper);
305
328
  }
306
- function formatList(textArray) {
307
- return textArray.join(`
308
- `).replace(/^/gm, " ".repeat(itemIndentWidth));
309
- }
310
- let output = [`Usage: ${helper.commandUsage(cmd)}`, ""];
329
+ let output = [
330
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
331
+ ""
332
+ ];
311
333
  const commandDescription = helper.commandDescription(cmd);
312
334
  if (commandDescription.length > 0) {
313
335
  output = output.concat([
314
- helper.wrap(commandDescription, helpWidth, 0),
336
+ helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth),
315
337
  ""
316
338
  ]);
317
339
  }
318
340
  const argumentList = helper.visibleArguments(cmd).map((argument) => {
319
- return formatItem(helper.argumentTerm(argument), helper.argumentDescription(argument));
341
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
320
342
  });
321
- if (argumentList.length > 0) {
322
- output = output.concat(["Arguments:", formatList(argumentList), ""]);
323
- }
324
- const optionList = helper.visibleOptions(cmd).map((option) => {
325
- return formatItem(helper.optionTerm(option), helper.optionDescription(option));
343
+ output = output.concat(this.formatItemList("Arguments:", argumentList, helper));
344
+ const optionGroups = this.groupItems(cmd.options, helper.visibleOptions(cmd), (option) => option.helpGroupHeading ?? "Options:");
345
+ optionGroups.forEach((options, group) => {
346
+ const optionList = options.map((option) => {
347
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
348
+ });
349
+ output = output.concat(this.formatItemList(group, optionList, helper));
326
350
  });
327
- if (optionList.length > 0) {
328
- output = output.concat(["Options:", formatList(optionList), ""]);
329
- }
330
- if (this.showGlobalOptions) {
351
+ if (helper.showGlobalOptions) {
331
352
  const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
332
- return formatItem(helper.optionTerm(option), helper.optionDescription(option));
353
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
333
354
  });
334
- if (globalOptionList.length > 0) {
335
- output = output.concat([
336
- "Global Options:",
337
- formatList(globalOptionList),
338
- ""
339
- ]);
340
- }
355
+ output = output.concat(this.formatItemList("Global Options:", globalOptionList, helper));
341
356
  }
342
- const commandList = helper.visibleCommands(cmd).map((cmd2) => {
343
- return formatItem(helper.subcommandTerm(cmd2), helper.subcommandDescription(cmd2));
357
+ const commandGroups = this.groupItems(cmd.commands, helper.visibleCommands(cmd), (sub) => sub.helpGroup() || "Commands:");
358
+ commandGroups.forEach((commands, group) => {
359
+ const commandList = commands.map((sub) => {
360
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)), helper.styleSubcommandDescription(helper.subcommandDescription(sub)));
361
+ });
362
+ output = output.concat(this.formatItemList(group, commandList, helper));
344
363
  });
345
- if (commandList.length > 0) {
346
- output = output.concat(["Commands:", formatList(commandList), ""]);
347
- }
348
364
  return output.join(`
349
365
  `);
350
366
  }
367
+ displayWidth(str) {
368
+ return stripColor(str).length;
369
+ }
370
+ styleTitle(str) {
371
+ return str;
372
+ }
373
+ styleUsage(str) {
374
+ return str.split(" ").map((word) => {
375
+ if (word === "[options]")
376
+ return this.styleOptionText(word);
377
+ if (word === "[command]")
378
+ return this.styleSubcommandText(word);
379
+ if (word[0] === "[" || word[0] === "<")
380
+ return this.styleArgumentText(word);
381
+ return this.styleCommandText(word);
382
+ }).join(" ");
383
+ }
384
+ styleCommandDescription(str) {
385
+ return this.styleDescriptionText(str);
386
+ }
387
+ styleOptionDescription(str) {
388
+ return this.styleDescriptionText(str);
389
+ }
390
+ styleSubcommandDescription(str) {
391
+ return this.styleDescriptionText(str);
392
+ }
393
+ styleArgumentDescription(str) {
394
+ return this.styleDescriptionText(str);
395
+ }
396
+ styleDescriptionText(str) {
397
+ return str;
398
+ }
399
+ styleOptionTerm(str) {
400
+ return this.styleOptionText(str);
401
+ }
402
+ styleSubcommandTerm(str) {
403
+ return str.split(" ").map((word) => {
404
+ if (word === "[options]")
405
+ return this.styleOptionText(word);
406
+ if (word[0] === "[" || word[0] === "<")
407
+ return this.styleArgumentText(word);
408
+ return this.styleSubcommandText(word);
409
+ }).join(" ");
410
+ }
411
+ styleArgumentTerm(str) {
412
+ return this.styleArgumentText(str);
413
+ }
414
+ styleOptionText(str) {
415
+ return str;
416
+ }
417
+ styleArgumentText(str) {
418
+ return str;
419
+ }
420
+ styleSubcommandText(str) {
421
+ return str;
422
+ }
423
+ styleCommandText(str) {
424
+ return str;
425
+ }
351
426
  padWidth(cmd, helper) {
352
427
  return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
353
428
  }
354
- wrap(str, width, indent, minColumnWidth = 40) {
355
- const indents = " \\f\\t\\v   -    \uFEFF";
356
- const manualIndent = new RegExp(`[\\n][${indents}]+`);
357
- if (str.match(manualIndent))
358
- return str;
359
- const columnWidth = width - indent;
360
- if (columnWidth < minColumnWidth)
429
+ preformatted(str) {
430
+ return /\n[^\S\r\n]/.test(str);
431
+ }
432
+ formatItem(term, termWidth, description, helper) {
433
+ const itemIndent = 2;
434
+ const itemIndentStr = " ".repeat(itemIndent);
435
+ if (!description)
436
+ return itemIndentStr + term;
437
+ const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
438
+ const spacerWidth = 2;
439
+ const helpWidth = this.helpWidth ?? 80;
440
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
441
+ let formattedDescription;
442
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
443
+ formattedDescription = description;
444
+ } else {
445
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
446
+ formattedDescription = wrappedDescription.replace(/\n/g, `
447
+ ` + " ".repeat(termWidth + spacerWidth));
448
+ }
449
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
450
+ ${itemIndentStr}`);
451
+ }
452
+ boxWrap(str, width) {
453
+ if (width < this.minWidthToWrap)
361
454
  return str;
362
- const leadingStr = str.slice(0, indent);
363
- const columnText = str.slice(indent).replace(`\r
364
- `, `
365
- `);
366
- const indentString = " ".repeat(indent);
367
- const zeroWidthSpace = "​";
368
- const breaks = `\\s${zeroWidthSpace}`;
369
- const regex = new RegExp(`
370
- |.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, "g");
371
- const lines = columnText.match(regex) || [];
372
- return leadingStr + lines.map((line, i) => {
373
- if (line === `
374
- `)
375
- return "";
376
- return (i > 0 ? indentString : "") + line.trimEnd();
377
- }).join(`
455
+ const rawLines = str.split(/\r\n|\n/);
456
+ const chunkPattern = /[\s]*[^\s]+/g;
457
+ const wrappedLines = [];
458
+ rawLines.forEach((line) => {
459
+ const chunks = line.match(chunkPattern);
460
+ if (chunks === null) {
461
+ wrappedLines.push("");
462
+ return;
463
+ }
464
+ let sumChunks = [chunks.shift()];
465
+ let sumWidth = this.displayWidth(sumChunks[0]);
466
+ chunks.forEach((chunk) => {
467
+ const visibleWidth = this.displayWidth(chunk);
468
+ if (sumWidth + visibleWidth <= width) {
469
+ sumChunks.push(chunk);
470
+ sumWidth += visibleWidth;
471
+ return;
472
+ }
473
+ wrappedLines.push(sumChunks.join(""));
474
+ const nextChunk = chunk.trimStart();
475
+ sumChunks = [nextChunk];
476
+ sumWidth = this.displayWidth(nextChunk);
477
+ });
478
+ wrappedLines.push(sumChunks.join(""));
479
+ });
480
+ return wrappedLines.join(`
378
481
  `);
379
482
  }
380
483
  }
484
+ function stripColor(str) {
485
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
486
+ return str.replace(sgrPattern, "");
487
+ }
381
488
  exports2.Help = Help;
489
+ exports2.stripColor = stripColor;
382
490
  });
383
491
 
384
492
  // node_modules/commander/lib/option.js
@@ -409,6 +517,7 @@ var require_option = __commonJS((exports2) => {
409
517
  this.argChoices = undefined;
410
518
  this.conflictsWith = [];
411
519
  this.implied = undefined;
520
+ this.helpGroupHeading = undefined;
412
521
  }
413
522
  default(value2, description) {
414
523
  this.defaultValue = value2;
@@ -473,7 +582,14 @@ var require_option = __commonJS((exports2) => {
473
582
  return this.short.replace(/^-/, "");
474
583
  }
475
584
  attributeName() {
476
- return camelcase(this.name().replace(/^no-/, ""));
585
+ if (this.negate) {
586
+ return camelcase(this.name().replace(/^no-/, ""));
587
+ }
588
+ return camelcase(this.name());
589
+ }
590
+ helpGroup(heading) {
591
+ this.helpGroupHeading = heading;
592
+ return this;
477
593
  }
478
594
  is(arg) {
479
595
  return this.short === arg || this.long === arg;
@@ -518,14 +634,38 @@ var require_option = __commonJS((exports2) => {
518
634
  function splitOptionFlags(flags) {
519
635
  let shortFlag;
520
636
  let longFlag;
521
- const flagParts = flags.split(/[ |,]+/);
522
- if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1]))
637
+ const shortFlagExp = /^-[^-]$/;
638
+ const longFlagExp = /^--[^-]/;
639
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
640
+ if (shortFlagExp.test(flagParts[0]))
523
641
  shortFlag = flagParts.shift();
524
- longFlag = flagParts.shift();
525
- if (!shortFlag && /^-[^-]$/.test(longFlag)) {
642
+ if (longFlagExp.test(flagParts[0]))
643
+ longFlag = flagParts.shift();
644
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
645
+ shortFlag = flagParts.shift();
646
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
526
647
  shortFlag = longFlag;
527
- longFlag = undefined;
528
- }
648
+ longFlag = flagParts.shift();
649
+ }
650
+ if (flagParts[0].startsWith("-")) {
651
+ const unsupportedFlag = flagParts[0];
652
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
653
+ if (/^-[^-][^-]/.test(unsupportedFlag))
654
+ throw new Error(`${baseError}
655
+ - a short flag is a single dash and a single character
656
+ - either use a single dash and a single character (for a short flag)
657
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
658
+ if (shortFlagExp.test(unsupportedFlag))
659
+ throw new Error(`${baseError}
660
+ - too many short flags`);
661
+ if (longFlagExp.test(unsupportedFlag))
662
+ throw new Error(`${baseError}
663
+ - too many long flags`);
664
+ throw new Error(`${baseError}
665
+ - unrecognised flag format`);
666
+ }
667
+ if (shortFlag === undefined && longFlag === undefined)
668
+ throw new Error(`option creation failed due to no flags found in '${flags}'.`);
529
669
  return { shortFlag, longFlag };
530
670
  }
531
671
  exports2.Option = Option;
@@ -614,7 +754,7 @@ var require_command = __commonJS((exports2) => {
614
754
  var process2 = __require("node:process");
615
755
  var { Argument, humanReadableArgName } = require_argument();
616
756
  var { CommanderError } = require_error();
617
- var { Help } = require_help();
757
+ var { Help, stripColor } = require_help();
618
758
  var { Option, DualOptions } = require_option();
619
759
  var { suggestSimilar } = require_suggestSimilar();
620
760
 
@@ -625,7 +765,7 @@ var require_command = __commonJS((exports2) => {
625
765
  this.options = [];
626
766
  this.parent = null;
627
767
  this._allowUnknownOption = false;
628
- this._allowExcessArguments = true;
768
+ this._allowExcessArguments = false;
629
769
  this.registeredArguments = [];
630
770
  this._args = this.registeredArguments;
631
771
  this.args = [];
@@ -652,18 +792,25 @@ var require_command = __commonJS((exports2) => {
652
792
  this._lifeCycleHooks = {};
653
793
  this._showHelpAfterError = false;
654
794
  this._showSuggestionAfterError = true;
795
+ this._savedState = null;
655
796
  this._outputConfiguration = {
656
797
  writeOut: (str) => process2.stdout.write(str),
657
798
  writeErr: (str) => process2.stderr.write(str),
799
+ outputError: (str, write) => write(str),
658
800
  getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
659
801
  getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
660
- outputError: (str, write) => write(str)
802
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
803
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
804
+ stripColor: (str) => stripColor(str)
661
805
  };
662
806
  this._hidden = false;
663
807
  this._helpOption = undefined;
664
808
  this._addImplicitHelpCommand = undefined;
665
809
  this._helpCommand = undefined;
666
810
  this._helpConfiguration = {};
811
+ this._helpGroupHeading = undefined;
812
+ this._defaultCommandGroup = undefined;
813
+ this._defaultOptionGroup = undefined;
667
814
  }
668
815
  copyInheritedSettings(sourceCommand) {
669
816
  this._outputConfiguration = sourceCommand._outputConfiguration;
@@ -728,7 +875,7 @@ var require_command = __commonJS((exports2) => {
728
875
  configureOutput(configuration) {
729
876
  if (configuration === undefined)
730
877
  return this._outputConfiguration;
731
- Object.assign(this._outputConfiguration, configuration);
878
+ this._outputConfiguration = Object.assign({}, this._outputConfiguration, configuration);
732
879
  return this;
733
880
  }
734
881
  showHelpAfterError(displayHelp = true) {
@@ -759,12 +906,12 @@ var require_command = __commonJS((exports2) => {
759
906
  createArgument(name, description) {
760
907
  return new Argument(name, description);
761
908
  }
762
- argument(name, description, fn, defaultValue) {
909
+ argument(name, description, parseArg, defaultValue) {
763
910
  const argument = this.createArgument(name, description);
764
- if (typeof fn === "function") {
765
- argument.default(defaultValue).argParser(fn);
911
+ if (typeof parseArg === "function") {
912
+ argument.default(defaultValue).argParser(parseArg);
766
913
  } else {
767
- argument.default(fn);
914
+ argument.default(parseArg);
768
915
  }
769
916
  this.addArgument(argument);
770
917
  return this;
@@ -789,10 +936,13 @@ var require_command = __commonJS((exports2) => {
789
936
  helpCommand(enableOrNameAndArgs, description) {
790
937
  if (typeof enableOrNameAndArgs === "boolean") {
791
938
  this._addImplicitHelpCommand = enableOrNameAndArgs;
939
+ if (enableOrNameAndArgs && this._defaultCommandGroup) {
940
+ this._initCommandGroup(this._getHelpCommand());
941
+ }
792
942
  return this;
793
943
  }
794
- enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
795
- const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
944
+ const nameAndArgs = enableOrNameAndArgs ?? "help [command]";
945
+ const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);
796
946
  const helpDescription = description ?? "display help for command";
797
947
  const helpCommand = this.createCommand(helpName);
798
948
  helpCommand.helpOption(false);
@@ -802,6 +952,8 @@ var require_command = __commonJS((exports2) => {
802
952
  helpCommand.description(helpDescription);
803
953
  this._addImplicitHelpCommand = true;
804
954
  this._helpCommand = helpCommand;
955
+ if (enableOrNameAndArgs || description)
956
+ this._initCommandGroup(helpCommand);
805
957
  return this;
806
958
  }
807
959
  addHelpCommand(helpCommand, deprecatedDescription) {
@@ -811,6 +963,7 @@ var require_command = __commonJS((exports2) => {
811
963
  }
812
964
  this._addImplicitHelpCommand = true;
813
965
  this._helpCommand = helpCommand;
966
+ this._initCommandGroup(helpCommand);
814
967
  return this;
815
968
  }
816
969
  _getHelpCommand() {
@@ -890,6 +1043,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
890
1043
  throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
891
1044
  - already used by option '${matchingOption.flags}'`);
892
1045
  }
1046
+ this._initOptionGroup(option);
893
1047
  this.options.push(option);
894
1048
  }
895
1049
  _registerCommand(command) {
@@ -902,6 +1056,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
902
1056
  const newCmd = knownBy(command).join("|");
903
1057
  throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
904
1058
  }
1059
+ this._initCommandGroup(command);
905
1060
  this.commands.push(command);
906
1061
  }
907
1062
  addOption(option) {
@@ -1089,15 +1244,53 @@ Expecting one of '${allowedValues.join("', '")}'`);
1089
1244
  return userArgs;
1090
1245
  }
1091
1246
  parse(argv, parseOptions) {
1247
+ this._prepareForParse();
1092
1248
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1093
1249
  this._parseCommand([], userArgs);
1094
1250
  return this;
1095
1251
  }
1096
1252
  async parseAsync(argv, parseOptions) {
1253
+ this._prepareForParse();
1097
1254
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1098
1255
  await this._parseCommand([], userArgs);
1099
1256
  return this;
1100
1257
  }
1258
+ _prepareForParse() {
1259
+ if (this._savedState === null) {
1260
+ this.saveStateBeforeParse();
1261
+ } else {
1262
+ this.restoreStateBeforeParse();
1263
+ }
1264
+ }
1265
+ saveStateBeforeParse() {
1266
+ this._savedState = {
1267
+ _name: this._name,
1268
+ _optionValues: { ...this._optionValues },
1269
+ _optionValueSources: { ...this._optionValueSources }
1270
+ };
1271
+ }
1272
+ restoreStateBeforeParse() {
1273
+ if (this._storeOptionsAsProperties)
1274
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
1275
+ - either make a new Command for each call to parse, or stop storing options as properties`);
1276
+ this._name = this._savedState._name;
1277
+ this._scriptPath = null;
1278
+ this.rawArgs = [];
1279
+ this._optionValues = { ...this._savedState._optionValues };
1280
+ this._optionValueSources = { ...this._savedState._optionValueSources };
1281
+ this.args = [];
1282
+ this.processedArgs = [];
1283
+ }
1284
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
1285
+ if (fs.existsSync(executableFile))
1286
+ return;
1287
+ 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";
1288
+ const executableMissing = `'${executableFile}' does not exist
1289
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1290
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1291
+ - ${executableDirMessage}`;
1292
+ throw new Error(executableMissing);
1293
+ }
1101
1294
  _executeSubCommand(subcommand, args) {
1102
1295
  args = args.slice();
1103
1296
  let launchWithNode = false;
@@ -1121,7 +1314,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1121
1314
  let resolvedScriptPath;
1122
1315
  try {
1123
1316
  resolvedScriptPath = fs.realpathSync(this._scriptPath);
1124
- } catch (err) {
1317
+ } catch {
1125
1318
  resolvedScriptPath = this._scriptPath;
1126
1319
  }
1127
1320
  executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
@@ -1147,6 +1340,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1147
1340
  proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1148
1341
  }
1149
1342
  } else {
1343
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1150
1344
  args.unshift(executableFile);
1151
1345
  args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1152
1346
  proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
@@ -1172,12 +1366,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1172
1366
  });
1173
1367
  proc.on("error", (err) => {
1174
1368
  if (err.code === "ENOENT") {
1175
- 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";
1176
- const executableMissing = `'${executableFile}' does not exist
1177
- - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1178
- - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1179
- - ${executableDirMessage}`;
1180
- throw new Error(executableMissing);
1369
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1181
1370
  } else if (err.code === "EACCES") {
1182
1371
  throw new Error(`'${executableFile}' not executable`);
1183
1372
  }
@@ -1195,6 +1384,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1195
1384
  const subCommand = this._findCommand(commandName);
1196
1385
  if (!subCommand)
1197
1386
  this.help({ error: true });
1387
+ subCommand._prepareForParse();
1198
1388
  let promiseChain;
1199
1389
  promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
1200
1390
  promiseChain = this._chainOrCall(promiseChain, () => {
@@ -1411,6 +1601,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1411
1601
  function maybeOption(arg) {
1412
1602
  return arg.length > 1 && arg[0] === "-";
1413
1603
  }
1604
+ const negativeNumberArg = (arg) => {
1605
+ if (!/^-\d*\.?\d+(e[+-]?\d+)?$/.test(arg))
1606
+ return false;
1607
+ return !this._getCommandAndAncestors().some((cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short)));
1608
+ };
1414
1609
  let activeVariadicOption = null;
1415
1610
  while (args.length) {
1416
1611
  const arg = args.shift();
@@ -1420,7 +1615,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1420
1615
  dest.push(...args);
1421
1616
  break;
1422
1617
  }
1423
- if (activeVariadicOption && !maybeOption(arg)) {
1618
+ if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
1424
1619
  this.emit(`option:${activeVariadicOption.name()}`, arg);
1425
1620
  continue;
1426
1621
  }
@@ -1435,7 +1630,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1435
1630
  this.emit(`option:${option.name()}`, value2);
1436
1631
  } else if (option.optional) {
1437
1632
  let value2 = null;
1438
- if (args.length > 0 && !maybeOption(args[0])) {
1633
+ if (args.length > 0 && (!maybeOption(args[0]) || negativeNumberArg(args[0]))) {
1439
1634
  value2 = args.shift();
1440
1635
  }
1441
1636
  this.emit(`option:${option.name()}`, value2);
@@ -1466,7 +1661,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1466
1661
  continue;
1467
1662
  }
1468
1663
  }
1469
- if (maybeOption(arg)) {
1664
+ if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
1470
1665
  dest = unknown;
1471
1666
  }
1472
1667
  if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
@@ -1701,6 +1896,32 @@ Expecting one of '${allowedValues.join("', '")}'`);
1701
1896
  this._name = str;
1702
1897
  return this;
1703
1898
  }
1899
+ helpGroup(heading) {
1900
+ if (heading === undefined)
1901
+ return this._helpGroupHeading ?? "";
1902
+ this._helpGroupHeading = heading;
1903
+ return this;
1904
+ }
1905
+ commandsGroup(heading) {
1906
+ if (heading === undefined)
1907
+ return this._defaultCommandGroup ?? "";
1908
+ this._defaultCommandGroup = heading;
1909
+ return this;
1910
+ }
1911
+ optionsGroup(heading) {
1912
+ if (heading === undefined)
1913
+ return this._defaultOptionGroup ?? "";
1914
+ this._defaultOptionGroup = heading;
1915
+ return this;
1916
+ }
1917
+ _initOptionGroup(option) {
1918
+ if (this._defaultOptionGroup && !option.helpGroupHeading)
1919
+ option.helpGroup(this._defaultOptionGroup);
1920
+ }
1921
+ _initCommandGroup(cmd) {
1922
+ if (this._defaultCommandGroup && !cmd.helpGroup())
1923
+ cmd.helpGroup(this._defaultCommandGroup);
1924
+ }
1704
1925
  nameFromFilename(filename) {
1705
1926
  this._name = path.basename(filename, path.extname(filename));
1706
1927
  return this;
@@ -1713,23 +1934,38 @@ Expecting one of '${allowedValues.join("', '")}'`);
1713
1934
  }
1714
1935
  helpInformation(contextOptions) {
1715
1936
  const helper = this.createHelp();
1716
- if (helper.helpWidth === undefined) {
1717
- helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
1718
- }
1719
- return helper.formatHelp(this, helper);
1937
+ const context = this._getOutputContext(contextOptions);
1938
+ helper.prepareContext({
1939
+ error: context.error,
1940
+ helpWidth: context.helpWidth,
1941
+ outputHasColors: context.hasColors
1942
+ });
1943
+ const text = helper.formatHelp(this, helper);
1944
+ if (context.hasColors)
1945
+ return text;
1946
+ return this._outputConfiguration.stripColor(text);
1720
1947
  }
1721
- _getHelpContext(contextOptions) {
1948
+ _getOutputContext(contextOptions) {
1722
1949
  contextOptions = contextOptions || {};
1723
- const context = { error: !!contextOptions.error };
1724
- let write;
1725
- if (context.error) {
1726
- write = (arg) => this._outputConfiguration.writeErr(arg);
1950
+ const error = !!contextOptions.error;
1951
+ let baseWrite;
1952
+ let hasColors;
1953
+ let helpWidth;
1954
+ if (error) {
1955
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
1956
+ hasColors = this._outputConfiguration.getErrHasColors();
1957
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
1727
1958
  } else {
1728
- write = (arg) => this._outputConfiguration.writeOut(arg);
1959
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
1960
+ hasColors = this._outputConfiguration.getOutHasColors();
1961
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
1729
1962
  }
1730
- context.write = contextOptions.write || write;
1731
- context.command = this;
1732
- return context;
1963
+ const write = (str) => {
1964
+ if (!hasColors)
1965
+ str = this._outputConfiguration.stripColor(str);
1966
+ return baseWrite(str);
1967
+ };
1968
+ return { error, write, hasColors, helpWidth };
1733
1969
  }
1734
1970
  outputHelp(contextOptions) {
1735
1971
  let deprecatedCallback;
@@ -1737,35 +1973,44 @@ Expecting one of '${allowedValues.join("', '")}'`);
1737
1973
  deprecatedCallback = contextOptions;
1738
1974
  contextOptions = undefined;
1739
1975
  }
1740
- const context = this._getHelpContext(contextOptions);
1741
- this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", context));
1742
- this.emit("beforeHelp", context);
1743
- let helpInformation = this.helpInformation(context);
1976
+ const outputContext = this._getOutputContext(contextOptions);
1977
+ const eventContext = {
1978
+ error: outputContext.error,
1979
+ write: outputContext.write,
1980
+ command: this
1981
+ };
1982
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
1983
+ this.emit("beforeHelp", eventContext);
1984
+ let helpInformation = this.helpInformation({ error: outputContext.error });
1744
1985
  if (deprecatedCallback) {
1745
1986
  helpInformation = deprecatedCallback(helpInformation);
1746
1987
  if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
1747
1988
  throw new Error("outputHelp callback must return a string or a Buffer");
1748
1989
  }
1749
1990
  }
1750
- context.write(helpInformation);
1991
+ outputContext.write(helpInformation);
1751
1992
  if (this._getHelpOption()?.long) {
1752
1993
  this.emit(this._getHelpOption().long);
1753
1994
  }
1754
- this.emit("afterHelp", context);
1755
- this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", context));
1995
+ this.emit("afterHelp", eventContext);
1996
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
1756
1997
  }
1757
1998
  helpOption(flags, description) {
1758
1999
  if (typeof flags === "boolean") {
1759
2000
  if (flags) {
1760
- this._helpOption = this._helpOption ?? undefined;
2001
+ if (this._helpOption === null)
2002
+ this._helpOption = undefined;
2003
+ if (this._defaultOptionGroup) {
2004
+ this._initOptionGroup(this._getHelpOption());
2005
+ }
1761
2006
  } else {
1762
2007
  this._helpOption = null;
1763
2008
  }
1764
2009
  return this;
1765
2010
  }
1766
- flags = flags ?? "-h, --help";
1767
- description = description ?? "display help for command";
1768
- this._helpOption = this.createOption(flags, description);
2011
+ this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
2012
+ if (flags || description)
2013
+ this._initOptionGroup(this._helpOption);
1769
2014
  return this;
1770
2015
  }
1771
2016
  _getHelpOption() {
@@ -1776,11 +2021,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
1776
2021
  }
1777
2022
  addHelpOption(option) {
1778
2023
  this._helpOption = option;
2024
+ this._initOptionGroup(option);
1779
2025
  return this;
1780
2026
  }
1781
2027
  help(contextOptions) {
1782
2028
  this.outputHelp(contextOptions);
1783
- let exitCode = process2.exitCode || 0;
2029
+ let exitCode = Number(process2.exitCode ?? 0);
1784
2030
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
1785
2031
  exitCode = 1;
1786
2032
  }
@@ -1845,7 +2091,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
1845
2091
  return arg;
1846
2092
  });
1847
2093
  }
2094
+ function useColor() {
2095
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
2096
+ return false;
2097
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
2098
+ return true;
2099
+ return;
2100
+ }
1848
2101
  exports2.Command = Command;
2102
+ exports2.useColor = useColor;
1849
2103
  });
1850
2104
 
1851
2105
  // node_modules/commander/index.js
@@ -441915,7 +442169,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
441915
442169
  import { execSync as execSync2 } from "node:child_process";
441916
442170
  var import_semver2 = __toESM2(require_semver2(), 1);
441917
442171
  // package.json
441918
- var version = "0.1.129";
442172
+ var version = "0.1.131";
441919
442173
  var package_default = {
441920
442174
  name: "@tscircuit/cli",
441921
442175
  version,
@@ -441939,7 +442193,7 @@ var package_default = {
441939
442193
  chokidar: "4.0.1",
441940
442194
  "circuit-json-to-readable-netlist": "^0.0.9",
441941
442195
  "circuit-to-svg": "^0.0.152",
441942
- commander: "^12.1.0",
442196
+ commander: "^14.0.0",
441943
442197
  conf: "^13.1.0",
441944
442198
  configstore: "^7.0.0",
441945
442199
  cosmiconfig: "^9.0.0",
@@ -496017,6 +496271,10 @@ var registerRemove = (program3) => {
496017
496271
  };
496018
496272
 
496019
496273
  // cli/build/register.ts
496274
+ import path25 from "node:path";
496275
+ import fs25 from "node:fs";
496276
+
496277
+ // cli/build/build-file.ts
496020
496278
  import path23 from "node:path";
496021
496279
  import fs23 from "node:fs";
496022
496280
 
@@ -496042,46 +496300,112 @@ function analyzeCircuitJson(circuitJson) {
496042
496300
  return { errors, warnings };
496043
496301
  }
496044
496302
 
496045
- // cli/build/register.ts
496046
- var registerBuild = (program3) => {
496047
- program3.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").action(async (file, options) => {
496048
- const entrypoint = await getEntrypoint({ filePath: file });
496049
- if (!entrypoint)
496050
- return process.exit(1);
496051
- const projectDir = path23.dirname(entrypoint);
496052
- const distDir = path23.join(projectDir, "dist");
496053
- const outputPath = path23.join(distDir, "circuit.json");
496054
- fs23.mkdirSync(distDir, { recursive: true });
496055
- try {
496056
- const result = await generateCircuitJson({ filePath: entrypoint });
496057
- fs23.writeFileSync(outputPath, JSON.stringify(result.circuitJson, null, 2));
496058
- console.log(`Circuit JSON written to ${path23.relative(projectDir, outputPath)}`);
496059
- const { errors, warnings } = analyzeCircuitJson(result.circuitJson);
496060
- if (!options?.ignoreWarnings) {
496061
- for (const warn of warnings) {
496062
- const msg = warn.message || JSON.stringify(warn);
496063
- console.log(kleur_default.yellow(msg));
496064
- }
496303
+ // cli/build/build-file.ts
496304
+ var buildFile = async (input, output, projectDir, options) => {
496305
+ try {
496306
+ const result = await generateCircuitJson({ filePath: input });
496307
+ fs23.mkdirSync(path23.dirname(output), { recursive: true });
496308
+ fs23.writeFileSync(output, JSON.stringify(result.circuitJson, null, 2));
496309
+ console.log(`Circuit JSON written to ${path23.relative(projectDir, output)}`);
496310
+ const { errors, warnings } = analyzeCircuitJson(result.circuitJson);
496311
+ if (!options?.ignoreWarnings) {
496312
+ for (const warn of warnings) {
496313
+ const msg = warn.message || JSON.stringify(warn);
496314
+ console.log(kleur_default.yellow(msg));
496065
496315
  }
496066
- if (!options?.ignoreErrors) {
496067
- for (const err of errors) {
496068
- const msg = err.message || JSON.stringify(err);
496069
- console.error(kleur_default.red(msg));
496070
- }
496316
+ }
496317
+ if (!options?.ignoreErrors) {
496318
+ for (const err of errors) {
496319
+ const msg = err.message || JSON.stringify(err);
496320
+ console.error(kleur_default.red(msg));
496071
496321
  }
496072
- if (errors.length > 0 && !options?.ignoreErrors) {
496073
- return process.exit(1);
496322
+ }
496323
+ return errors.length === 0;
496324
+ } catch (err) {
496325
+ console.error(`Build failed: ${err}`);
496326
+ return false;
496327
+ }
496328
+ };
496329
+
496330
+ // cli/build/get-build-entrypoints.ts
496331
+ import fs24 from "node:fs";
496332
+ import path24 from "node:path";
496333
+ async function getBuildEntrypoints({
496334
+ fileOrDir,
496335
+ rootDir = process.cwd()
496336
+ }) {
496337
+ const resolvedRoot = path24.resolve(rootDir);
496338
+ if (fileOrDir) {
496339
+ const resolved = path24.resolve(resolvedRoot, fileOrDir);
496340
+ if (fs24.existsSync(resolved) && fs24.statSync(resolved).isDirectory()) {
496341
+ const projectDir2 = resolved;
496342
+ const circuitFiles2 = [];
496343
+ const mainEntrypoint2 = await getEntrypoint({
496344
+ projectDir: projectDir2,
496345
+ onError: () => {}
496346
+ });
496347
+ const files2 = globbySync("**/*.circuit.tsx", {
496348
+ cwd: projectDir2,
496349
+ ignore: DEFAULT_IGNORED_PATTERNS
496350
+ });
496351
+ for (const f of files2) {
496352
+ circuitFiles2.push(path24.join(projectDir2, f));
496074
496353
  }
496075
- } catch (err) {
496076
- console.error(`Build failed: ${err}`);
496077
- return process.exit(1);
496354
+ return {
496355
+ projectDir: projectDir2,
496356
+ mainEntrypoint: mainEntrypoint2 || undefined,
496357
+ circuitFiles: circuitFiles2
496358
+ };
496359
+ }
496360
+ return { projectDir: path24.dirname(resolved), circuitFiles: [resolved] };
496361
+ }
496362
+ const projectDir = resolvedRoot;
496363
+ const circuitFiles = [];
496364
+ const mainEntrypoint = await getEntrypoint({ projectDir, onError: () => {} });
496365
+ const files = globbySync("**/*.circuit.tsx", {
496366
+ cwd: projectDir,
496367
+ ignore: DEFAULT_IGNORED_PATTERNS
496368
+ });
496369
+ for (const f of files) {
496370
+ circuitFiles.push(path24.join(projectDir, f));
496371
+ }
496372
+ return {
496373
+ projectDir,
496374
+ mainEntrypoint: mainEntrypoint || undefined,
496375
+ circuitFiles
496376
+ };
496377
+ }
496378
+
496379
+ // cli/build/register.ts
496380
+ var registerBuild = (program3) => {
496381
+ program3.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").action(async (file, options) => {
496382
+ const { projectDir, mainEntrypoint, circuitFiles } = await getBuildEntrypoints({ fileOrDir: file });
496383
+ const distDir = path25.join(projectDir, "dist");
496384
+ fs25.mkdirSync(distDir, { recursive: true });
496385
+ let hasErrors = false;
496386
+ if (mainEntrypoint) {
496387
+ const outputPath = path25.join(distDir, "circuit.json");
496388
+ const ok = await buildFile(mainEntrypoint, outputPath, projectDir, options);
496389
+ if (!ok)
496390
+ hasErrors = true;
496391
+ }
496392
+ for (const filePath of circuitFiles) {
496393
+ const relative6 = path25.relative(projectDir, filePath);
496394
+ const isCircuit = filePath.endsWith(".circuit.tsx");
496395
+ const outputPath = isCircuit ? path25.join(distDir, relative6.replace(/\.circuit\.tsx$/, ""), "circuit.json") : path25.join(distDir, "circuit.json");
496396
+ const ok = await buildFile(filePath, outputPath, projectDir, options);
496397
+ if (!ok)
496398
+ hasErrors = true;
496399
+ }
496400
+ if (hasErrors && !options?.ignoreErrors) {
496401
+ process.exit(1);
496078
496402
  }
496079
496403
  });
496080
496404
  };
496081
496405
 
496082
496406
  // lib/shared/snapshot-project.ts
496083
- import fs24 from "node:fs";
496084
- import path24 from "node:path";
496407
+ import fs26 from "node:fs";
496408
+ import path26 from "node:path";
496085
496409
  init_dist6();
496086
496410
 
496087
496411
  // node_modules/circuit-json-to-simple-3d/dist/index.js
@@ -496735,7 +497059,7 @@ var snapshotProject = async ({
496735
497059
  ...ignored.map(normalizeIgnorePattern)
496736
497060
  ];
496737
497061
  const boardFiles = globbySync("**/*.board.tsx", { cwd: projectDir, ignore });
496738
- let files = boardFiles.map((f) => path24.join(projectDir, f));
497062
+ let files = boardFiles.map((f) => path26.join(projectDir, f));
496739
497063
  if (files.length === 0) {
496740
497064
  const entry = await getEntrypoint({
496741
497065
  projectDir,
@@ -496752,9 +497076,9 @@ var snapshotProject = async ({
496752
497076
  const pcbSvg = convertCircuitJsonToPcbSvg(circuitJson);
496753
497077
  const schSvg = convertCircuitJsonToSchematicSvg(circuitJson);
496754
497078
  const svg3d = threeD ? await convertCircuitJsonToSimple3dSvg(circuitJson) : null;
496755
- const snapDir = path24.join(path24.dirname(file), "__snapshots__");
496756
- fs24.mkdirSync(snapDir, { recursive: true });
496757
- const base = path24.basename(file).replace(/\.tsx$/, "");
497079
+ const snapDir = path26.join(path26.dirname(file), "__snapshots__");
497080
+ fs26.mkdirSync(snapDir, { recursive: true });
497081
+ const base = path26.basename(file).replace(/\.tsx$/, "");
496758
497082
  const snapshotPairs = [
496759
497083
  ["pcb", pcbSvg],
496760
497084
  ["schematic", schSvg]
@@ -496763,11 +497087,11 @@ var snapshotProject = async ({
496763
497087
  snapshotPairs.push(["3d", svg3d]);
496764
497088
  }
496765
497089
  for (const [type, svg] of snapshotPairs) {
496766
- const snapPath = path24.join(snapDir, `${base}-${type}.snap.svg`);
496767
- if (update || !fs24.existsSync(snapPath)) {
496768
- fs24.writeFileSync(snapPath, svg);
497090
+ const snapPath = path26.join(snapDir, `${base}-${type}.snap.svg`);
497091
+ if (update || !fs26.existsSync(snapPath)) {
497092
+ fs26.writeFileSync(snapPath, svg);
496769
497093
  } else {
496770
- const existing = fs24.readFileSync(snapPath, "utf-8");
497094
+ const existing = fs26.readFileSync(snapPath, "utf-8");
496771
497095
  if (existing !== svg)
496772
497096
  mismatches.push(snapPath);
496773
497097
  }
@@ -496801,11 +497125,22 @@ var registerSnapshot = (program3) => {
496801
497125
  };
496802
497126
 
496803
497127
  // lib/shared/setup-github-actions.ts
496804
- import fs25 from "node:fs";
496805
- import path25 from "node:path";
497128
+ import fs27 from "node:fs";
497129
+ import path27 from "node:path";
496806
497130
  var setupGithubActions = (projectDir = process.cwd()) => {
496807
- const workflowsDir = path25.join(projectDir, ".github", "workflows");
496808
- fs25.mkdirSync(workflowsDir, { recursive: true });
497131
+ const findGitRoot = (startDir) => {
497132
+ let dir = path27.resolve(startDir);
497133
+ while (dir !== path27.parse(dir).root) {
497134
+ if (fs27.existsSync(path27.join(dir, ".git"))) {
497135
+ return dir;
497136
+ }
497137
+ dir = path27.dirname(dir);
497138
+ }
497139
+ return null;
497140
+ };
497141
+ const gitRoot = findGitRoot(projectDir) ?? projectDir;
497142
+ const workflowsDir = path27.join(gitRoot, ".github", "workflows");
497143
+ fs27.mkdirSync(workflowsDir, { recursive: true });
496809
497144
  const buildWorkflow = `name: tscircuit Build
496810
497145
 
496811
497146
  on:
@@ -496844,8 +497179,8 @@ jobs:
496844
497179
  git commit -m "Update snapshots" || echo "No changes to commit"
496845
497180
  git push
496846
497181
  `;
496847
- writeFileIfNotExists(path25.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
496848
- writeFileIfNotExists(path25.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
497182
+ writeFileIfNotExists(path27.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
497183
+ writeFileIfNotExists(path27.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
496849
497184
  };
496850
497185
 
496851
497186
  // cli/setup/register.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.130",
3
+ "version": "0.1.132",
4
4
  "main": "dist/main.js",
5
5
  "devDependencies": {
6
6
  "@babel/standalone": "^7.26.9",
@@ -21,7 +21,7 @@
21
21
  "chokidar": "4.0.1",
22
22
  "circuit-json-to-readable-netlist": "^0.0.9",
23
23
  "circuit-to-svg": "^0.0.152",
24
- "commander": "^12.1.0",
24
+ "commander": "^14.0.0",
25
25
  "conf": "^13.1.0",
26
26
  "configstore": "^7.0.0",
27
27
  "cosmiconfig": "^9.0.0",