@tscircuit/cli 0.1.2450 → 0.1.2452

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.
@@ -40739,6 +40739,24 @@ import fs2 from "node:fs";
40739
40739
  import path2 from "node:path";
40740
40740
  import { convertCircuitJsonToPcbSvg } from "circuit-to-svg";
40741
40741
 
40742
+ // lib/shared/compute-cost-summary.ts
40743
+ var labelComputeCostSummary = (summary, getPcbPortLabel) => ({
40744
+ ...summary,
40745
+ topPairs: summary.topPairs.map((pair) => ({
40746
+ ...pair,
40747
+ labels: pair.pcbPortIds.map((pcbPortId) => {
40748
+ if (pcbPortId === null)
40749
+ return pair.connectionName;
40750
+ return getPcbPortLabel(pcbPortId) ?? pair.connectionName;
40751
+ })
40752
+ }))
40753
+ });
40754
+ var formatHardestConnections = (summary, count = 5) => summary.topPairs.slice(0, count).map((pair) => {
40755
+ const [from, to] = pair.labels;
40756
+ const endpoints = from === to ? from : `${from} -> ${to}`;
40757
+ return `${endpoints} (${pair.iterations} iters)`;
40758
+ }).join(", ");
40759
+
40742
40760
  // lib/shared/convert-svg-to-png.ts
40743
40761
  import { Resvg } from "@resvg/resvg-js";
40744
40762
  var convertSvgToPngBuffer = (svg) => {
@@ -40802,6 +40820,7 @@ class AutorouterDiagnostics {
40802
40820
  options;
40803
40821
  phaseOrdinalBySubcircuit = new Map;
40804
40822
  traceCountBySubcircuit = new Map;
40823
+ computeCostByStage = new Map;
40805
40824
  activePhase = null;
40806
40825
  completedPhaseTraces = [];
40807
40826
  hasWrittenPlacementSnapshot = false;
@@ -40877,6 +40896,7 @@ class AutorouterDiagnostics {
40877
40896
  phaseStageCount: event.phaseStageCount,
40878
40897
  routingPhaseIndex,
40879
40898
  phaseOrdinal,
40899
+ _actualRoutingPhaseOrderIndex: event._actualRoutingPhaseOrderIndex,
40880
40900
  phaseCount: event.phaseCount,
40881
40901
  connectionCount,
40882
40902
  obstacleCount,
@@ -40911,10 +40931,12 @@ class AutorouterDiagnostics {
40911
40931
  }
40912
40932
  }
40913
40933
  handleProgress(event) {
40934
+ this.rememberComputeCost(event);
40914
40935
  if (!this.activePhase)
40915
40936
  return;
40916
40937
  const now = performance.now();
40917
- this.activePhase.lastProgress = event;
40938
+ const { computeCostSummary: _computeCostSummary, ...progress } = event;
40939
+ this.activePhase.lastProgress = progress;
40918
40940
  if (!this.shouldLogPhaseDetails(this.activePhase))
40919
40941
  return;
40920
40942
  if (this.activePhase.lastProgressLogAt > 0 && now - this.activePhase.lastProgressLogAt < PROGRESS_LOG_INTERVAL_MS) {
@@ -40924,9 +40946,12 @@ class AutorouterDiagnostics {
40924
40946
  this.logProgress(this.activePhase, event, now);
40925
40947
  }
40926
40948
  handleEnd(event) {
40949
+ const computeCostSummary = this.reportComputeCost(event, "end");
40927
40950
  const activePhase = this.matchActivePhase(event);
40928
- if (!activePhase)
40951
+ if (!activePhase) {
40952
+ this.recordUntrackedStage(event, computeCostSummary);
40929
40953
  return;
40954
+ }
40930
40955
  const elapsedMs = performance.now() - activePhase.startedAt;
40931
40956
  const outputSrj = event.simpleRouteJson;
40932
40957
  const outputTraceCount = outputSrj?.traces?.length ?? 0;
@@ -40943,6 +40968,8 @@ class AutorouterDiagnostics {
40943
40968
  phaseStageCount: activePhase.phaseStageCount,
40944
40969
  routingPhaseIndex: activePhase.routingPhaseIndex,
40945
40970
  phaseOrdinal: activePhase.phaseOrdinal,
40971
+ _actualRoutingPhaseOrderIndex: activePhase._actualRoutingPhaseOrderIndex,
40972
+ computeCostSummary,
40946
40973
  phaseCount: activePhase.phaseCount,
40947
40974
  connectionCount: activePhase.connectionCount,
40948
40975
  obstacleCount: activePhase.obstacleCount,
@@ -40980,9 +41007,12 @@ class AutorouterDiagnostics {
40980
41007
  }
40981
41008
  }
40982
41009
  handleError(event) {
41010
+ const computeCostSummary = this.reportComputeCost(event, "error");
40983
41011
  const activePhase = this.matchActivePhase(event);
40984
- if (!activePhase)
41012
+ if (!activePhase) {
41013
+ this.recordUntrackedStage(event, computeCostSummary, event.error);
40985
41014
  return;
41015
+ }
40986
41016
  const elapsedMs = performance.now() - activePhase.startedAt;
40987
41017
  const error = this.serializeError(event.error);
40988
41018
  this.summary.push({
@@ -40993,6 +41023,8 @@ class AutorouterDiagnostics {
40993
41023
  phaseStageCount: activePhase.phaseStageCount,
40994
41024
  routingPhaseIndex: activePhase.routingPhaseIndex,
40995
41025
  phaseOrdinal: activePhase.phaseOrdinal,
41026
+ _actualRoutingPhaseOrderIndex: activePhase._actualRoutingPhaseOrderIndex,
41027
+ computeCostSummary,
40996
41028
  phaseCount: activePhase.phaseCount,
40997
41029
  connectionCount: activePhase.connectionCount,
40998
41030
  obstacleCount: activePhase.obstacleCount,
@@ -41046,6 +41078,7 @@ class AutorouterDiagnostics {
41046
41078
  return this.writeJson(timeoutFile, {
41047
41079
  type: "autorouter_phase_timeout",
41048
41080
  subcircuit_id: activePhase.subcircuitId,
41081
+ _actualRoutingPhaseOrderIndex: activePhase._actualRoutingPhaseOrderIndex,
41049
41082
  componentDisplayName: activePhase.componentDisplayName,
41050
41083
  routingPhaseIndex: activePhase.routingPhaseIndex,
41051
41084
  phaseName: activePhase.phaseName,
@@ -41058,6 +41091,7 @@ class AutorouterDiagnostics {
41058
41091
  obstacleCount: activePhase.obstacleCount,
41059
41092
  previousTraceCount: activePhase.previousTraceCount,
41060
41093
  ...this.getExecutionMetadata(activePhase),
41094
+ computeCostSummary: this.getLabeledComputeCost(activePhase),
41061
41095
  files: {
41062
41096
  inputSimpleRouteJson: inputFile,
41063
41097
  previousOutputTraces: previousTracesFile,
@@ -41066,6 +41100,72 @@ class AutorouterDiagnostics {
41066
41100
  lastProgress: activePhase.lastProgress
41067
41101
  });
41068
41102
  }
41103
+ getStageKey(stage) {
41104
+ const subcircuitId = stage.subcircuit_id ?? stage.subcircuitId;
41105
+ if (!subcircuitId)
41106
+ return;
41107
+ const stageOrder = stage._actualRoutingPhaseOrderIndex ?? stage.phaseOrdinal ?? this.phaseOrdinalBySubcircuit.get(subcircuitId);
41108
+ if (stageOrder === undefined)
41109
+ return;
41110
+ return `${subcircuitId}|${stageOrder}`;
41111
+ }
41112
+ rememberComputeCost(event) {
41113
+ if (this.targetPhaseReached || !event.computeCostSummary)
41114
+ return;
41115
+ const key = this.getStageKey(event);
41116
+ if (key)
41117
+ this.computeCostByStage.set(key, event.computeCostSummary);
41118
+ }
41119
+ getLabeledComputeCost(stage) {
41120
+ const key = this.getStageKey(stage);
41121
+ const summary = stage.computeCostSummary ?? (key ? this.computeCostByStage.get(key) : undefined);
41122
+ if (!summary)
41123
+ return;
41124
+ try {
41125
+ const circuitJson = this.getCurrentCircuitJson();
41126
+ return labelComputeCostSummary(summary, (pcbPortId) => this.getPcbPortLabel(pcbPortId, circuitJson));
41127
+ } catch (error) {
41128
+ this.log(kleur_default.yellow(`Warning: Could not format autorouter compute cost: ${error}`));
41129
+ return;
41130
+ }
41131
+ }
41132
+ getPcbPortLabel(pcbPortId, circuitJson) {
41133
+ const pcbPort = circuitJson.find((element) => element.type === "pcb_port" && element.pcb_port_id === pcbPortId);
41134
+ if (!pcbPort)
41135
+ return null;
41136
+ return this.getPortSelectorById(pcbPort.source_port_id, circuitJson);
41137
+ }
41138
+ reportComputeCost(event, outcome) {
41139
+ if (this.targetPhaseReached)
41140
+ return;
41141
+ const computeCostSummary = this.getLabeledComputeCost(event);
41142
+ if (!computeCostSummary)
41143
+ return;
41144
+ const shouldPrint = this.options.enabled || outcome === "error" && this.options.logOnError;
41145
+ if (shouldPrint) {
41146
+ const hardest = formatHardestConnections(computeCostSummary);
41147
+ if (hardest)
41148
+ this.log(` hardest connections: ${hardest}`);
41149
+ }
41150
+ return computeCostSummary;
41151
+ }
41152
+ recordUntrackedStage(event, computeCostSummary, error) {
41153
+ if (!computeCostSummary)
41154
+ return;
41155
+ const subcircuitId = event.subcircuit_id ?? event.subcircuitId;
41156
+ this.summary.push({
41157
+ subcircuit_id: subcircuitId,
41158
+ _actualRoutingPhaseOrderIndex: event._actualRoutingPhaseOrderIndex,
41159
+ phaseOrdinal: event.phaseOrdinal ?? this.phaseOrdinalBySubcircuit.get(subcircuitId ?? ""),
41160
+ phaseName: event.phaseName,
41161
+ componentDisplayName: event.componentDisplayName,
41162
+ routingPhaseIndex: event.routingPhaseIndex,
41163
+ phaseStageIndex: event.phaseStageIndex,
41164
+ phaseStageCount: event.phaseStageCount,
41165
+ ...error !== undefined ? { error: this.serializeError(error) } : {},
41166
+ computeCostSummary
41167
+ });
41168
+ }
41069
41169
  checkLongRunning() {
41070
41170
  if (!this.activePhase)
41071
41171
  return;
package/dist/cli/main.js CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/cli/main.js
3
- size: 47857017 bytes
4
- sha256: 9fd97f4ce16e924b68da1dbdcc6bd8bfcb059731996f50b92b7f19b5992ca7c8
3
+ size: 47861683 bytes
4
+ sha256: 3e013b98061dfbe5767ec63eb724f88f467d11fd79667c049e492cd102832b72
@@ -19958,6 +19958,24 @@ import fs2 from "node:fs";
19958
19958
  import path2 from "node:path";
19959
19959
  import { convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg2 } from "circuit-to-svg";
19960
19960
 
19961
+ // lib/shared/compute-cost-summary.ts
19962
+ var labelComputeCostSummary = (summary, getPcbPortLabel) => ({
19963
+ ...summary,
19964
+ topPairs: summary.topPairs.map((pair) => ({
19965
+ ...pair,
19966
+ labels: pair.pcbPortIds.map((pcbPortId) => {
19967
+ if (pcbPortId === null)
19968
+ return pair.connectionName;
19969
+ return getPcbPortLabel(pcbPortId) ?? pair.connectionName;
19970
+ })
19971
+ }))
19972
+ });
19973
+ var formatHardestConnections = (summary, count = 5) => summary.topPairs.slice(0, count).map((pair) => {
19974
+ const [from, to] = pair.labels;
19975
+ const endpoints = from === to ? from : `${from} -> ${to}`;
19976
+ return `${endpoints} (${pair.iterations} iters)`;
19977
+ }).join(", ");
19978
+
19961
19979
  // lib/shared/convert-svg-to-png.ts
19962
19980
  import { Resvg } from "@resvg/resvg-js";
19963
19981
  var convertSvgToPngBuffer = (svg) => {
@@ -20021,6 +20039,7 @@ class AutorouterDiagnostics {
20021
20039
  options;
20022
20040
  phaseOrdinalBySubcircuit = new Map;
20023
20041
  traceCountBySubcircuit = new Map;
20042
+ computeCostByStage = new Map;
20024
20043
  activePhase = null;
20025
20044
  completedPhaseTraces = [];
20026
20045
  hasWrittenPlacementSnapshot = false;
@@ -20096,6 +20115,7 @@ class AutorouterDiagnostics {
20096
20115
  phaseStageCount: event.phaseStageCount,
20097
20116
  routingPhaseIndex,
20098
20117
  phaseOrdinal,
20118
+ _actualRoutingPhaseOrderIndex: event._actualRoutingPhaseOrderIndex,
20099
20119
  phaseCount: event.phaseCount,
20100
20120
  connectionCount,
20101
20121
  obstacleCount,
@@ -20130,10 +20150,12 @@ class AutorouterDiagnostics {
20130
20150
  }
20131
20151
  }
20132
20152
  handleProgress(event) {
20153
+ this.rememberComputeCost(event);
20133
20154
  if (!this.activePhase)
20134
20155
  return;
20135
20156
  const now = performance.now();
20136
- this.activePhase.lastProgress = event;
20157
+ const { computeCostSummary: _computeCostSummary, ...progress } = event;
20158
+ this.activePhase.lastProgress = progress;
20137
20159
  if (!this.shouldLogPhaseDetails(this.activePhase))
20138
20160
  return;
20139
20161
  if (this.activePhase.lastProgressLogAt > 0 && now - this.activePhase.lastProgressLogAt < PROGRESS_LOG_INTERVAL_MS) {
@@ -20143,9 +20165,12 @@ class AutorouterDiagnostics {
20143
20165
  this.logProgress(this.activePhase, event, now);
20144
20166
  }
20145
20167
  handleEnd(event) {
20168
+ const computeCostSummary = this.reportComputeCost(event, "end");
20146
20169
  const activePhase = this.matchActivePhase(event);
20147
- if (!activePhase)
20170
+ if (!activePhase) {
20171
+ this.recordUntrackedStage(event, computeCostSummary);
20148
20172
  return;
20173
+ }
20149
20174
  const elapsedMs = performance.now() - activePhase.startedAt;
20150
20175
  const outputSrj = event.simpleRouteJson;
20151
20176
  const outputTraceCount = outputSrj?.traces?.length ?? 0;
@@ -20162,6 +20187,8 @@ class AutorouterDiagnostics {
20162
20187
  phaseStageCount: activePhase.phaseStageCount,
20163
20188
  routingPhaseIndex: activePhase.routingPhaseIndex,
20164
20189
  phaseOrdinal: activePhase.phaseOrdinal,
20190
+ _actualRoutingPhaseOrderIndex: activePhase._actualRoutingPhaseOrderIndex,
20191
+ computeCostSummary,
20165
20192
  phaseCount: activePhase.phaseCount,
20166
20193
  connectionCount: activePhase.connectionCount,
20167
20194
  obstacleCount: activePhase.obstacleCount,
@@ -20199,9 +20226,12 @@ class AutorouterDiagnostics {
20199
20226
  }
20200
20227
  }
20201
20228
  handleError(event) {
20229
+ const computeCostSummary = this.reportComputeCost(event, "error");
20202
20230
  const activePhase = this.matchActivePhase(event);
20203
- if (!activePhase)
20231
+ if (!activePhase) {
20232
+ this.recordUntrackedStage(event, computeCostSummary, event.error);
20204
20233
  return;
20234
+ }
20205
20235
  const elapsedMs = performance.now() - activePhase.startedAt;
20206
20236
  const error = this.serializeError(event.error);
20207
20237
  this.summary.push({
@@ -20212,6 +20242,8 @@ class AutorouterDiagnostics {
20212
20242
  phaseStageCount: activePhase.phaseStageCount,
20213
20243
  routingPhaseIndex: activePhase.routingPhaseIndex,
20214
20244
  phaseOrdinal: activePhase.phaseOrdinal,
20245
+ _actualRoutingPhaseOrderIndex: activePhase._actualRoutingPhaseOrderIndex,
20246
+ computeCostSummary,
20215
20247
  phaseCount: activePhase.phaseCount,
20216
20248
  connectionCount: activePhase.connectionCount,
20217
20249
  obstacleCount: activePhase.obstacleCount,
@@ -20265,6 +20297,7 @@ class AutorouterDiagnostics {
20265
20297
  return this.writeJson(timeoutFile, {
20266
20298
  type: "autorouter_phase_timeout",
20267
20299
  subcircuit_id: activePhase.subcircuitId,
20300
+ _actualRoutingPhaseOrderIndex: activePhase._actualRoutingPhaseOrderIndex,
20268
20301
  componentDisplayName: activePhase.componentDisplayName,
20269
20302
  routingPhaseIndex: activePhase.routingPhaseIndex,
20270
20303
  phaseName: activePhase.phaseName,
@@ -20277,6 +20310,7 @@ class AutorouterDiagnostics {
20277
20310
  obstacleCount: activePhase.obstacleCount,
20278
20311
  previousTraceCount: activePhase.previousTraceCount,
20279
20312
  ...this.getExecutionMetadata(activePhase),
20313
+ computeCostSummary: this.getLabeledComputeCost(activePhase),
20280
20314
  files: {
20281
20315
  inputSimpleRouteJson: inputFile,
20282
20316
  previousOutputTraces: previousTracesFile,
@@ -20285,6 +20319,72 @@ class AutorouterDiagnostics {
20285
20319
  lastProgress: activePhase.lastProgress
20286
20320
  });
20287
20321
  }
20322
+ getStageKey(stage) {
20323
+ const subcircuitId = stage.subcircuit_id ?? stage.subcircuitId;
20324
+ if (!subcircuitId)
20325
+ return;
20326
+ const stageOrder = stage._actualRoutingPhaseOrderIndex ?? stage.phaseOrdinal ?? this.phaseOrdinalBySubcircuit.get(subcircuitId);
20327
+ if (stageOrder === undefined)
20328
+ return;
20329
+ return `${subcircuitId}|${stageOrder}`;
20330
+ }
20331
+ rememberComputeCost(event) {
20332
+ if (this.targetPhaseReached || !event.computeCostSummary)
20333
+ return;
20334
+ const key = this.getStageKey(event);
20335
+ if (key)
20336
+ this.computeCostByStage.set(key, event.computeCostSummary);
20337
+ }
20338
+ getLabeledComputeCost(stage) {
20339
+ const key = this.getStageKey(stage);
20340
+ const summary = stage.computeCostSummary ?? (key ? this.computeCostByStage.get(key) : undefined);
20341
+ if (!summary)
20342
+ return;
20343
+ try {
20344
+ const circuitJson = this.getCurrentCircuitJson();
20345
+ return labelComputeCostSummary(summary, (pcbPortId) => this.getPcbPortLabel(pcbPortId, circuitJson));
20346
+ } catch (error) {
20347
+ this.log(kleur_default.yellow(`Warning: Could not format autorouter compute cost: ${error}`));
20348
+ return;
20349
+ }
20350
+ }
20351
+ getPcbPortLabel(pcbPortId, circuitJson) {
20352
+ const pcbPort = circuitJson.find((element) => element.type === "pcb_port" && element.pcb_port_id === pcbPortId);
20353
+ if (!pcbPort)
20354
+ return null;
20355
+ return this.getPortSelectorById(pcbPort.source_port_id, circuitJson);
20356
+ }
20357
+ reportComputeCost(event, outcome) {
20358
+ if (this.targetPhaseReached)
20359
+ return;
20360
+ const computeCostSummary = this.getLabeledComputeCost(event);
20361
+ if (!computeCostSummary)
20362
+ return;
20363
+ const shouldPrint = this.options.enabled || outcome === "error" && this.options.logOnError;
20364
+ if (shouldPrint) {
20365
+ const hardest = formatHardestConnections(computeCostSummary);
20366
+ if (hardest)
20367
+ this.log(` hardest connections: ${hardest}`);
20368
+ }
20369
+ return computeCostSummary;
20370
+ }
20371
+ recordUntrackedStage(event, computeCostSummary, error) {
20372
+ if (!computeCostSummary)
20373
+ return;
20374
+ const subcircuitId = event.subcircuit_id ?? event.subcircuitId;
20375
+ this.summary.push({
20376
+ subcircuit_id: subcircuitId,
20377
+ _actualRoutingPhaseOrderIndex: event._actualRoutingPhaseOrderIndex,
20378
+ phaseOrdinal: event.phaseOrdinal ?? this.phaseOrdinalBySubcircuit.get(subcircuitId ?? ""),
20379
+ phaseName: event.phaseName,
20380
+ componentDisplayName: event.componentDisplayName,
20381
+ routingPhaseIndex: event.routingPhaseIndex,
20382
+ phaseStageIndex: event.phaseStageIndex,
20383
+ phaseStageCount: event.phaseStageCount,
20384
+ ...error !== undefined ? { error: this.serializeError(error) } : {},
20385
+ computeCostSummary
20386
+ });
20387
+ }
20288
20388
  checkLongRunning() {
20289
20389
  if (!this.activePhase)
20290
20390
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.2450",
3
+ "version": "0.1.2452",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/tscircuit/cli"