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

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 7f18700be295061f294b748d3d7aa957f34ddd1c at 2026-07-25T13:19:21.672Z. Source: https://github.com/ecto/vcad
9
+ Built from ae87eb41a99471811d47dbc26cf18a794a79d2d3 at 2026-07-25T16:50:53.464Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -125,6 +125,7 @@ __export(vcad_kernel_wasm_exports, {
125
125
  ecadDfmDefaultPack: () => ecadDfmDefaultPack,
126
126
  ecadEvaluateMotor: () => ecadEvaluateMotor,
127
127
  ecadExportFab: () => ecadExportFab,
128
+ ecadFabPrep: () => ecadFabPrep,
128
129
  ecadFillZones: () => ecadFillZones,
129
130
  ecadFindAlternatives: () => ecadFindAlternatives,
130
131
  ecadFootprintForName: () => ecadFootprintForName,
@@ -1267,6 +1268,17 @@ function ecadExportFab(pcb_json) {
1267
1268
  }
1268
1269
  return takeFromExternrefTable0(ret[0]);
1269
1270
  }
1271
+ function ecadFabPrep(pcb_json, options_json) {
1272
+ const ptr0 = passStringToWasm0(pcb_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1273
+ const len0 = WASM_VECTOR_LEN;
1274
+ var ptr1 = isLikeNone(options_json) ? 0 : passStringToWasm0(options_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1275
+ var len1 = WASM_VECTOR_LEN;
1276
+ const ret = wasm.ecadFabPrep(ptr0, len0, ptr1, len1);
1277
+ if (ret[2]) {
1278
+ throw takeFromExternrefTable0(ret[1]);
1279
+ }
1280
+ return takeFromExternrefTable0(ret[0]);
1281
+ }
1270
1282
  function ecadFillZones(pcb_json) {
1271
1283
  const ptr0 = passStringToWasm0(pcb_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1272
1284
  const len0 = WASM_VECTOR_LEN;
@@ -10406,6 +10418,7 @@ async function routeAll(pcb, width, netsFilter = [], effort = 1) {
10406
10418
  const empty = {
10407
10419
  traces: [],
10408
10420
  vias: [],
10421
+ zones: [],
10409
10422
  routed_nets: [],
10410
10423
  unrouted_nets: [],
10411
10424
  diagnostics: [],
@@ -40848,6 +40861,83 @@ var init_CHANGELOG = __esm({
40848
40861
  CHANGELOG_default = {
40849
40862
  $schema: "./changelog.schema.json",
40850
40863
  entries: [
40864
+ {
40865
+ id: "2026-07-25-router-window-repair-commit-parity",
40866
+ version: "0.9.4",
40867
+ date: "2026-07-25",
40868
+ category: "fix",
40869
+ title: "Autoroute keeps window-repaired connections it used to drop",
40870
+ summary: "The last-resort window repair now searches at the widest net-class width, merges stacked via barrels, and probes real drills, so routings it finds survive the commit.",
40871
+ features: [
40872
+ "pcb",
40873
+ "routing",
40874
+ "drc"
40875
+ ],
40876
+ mcpTools: [
40877
+ "route_nets",
40878
+ "run_drc"
40879
+ ]
40880
+ },
40881
+ {
40882
+ id: "2026-07-25-router-diff-pair-si",
40883
+ version: "0.9.4",
40884
+ date: "2026-07-25",
40885
+ category: "fix",
40886
+ title: "Differential pairs route coupled and length-matched",
40887
+ summary: "Coupled pairs can now escape a BGA on an inner layer instead of failing outright, USB DP/DM pairs are recognized, and a finishing pass re-couples, descends and phase-compensates each pair so intra-pair skew lands inside the signal-integrity receipt's bounds.",
40888
+ features: [
40889
+ "pcb",
40890
+ "autorouter",
40891
+ "diff-pairs",
40892
+ "signal-integrity",
40893
+ "drc"
40894
+ ],
40895
+ mcpTools: [
40896
+ "route_nets",
40897
+ "route_diff_pair",
40898
+ "run_drc",
40899
+ "build_receipt"
40900
+ ]
40901
+ },
40902
+ {
40903
+ id: "2026-07-25-impedance-geometry-per-layer",
40904
+ version: "0.9.4",
40905
+ date: "2026-07-25",
40906
+ category: "feat",
40907
+ title: "Controlled-impedance geometry solved per layer",
40908
+ summary: "A net class can declare a target impedance and vcad derives the trace and diff-pair width per layer from the board stackup \u2014 microstrip on the outers, stripline on the inners \u2014 with the router preferring layers where the geometry is impedance-correct.",
40909
+ features: [
40910
+ "pcb",
40911
+ "autorouter",
40912
+ "diff-pairs",
40913
+ "signal-integrity",
40914
+ "stackup"
40915
+ ],
40916
+ mcpTools: [
40917
+ "route_nets",
40918
+ "set_design_rules",
40919
+ "set_stackup",
40920
+ "calc_impedance",
40921
+ "build_receipt"
40922
+ ]
40923
+ },
40924
+ {
40925
+ id: "2026-07-25-gerber-pad-rotation",
40926
+ version: "0.9.4",
40927
+ date: "2026-07-25",
40928
+ category: "fix",
40929
+ title: "Gerber export honours pad rotation",
40930
+ summary: "Pads on rotated footprints are exported with the correct orientation; previously every non-square pad was flashed axis-aligned, shorting fine-pitch packages.",
40931
+ features: [
40932
+ "pcb",
40933
+ "gerber",
40934
+ "fabrication"
40935
+ ],
40936
+ mcpTools: [
40937
+ "export_gerber",
40938
+ "fab_prep"
40939
+ ]
40940
+ },
40851
40941
  {
40852
40942
  id: "2026-07-24-visionos-app",
40853
40943
  version: "0.9.4",
@@ -40862,6 +40952,57 @@ var init_CHANGELOG = __esm({
40862
40952
  "patterns"
40863
40953
  ]
40864
40954
  },
40955
+ {
40956
+ id: "2026-07-24-router-via-hole-to-hole",
40957
+ version: "0.9.4",
40958
+ date: "2026-07-24",
40959
+ category: "fix",
40960
+ title: "Autorouter enforces via hole-to-hole spacing",
40961
+ summary: "route_nets' legality oracle now indexes drilled holes independently of copper, so two vias whose layer spans don't overlap can no longer be placed with colliding drills \u2014 the hole-to-hole rule is enforced at probe time, not found by a later DRC.",
40962
+ features: [
40963
+ "pcb",
40964
+ "autorouter",
40965
+ "drc"
40966
+ ],
40967
+ mcpTools: [
40968
+ "route_nets",
40969
+ "run_drc",
40970
+ "validate_for_fab"
40971
+ ]
40972
+ },
40973
+ {
40974
+ id: "2026-07-24-router-prune-dangling-copper",
40975
+ version: "0.9.4",
40976
+ date: "2026-07-24",
40977
+ category: "fix",
40978
+ title: "Autorouter no longer leaves dead copper behind",
40979
+ summary: "route_nets now prunes its own dangling copper before returning \u2014 traces and vias whose island reaches no pad and no pour, left over from rip-up \u2014 cutting the CM5 40-net route from 1292 to 789 segments with routability unchanged.",
40980
+ features: [
40981
+ "pcb",
40982
+ "autorouter",
40983
+ "drc"
40984
+ ],
40985
+ mcpTools: [
40986
+ "route_nets",
40987
+ "run_drc"
40988
+ ]
40989
+ },
40990
+ {
40991
+ id: "2026-07-24-router-negotiation-first-ordering",
40992
+ version: "0.9.4",
40993
+ date: "2026-07-24",
40994
+ category: "perf",
40995
+ title: "Autorouter routes large boards in minutes, not hours",
40996
+ summary: "On layer-rich boards the GPU negotiator now takes the unrouted tail before the sequential CPU rescue arsenal, which fires once over its leftovers; the rip-up rounds it replaced are skipped and speculative rounds are budgeted against the baseline.",
40997
+ features: [
40998
+ "pcb",
40999
+ "autorouter",
41000
+ "gpu"
41001
+ ],
41002
+ mcpTools: [
41003
+ "route_nets"
41004
+ ]
41005
+ },
40865
41006
  {
40866
41007
  id: "2026-07-24-router-keepout-edge-clearance",
40867
41008
  version: "0.9.4",
@@ -40898,6 +41039,26 @@ var init_CHANGELOG = __esm({
40898
41039
  "validate_for_fab"
40899
41040
  ]
40900
41041
  },
41042
+ {
41043
+ id: "2026-07-24-router-copper-pour-synthesis",
41044
+ version: "0.9.4",
41045
+ date: "2026-07-24",
41046
+ category: "feat",
41047
+ title: "Autorouter pours planes for high-current nets",
41048
+ summary: "route_nets now synthesizes copper pours for power nets instead of routing them as thin traces: it sizes current with the same IPC-2221 model as size_trace_for_current, floods a layer, and stitches every pad to the plane.",
41049
+ features: [
41050
+ "pcb",
41051
+ "autorouter",
41052
+ "copper-pour",
41053
+ "power-integrity"
41054
+ ],
41055
+ mcpTools: [
41056
+ "route_nets",
41057
+ "size_trace_for_current",
41058
+ "run_drc",
41059
+ "validate_for_fab"
41060
+ ]
41061
+ },
40901
41062
  {
40902
41063
  id: "2026-07-24-lattice-gauge-mcp",
40903
41064
  version: "0.9.4",
@@ -58213,6 +58374,7 @@ async function routeNets(args) {
58213
58374
  }
58214
58375
  let tracesRemoved = 0;
58215
58376
  let viasRemoved = 0;
58377
+ let zonesAdded = 0;
58216
58378
  if (targetNets.size > 0) {
58217
58379
  const beforeT = pcb.traces.length;
58218
58380
  const beforeV = pcb.vias.length;
@@ -58256,6 +58418,10 @@ async function routeNets(args) {
58256
58418
  return 0;
58257
58419
  };
58258
58420
  const applyRoute = (result) => {
58421
+ for (const z of result.zones ?? []) {
58422
+ pcb.zones.push(structuredClone(z));
58423
+ zonesAdded++;
58424
+ }
58259
58425
  for (const t2 of result.traces) {
58260
58426
  pcb.traces.push({
58261
58427
  start: { x: t2.start.x, y: t2.start.y },
@@ -58464,6 +58630,9 @@ async function routeNets(args) {
58464
58630
  nets_routed: routedNets.size,
58465
58631
  routability,
58466
58632
  traces_added: tracesAdded,
58633
+ // Copper pours the router synthesized for high-current nets: those
58634
+ // nets are now carried by a plane and stitched to it, not traced.
58635
+ ...zonesAdded > 0 ? { zones_added: zonesAdded } : {},
58467
58636
  // Copper hygiene: re-routing rips the prior route up first, so a
58468
58637
  // re-route reports both what it removed and what it laid — `added`
58469
58638
  // alone reads like monotonic growth even when copper is being
@@ -77931,8 +78100,8 @@ var init_server3 = __esm({
77931
78100
  init_order_feed();
77932
78101
  init_animate();
77933
78102
  PKG_VERSION = (() => {
77934
- if ("0.9.4-main.19") {
77935
- return "0.9.4-main.19";
78103
+ if ("0.9.4-main.21") {
78104
+ return "0.9.4-main.21";
77936
78105
  }
77937
78106
  try {
77938
78107
  const req = createRequire2(import.meta.url);
@@ -77941,8 +78110,8 @@ var init_server3 = __esm({
77941
78110
  return "0.0.0";
77942
78111
  }
77943
78112
  })();
77944
- BUILD_SHA = "7f18700be295061f294b748d3d7aa957f34ddd1c";
77945
- BUILD_TIME = "2026-07-25T13:19:21.672Z";
78113
+ BUILD_SHA = "ae87eb41a99471811d47dbc26cf18a794a79d2d3";
78114
+ BUILD_TIME = "2026-07-25T16:50:53.464Z";
77946
78115
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
77947
78116
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
77948
78117
  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.19",
3
+ "version": "0.9.4-main.21",
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": "7f18700be295061f294b748d3d7aa957f34ddd1c",
23
- "builtAt": "2026-07-25T13:19:21.672Z"
22
+ "sha": "ae87eb41a99471811d47dbc26cf18a794a79d2d3",
23
+ "builtAt": "2026-07-25T16:50:53.464Z"
24
24
  }
25
25
  }
Binary file