@tscircuit/cli 0.1.142 → 0.1.144

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 +1 -1
  2. package/dist/main.js +117 -60
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -54,7 +54,7 @@ Commands:
54
54
  add <component> Add a tscircuit component package to your project
55
55
  remove <component> Remove a tscircuit component package from your
56
56
  project
57
- snapshot [options] Generate schematic and PCB snapshots (add --3d for
57
+ snapshot [options] [file] Generate schematic and PCB snapshots (add --3d for
58
58
  3d preview)
59
59
  setup Setup utilities like GitHub Actions
60
60
  upgrade Upgrade CLI to the latest version
package/dist/main.js CHANGED
@@ -442238,7 +442238,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
442238
442238
  import { execSync as execSync2 } from "node:child_process";
442239
442239
  var import_semver2 = __toESM2(require_semver2(), 1);
442240
442240
  // package.json
442241
- var version = "0.1.141";
442241
+ var version = "0.1.143";
442242
442242
  var package_default = {
442243
442243
  name: "@tscircuit/cli",
442244
442244
  version,
@@ -442286,7 +442286,7 @@ var package_default = {
442286
442286
  redaxios: "^0.5.1",
442287
442287
  semver: "^7.6.3",
442288
442288
  tempy: "^3.1.0",
442289
- tscircuit: "^0.0.500",
442289
+ tscircuit: "^0.0.502",
442290
442290
  "typed-ky": "^0.0.4"
442291
442291
  },
442292
442292
  peerDependencies: {
@@ -481147,7 +481147,7 @@ var CapacityMeshSolver = AutoroutingPipelineSolver;
481147
481147
  var package_default2 = {
481148
481148
  name: "@tscircuit/capacity-autorouter",
481149
481149
  main: "./dist/index.js",
481150
- version: "0.0.75",
481150
+ version: "0.0.76",
481151
481151
  type: "module",
481152
481152
  files: [
481153
481153
  "dist"
@@ -486745,6 +486745,7 @@ var orderedRenderPhases = [
486745
486745
  "CreateTracesFromProps",
486746
486746
  "CreateTracesFromNetLabels",
486747
486747
  "CreateTraceHintsFromProps",
486748
+ "SourceGroupRender",
486748
486749
  "SourceRender",
486749
486750
  "SourceParentAttachment",
486750
486751
  "PortMatching",
@@ -490664,13 +490665,42 @@ var Trace2 = class extends PrimitiveComponent2 {
490664
490665
  }));
490665
490666
  for (const { selector, port } of portsWithSelectors) {
490666
490667
  if (!port) {
490667
- const parentSelector = selector.replace(/(\> )?[^ ]+$/, "");
490668
- const targetComponent = this.getSubcircuit().selectOne(parentSelector);
490668
+ let parentSelector;
490669
+ let portToken;
490670
+ const dotIndex = selector.lastIndexOf(".");
490671
+ if (dotIndex !== -1 && dotIndex > selector.lastIndexOf(" ")) {
490672
+ parentSelector = selector.slice(0, dotIndex);
490673
+ portToken = selector.slice(dotIndex + 1);
490674
+ } else {
490675
+ const match = selector.match(/^(.*[ >])?([^ >]+)$/);
490676
+ parentSelector = match?.[1]?.trim() ?? "";
490677
+ portToken = match?.[2] ?? selector;
490678
+ }
490679
+ let targetComponent = parentSelector ? this.getSubcircuit().selectOne(parentSelector) : null;
490680
+ if (!targetComponent && parentSelector && !/[.#\[]/.test(parentSelector)) {
490681
+ targetComponent = this.getSubcircuit().selectOne(`.${parentSelector}`);
490682
+ }
490669
490683
  if (!targetComponent) {
490670
- this.renderError(`Could not find port for selector "${selector}"`);
490684
+ if (parentSelector) {
490685
+ this.renderError(`Could not find port for selector "${selector}". Component "${parentSelector}" not found`);
490686
+ } else {
490687
+ this.renderError(`Could not find port for selector "${selector}"`);
490688
+ }
490671
490689
  } else {
490672
- this.renderError(`Could not find port for selector "${selector}" (did you forget to include the pin name?)
490673
- searched component ${targetComponent.getString()}, which has ports: ${targetComponent.children.filter((c) => c.componentName === "Port").map((c) => `${c.getString()}(${c.getNameAndAliases().join(",")})`).join(" & ")}`);
490690
+ const ports = targetComponent.children.filter((c) => c.componentName === "Port");
490691
+ const portLabel = portToken.includes(".") ? portToken.split(".").pop() ?? "" : portToken;
490692
+ const portNames = ports.map((c) => c.getNameAndAliases()).flat();
490693
+ const hasCustomLabels = portNames.some((n2) => !/^(pin\d+|\d+)$/.test(n2));
490694
+ const labelList = Array.from(new Set(portNames)).join(", ");
490695
+ let detail;
490696
+ if (ports.length === 0) {
490697
+ detail = "It has no ports";
490698
+ } else if (!hasCustomLabels) {
490699
+ detail = `It has ${ports.length} pins and no pinLabels (consider adding pinLabels)`;
490700
+ } else {
490701
+ detail = `It has [${labelList}]`;
490702
+ }
490703
+ this.renderError(`Could not find port for selector "${selector}". Component "${targetComponent.props.name ?? parentSelector}" found, but does not have pin "${portLabel}". ${detail}`);
490674
490704
  }
490675
490705
  }
490676
490706
  }
@@ -491178,6 +491208,14 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
491178
491208
  const conn = nl._parsedProps.connection ?? nl._parsedProps.connectsTo;
491179
491209
  if (!conn)
491180
491210
  return false;
491211
+ if (Array.isArray(conn)) {
491212
+ return conn.some((selector) => {
491213
+ const targetPort2 = this.getSubcircuit().selectOne(selector, {
491214
+ port: true
491215
+ });
491216
+ return targetPort2 === port;
491217
+ });
491218
+ }
491181
491219
  const targetPort = this.getSubcircuit().selectOne(conn, {
491182
491220
  port: true
491183
491221
  });
@@ -492501,6 +492539,23 @@ var getSimpleRouteJsonFromCircuitJson = ({
492501
492539
  maxY: Math.max(...allPoints.map((p) => p.y)) + 1
492502
492540
  };
492503
492541
  }
492542
+ if (subcircuit_id) {
492543
+ const group = db.pcb_group.getWhere({ subcircuit_id });
492544
+ if (group) {
492545
+ const groupBounds = {
492546
+ minX: group.center.x - group.width / 2,
492547
+ maxX: group.center.x + group.width / 2,
492548
+ minY: group.center.y - group.height / 2,
492549
+ maxY: group.center.y + group.height / 2
492550
+ };
492551
+ bounds6 = {
492552
+ minX: Math.min(bounds6.minX, groupBounds.minX),
492553
+ maxX: Math.max(bounds6.maxX, groupBounds.maxX),
492554
+ minY: Math.min(bounds6.minY, groupBounds.minY),
492555
+ maxY: Math.max(bounds6.maxY, groupBounds.maxY)
492556
+ };
492557
+ }
492558
+ }
492504
492559
  const directTraceConnections = db.source_trace.list().map((trace) => {
492505
492560
  const connectedPorts = trace.connected_source_port_ids.map((id) => {
492506
492561
  const source_port3 = db.source_port.get(id);
@@ -493218,17 +493273,22 @@ var Group = class extends NormalComponent {
493218
493273
  componentName: "Group"
493219
493274
  };
493220
493275
  }
493221
- doInitialSourceRender() {
493276
+ doInitialSourceGroupRender() {
493222
493277
  const { db } = this.root;
493223
493278
  const source_group3 = db.source_group.insert({
493224
493279
  name: this._parsedProps.name,
493225
493280
  is_subcircuit: this.isSubcircuit
493226
493281
  });
493227
- this.subcircuit_id = `subcircuit_${source_group3.source_group_id}`;
493228
493282
  this.source_group_id = source_group3.source_group_id;
493229
- db.source_group.update(source_group3.source_group_id, {
493230
- subcircuit_id: this.subcircuit_id
493231
- });
493283
+ if (this.isSubcircuit) {
493284
+ this.subcircuit_id = `subcircuit_${source_group3.source_group_id}`;
493285
+ db.source_group.update(source_group3.source_group_id, {
493286
+ subcircuit_id: this.subcircuit_id
493287
+ });
493288
+ }
493289
+ }
493290
+ doInitialSourceRender() {
493291
+ const { db } = this.root;
493232
493292
  for (const child of this.children) {
493233
493293
  db.source_component.update(child.source_component_id, {
493234
493294
  source_group_id: this.source_group_id
@@ -494306,30 +494366,38 @@ var Jumper = class extends NormalComponent {
494306
494366
  };
494307
494367
  var SolderJumper = class extends NormalComponent {
494308
494368
  schematicDimensions = null;
494369
+ _getPinNumberFromBridgedPinName(pinName) {
494370
+ const port = this.selectOne(`port.${pinName}`, {
494371
+ type: "port"
494372
+ });
494373
+ return port?._parsedProps.pinNumber ?? null;
494374
+ }
494309
494375
  get defaultInternallyConnectedPinNames() {
494310
494376
  return this._parsedProps.bridgedPins ?? [];
494311
494377
  }
494312
494378
  get config() {
494313
- let resolvedPinCount = this.props.pinCount;
494379
+ const props = this._parsedProps ?? this.props;
494380
+ let resolvedPinCount = props.pinCount;
494314
494381
  if (!resolvedPinCount) {
494315
- const nums = (this.props.bridgedPins ?? []).flat().map((p) => {
494316
- if (typeof p === "number")
494317
- return p;
494318
- if (p.startsWith("pin"))
494319
- return Number(p.slice(3));
494320
- return Number(p);
494321
- }).filter((n2) => !Number.isNaN(n2));
494322
- const maxPin = nums.length > 0 ? Math.max(...nums) : 0;
494323
- if (maxPin === 2 || maxPin === 3) {
494324
- resolvedPinCount = maxPin;
494382
+ const nums = (props.bridgedPins ?? []).flat().map((p_str) => this._getPinNumberFromBridgedPinName(p_str)).filter((n2) => n2 !== null);
494383
+ const maxPinFromBridged = nums.length > 0 ? Math.max(...nums) : 0;
494384
+ const pinCountFromLabels = props.pinLabels ? Object.keys(props.pinLabels).length : 0;
494385
+ const finalPinCount = Math.max(maxPinFromBridged, pinCountFromLabels);
494386
+ if (finalPinCount === 2 || finalPinCount === 3) {
494387
+ resolvedPinCount = finalPinCount;
494325
494388
  }
494326
494389
  }
494327
494390
  let symbolName = "";
494328
- if (resolvedPinCount)
494391
+ if (resolvedPinCount) {
494329
494392
  symbolName += `solderjumper${resolvedPinCount}`;
494330
- if (Array.isArray(this.props.bridgedPins) && this.props.bridgedPins.length > 0) {
494331
- const pins = Array.from(new Set(this.props.bridgedPins.flat())).sort().join("");
494332
- symbolName += `_bridged${pins}`;
494393
+ } else {
494394
+ symbolName = "solderjumper";
494395
+ }
494396
+ if (Array.isArray(props.bridgedPins) && props.bridgedPins.length > 0) {
494397
+ const pinNumbers = Array.from(new Set(props.bridgedPins.flat().map((pinName) => this._getPinNumberFromBridgedPinName(pinName)).filter((n2) => n2 !== null))).sort((a, b) => a - b);
494398
+ if (pinNumbers.length > 0) {
494399
+ symbolName += `_bridged${pinNumbers.join("")}`;
494400
+ }
494333
494401
  }
494334
494402
  return {
494335
494403
  schematicSymbolName: symbolName,
@@ -495694,8 +495762,8 @@ var SchematicText = class extends PrimitiveComponent2 {
495694
495762
  font_size: props.fontSize,
495695
495763
  color: props.color || "#000000",
495696
495764
  position: {
495697
- x: props.schX,
495698
- y: props.schY
495765
+ x: props.schX ?? 0,
495766
+ y: props.schY ?? 0
495699
495767
  },
495700
495768
  rotation: props.schRotation ?? 0
495701
495769
  });
@@ -495895,7 +495963,7 @@ var SchematicBox = class extends PrimitiveComponent2 {
495895
495963
  var package_default3 = {
495896
495964
  name: "@tscircuit/core",
495897
495965
  type: "module",
495898
- version: "0.0.490",
495966
+ version: "0.0.503",
495899
495967
  types: "dist/index.d.ts",
495900
495968
  main: "dist/index.js",
495901
495969
  module: "dist/index.js",
@@ -495927,7 +495995,7 @@ var package_default3 = {
495927
495995
  "@tscircuit/layout": "^0.0.28",
495928
495996
  "@tscircuit/log-soup": "^1.0.2",
495929
495997
  "@tscircuit/math-utils": "^0.0.18",
495930
- "@tscircuit/props": "^0.0.234",
495998
+ "@tscircuit/props": "^0.0.238",
495931
495999
  "@tscircuit/schematic-autolayout": "^0.0.6",
495932
496000
  "@tscircuit/schematic-match-adapt": "^0.0.16",
495933
496001
  "@tscircuit/simple-3d-svg": "^0.0.6",
@@ -496203,7 +496271,9 @@ var useChip = (pinLabels) => createUseComponent((props) => /* @__PURE__ */ impor
496203
496271
  var useDiode = createUseComponent((props) => /* @__PURE__ */ import_jsx_runtime4.jsx("diode", { ...props }), diodePins);
496204
496272
  var useLed = createUseComponent((props) => /* @__PURE__ */ import_jsx_runtime5.jsx("led", { ...props }), ledPins);
496205
496273
  var useResistor = createUseComponent((props) => /* @__PURE__ */ import_jsx_runtime6.jsx("resistor", { ...props }), resistorPins);
496206
- var sel = new Proxy({}, {
496274
+ var sel = new Proxy((refdes) => new Proxy({}, {
496275
+ get: (_, pin) => `.${refdes} > .${pin}`
496276
+ }), {
496207
496277
  get: (_, prop1) => {
496208
496278
  const fn = (...args) => {
496209
496279
  const chipFnOrPinType = args[0];
@@ -496240,7 +496310,8 @@ var sel = new Proxy({}, {
496240
496310
  return new Proxy({}, {
496241
496311
  get: (_3, pinOrSubComponentName) => {
496242
496312
  const pinResult = `.${prop1} > .${pinOrSubComponentName}`;
496243
- if (prop1.startsWith("U")) {
496313
+ const chipPrefixes = ["U", "J", "CN"];
496314
+ if (chipPrefixes.some((p) => prop1.startsWith(p))) {
496244
496315
  return pinResult;
496245
496316
  }
496246
496317
  return new Proxy(new String(pinResult), {
@@ -497486,15 +497557,15 @@ var setupDefaultEntrypointIfNeeded = (opts) => {
497486
497557
  opts.mainComponentPath = "index.ts";
497487
497558
  } else if (Object.keys(opts.fsMap).filter((k) => k.endsWith(".tsx")).length === 1) {
497488
497559
  opts.mainComponentPath = Object.keys(opts.fsMap)[0];
497489
- } else if ("tscircuit.config.js" in opts.fsMap) {
497490
- const configContent = opts.fsMap["tscircuit.config.js"];
497560
+ } else if ("tscircuit.config.json" in opts.fsMap) {
497561
+ const configContent = opts.fsMap["tscircuit.config.json"];
497491
497562
  try {
497492
497563
  const config = JSON.parse(configContent);
497493
497564
  if (config.mainEntrypoint) {
497494
- opts.mainComponentPath = config.mainEntrypoint;
497565
+ opts.entrypoint = config.mainEntrypoint;
497495
497566
  }
497496
497567
  } catch (e) {
497497
- console.warn("Failed to parse tscircuit.config.js:", e);
497568
+ console.warn("Failed to parse tscircuit.config.json:", e);
497498
497569
  }
497499
497570
  } else {
497500
497571
  throw new Error("Either entrypoint or mainComponentPath must be provided (no index file, could not infer entrypoint)");
@@ -498761,20 +498832,10 @@ var snapshotProject = async ({
498761
498832
  ignore
498762
498833
  });
498763
498834
  files = boardFiles.map((f) => path26.join(projectDir, f));
498764
- const entry = await getEntrypoint({
498765
- projectDir,
498766
- onError,
498767
- onSuccess: () => {}
498768
- });
498769
- if (entry) {
498770
- const resolved = path26.resolve(projectDir, entry);
498771
- if (!files.includes(resolved)) {
498772
- files.unshift(resolved);
498773
- }
498774
- }
498775
498835
  }
498776
498836
  if (files.length === 0) {
498777
- return onExit(1);
498837
+ console.log("No entrypoint found. Run 'tsci init' to bootstrap a basic project or specify a file with 'tsci snapshot <file>'");
498838
+ return onExit(0);
498778
498839
  }
498779
498840
  const mismatches = [];
498780
498841
  for (const file of files) {
@@ -498814,7 +498875,9 @@ var snapshotProject = async ({
498814
498875
  if (mismatches.length > 0) {
498815
498876
  onError(`Snapshot mismatch:
498816
498877
  ${mismatches.join(`
498817
- `)}`);
498878
+ `)}
498879
+
498880
+ Run with --update to fix.`);
498818
498881
  return onExit(1);
498819
498882
  }
498820
498883
  onSuccess("All snapshots match");
@@ -498875,6 +498938,7 @@ jobs:
498875
498938
  on:
498876
498939
  push:
498877
498940
  branches: [main]
498941
+ pull_request:
498878
498942
 
498879
498943
  jobs:
498880
498944
  snapshot:
@@ -498883,14 +498947,7 @@ jobs:
498883
498947
  - uses: actions/checkout@v4
498884
498948
  - uses: oven-sh/setup-bun@v2
498885
498949
  - run: bun install
498886
- - run: bunx tsci snapshot --update
498887
- - name: Commit snapshots
498888
- run: |
498889
- git config --global user.name "github-actions[bot]"
498890
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
498891
- git add .
498892
- git commit -m "Update snapshots" || echo "No changes to commit"
498893
- git push
498950
+ - run: bunx tsci snapshot
498894
498951
  `;
498895
498952
  writeFileIfNotExists(path27.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
498896
498953
  writeFileIfNotExists(path27.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
@@ -498907,7 +498964,7 @@ var registerSetup = (program3) => {
498907
498964
  {
498908
498965
  title: "GitHub Action",
498909
498966
  value: "github-action",
498910
- description: "Automatically build, check and commit snapshots to the main branch",
498967
+ description: "Automatically build and check snapshots on push/pull-request",
498911
498968
  selected: true
498912
498969
  }
498913
498970
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.142",
3
+ "version": "0.1.144",
4
4
  "main": "dist/main.js",
5
5
  "devDependencies": {
6
6
  "@babel/standalone": "^7.26.9",
@@ -45,7 +45,7 @@
45
45
  "redaxios": "^0.5.1",
46
46
  "semver": "^7.6.3",
47
47
  "tempy": "^3.1.0",
48
- "tscircuit": "^0.0.500",
48
+ "tscircuit": "^0.0.502",
49
49
  "typed-ky": "^0.0.4"
50
50
  },
51
51
  "peerDependencies": {