@tscircuit/cli 0.1.1835 → 0.1.1836

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.
package/README.md CHANGED
@@ -126,6 +126,10 @@ The debug directory contains:
126
126
  Use `--autorouter-dump-srj failed` to keep only failed-stage routing data, or
127
127
  `--autorouter-dump-srj phase:N` to capture a single stage.
128
128
 
129
+ Use `--autorouter-phase <name>` to enable the debugger automatically and keep
130
+ debugging through the named `<autoroutingphase name="..." />`. Later phases
131
+ are left out of the debug artifacts.
132
+
129
133
  ### Debug solver inputs
130
134
 
131
135
  Use `--solver-debug` to record the constructor inputs for every solver that
@@ -12017,6 +12017,13 @@ var parseAutorouterTimeout = (duration) => {
12017
12017
  }
12018
12018
  return timeoutMs;
12019
12019
  };
12020
+ var parseAutorouterPhaseName = (value) => {
12021
+ const phaseName = value.trim();
12022
+ if (!phaseName) {
12023
+ throw new Error("Invalid --autorouter-phase value. The phase name must not be empty.");
12024
+ }
12025
+ return phaseName;
12026
+ };
12020
12027
  var parseAutorouterDumpSrjMode = (value) => {
12021
12028
  if (value === undefined || value === false)
12022
12029
  return;
@@ -12046,17 +12053,21 @@ class AutorouterDiagnostics {
12046
12053
  activePhase = null;
12047
12054
  completedPhaseTraces = [];
12048
12055
  hasWrittenPlacementSnapshot = false;
12056
+ targetPhaseReached = false;
12049
12057
  summary = [];
12050
12058
  rootCircuit;
12051
12059
  constructor(options = {}) {
12060
+ const phaseName = options.phaseName?.trim() || undefined;
12052
12061
  this.options = {
12053
12062
  ...options,
12063
+ enabled: options.enabled || phaseName !== undefined,
12064
+ phaseName,
12054
12065
  debugDir: options.debugDir ?? DEFAULT_DEBUG_DIR,
12055
12066
  log: options.log ?? console.log
12056
12067
  };
12057
12068
  }
12058
12069
  get isActive() {
12059
- return Boolean(this.options.enabled || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
12070
+ return Boolean(this.options.enabled || this.options.phaseName || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
12060
12071
  }
12061
12072
  attachToRootCircuit(rootCircuit) {
12062
12073
  if (!this.isActive)
@@ -12089,10 +12100,14 @@ class AutorouterDiagnostics {
12089
12100
  generatedAt: new Date().toISOString(),
12090
12101
  phaseCount: this.summary.length,
12091
12102
  phases: this.summary,
12092
- circuitJsonElementCount: circuitJson?.length
12103
+ circuitJsonElementCount: circuitJson?.length,
12104
+ targetPhaseName: this.options.phaseName,
12105
+ targetPhaseReached: this.targetPhaseReached
12093
12106
  });
12094
12107
  }
12095
12108
  handleStart(event) {
12109
+ if (this.targetPhaseReached)
12110
+ return;
12096
12111
  const simpleRouteJson = event.simpleRouteJson;
12097
12112
  const subcircuitId = event.subcircuit_id ?? event.subcircuitId ?? "unknown-subcircuit";
12098
12113
  const previousOrdinal = this.phaseOrdinalBySubcircuit.get(subcircuitId) ?? 0;
@@ -12105,6 +12120,9 @@ class AutorouterDiagnostics {
12105
12120
  this.activePhase = {
12106
12121
  subcircuitId,
12107
12122
  componentDisplayName: event.componentDisplayName ?? "subcircuit",
12123
+ phaseName: event.phaseName,
12124
+ phaseStageIndex: event.phaseStageIndex,
12125
+ phaseStageCount: event.phaseStageCount,
12108
12126
  routingPhaseIndex,
12109
12127
  phaseOrdinal,
12110
12128
  phaseCount: event.phaseCount,
@@ -12159,6 +12177,9 @@ class AutorouterDiagnostics {
12159
12177
  this.summary.push({
12160
12178
  subcircuit_id: activePhase.subcircuitId,
12161
12179
  componentDisplayName: activePhase.componentDisplayName,
12180
+ phaseName: activePhase.phaseName,
12181
+ phaseStageIndex: activePhase.phaseStageIndex,
12182
+ phaseStageCount: activePhase.phaseStageCount,
12162
12183
  routingPhaseIndex: activePhase.routingPhaseIndex,
12163
12184
  phaseOrdinal: activePhase.phaseOrdinal,
12164
12185
  phaseCount: activePhase.phaseCount,
@@ -12189,6 +12210,9 @@ class AutorouterDiagnostics {
12189
12210
  if (this.options.enabled) {
12190
12211
  this.writePngSnapshot(`phase-${activePhase.routingPhaseIndex}-routed.png`, this.getCircuitJsonWithCompletedPhaseTraces());
12191
12212
  }
12213
+ if (this.isFinalTargetPhaseStage(activePhase)) {
12214
+ this.targetPhaseReached = true;
12215
+ }
12192
12216
  if (this.activePhase === activePhase) {
12193
12217
  this.activePhase = null;
12194
12218
  }
@@ -12202,6 +12226,9 @@ class AutorouterDiagnostics {
12202
12226
  this.summary.push({
12203
12227
  subcircuit_id: activePhase.subcircuitId,
12204
12228
  componentDisplayName: activePhase.componentDisplayName,
12229
+ phaseName: activePhase.phaseName,
12230
+ phaseStageIndex: activePhase.phaseStageIndex,
12231
+ phaseStageCount: activePhase.phaseStageCount,
12205
12232
  routingPhaseIndex: activePhase.routingPhaseIndex,
12206
12233
  phaseOrdinal: activePhase.phaseOrdinal,
12207
12234
  phaseCount: activePhase.phaseCount,
@@ -12225,6 +12252,9 @@ class AutorouterDiagnostics {
12225
12252
  type: "autorouter_phase_error",
12226
12253
  subcircuit_id: activePhase.subcircuitId,
12227
12254
  routingPhaseIndex: activePhase.routingPhaseIndex,
12255
+ phaseName: activePhase.phaseName,
12256
+ phaseStageIndex: activePhase.phaseStageIndex,
12257
+ phaseStageCount: activePhase.phaseStageCount,
12228
12258
  phaseOrdinal: activePhase.phaseOrdinal,
12229
12259
  phaseCount: activePhase.phaseCount,
12230
12260
  elapsedMs: Math.round(elapsedMs),
@@ -12234,6 +12264,9 @@ class AutorouterDiagnostics {
12234
12264
  error
12235
12265
  });
12236
12266
  }
12267
+ if (this.isFinalTargetPhaseStage(activePhase)) {
12268
+ this.targetPhaseReached = true;
12269
+ }
12237
12270
  if (this.activePhase === activePhase) {
12238
12271
  this.activePhase = null;
12239
12272
  }
@@ -12251,6 +12284,9 @@ class AutorouterDiagnostics {
12251
12284
  subcircuit_id: activePhase.subcircuitId,
12252
12285
  componentDisplayName: activePhase.componentDisplayName,
12253
12286
  routingPhaseIndex: activePhase.routingPhaseIndex,
12287
+ phaseName: activePhase.phaseName,
12288
+ phaseStageIndex: activePhase.phaseStageIndex,
12289
+ phaseStageCount: activePhase.phaseStageCount,
12254
12290
  phaseOrdinal: activePhase.phaseOrdinal,
12255
12291
  phaseCount: activePhase.phaseCount,
12256
12292
  elapsedMs: Math.round(elapsedMs),
@@ -12422,10 +12458,22 @@ class AutorouterDiagnostics {
12422
12458
  return `phase-${phaseNumber}.${suffix}`;
12423
12459
  }
12424
12460
  getPhaseLabel(activePhase) {
12461
+ const phaseName = activePhase.phaseName ? ` "${activePhase.phaseName}"` : "";
12462
+ const stageLabel = activePhase.phaseStageIndex !== undefined && activePhase.phaseStageCount !== undefined && activePhase.phaseStageCount > 1 ? ` stage ${activePhase.phaseStageIndex + 1}/${activePhase.phaseStageCount}` : "";
12425
12463
  if (activePhase.phaseCount) {
12426
- return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}`;
12464
+ return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}${phaseName}${stageLabel}`;
12465
+ }
12466
+ return `phase ${activePhase.phaseOrdinal}${phaseName}${stageLabel}`;
12467
+ }
12468
+ isFinalTargetPhaseStage(activePhase) {
12469
+ if (!this.options.phaseName)
12470
+ return false;
12471
+ if (activePhase.phaseName !== this.options.phaseName)
12472
+ return false;
12473
+ if (activePhase.phaseStageIndex === undefined || activePhase.phaseStageCount === undefined) {
12474
+ return true;
12427
12475
  }
12428
- return `phase ${activePhase.phaseOrdinal}`;
12476
+ return activePhase.phaseStageIndex >= activePhase.phaseStageCount - 1;
12429
12477
  }
12430
12478
  formatElapsed(elapsedMs) {
12431
12479
  if (elapsedMs < 1000)
package/dist/cli/main.js CHANGED
@@ -135252,7 +135252,7 @@ var import_perfect_cli = __toESM2(require_dist2(), 1);
135252
135252
  // lib/getVersion.ts
135253
135253
  import { createRequire as createRequire2 } from "node:module";
135254
135254
  // package.json
135255
- var version = "0.1.1834";
135255
+ var version = "0.1.1835";
135256
135256
  var package_default = {
135257
135257
  name: "@tscircuit/cli",
135258
135258
  version,
@@ -139561,6 +139561,13 @@ var parseAutorouterTimeout = (duration) => {
139561
139561
  }
139562
139562
  return timeoutMs;
139563
139563
  };
139564
+ var parseAutorouterPhaseName = (value) => {
139565
+ const phaseName = value.trim();
139566
+ if (!phaseName) {
139567
+ throw new Error("Invalid --autorouter-phase value. The phase name must not be empty.");
139568
+ }
139569
+ return phaseName;
139570
+ };
139564
139571
  var parseAutorouterDumpSrjMode = (value) => {
139565
139572
  if (value === undefined || value === false)
139566
139573
  return;
@@ -139590,17 +139597,21 @@ class AutorouterDiagnostics {
139590
139597
  activePhase = null;
139591
139598
  completedPhaseTraces = [];
139592
139599
  hasWrittenPlacementSnapshot = false;
139600
+ targetPhaseReached = false;
139593
139601
  summary = [];
139594
139602
  rootCircuit;
139595
139603
  constructor(options = {}) {
139604
+ const phaseName = options.phaseName?.trim() || undefined;
139596
139605
  this.options = {
139597
139606
  ...options,
139607
+ enabled: options.enabled || phaseName !== undefined,
139608
+ phaseName,
139598
139609
  debugDir: options.debugDir ?? DEFAULT_DEBUG_DIR,
139599
139610
  log: options.log ?? console.log
139600
139611
  };
139601
139612
  }
139602
139613
  get isActive() {
139603
- return Boolean(this.options.enabled || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
139614
+ return Boolean(this.options.enabled || this.options.phaseName || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
139604
139615
  }
139605
139616
  attachToRootCircuit(rootCircuit) {
139606
139617
  if (!this.isActive)
@@ -139633,10 +139644,14 @@ class AutorouterDiagnostics {
139633
139644
  generatedAt: new Date().toISOString(),
139634
139645
  phaseCount: this.summary.length,
139635
139646
  phases: this.summary,
139636
- circuitJsonElementCount: circuitJson?.length
139647
+ circuitJsonElementCount: circuitJson?.length,
139648
+ targetPhaseName: this.options.phaseName,
139649
+ targetPhaseReached: this.targetPhaseReached
139637
139650
  });
139638
139651
  }
139639
139652
  handleStart(event) {
139653
+ if (this.targetPhaseReached)
139654
+ return;
139640
139655
  const simpleRouteJson = event.simpleRouteJson;
139641
139656
  const subcircuitId = event.subcircuit_id ?? event.subcircuitId ?? "unknown-subcircuit";
139642
139657
  const previousOrdinal = this.phaseOrdinalBySubcircuit.get(subcircuitId) ?? 0;
@@ -139649,6 +139664,9 @@ class AutorouterDiagnostics {
139649
139664
  this.activePhase = {
139650
139665
  subcircuitId,
139651
139666
  componentDisplayName: event.componentDisplayName ?? "subcircuit",
139667
+ phaseName: event.phaseName,
139668
+ phaseStageIndex: event.phaseStageIndex,
139669
+ phaseStageCount: event.phaseStageCount,
139652
139670
  routingPhaseIndex,
139653
139671
  phaseOrdinal,
139654
139672
  phaseCount: event.phaseCount,
@@ -139703,6 +139721,9 @@ class AutorouterDiagnostics {
139703
139721
  this.summary.push({
139704
139722
  subcircuit_id: activePhase.subcircuitId,
139705
139723
  componentDisplayName: activePhase.componentDisplayName,
139724
+ phaseName: activePhase.phaseName,
139725
+ phaseStageIndex: activePhase.phaseStageIndex,
139726
+ phaseStageCount: activePhase.phaseStageCount,
139706
139727
  routingPhaseIndex: activePhase.routingPhaseIndex,
139707
139728
  phaseOrdinal: activePhase.phaseOrdinal,
139708
139729
  phaseCount: activePhase.phaseCount,
@@ -139733,6 +139754,9 @@ class AutorouterDiagnostics {
139733
139754
  if (this.options.enabled) {
139734
139755
  this.writePngSnapshot(`phase-${activePhase.routingPhaseIndex}-routed.png`, this.getCircuitJsonWithCompletedPhaseTraces());
139735
139756
  }
139757
+ if (this.isFinalTargetPhaseStage(activePhase)) {
139758
+ this.targetPhaseReached = true;
139759
+ }
139736
139760
  if (this.activePhase === activePhase) {
139737
139761
  this.activePhase = null;
139738
139762
  }
@@ -139746,6 +139770,9 @@ class AutorouterDiagnostics {
139746
139770
  this.summary.push({
139747
139771
  subcircuit_id: activePhase.subcircuitId,
139748
139772
  componentDisplayName: activePhase.componentDisplayName,
139773
+ phaseName: activePhase.phaseName,
139774
+ phaseStageIndex: activePhase.phaseStageIndex,
139775
+ phaseStageCount: activePhase.phaseStageCount,
139749
139776
  routingPhaseIndex: activePhase.routingPhaseIndex,
139750
139777
  phaseOrdinal: activePhase.phaseOrdinal,
139751
139778
  phaseCount: activePhase.phaseCount,
@@ -139769,6 +139796,9 @@ class AutorouterDiagnostics {
139769
139796
  type: "autorouter_phase_error",
139770
139797
  subcircuit_id: activePhase.subcircuitId,
139771
139798
  routingPhaseIndex: activePhase.routingPhaseIndex,
139799
+ phaseName: activePhase.phaseName,
139800
+ phaseStageIndex: activePhase.phaseStageIndex,
139801
+ phaseStageCount: activePhase.phaseStageCount,
139772
139802
  phaseOrdinal: activePhase.phaseOrdinal,
139773
139803
  phaseCount: activePhase.phaseCount,
139774
139804
  elapsedMs: Math.round(elapsedMs),
@@ -139778,6 +139808,9 @@ class AutorouterDiagnostics {
139778
139808
  error
139779
139809
  });
139780
139810
  }
139811
+ if (this.isFinalTargetPhaseStage(activePhase)) {
139812
+ this.targetPhaseReached = true;
139813
+ }
139781
139814
  if (this.activePhase === activePhase) {
139782
139815
  this.activePhase = null;
139783
139816
  }
@@ -139795,6 +139828,9 @@ class AutorouterDiagnostics {
139795
139828
  subcircuit_id: activePhase.subcircuitId,
139796
139829
  componentDisplayName: activePhase.componentDisplayName,
139797
139830
  routingPhaseIndex: activePhase.routingPhaseIndex,
139831
+ phaseName: activePhase.phaseName,
139832
+ phaseStageIndex: activePhase.phaseStageIndex,
139833
+ phaseStageCount: activePhase.phaseStageCount,
139798
139834
  phaseOrdinal: activePhase.phaseOrdinal,
139799
139835
  phaseCount: activePhase.phaseCount,
139800
139836
  elapsedMs: Math.round(elapsedMs),
@@ -139966,10 +140002,22 @@ class AutorouterDiagnostics {
139966
140002
  return `phase-${phaseNumber}.${suffix}`;
139967
140003
  }
139968
140004
  getPhaseLabel(activePhase) {
140005
+ const phaseName = activePhase.phaseName ? ` "${activePhase.phaseName}"` : "";
140006
+ const stageLabel = activePhase.phaseStageIndex !== undefined && activePhase.phaseStageCount !== undefined && activePhase.phaseStageCount > 1 ? ` stage ${activePhase.phaseStageIndex + 1}/${activePhase.phaseStageCount}` : "";
139969
140007
  if (activePhase.phaseCount) {
139970
- return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}`;
140008
+ return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}${phaseName}${stageLabel}`;
140009
+ }
140010
+ return `phase ${activePhase.phaseOrdinal}${phaseName}${stageLabel}`;
140011
+ }
140012
+ isFinalTargetPhaseStage(activePhase) {
140013
+ if (!this.options.phaseName)
140014
+ return false;
140015
+ if (activePhase.phaseName !== this.options.phaseName)
140016
+ return false;
140017
+ if (activePhase.phaseStageIndex === undefined || activePhase.phaseStageCount === undefined) {
140018
+ return true;
139971
140019
  }
139972
- return `phase ${activePhase.phaseOrdinal}`;
140020
+ return activePhase.phaseStageIndex >= activePhase.phaseStageCount - 1;
139973
140021
  }
139974
140022
  formatElapsed(elapsedMs) {
139975
140023
  if (elapsedMs < 1000)
@@ -152276,7 +152324,7 @@ var parseInjectedProps = ({
152276
152324
  return parsed;
152277
152325
  };
152278
152326
  var registerBuild = (program2) => {
152279
- program2.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ci", "Run install and optional prebuild/build commands (or default CI build)").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").option("--ignore-netlist-drc", "Ignore netlist DRC errors/warnings").option("--ignore-pin-specification-drc", "Ignore pin-specification DRC errors/warnings").option("--ignore-placement-drc", "Ignore placement DRC errors/warnings").option("--ignore-routing-drc", "Ignore routing DRC errors/warnings").option("--ignore-config", "Ignore options from tscircuit.config.json").option("--disable-pcb", "Disable PCB outputs").option("--routing-disabled", "Disable routing during circuit generation").option("--disable-parts-engine", "Disable the parts engine").option("--site", "Generate a static site in the dist directory").option("--transpile", "Transpile the entry file to JavaScript").option("--preview-images", "Generate preview images in the dist directory").option("--all-images", "Generate preview images for every successful build output").option("--pngs", "Generate PNG outputs during build generation").option("--pcb-png", "Generate PCB PNG outputs during build generation").option("--schematic-png", "Generate schematic PNG outputs during build generation").option("--svgs", "Generate SVG outputs during build generation").option("--pcb-svgs", "Generate PCB SVG outputs during build generation").option("--schematic-svgs", "Generate schematic SVG outputs during build generation").option("--simulation-svgs", "Generate simulation graph SVG outputs during build generation").option("--simulation-schematic-svgs", "Generate schematic simulation SVG outputs during build generation").option("--3d-png", "Generate 3D PNG outputs during build generation").option("--3d", "Generate 3D PNG outputs during build generation").option("--pcb-only", "Generate only PCB SVG outputs during build generation").option("--schematic-only", "Generate only schematic SVG outputs during build generation").option("--kicad-project", "Generate KiCad project directories for each successful build output").option("--kicad-project-zip", "Generate a zipped KiCad project for each successful build output").option("--kicad-library", "Generate KiCad library in dist/kicad-library").option("--kicad-library-name <name>", "Specify the name of the KiCad library").option("--preview-gltf", "Generate a GLTF file from the preview entrypoint").option("--show-courtyards", "Show courtyard outlines in PCB SVG outputs").option("--glbs", "Generate GLB 3D model files for every successful build").option("--step", "Generate STEP 3D model files for every successful build").option("--profile", "Log per-circuit circuit.json generation time during build").option("--autorouter-debug", "Log autorouting phases and write unrouted/per-phase PNG artifacts").option("--autorouter-timeout <duration>", 'Abort an autorouting phase after a duration, e.g. "120s" or "2m"').option("--autorouter-debug-dir <path>", "Directory for autorouting debug artifacts (default: dist/autorouter-debug)").option("--autorouter-dump-srj [mode]", 'Dump SimpleRouteJson inputs/outputs: "all", "failed", or "phase:<index>" (default: failed)').option("--solver-debug", "Write constructor inputs for every solver event emitted during the build").option("--solver-debug-dir <path>", "Directory for solver input artifacts (default: dist/solver-debug)").option("--kicad-pcm", "Generate KiCad PCM (Plugin and Content Manager) assets in dist/pcm").option("--use-cdn-javascript", "Use CDN-hosted JavaScript instead of bundled standalone file for --site").option("--concurrency <number>", "Number of files to build in parallel (default: 1)", "1").option("--inject-props <json>", "Inject JSON props into the built file's default export").option("--inject-props-file <path>", "Inject JSON props from a file into the built file's default export").action(async (file, options) => {
152327
+ program2.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ci", "Run install and optional prebuild/build commands (or default CI build)").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").option("--ignore-netlist-drc", "Ignore netlist DRC errors/warnings").option("--ignore-pin-specification-drc", "Ignore pin-specification DRC errors/warnings").option("--ignore-placement-drc", "Ignore placement DRC errors/warnings").option("--ignore-routing-drc", "Ignore routing DRC errors/warnings").option("--ignore-config", "Ignore options from tscircuit.config.json").option("--disable-pcb", "Disable PCB outputs").option("--routing-disabled", "Disable routing during circuit generation").option("--disable-parts-engine", "Disable the parts engine").option("--site", "Generate a static site in the dist directory").option("--transpile", "Transpile the entry file to JavaScript").option("--preview-images", "Generate preview images in the dist directory").option("--all-images", "Generate preview images for every successful build output").option("--pngs", "Generate PNG outputs during build generation").option("--pcb-png", "Generate PCB PNG outputs during build generation").option("--schematic-png", "Generate schematic PNG outputs during build generation").option("--svgs", "Generate SVG outputs during build generation").option("--pcb-svgs", "Generate PCB SVG outputs during build generation").option("--schematic-svgs", "Generate schematic SVG outputs during build generation").option("--simulation-svgs", "Generate simulation graph SVG outputs during build generation").option("--simulation-schematic-svgs", "Generate schematic simulation SVG outputs during build generation").option("--3d-png", "Generate 3D PNG outputs during build generation").option("--3d", "Generate 3D PNG outputs during build generation").option("--pcb-only", "Generate only PCB SVG outputs during build generation").option("--schematic-only", "Generate only schematic SVG outputs during build generation").option("--kicad-project", "Generate KiCad project directories for each successful build output").option("--kicad-project-zip", "Generate a zipped KiCad project for each successful build output").option("--kicad-library", "Generate KiCad library in dist/kicad-library").option("--kicad-library-name <name>", "Specify the name of the KiCad library").option("--preview-gltf", "Generate a GLTF file from the preview entrypoint").option("--show-courtyards", "Show courtyard outlines in PCB SVG outputs").option("--glbs", "Generate GLB 3D model files for every successful build").option("--step", "Generate STEP 3D model files for every successful build").option("--profile", "Log per-circuit circuit.json generation time during build").option("--autorouter-debug", "Log autorouting phases and write unrouted/per-phase PNG artifacts").option("--autorouter-phase <name>", "Enable autorouting debugging through the named phase").option("--autorouter-timeout <duration>", 'Abort an autorouting phase after a duration, e.g. "120s" or "2m"').option("--autorouter-debug-dir <path>", "Directory for autorouting debug artifacts (default: dist/autorouter-debug)").option("--autorouter-dump-srj [mode]", 'Dump SimpleRouteJson inputs/outputs: "all", "failed", or "phase:<index>" (default: failed)').option("--solver-debug", "Write constructor inputs for every solver event emitted during the build").option("--solver-debug-dir <path>", "Directory for solver input artifacts (default: dist/solver-debug)").option("--kicad-pcm", "Generate KiCad PCM (Plugin and Content Manager) assets in dist/pcm").option("--use-cdn-javascript", "Use CDN-hosted JavaScript instead of bundled standalone file for --site").option("--concurrency <number>", "Number of files to build in parallel (default: 1)", "1").option("--inject-props <json>", "Inject JSON props into the built file's default export").option("--inject-props-file <path>", "Inject JSON props from a file into the built file's default export").action(async (file, options) => {
152280
152328
  try {
152281
152329
  const transpileExplicitlyRequested = options?.transpile === true;
152282
152330
  const resolvedRoot = path45.resolve(process.cwd());
@@ -152342,10 +152390,12 @@ var registerBuild = (program2) => {
152342
152390
  const distDir = path45.join(projectDir, "dist");
152343
152391
  fs42.mkdirSync(distDir, { recursive: true });
152344
152392
  const autorouterTimeoutMs = resolvedOptions?.autorouterTimeout ? parseAutorouterTimeout(resolvedOptions.autorouterTimeout) : undefined;
152393
+ const autorouterPhaseName = resolvedOptions?.autorouterPhase !== undefined ? parseAutorouterPhaseName(resolvedOptions.autorouterPhase) : undefined;
152345
152394
  const autorouterDumpSrj = parseAutorouterDumpSrjMode(resolvedOptions?.autorouterDumpSrj);
152346
152395
  const autorouterDebugDir = resolvedOptions?.autorouterDebugDir ? path45.resolve(projectDir, resolvedOptions.autorouterDebugDir) : path45.join(distDir, "autorouter-debug");
152347
152396
  const autorouterDiagnostics = {
152348
- enabled: resolvedOptions?.autorouterDebug,
152397
+ enabled: resolvedOptions?.autorouterDebug || autorouterPhaseName !== undefined,
152398
+ phaseName: autorouterPhaseName,
152349
152399
  timeoutMs: autorouterTimeoutMs,
152350
152400
  debugDir: autorouterDebugDir,
152351
152401
  dumpSrj: autorouterDumpSrj,
@@ -152808,6 +152858,7 @@ var registerBuild = (program2) => {
152808
152858
  resolvedOptions?.previewGltf && "preview-gltf",
152809
152859
  resolvedOptions?.profile && "profile",
152810
152860
  resolvedOptions?.autorouterDebug && "autorouter-debug",
152861
+ resolvedOptions?.autorouterPhase && "autorouter-phase",
152811
152862
  resolvedOptions?.autorouterTimeout && "autorouter-timeout",
152812
152863
  resolvedOptions?.autorouterDumpSrj && "autorouter-dump-srj",
152813
152864
  resolvedOptions?.solverDebug && "solver-debug"
@@ -302039,10 +302090,12 @@ var loadTraceLengthAnalyzer = async () => {
302039
302090
  };
302040
302091
  var getAutorouterDiagnosticsOptions = (options = {}) => {
302041
302092
  const timeoutMs = options.autorouterTimeout ? parseAutorouterTimeout(options.autorouterTimeout) : undefined;
302093
+ const phaseName = options.autorouterPhase !== undefined ? parseAutorouterPhaseName(options.autorouterPhase) : undefined;
302042
302094
  const dumpSrj = parseAutorouterDumpSrjMode(options.autorouterDumpSrj);
302043
302095
  const debugDir = options.autorouterDebugDir ? path50.resolve(process.cwd(), options.autorouterDebugDir) : path50.resolve(process.cwd(), "dist", "autorouter-debug");
302044
302096
  return {
302045
- enabled: options.autorouterDebug,
302097
+ enabled: options.autorouterDebug || phaseName !== undefined,
302098
+ phaseName,
302046
302099
  timeoutMs,
302047
302100
  debugDir,
302048
302101
  dumpSrj,
@@ -302068,7 +302121,7 @@ var checkTraceLength = async (pinOrNetRef, file, options = {}) => {
302068
302121
  return analysis.toString();
302069
302122
  };
302070
302123
  var registerCheckTraceLength = (program2) => {
302071
- program2.commands.find((c3) => c3.name() === "check").command("trace-length").description("Analyze trace length for a pin or net").argument("<pinOrNetRef>", "Pin or net target to analyze").argument("[file]", "Path to the entry file").option("--autorouter-debug", "Log autorouting phases and write unrouted/per-phase PNG artifacts").option("--autorouter-timeout <duration>", 'Abort an autorouting phase after a duration, e.g. "120s" or "2m"').option("--autorouter-debug-dir <path>", "Directory for autorouting debug artifacts (default: dist/autorouter-debug)").option("--autorouter-dump-srj [mode]", 'Dump SimpleRouteJson inputs/outputs: "all", "failed", or "phase:<index>" (default: failed)').action(async (pinOrNetRef, file, options) => {
302124
+ program2.commands.find((c3) => c3.name() === "check").command("trace-length").description("Analyze trace length for a pin or net").argument("<pinOrNetRef>", "Pin or net target to analyze").argument("[file]", "Path to the entry file").option("--autorouter-debug", "Log autorouting phases and write unrouted/per-phase PNG artifacts").option("--autorouter-phase <name>", "Enable autorouting debugging through the named phase").option("--autorouter-timeout <duration>", 'Abort an autorouting phase after a duration, e.g. "120s" or "2m"').option("--autorouter-debug-dir <path>", "Directory for autorouting debug artifacts (default: dist/autorouter-debug)").option("--autorouter-dump-srj [mode]", 'Dump SimpleRouteJson inputs/outputs: "all", "failed", or "phase:<index>" (default: failed)').action(async (pinOrNetRef, file, options) => {
302072
302125
  try {
302073
302126
  const output = await checkTraceLength(pinOrNetRef, file, options);
302074
302127
  console.log(output);
@@ -308823,6 +308876,7 @@ var CIRCUIT_JSON_ID_PATTERN3 = /\b(?:source|pcb|schematic|subcircuit|cad|simulat
308823
308876
  var formatAutorouterDebugEvent = (event) => {
308824
308877
  const parts = [
308825
308878
  typeof event.componentDisplayName === "string" ? `component=${event.componentDisplayName}` : null,
308879
+ typeof event.phaseName === "string" ? `autorouter_phase=${event.phaseName}` : null,
308826
308880
  typeof event.phase === "string" ? `phase=${event.phase}` : null,
308827
308881
  typeof event.solverName === "string" ? `solver=${event.solverName}` : null,
308828
308882
  typeof event.connectionCount === "number" ? `connections=${event.connectionCount}` : null,
@@ -308849,23 +308903,27 @@ class DevServer {
308849
308903
  ignoredFiles;
308850
308904
  kicadPcm;
308851
308905
  autorouterDebug;
308906
+ autorouterPhase;
308852
308907
  httpServer;
308853
308908
  eventsWatcher;
308854
308909
  fsKy;
308855
308910
  filesystemWatcher;
308856
308911
  uploadedNodeModules = new Set;
308912
+ autorouterPhaseReached = false;
308857
308913
  constructor({
308858
308914
  port,
308859
308915
  componentFilePath,
308860
308916
  projectDir,
308861
308917
  kicadPcm,
308862
- autorouterDebug
308918
+ autorouterDebug,
308919
+ autorouterPhase
308863
308920
  }) {
308864
308921
  this.port = port;
308865
308922
  this.componentFilePath = componentFilePath;
308866
308923
  this.projectDir = projectDir ?? path66.dirname(componentFilePath);
308867
308924
  this.kicadPcm = kicadPcm ?? false;
308868
308925
  this.autorouterDebug = autorouterDebug ?? false;
308926
+ this.autorouterPhase = autorouterPhase?.trim() || undefined;
308869
308927
  const projectConfig2 = loadProjectConfig(this.projectDir);
308870
308928
  this.ignoredFiles = projectConfig2?.ignoredFiles ?? [];
308871
308929
  this.fsKy = distribution_default.create({
@@ -308892,7 +308950,12 @@ class DevServer {
308892
308950
  this.eventsWatcher.on("*", (event) => {
308893
308951
  if (!String(event.event_type).startsWith("autorouting:"))
308894
308952
  return;
308953
+ if (this.autorouterPhaseReached)
308954
+ return;
308895
308955
  console.log(kleur_default.cyan(formatAutorouterDebugEvent(event)));
308956
+ if (event.event_type === "autorouting:end" && event.phaseName === this.autorouterPhase && (event.phaseStageIndex === undefined || event.phaseStageCount === undefined || event.phaseStageIndex >= event.phaseStageCount - 1)) {
308957
+ this.autorouterPhaseReached = true;
308958
+ }
308896
308959
  });
308897
308960
  }
308898
308961
  this.filesystemWatcher = watch(this.projectDir, {
@@ -308910,6 +308973,7 @@ class DevServer {
308910
308973
  async handleFileUpdatedEventFromServer(ev2) {
308911
308974
  if (ev2.initiator === "filesystem_change")
308912
308975
  return;
308976
+ this.autorouterPhaseReached = false;
308913
308977
  const { file } = await this.fsKy.get("api/files/get", {
308914
308978
  searchParams: { file_path: ev2.file_path }
308915
308979
  }).json();
@@ -308938,6 +309002,7 @@ class DevServer {
308938
309002
  return;
308939
309003
  if (shouldIgnorePath(relativeFilePath, this.ignoredFiles))
308940
309004
  return;
309005
+ this.autorouterPhaseReached = false;
308941
309006
  const filePayload = this.createFileUploadPayload(absoluteFilePath, relativeFilePath);
308942
309007
  console.log(kleur_default.green(`Saving: ${relativeFilePath}`));
308943
309008
  await this.postFileUpsert({
@@ -308971,6 +309036,7 @@ class DevServer {
308971
309036
  const relativeFilePath = path66.relative(this.projectDir, absoluteFilePath);
308972
309037
  if (shouldIgnorePath(relativeFilePath, this.ignoredFiles))
308973
309038
  return;
309039
+ this.autorouterPhaseReached = false;
308974
309040
  if (!relativeFilePath || relativeFilePath.trim() === "") {
308975
309041
  debug13("Skipping delete for empty file path");
308976
309042
  return;
@@ -309211,7 +309277,7 @@ var warnIfTsconfigMissingTscircuitType = (projectDir) => {
309211
309277
  } catch {}
309212
309278
  };
309213
309279
  var registerDev = (program2) => {
309214
- program2.command("dev").description("Start development server for a package").argument("[file]", "Path to the package file or directory").option("-p, --port <number>", "Port to run server on", "3020").option("--kicad-pcm", "Enable KiCad PCM proxy server at /pcm/*").option("--autorouter-debug", "Log autorouting diagnostics emitted by the dev runframe").option("--autorouter-timeout <duration>", "Accepted for parity with build; dev autorouting timeouts are handled in the browser runframe").option("--autorouter-debug-dir <path>", "Accepted for parity with build; dev debug artifacts are handled in the browser runframe").option("--autorouter-dump-srj [mode]", "Accepted for parity with build; dev SRJ downloads are handled in the browser runframe").action(async (file, options) => {
309280
+ program2.command("dev").description("Start development server for a package").argument("[file]", "Path to the package file or directory").option("-p, --port <number>", "Port to run server on", "3020").option("--kicad-pcm", "Enable KiCad PCM proxy server at /pcm/*").option("--autorouter-debug", "Log autorouting diagnostics emitted by the dev runframe").option("--autorouter-phase <name>", "Log autorouting diagnostics through the named phase").option("--autorouter-timeout <duration>", "Accepted for parity with build; dev autorouting timeouts are handled in the browser runframe").option("--autorouter-debug-dir <path>", "Accepted for parity with build; dev debug artifacts are handled in the browser runframe").option("--autorouter-dump-srj [mode]", "Accepted for parity with build; dev SRJ downloads are handled in the browser runframe").action(async (file, options) => {
309215
309281
  let port = parseInt(options.port);
309216
309282
  const startTime = Date.now();
309217
309283
  while (!await isPortAvailable(port)) {
@@ -309222,13 +309288,15 @@ var registerDev = (program2) => {
309222
309288
  if (!target)
309223
309289
  return;
309224
309290
  const { absolutePath, projectDir } = target;
309291
+ const autorouterPhase = options.autorouterPhase !== undefined ? parseAutorouterPhaseName(options.autorouterPhase) : undefined;
309225
309292
  warnIfTsconfigMissingTscircuitType(projectDir);
309226
309293
  const server = new DevServer({
309227
309294
  port,
309228
309295
  componentFilePath: absolutePath,
309229
309296
  projectDir,
309230
309297
  kicadPcm: options.kicadPcm,
309231
- autorouterDebug: options.autorouterDebug
309298
+ autorouterDebug: options.autorouterDebug || autorouterPhase !== undefined,
309299
+ autorouterPhase
309232
309300
  });
309233
309301
  await server.start();
309234
309302
  const timeToStart = Date.now() - startTime;
@@ -309245,7 +309313,7 @@ var registerDev = (program2) => {
309245
309313
  ${kleur_default.bold("➜ Auto-updating KiCad PCM Server:")} ${kleur_default.underline(kleur_default.cyan(`http://localhost:${port}/pcm/repository.json`))}
309246
309314
  `);
309247
309315
  }
309248
- if (options.autorouterTimeout || options.autorouterDebugDir || options.autorouterDumpSrj) {
309316
+ if (options.autorouterTimeout || options.autorouterDebugDir || options.autorouterDumpSrj || autorouterPhase) {
309249
309317
  console.log(kleur_default.gray("Autorouter timeout/debug artifact flags are fully supported by `tsci build`; `tsci dev` currently logs autorouting events emitted by runframe."));
309250
309318
  }
309251
309319
  });
@@ -2965,6 +2965,13 @@ var parseAutorouterTimeout = (duration) => {
2965
2965
  }
2966
2966
  return timeoutMs;
2967
2967
  };
2968
+ var parseAutorouterPhaseName = (value) => {
2969
+ const phaseName = value.trim();
2970
+ if (!phaseName) {
2971
+ throw new Error("Invalid --autorouter-phase value. The phase name must not be empty.");
2972
+ }
2973
+ return phaseName;
2974
+ };
2968
2975
  var parseAutorouterDumpSrjMode = (value) => {
2969
2976
  if (value === undefined || value === false)
2970
2977
  return;
@@ -2994,17 +3001,21 @@ class AutorouterDiagnostics {
2994
3001
  activePhase = null;
2995
3002
  completedPhaseTraces = [];
2996
3003
  hasWrittenPlacementSnapshot = false;
3004
+ targetPhaseReached = false;
2997
3005
  summary = [];
2998
3006
  rootCircuit;
2999
3007
  constructor(options = {}) {
3008
+ const phaseName = options.phaseName?.trim() || undefined;
3000
3009
  this.options = {
3001
3010
  ...options,
3011
+ enabled: options.enabled || phaseName !== undefined,
3012
+ phaseName,
3002
3013
  debugDir: options.debugDir ?? DEFAULT_DEBUG_DIR,
3003
3014
  log: options.log ?? console.log
3004
3015
  };
3005
3016
  }
3006
3017
  get isActive() {
3007
- return Boolean(this.options.enabled || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
3018
+ return Boolean(this.options.enabled || this.options.phaseName || this.options.timeoutMs || this.options.dumpSrj || this.options.logOnError || this.options.longRunningLogThresholdMs);
3008
3019
  }
3009
3020
  attachToRootCircuit(rootCircuit) {
3010
3021
  if (!this.isActive)
@@ -3037,10 +3048,14 @@ class AutorouterDiagnostics {
3037
3048
  generatedAt: new Date().toISOString(),
3038
3049
  phaseCount: this.summary.length,
3039
3050
  phases: this.summary,
3040
- circuitJsonElementCount: circuitJson?.length
3051
+ circuitJsonElementCount: circuitJson?.length,
3052
+ targetPhaseName: this.options.phaseName,
3053
+ targetPhaseReached: this.targetPhaseReached
3041
3054
  });
3042
3055
  }
3043
3056
  handleStart(event) {
3057
+ if (this.targetPhaseReached)
3058
+ return;
3044
3059
  const simpleRouteJson = event.simpleRouteJson;
3045
3060
  const subcircuitId = event.subcircuit_id ?? event.subcircuitId ?? "unknown-subcircuit";
3046
3061
  const previousOrdinal = this.phaseOrdinalBySubcircuit.get(subcircuitId) ?? 0;
@@ -3053,6 +3068,9 @@ class AutorouterDiagnostics {
3053
3068
  this.activePhase = {
3054
3069
  subcircuitId,
3055
3070
  componentDisplayName: event.componentDisplayName ?? "subcircuit",
3071
+ phaseName: event.phaseName,
3072
+ phaseStageIndex: event.phaseStageIndex,
3073
+ phaseStageCount: event.phaseStageCount,
3056
3074
  routingPhaseIndex,
3057
3075
  phaseOrdinal,
3058
3076
  phaseCount: event.phaseCount,
@@ -3107,6 +3125,9 @@ class AutorouterDiagnostics {
3107
3125
  this.summary.push({
3108
3126
  subcircuit_id: activePhase.subcircuitId,
3109
3127
  componentDisplayName: activePhase.componentDisplayName,
3128
+ phaseName: activePhase.phaseName,
3129
+ phaseStageIndex: activePhase.phaseStageIndex,
3130
+ phaseStageCount: activePhase.phaseStageCount,
3110
3131
  routingPhaseIndex: activePhase.routingPhaseIndex,
3111
3132
  phaseOrdinal: activePhase.phaseOrdinal,
3112
3133
  phaseCount: activePhase.phaseCount,
@@ -3137,6 +3158,9 @@ class AutorouterDiagnostics {
3137
3158
  if (this.options.enabled) {
3138
3159
  this.writePngSnapshot(`phase-${activePhase.routingPhaseIndex}-routed.png`, this.getCircuitJsonWithCompletedPhaseTraces());
3139
3160
  }
3161
+ if (this.isFinalTargetPhaseStage(activePhase)) {
3162
+ this.targetPhaseReached = true;
3163
+ }
3140
3164
  if (this.activePhase === activePhase) {
3141
3165
  this.activePhase = null;
3142
3166
  }
@@ -3150,6 +3174,9 @@ class AutorouterDiagnostics {
3150
3174
  this.summary.push({
3151
3175
  subcircuit_id: activePhase.subcircuitId,
3152
3176
  componentDisplayName: activePhase.componentDisplayName,
3177
+ phaseName: activePhase.phaseName,
3178
+ phaseStageIndex: activePhase.phaseStageIndex,
3179
+ phaseStageCount: activePhase.phaseStageCount,
3153
3180
  routingPhaseIndex: activePhase.routingPhaseIndex,
3154
3181
  phaseOrdinal: activePhase.phaseOrdinal,
3155
3182
  phaseCount: activePhase.phaseCount,
@@ -3173,6 +3200,9 @@ class AutorouterDiagnostics {
3173
3200
  type: "autorouter_phase_error",
3174
3201
  subcircuit_id: activePhase.subcircuitId,
3175
3202
  routingPhaseIndex: activePhase.routingPhaseIndex,
3203
+ phaseName: activePhase.phaseName,
3204
+ phaseStageIndex: activePhase.phaseStageIndex,
3205
+ phaseStageCount: activePhase.phaseStageCount,
3176
3206
  phaseOrdinal: activePhase.phaseOrdinal,
3177
3207
  phaseCount: activePhase.phaseCount,
3178
3208
  elapsedMs: Math.round(elapsedMs),
@@ -3182,6 +3212,9 @@ class AutorouterDiagnostics {
3182
3212
  error
3183
3213
  });
3184
3214
  }
3215
+ if (this.isFinalTargetPhaseStage(activePhase)) {
3216
+ this.targetPhaseReached = true;
3217
+ }
3185
3218
  if (this.activePhase === activePhase) {
3186
3219
  this.activePhase = null;
3187
3220
  }
@@ -3199,6 +3232,9 @@ class AutorouterDiagnostics {
3199
3232
  subcircuit_id: activePhase.subcircuitId,
3200
3233
  componentDisplayName: activePhase.componentDisplayName,
3201
3234
  routingPhaseIndex: activePhase.routingPhaseIndex,
3235
+ phaseName: activePhase.phaseName,
3236
+ phaseStageIndex: activePhase.phaseStageIndex,
3237
+ phaseStageCount: activePhase.phaseStageCount,
3202
3238
  phaseOrdinal: activePhase.phaseOrdinal,
3203
3239
  phaseCount: activePhase.phaseCount,
3204
3240
  elapsedMs: Math.round(elapsedMs),
@@ -3370,10 +3406,22 @@ class AutorouterDiagnostics {
3370
3406
  return `phase-${phaseNumber}.${suffix}`;
3371
3407
  }
3372
3408
  getPhaseLabel(activePhase) {
3409
+ const phaseName = activePhase.phaseName ? ` "${activePhase.phaseName}"` : "";
3410
+ const stageLabel = activePhase.phaseStageIndex !== undefined && activePhase.phaseStageCount !== undefined && activePhase.phaseStageCount > 1 ? ` stage ${activePhase.phaseStageIndex + 1}/${activePhase.phaseStageCount}` : "";
3373
3411
  if (activePhase.phaseCount) {
3374
- return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}`;
3412
+ return `phase ${activePhase.phaseOrdinal}/${activePhase.phaseCount}${phaseName}${stageLabel}`;
3413
+ }
3414
+ return `phase ${activePhase.phaseOrdinal}${phaseName}${stageLabel}`;
3415
+ }
3416
+ isFinalTargetPhaseStage(activePhase) {
3417
+ if (!this.options.phaseName)
3418
+ return false;
3419
+ if (activePhase.phaseName !== this.options.phaseName)
3420
+ return false;
3421
+ if (activePhase.phaseStageIndex === undefined || activePhase.phaseStageCount === undefined) {
3422
+ return true;
3375
3423
  }
3376
- return `phase ${activePhase.phaseOrdinal}`;
3424
+ return activePhase.phaseStageIndex >= activePhase.phaseStageCount - 1;
3377
3425
  }
3378
3426
  formatElapsed(elapsedMs) {
3379
3427
  if (elapsedMs < 1000)
package/dist/lib/index.js CHANGED
@@ -65757,7 +65757,7 @@ var getNodeHandler = (winterSpec, { port, middleware = [] }) => {
65757
65757
  }));
65758
65758
  };
65759
65759
  // package.json
65760
- var version = "0.1.1834";
65760
+ var version = "0.1.1835";
65761
65761
  var package_default = {
65762
65762
  name: "@tscircuit/cli",
65763
65763
  version,
@@ -80359,6 +80359,7 @@ var CIRCUIT_JSON_ID_PATTERN = /\b(?:source|pcb|schematic|subcircuit|cad|simulati
80359
80359
  var formatAutorouterDebugEvent = (event) => {
80360
80360
  const parts = [
80361
80361
  typeof event.componentDisplayName === "string" ? `component=${event.componentDisplayName}` : null,
80362
+ typeof event.phaseName === "string" ? `autorouter_phase=${event.phaseName}` : null,
80362
80363
  typeof event.phase === "string" ? `phase=${event.phase}` : null,
80363
80364
  typeof event.solverName === "string" ? `solver=${event.solverName}` : null,
80364
80365
  typeof event.connectionCount === "number" ? `connections=${event.connectionCount}` : null,
@@ -80385,23 +80386,27 @@ class DevServer {
80385
80386
  ignoredFiles;
80386
80387
  kicadPcm;
80387
80388
  autorouterDebug;
80389
+ autorouterPhase;
80388
80390
  httpServer;
80389
80391
  eventsWatcher;
80390
80392
  fsKy;
80391
80393
  filesystemWatcher;
80392
80394
  uploadedNodeModules = new Set;
80395
+ autorouterPhaseReached = false;
80393
80396
  constructor({
80394
80397
  port,
80395
80398
  componentFilePath,
80396
80399
  projectDir,
80397
80400
  kicadPcm,
80398
- autorouterDebug
80401
+ autorouterDebug,
80402
+ autorouterPhase
80399
80403
  }) {
80400
80404
  this.port = port;
80401
80405
  this.componentFilePath = componentFilePath;
80402
80406
  this.projectDir = projectDir ?? path27.dirname(componentFilePath);
80403
80407
  this.kicadPcm = kicadPcm ?? false;
80404
80408
  this.autorouterDebug = autorouterDebug ?? false;
80409
+ this.autorouterPhase = autorouterPhase?.trim() || undefined;
80405
80410
  const projectConfig = loadProjectConfig(this.projectDir);
80406
80411
  this.ignoredFiles = projectConfig?.ignoredFiles ?? [];
80407
80412
  this.fsKy = distribution_default.create({
@@ -80428,7 +80433,12 @@ class DevServer {
80428
80433
  this.eventsWatcher.on("*", (event) => {
80429
80434
  if (!String(event.event_type).startsWith("autorouting:"))
80430
80435
  return;
80436
+ if (this.autorouterPhaseReached)
80437
+ return;
80431
80438
  console.log(kleur_default.cyan(formatAutorouterDebugEvent(event)));
80439
+ if (event.event_type === "autorouting:end" && event.phaseName === this.autorouterPhase && (event.phaseStageIndex === undefined || event.phaseStageCount === undefined || event.phaseStageIndex >= event.phaseStageCount - 1)) {
80440
+ this.autorouterPhaseReached = true;
80441
+ }
80432
80442
  });
80433
80443
  }
80434
80444
  this.filesystemWatcher = watch(this.projectDir, {
@@ -80446,6 +80456,7 @@ class DevServer {
80446
80456
  async handleFileUpdatedEventFromServer(ev) {
80447
80457
  if (ev.initiator === "filesystem_change")
80448
80458
  return;
80459
+ this.autorouterPhaseReached = false;
80449
80460
  const { file } = await this.fsKy.get("api/files/get", {
80450
80461
  searchParams: { file_path: ev.file_path }
80451
80462
  }).json();
@@ -80474,6 +80485,7 @@ class DevServer {
80474
80485
  return;
80475
80486
  if (shouldIgnorePath(relativeFilePath, this.ignoredFiles))
80476
80487
  return;
80488
+ this.autorouterPhaseReached = false;
80477
80489
  const filePayload = this.createFileUploadPayload(absoluteFilePath, relativeFilePath);
80478
80490
  console.log(kleur_default.green(`Saving: ${relativeFilePath}`));
80479
80491
  await this.postFileUpsert({
@@ -80507,6 +80519,7 @@ class DevServer {
80507
80519
  const relativeFilePath = path27.relative(this.projectDir, absoluteFilePath);
80508
80520
  if (shouldIgnorePath(relativeFilePath, this.ignoredFiles))
80509
80521
  return;
80522
+ this.autorouterPhaseReached = false;
80510
80523
  if (!relativeFilePath || relativeFilePath.trim() === "") {
80511
80524
  debug2("Skipping delete for empty file path");
80512
80525
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.1835",
3
+ "version": "0.1.1836",
4
4
  "main": "dist/cli/main.js",
5
5
  "exports": {
6
6
  ".": "./dist/cli/main.js",