@tscircuit/cli 0.1.1055 → 0.1.1057

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/dist/cli/main.js CHANGED
@@ -71664,7 +71664,7 @@ var registerStaticAssetLoaders = () => {
71664
71664
  // cli/main.ts
71665
71665
  var import_perfect_cli = __toESM2(require_dist2(), 1);
71666
71666
  // package.json
71667
- var version = "0.1.1054";
71667
+ var version = "0.1.1055";
71668
71668
  var package_default = {
71669
71669
  name: "@tscircuit/cli",
71670
71670
  version,
@@ -71676,7 +71676,7 @@ var package_default = {
71676
71676
  devDependencies: {
71677
71677
  "@babel/standalone": "^7.26.9",
71678
71678
  "@biomejs/biome": "^1.9.4",
71679
- "@tscircuit/circuit-json-placement-analysis": "^0.0.1",
71679
+ "@tscircuit/circuit-json-placement-analysis": "^0.0.4",
71680
71680
  "@tscircuit/circuit-json-util": "0.0.81",
71681
71681
  "@tscircuit/fake-snippets": "^0.0.182",
71682
71682
  "@tscircuit/file-server": "^0.0.32",
@@ -82803,7 +82803,8 @@ var resolveInputFilePath = async (file) => {
82803
82803
  var checkNetlist = async (file) => {
82804
82804
  const resolvedInputFilePath = await resolveInputFilePath(file);
82805
82805
  const completePlatformConfig = getCompletePlatformConfig({
82806
- routingDrcChecksDisabled: true,
82806
+ pcbDisabled: true,
82807
+ routingDisabled: true,
82807
82808
  placementDrcChecksDisabled: true
82808
82809
  });
82809
82810
  const { circuitJson } = await generateCircuitJson({
@@ -82887,6 +82888,66 @@ var getComponentToBoardCalcString = (componentName, direction, distance) => {
82887
82888
  return `${componentName}.centerY=calc(board.centerY+${d})`;
82888
82889
  }
82889
82890
  };
82891
+ var getPadBounds = (element) => {
82892
+ if (element.type === "pcb_smtpad") {
82893
+ const x = toNumber2(element.x);
82894
+ const y = toNumber2(element.y);
82895
+ const width = toNumber2(element.width);
82896
+ const height = toNumber2(element.height);
82897
+ if (x === null || y === null || width === null || height === null)
82898
+ return null;
82899
+ return {
82900
+ minX: x - width / 2,
82901
+ maxX: x + width / 2,
82902
+ minY: y - height / 2,
82903
+ maxY: y + height / 2
82904
+ };
82905
+ }
82906
+ if (element.type === "pcb_plated_hole") {
82907
+ const x = toNumber2(element.x);
82908
+ const y = toNumber2(element.y);
82909
+ const rectPadWidth = toNumber2(element.rect_pad_width);
82910
+ const rectPadHeight = toNumber2(element.rect_pad_height);
82911
+ const holeDiameter = toNumber2(element.hole_diameter);
82912
+ if (x === null || y === null)
82913
+ return null;
82914
+ const width = rectPadWidth ?? holeDiameter;
82915
+ const height = rectPadHeight ?? holeDiameter;
82916
+ if (width === null || height === null)
82917
+ return null;
82918
+ return {
82919
+ minX: x - width / 2,
82920
+ maxX: x + width / 2,
82921
+ minY: y - height / 2,
82922
+ maxY: y + height / 2
82923
+ };
82924
+ }
82925
+ return null;
82926
+ };
82927
+ var getBoundsClearance = (a, b) => {
82928
+ const dx = Math.max(0, a.minX - b.maxX, b.minX - a.maxX);
82929
+ const dy = Math.max(0, a.minY - b.maxY, b.minY - a.maxY);
82930
+ return Math.hypot(dx, dy);
82931
+ };
82932
+ var getPadDisplayName = (pad, componentName, sourcePortNameByPcbPortId) => {
82933
+ const pcbPortId = typeof pad.pcb_port_id === "string" ? pad.pcb_port_id : null;
82934
+ if (pcbPortId) {
82935
+ const sourcePortName = sourcePortNameByPcbPortId.get(pcbPortId);
82936
+ if (sourcePortName)
82937
+ return `${componentName}.${sourcePortName}`;
82938
+ }
82939
+ if (Array.isArray(pad.port_hints)) {
82940
+ const pinHint = pad.port_hints.find((hint) => typeof hint === "string" && /^pin\d+$/i.test(hint));
82941
+ if (typeof pinHint === "string")
82942
+ return `${componentName}.${pinHint}`;
82943
+ const numericHint = pad.port_hints.find((hint) => typeof hint === "string" && /^\d+$/.test(hint));
82944
+ if (typeof numericHint === "string")
82945
+ return `${componentName}.pin${numericHint}`;
82946
+ }
82947
+ if (pcbPortId)
82948
+ return `${componentName}.${pcbPortId}`;
82949
+ return `${componentName}.pad`;
82950
+ };
82890
82951
  var getDirectionAndDistance = (fromX, fromY, toX, toY) => {
82891
82952
  const dx = toX - fromX;
82892
82953
  const dy = toY - fromY;
@@ -82903,6 +82964,13 @@ var getDirectionAndDistance = (fromX, fromY, toX, toY) => {
82903
82964
  axis: "y"
82904
82965
  };
82905
82966
  };
82967
+ var getPinCenter = (pad) => {
82968
+ const x = toNumber2(pad.x);
82969
+ const y = toNumber2(pad.y);
82970
+ if (x === null || y === null)
82971
+ return null;
82972
+ return { x, y };
82973
+ };
82906
82974
  var lineItemToString = (lineItem) => {
82907
82975
  switch (lineItem.line_item_type) {
82908
82976
  case "absolute_component_position":
@@ -82933,6 +83001,10 @@ var lineItemToString = (lineItem) => {
82933
83001
  return `${lineItem.component_name}.orientation=${lineItem.orientation}`;
82934
83002
  case "relative_component_edge_to_board_edge_position":
82935
83003
  return `${lineItem.component_name}.${lineItem.component_edge}=calc(${lineItem.board_edge}${withSignedMm(lineItem.offset)})${isOffBoardEdgeOffset(lineItem.board_edge, lineItem.offset) ? " [offboard]" : ""}`;
83004
+ case "component_pad_clearance":
83005
+ return `${lineItem.component_name}.padClearance=${fmtMm(lineItem.clearance)} [nearest=${lineItem.nearest_pad_name}]`;
83006
+ case "direct_pin_to_pin_distance":
83007
+ return `${lineItem.from_pin_name} -> ${lineItem.to_pin_name} distance: ${fmtMm(lineItem.distance)}`;
82936
83008
  default:
82937
83009
  return "";
82938
83010
  }
@@ -83076,6 +83148,151 @@ var analyzeComponentPlacement = (circuitJson, componentName) => {
83076
83148
  };
83077
83149
  lineItems.push(boardLineItem);
83078
83150
  }
83151
+ const sourcePortNameByPcbPortId = /* @__PURE__ */ new Map;
83152
+ for (const el of circuitJson) {
83153
+ if (el.type === "pcb_port" && typeof el.pcb_port_id === "string" && typeof el.source_port_id === "string") {
83154
+ const sourcePort = circuitJson.find((candidate) => candidate.type === "source_port" && candidate.source_port_id === el.source_port_id && typeof candidate.name === "string");
83155
+ if (sourcePort && typeof sourcePort.name === "string") {
83156
+ sourcePortNameByPcbPortId.set(el.pcb_port_id, sourcePort.name);
83157
+ }
83158
+ }
83159
+ }
83160
+ const sourcePortById = /* @__PURE__ */ new Map;
83161
+ for (const el of circuitJson) {
83162
+ if (el.type === "source_port" && typeof el.source_port_id === "string") {
83163
+ sourcePortById.set(el.source_port_id, el);
83164
+ }
83165
+ }
83166
+ const sourcePortDisplayNameById = /* @__PURE__ */ new Map;
83167
+ for (const el of circuitJson) {
83168
+ if (el.type === "source_port" && typeof el.source_port_id === "string") {
83169
+ if (typeof el.source_component_id === "string" && typeof el.name === "string") {
83170
+ const sourceComp = circuitJson.find((candidate) => candidate.type === "source_component" && candidate.source_component_id === el.source_component_id && typeof candidate.name === "string");
83171
+ if (sourceComp && typeof sourceComp.name === "string") {
83172
+ sourcePortDisplayNameById.set(el.source_port_id, `${sourceComp.name}.${el.name}`);
83173
+ continue;
83174
+ }
83175
+ }
83176
+ if (typeof el.name === "string") {
83177
+ sourcePortDisplayNameById.set(el.source_port_id, el.name);
83178
+ }
83179
+ }
83180
+ }
83181
+ const padBySourcePortId = /* @__PURE__ */ new Map;
83182
+ if (typeof pcbComponent?.pcb_component_id === "string") {
83183
+ for (const el of circuitJson) {
83184
+ if ((el.type === "pcb_smtpad" || el.type === "pcb_plated_hole") && typeof el.pcb_component_id === "string" && typeof el.pcb_port_id === "string") {
83185
+ const pcbPort = circuitJson.find((candidate) => candidate.type === "pcb_port" && candidate.pcb_port_id === el.pcb_port_id && typeof candidate.source_port_id === "string");
83186
+ if (!pcbPort || typeof pcbPort.source_port_id !== "string")
83187
+ continue;
83188
+ const center2 = getPinCenter(el);
83189
+ if (!center2)
83190
+ continue;
83191
+ const sourcePort = sourcePortById.get(pcbPort.source_port_id);
83192
+ const sourcePortComponentId = typeof sourcePort?.source_component_id === "string" ? sourcePort.source_component_id : null;
83193
+ if (sourcePortComponentId !== sourceComponentId)
83194
+ continue;
83195
+ padBySourcePortId.set(pcbPort.source_port_id, {
83196
+ pad: el,
83197
+ padName: getPadDisplayName(el, componentName, sourcePortNameByPcbPortId),
83198
+ center: center2
83199
+ });
83200
+ }
83201
+ }
83202
+ }
83203
+ const directPinDistanceLineItems = [];
83204
+ for (const fromPortId of padBySourcePortId.keys()) {
83205
+ const directPinToPinTraces = circuitJson.filter((el) => el.type === "source_trace" && Array.isArray(el.connected_source_port_ids) && el.connected_source_port_ids.length === 2 && el.connected_source_port_ids.includes(fromPortId) && Array.isArray(el.connected_source_net_ids) && el.connected_source_net_ids.length === 0);
83206
+ if (directPinToPinTraces.length !== 1)
83207
+ continue;
83208
+ const trace = directPinToPinTraces[0];
83209
+ if (!trace)
83210
+ continue;
83211
+ const connectedPortIds = Array.isArray(trace.connected_source_port_ids) ? trace.connected_source_port_ids.filter((value) => typeof value === "string") : [];
83212
+ const otherPortId = connectedPortIds.find((portId) => portId !== fromPortId);
83213
+ if (!otherPortId)
83214
+ continue;
83215
+ const fromPin = padBySourcePortId.get(fromPortId);
83216
+ if (!fromPin)
83217
+ continue;
83218
+ const otherPcbPort = circuitJson.find((candidate) => candidate.type === "pcb_port" && candidate.source_port_id === otherPortId && typeof candidate.pcb_port_id === "string");
83219
+ if (!otherPcbPort || typeof otherPcbPort.pcb_port_id !== "string")
83220
+ continue;
83221
+ const otherPad = circuitJson.find((candidate) => (candidate.type === "pcb_smtpad" || candidate.type === "pcb_plated_hole") && candidate.pcb_port_id === otherPcbPort.pcb_port_id);
83222
+ if (!otherPad)
83223
+ continue;
83224
+ const otherCenter = getPinCenter(otherPad);
83225
+ if (!otherCenter)
83226
+ continue;
83227
+ const fromPortDisplayName = sourcePortDisplayNameById.get(fromPortId);
83228
+ const toPortDisplayName = sourcePortDisplayNameById.get(otherPortId);
83229
+ if (!fromPortDisplayName || !toPortDisplayName)
83230
+ continue;
83231
+ directPinDistanceLineItems.push({
83232
+ line_item_type: "direct_pin_to_pin_distance",
83233
+ component_name: componentName,
83234
+ from_pin_name: fromPortDisplayName,
83235
+ to_pin_name: toPortDisplayName,
83236
+ distance: Math.hypot(otherCenter.x - fromPin.center.x, otherCenter.y - fromPin.center.y)
83237
+ });
83238
+ }
83239
+ lineItems.push(...directPinDistanceLineItems);
83240
+ const componentPadBounds = typeof pcbComponent?.pcb_component_id === "string" ? circuitJson.filter((el) => (el.type === "pcb_smtpad" || el.type === "pcb_plated_hole") && el.pcb_component_id === pcbComponent.pcb_component_id).map((pad) => {
83241
+ const bounds = getPadBounds(pad);
83242
+ if (!bounds)
83243
+ return null;
83244
+ return {
83245
+ bounds,
83246
+ padName: getPadDisplayName(pad, componentName, sourcePortNameByPcbPortId)
83247
+ };
83248
+ }).filter((pad) => pad !== null) : [];
83249
+ if (componentPadBounds.length > 0 && typeof pcbComponent?.pcb_component_id === "string") {
83250
+ const sourceComponentNameByPcbComponentId = /* @__PURE__ */ new Map;
83251
+ for (const el of circuitJson) {
83252
+ if (el.type === "pcb_component" && typeof el.pcb_component_id === "string" && typeof el.source_component_id === "string") {
83253
+ const sourceName = circuitJson.find((candidate) => candidate.type === "source_component" && candidate.source_component_id === el.source_component_id && typeof candidate.name === "string");
83254
+ if (sourceName && typeof sourceName.name === "string") {
83255
+ sourceComponentNameByPcbComponentId.set(el.pcb_component_id, sourceName.name);
83256
+ }
83257
+ }
83258
+ }
83259
+ const otherComponentPadBounds = circuitJson.filter((el) => (el.type === "pcb_smtpad" || el.type === "pcb_plated_hole") && typeof el.pcb_component_id === "string" && el.pcb_component_id !== pcbComponent.pcb_component_id).map((el) => {
83260
+ const bounds = getPadBounds(el);
83261
+ if (!bounds)
83262
+ return null;
83263
+ const otherComponentName = sourceComponentNameByPcbComponentId.get(el.pcb_component_id);
83264
+ if (!otherComponentName)
83265
+ return null;
83266
+ return {
83267
+ bounds,
83268
+ componentName: otherComponentName,
83269
+ padName: getPadDisplayName(el, otherComponentName, sourcePortNameByPcbPortId)
83270
+ };
83271
+ }).filter((entry) => entry !== null);
83272
+ let nearestPadClearance = null;
83273
+ for (const ownPad of componentPadBounds) {
83274
+ for (const otherPad of otherComponentPadBounds) {
83275
+ const clearance = getBoundsClearance(ownPad.bounds, otherPad.bounds);
83276
+ if (!nearestPadClearance || clearance < nearestPadClearance.clearance) {
83277
+ nearestPadClearance = {
83278
+ clearance,
83279
+ componentName: otherPad.componentName,
83280
+ padName: otherPad.padName
83281
+ };
83282
+ }
83283
+ }
83284
+ }
83285
+ if (nearestPadClearance) {
83286
+ const padClearanceLineItem = {
83287
+ line_item_type: "component_pad_clearance",
83288
+ component_name: componentName,
83289
+ clearance: nearestPadClearance.clearance,
83290
+ nearest_component_name: nearestPadClearance.componentName,
83291
+ nearest_pad_name: nearestPadClearance.padName
83292
+ };
83293
+ lineItems.push(padClearanceLineItem);
83294
+ }
83295
+ }
83079
83296
  if (centerX !== null && centerY !== null) {
83080
83297
  const sourceComponentsById = /* @__PURE__ */ new Map;
83081
83298
  for (const el of circuitJson) {
package/dist/lib/index.js CHANGED
@@ -60435,7 +60435,7 @@ var getNodeHandler = (winterSpec, { port, middleware = [] }) => {
60435
60435
  }));
60436
60436
  };
60437
60437
  // package.json
60438
- var version = "0.1.1054";
60438
+ var version = "0.1.1055";
60439
60439
  var package_default = {
60440
60440
  name: "@tscircuit/cli",
60441
60441
  version,
@@ -60447,7 +60447,7 @@ var package_default = {
60447
60447
  devDependencies: {
60448
60448
  "@babel/standalone": "^7.26.9",
60449
60449
  "@biomejs/biome": "^1.9.4",
60450
- "@tscircuit/circuit-json-placement-analysis": "^0.0.1",
60450
+ "@tscircuit/circuit-json-placement-analysis": "^0.0.4",
60451
60451
  "@tscircuit/circuit-json-util": "0.0.81",
60452
60452
  "@tscircuit/fake-snippets": "^0.0.182",
60453
60453
  "@tscircuit/file-server": "^0.0.32",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.1055",
3
+ "version": "0.1.1057",
4
4
  "main": "dist/cli/main.js",
5
5
  "exports": {
6
6
  ".": "./dist/cli/main.js",
@@ -9,7 +9,7 @@
9
9
  "devDependencies": {
10
10
  "@babel/standalone": "^7.26.9",
11
11
  "@biomejs/biome": "^1.9.4",
12
- "@tscircuit/circuit-json-placement-analysis": "^0.0.1",
12
+ "@tscircuit/circuit-json-placement-analysis": "^0.0.4",
13
13
  "@tscircuit/circuit-json-util": "0.0.81",
14
14
  "@tscircuit/fake-snippets": "^0.0.182",
15
15
  "@tscircuit/file-server": "^0.0.32",