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

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 c5938bcd3843b4e600b28e18b5472d41337bd478 at 2026-07-25T14:49:15.914Z. 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,44 @@ 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
+ },
40851
40902
  {
40852
40903
  id: "2026-07-24-visionos-app",
40853
40904
  version: "0.9.4",
@@ -40862,6 +40913,57 @@ var init_CHANGELOG = __esm({
40862
40913
  "patterns"
40863
40914
  ]
40864
40915
  },
40916
+ {
40917
+ id: "2026-07-24-router-via-hole-to-hole",
40918
+ version: "0.9.4",
40919
+ date: "2026-07-24",
40920
+ category: "fix",
40921
+ title: "Autorouter enforces via hole-to-hole spacing",
40922
+ 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.",
40923
+ features: [
40924
+ "pcb",
40925
+ "autorouter",
40926
+ "drc"
40927
+ ],
40928
+ mcpTools: [
40929
+ "route_nets",
40930
+ "run_drc",
40931
+ "validate_for_fab"
40932
+ ]
40933
+ },
40934
+ {
40935
+ id: "2026-07-24-router-prune-dangling-copper",
40936
+ version: "0.9.4",
40937
+ date: "2026-07-24",
40938
+ category: "fix",
40939
+ title: "Autorouter no longer leaves dead copper behind",
40940
+ 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.",
40941
+ features: [
40942
+ "pcb",
40943
+ "autorouter",
40944
+ "drc"
40945
+ ],
40946
+ mcpTools: [
40947
+ "route_nets",
40948
+ "run_drc"
40949
+ ]
40950
+ },
40951
+ {
40952
+ id: "2026-07-24-router-negotiation-first-ordering",
40953
+ version: "0.9.4",
40954
+ date: "2026-07-24",
40955
+ category: "perf",
40956
+ title: "Autorouter routes large boards in minutes, not hours",
40957
+ 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.",
40958
+ features: [
40959
+ "pcb",
40960
+ "autorouter",
40961
+ "gpu"
40962
+ ],
40963
+ mcpTools: [
40964
+ "route_nets"
40965
+ ]
40966
+ },
40865
40967
  {
40866
40968
  id: "2026-07-24-router-keepout-edge-clearance",
40867
40969
  version: "0.9.4",
@@ -40898,6 +41000,26 @@ var init_CHANGELOG = __esm({
40898
41000
  "validate_for_fab"
40899
41001
  ]
40900
41002
  },
41003
+ {
41004
+ id: "2026-07-24-router-copper-pour-synthesis",
41005
+ version: "0.9.4",
41006
+ date: "2026-07-24",
41007
+ category: "feat",
41008
+ title: "Autorouter pours planes for high-current nets",
41009
+ 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.",
41010
+ features: [
41011
+ "pcb",
41012
+ "autorouter",
41013
+ "copper-pour",
41014
+ "power-integrity"
41015
+ ],
41016
+ mcpTools: [
41017
+ "route_nets",
41018
+ "size_trace_for_current",
41019
+ "run_drc",
41020
+ "validate_for_fab"
41021
+ ]
41022
+ },
40901
41023
  {
40902
41024
  id: "2026-07-24-lattice-gauge-mcp",
40903
41025
  version: "0.9.4",
@@ -58213,6 +58335,7 @@ async function routeNets(args) {
58213
58335
  }
58214
58336
  let tracesRemoved = 0;
58215
58337
  let viasRemoved = 0;
58338
+ let zonesAdded = 0;
58216
58339
  if (targetNets.size > 0) {
58217
58340
  const beforeT = pcb.traces.length;
58218
58341
  const beforeV = pcb.vias.length;
@@ -58256,6 +58379,10 @@ async function routeNets(args) {
58256
58379
  return 0;
58257
58380
  };
58258
58381
  const applyRoute = (result) => {
58382
+ for (const z of result.zones ?? []) {
58383
+ pcb.zones.push(structuredClone(z));
58384
+ zonesAdded++;
58385
+ }
58259
58386
  for (const t2 of result.traces) {
58260
58387
  pcb.traces.push({
58261
58388
  start: { x: t2.start.x, y: t2.start.y },
@@ -58464,6 +58591,9 @@ async function routeNets(args) {
58464
58591
  nets_routed: routedNets.size,
58465
58592
  routability,
58466
58593
  traces_added: tracesAdded,
58594
+ // Copper pours the router synthesized for high-current nets: those
58595
+ // nets are now carried by a plane and stitched to it, not traced.
58596
+ ...zonesAdded > 0 ? { zones_added: zonesAdded } : {},
58467
58597
  // Copper hygiene: re-routing rips the prior route up first, so a
58468
58598
  // re-route reports both what it removed and what it laid — `added`
58469
58599
  // alone reads like monotonic growth even when copper is being
@@ -77931,8 +78061,8 @@ var init_server3 = __esm({
77931
78061
  init_order_feed();
77932
78062
  init_animate();
77933
78063
  PKG_VERSION = (() => {
77934
- if ("0.9.4-main.19") {
77935
- return "0.9.4-main.19";
78064
+ if ("0.9.4-main.20") {
78065
+ return "0.9.4-main.20";
77936
78066
  }
77937
78067
  try {
77938
78068
  const req = createRequire2(import.meta.url);
@@ -77941,8 +78071,8 @@ var init_server3 = __esm({
77941
78071
  return "0.0.0";
77942
78072
  }
77943
78073
  })();
77944
- BUILD_SHA = "7f18700be295061f294b748d3d7aa957f34ddd1c";
77945
- BUILD_TIME = "2026-07-25T13:19:21.672Z";
78074
+ BUILD_SHA = "c5938bcd3843b4e600b28e18b5472d41337bd478";
78075
+ BUILD_TIME = "2026-07-25T14:49:15.914Z";
77946
78076
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
77947
78077
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
77948
78078
  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.20",
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": "c5938bcd3843b4e600b28e18b5472d41337bd478",
23
+ "builtAt": "2026-07-25T14:49:15.914Z"
24
24
  }
25
25
  }
Binary file