@vcad/mcp 0.9.4-main.21 → 0.9.4-main.22

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
@@ -6,4 +6,4 @@ vcad's MCP server as a self-contained bundle (server + BRep kernel WASM).
6
6
  { "mcpServers": { "vcad": { "command": "npx", "args": ["-y", "@vcad/mcp"] } } }
7
7
  ```
8
8
 
9
- Built from ae87eb41a99471811d47dbc26cf18a794a79d2d3 at 2026-07-25T16:50:53.464Z. Source: https://github.com/ecto/vcad
9
+ Built from 34f31195abaa154019b219eda75a0e900b7ece93 at 2026-07-25T19:25:56.201Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -40878,6 +40878,24 @@ var init_CHANGELOG = __esm({
40878
40878
  "run_drc"
40879
40879
  ]
40880
40880
  },
40881
+ {
40882
+ id: "2026-07-25-router-pair-connector-vias",
40883
+ version: "0.9.4",
40884
+ date: "2026-07-25",
40885
+ category: "fix",
40886
+ title: "Autoroute no longer routes traces through diff-pair vias",
40887
+ summary: "Differential-pair breakout vias were written onto the board but never registered with the router's clearance oracle, so later nets were routed straight through the barrel.",
40888
+ features: [
40889
+ "pcb",
40890
+ "routing",
40891
+ "drc"
40892
+ ],
40893
+ mcpTools: [
40894
+ "route_nets",
40895
+ "route_diff_pair",
40896
+ "run_drc"
40897
+ ]
40898
+ },
40881
40899
  {
40882
40900
  id: "2026-07-25-router-diff-pair-si",
40883
40901
  version: "0.9.4",
@@ -60773,16 +60791,61 @@ async function addCoil(args, opts) {
60773
60791
  if ("error" in lr) return fail2(`layers entry: ${lr.error}`);
60774
60792
  }
60775
60793
  const stitchVias = [];
60776
- const perLayerLen = segLength(pts);
60794
+ const dTheta = sign * turns * 2 * Math.PI;
60795
+ const spiralSteps = Math.max(2, Math.ceil(turns * segmentsPerTurn));
60796
+ const drill = pcb.rules.defaultRules.viaDrill;
60797
+ const holePitch = drill + 0.5 + 0.05;
60798
+ const staggerR = Math.max(innerR, traceWidth);
60799
+ const stagger = Math.min(Math.PI / 4, holePitch / (2 * staggerR));
60800
+ const boundary = (li) => li < 0 ? theta0 + dTheta : theta0 - li * dTheta - sign * (li + 1) * stagger;
60801
+ const layerPts = [];
60802
+ for (let li = 0; li < layersIn.length; li++) {
60803
+ const thetaFrom = boundary(li - 1);
60804
+ const thetaTo = boundary(li);
60805
+ const outward = li % 2 === 1;
60806
+ const rFrom = outward ? innerR : outerR;
60807
+ const rTo = outward ? outerR : innerR;
60808
+ const lp = [];
60809
+ for (let s = 0; s <= spiralSteps; s++) {
60810
+ const t2 = s / spiralSteps;
60811
+ const theta = thetaFrom + t2 * (thetaTo - thetaFrom);
60812
+ const r = rFrom + t2 * (rTo - rFrom);
60813
+ const p = {
60814
+ x: round33(center.x + r * Math.cos(theta)),
60815
+ y: round33(center.y + r * Math.sin(theta))
60816
+ };
60817
+ const prev = lp[lp.length - 1];
60818
+ if (!prev || prev.x !== p.x || prev.y !== p.y) lp.push(p);
60819
+ }
60820
+ layerPts.push(lp);
60821
+ }
60822
+ if (innerLeadOut > 0) {
60823
+ for (let li = 0; li + 1 < layersIn.length; li++) {
60824
+ if (li % 2 !== 0) continue;
60825
+ const end = layerPts[li][layerPts[li].length - 1];
60826
+ const thetaEnd = boundary(li);
60827
+ const tx = Math.sin(thetaEnd) * sign;
60828
+ const ty = -Math.cos(thetaEnd) * sign;
60829
+ const T = {
60830
+ x: round33(end.x + tx * innerLeadOut),
60831
+ y: round33(end.y + ty * innerLeadOut)
60832
+ };
60833
+ if (T.x !== end.x || T.y !== end.y) {
60834
+ layerPts[li].push(T);
60835
+ layerPts[li + 1].unshift(T);
60836
+ }
60837
+ }
60838
+ }
60777
60839
  let totalLengthMm = 0;
60778
60840
  let totalTraces = 0;
60779
60841
  let totalResistance = 0;
60780
60842
  for (let li = 0; li < layersIn.length; li++) {
60781
60843
  const lyr = layersIn[li];
60782
- for (let i = 0; i + 1 < pts.length; i++) {
60844
+ const lp = layerPts[li];
60845
+ for (let i = 0; i + 1 < lp.length; i++) {
60783
60846
  pcb.traces.push({
60784
- start: pts[i],
60785
- end: pts[i + 1],
60847
+ start: lp[i],
60848
+ end: lp[i + 1],
60786
60849
  width: traceWidth,
60787
60850
  layer: lyr,
60788
60851
  net,
@@ -60790,12 +60853,12 @@ async function addCoil(args, opts) {
60790
60853
  });
60791
60854
  totalTraces++;
60792
60855
  }
60793
- totalLengthMm += perLayerLen;
60856
+ const layerLen = segLength(lp);
60857
+ totalLengthMm += layerLen;
60794
60858
  const cuT = pcb.stackup.layers.find((s) => s.layer === lyr)?.copperThickness ?? 0.035;
60795
- totalResistance += 168e-7 * perLayerLen / (traceWidth * cuT);
60859
+ totalResistance += 168e-7 * layerLen / (traceWidth * cuT);
60796
60860
  if (li + 1 < layersIn.length) {
60797
- const atInner = li % 2 === 0;
60798
- const stitchPt = atInner ? pts[0] : pts[pts.length - 1];
60861
+ const stitchPt = lp[lp.length - 1];
60799
60862
  pcb.vias.push({
60800
60863
  position: stitchPt,
60801
60864
  diameter: pcb.rules.defaultRules.viaDiameter,
@@ -60808,9 +60871,10 @@ async function addCoil(args, opts) {
60808
60871
  stitchVias.push({ position: stitchPt, startLayer: lyr, endLayer: layersIn[li + 1] });
60809
60872
  }
60810
60873
  }
60811
- const lastFreeInner = (layersIn.length - 1) % 2 === 0;
60812
- const terminalA = pts[pts.length - 1];
60813
- const terminalB = lastFreeInner ? pts[0] : pts[pts.length - 1];
60874
+ const lastLp = layerPts[layerPts.length - 1];
60875
+ const terminalA = layerPts[0][0];
60876
+ const terminalB = lastLp[lastLp.length - 1];
60877
+ const lastFreeInner = layersIn.length % 2 === 1;
60814
60878
  return {
60815
60879
  content: [
60816
60880
  {
@@ -60822,14 +60886,14 @@ async function addCoil(args, opts) {
60822
60886
  direction,
60823
60887
  layers_used: layersIn,
60824
60888
  multilayer: true,
60825
- note: "Multilayer stacked coil: `layer` and inner_via/via_to_layer ignored; layers stitched with alternating inner/outer vias.",
60889
+ note: "Multilayer stacked coil: `layer` and inner_via/via_to_layer ignored. One continuous spiral in angle across the stack \u2014 the radius zigzags inner\u2194outer with a stitch via at each turnaround \u2014 so every layer circulates the same way and their fields add.",
60826
60890
  total_traces: totalTraces,
60827
60891
  total_length_mm: Math.round(totalLengthMm * 100) / 100,
60828
60892
  total_resistance_ohms: Math.round(totalResistance * 1e3) / 1e3,
60829
60893
  stitch_vias: stitchVias,
60830
60894
  terminals: { a: terminalA, b: terminalB },
60831
- inner_endpoint: pts[0],
60832
- outer_endpoint: pts[pts.length - 1],
60895
+ inner_endpoint: lastFreeInner ? terminalB : layerPts[0][layerPts[0].length - 1],
60896
+ outer_endpoint: terminalA,
60833
60897
  ...drcCap ? { drc_delta: await drcCap.finish() } : {},
60834
60898
  ...docResultPayload(ctx)
60835
60899
  })
@@ -78100,8 +78164,8 @@ var init_server3 = __esm({
78100
78164
  init_order_feed();
78101
78165
  init_animate();
78102
78166
  PKG_VERSION = (() => {
78103
- if ("0.9.4-main.21") {
78104
- return "0.9.4-main.21";
78167
+ if ("0.9.4-main.22") {
78168
+ return "0.9.4-main.22";
78105
78169
  }
78106
78170
  try {
78107
78171
  const req = createRequire2(import.meta.url);
@@ -78110,8 +78174,8 @@ var init_server3 = __esm({
78110
78174
  return "0.0.0";
78111
78175
  }
78112
78176
  })();
78113
- BUILD_SHA = "ae87eb41a99471811d47dbc26cf18a794a79d2d3";
78114
- BUILD_TIME = "2026-07-25T16:50:53.464Z";
78177
+ BUILD_SHA = "34f31195abaa154019b219eda75a0e900b7ece93";
78178
+ BUILD_TIME = "2026-07-25T19:25:56.201Z";
78115
78179
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
78116
78180
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
78117
78181
  INSTANCE_ID = randomUUID6().slice(0, 8);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcad/mcp",
3
- "version": "0.9.4-main.21",
3
+ "version": "0.9.4-main.22",
4
4
  "description": "vcad MCP server — parametric CAD + PCB design tools for AI agents (self-contained: bundled server + kernel WASM)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "homepage": "https://vcad.io",
21
21
  "vcadBuild": {
22
- "sha": "ae87eb41a99471811d47dbc26cf18a794a79d2d3",
23
- "builtAt": "2026-07-25T16:50:53.464Z"
22
+ "sha": "34f31195abaa154019b219eda75a0e900b7ece93",
23
+ "builtAt": "2026-07-25T19:25:56.201Z"
24
24
  }
25
25
  }
Binary file