@vcad/mcp 0.10.0-main.94 → 0.10.0-main.95

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 6176496f3a4b9477437d5eec85aea4bc40cde13c at 2026-10-17T18:45:10.765Z. Source: https://github.com/ecto/vcad
9
+ Built from 2182e0fa666586bfac3ebff40ad17af91836bf97 at 2026-10-17T19:27:56.972Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -31224,6 +31224,68 @@ var init_ecad_sync = __esm({
31224
31224
  }
31225
31225
  });
31226
31226
 
31227
+ // ../core/dist/utils/pcb-layers.js
31228
+ function isCopperLayer(layer) {
31229
+ return COPPER_RE.test(layer);
31230
+ }
31231
+ function innerCopperIndex(layer) {
31232
+ const m = COPPER_RE.exec(layer);
31233
+ return m?.[2] ? Number(m[2]) : 0;
31234
+ }
31235
+ function innerCopperLayerName(n) {
31236
+ return `In${n}Cu`;
31237
+ }
31238
+ function copperLayerNames(count) {
31239
+ if (!Number.isInteger(count) || count < 1) {
31240
+ throw new Error(`invalid copper layer count ${count}`);
31241
+ }
31242
+ if (count === 1)
31243
+ return ["FCu"];
31244
+ const inner = Array.from({ length: count - 2 }, (_, i) => innerCopperLayerName(i + 1));
31245
+ return ["FCu", ...inner, "BCu"];
31246
+ }
31247
+ function assertSupportedCopperCount(count) {
31248
+ const ok4 = Number.isInteger(count) && count >= 1 && (count === 1 || count % 2 === 0) && count <= MAX_COPPER_LAYERS;
31249
+ if (!ok4) {
31250
+ throw new Error(`unsupported PCB layer count ${count}: expected 1 or an even number from 2 to ${MAX_COPPER_LAYERS}`);
31251
+ }
31252
+ }
31253
+ function copperSortKey(layer) {
31254
+ if (layer === "FCu")
31255
+ return 0;
31256
+ if (layer === "BCu")
31257
+ return Number.MAX_SAFE_INTEGER;
31258
+ return innerCopperIndex(layer);
31259
+ }
31260
+ function boardCopperLayers(pcb) {
31261
+ const seen = /* @__PURE__ */ new Set();
31262
+ const add = (l) => {
31263
+ if (l && isCopperLayer(l))
31264
+ seen.add(l);
31265
+ };
31266
+ for (const l of pcb?.stackup?.layers ?? [])
31267
+ add(l.layer);
31268
+ for (const t2 of pcb?.traces ?? [])
31269
+ add(t2.layer);
31270
+ for (const z of pcb?.zones ?? [])
31271
+ add(z.layer);
31272
+ for (const v of pcb?.vias ?? []) {
31273
+ add(v.startLayer);
31274
+ add(v.endLayer);
31275
+ }
31276
+ if (seen.size === 0)
31277
+ return ["FCu", "BCu"];
31278
+ return [...seen].sort((a, b) => copperSortKey(a) - copperSortKey(b));
31279
+ }
31280
+ var COPPER_RE, MAX_COPPER_LAYERS;
31281
+ var init_pcb_layers = __esm({
31282
+ "../core/dist/utils/pcb-layers.js"() {
31283
+ "use strict";
31284
+ COPPER_RE = /^(FCu|BCu|In(\d+)Cu)$/;
31285
+ MAX_COPPER_LAYERS = 32;
31286
+ }
31287
+ });
31288
+
31227
31289
  // ../core/dist/stores/document-store.js
31228
31290
  function crdtF64(v) {
31229
31291
  return { F64: v };
@@ -31466,6 +31528,7 @@ var init_document_store = __esm({
31466
31528
  init_ui_store();
31467
31529
  init_parameters_store();
31468
31530
  init_ecad_sync();
31531
+ init_pcb_layers();
31469
31532
  _sceneSettingsFeatureId = null;
31470
31533
  _schematicFeatureId = null;
31471
31534
  _analysisStudiesFeatureId = null;
@@ -32572,28 +32635,13 @@ var init_document_store = __esm({
32572
32635
  const traceWidth = options?.traceWidth ?? 0.15;
32573
32636
  const clearance = options?.clearance ?? 0.15;
32574
32637
  const boardName2 = options?.name ?? "PCB Board";
32575
- const stackupLayers = [];
32576
- stackupLayers.push({ layer: "FCu", copperThickness: 0.035 });
32577
- if (layerCount >= 4) {
32578
- const innerCount = layerCount - 2;
32579
- if (innerCount > 30)
32580
- throw new Error(`layers ${layerCount} exceeds 32 copper layers`);
32581
- const innerLayerNames = Array.from({ length: 30 }, (_, i) => `In${i + 1}Cu`);
32582
- const dielectricPerLayer = thickness / (layerCount - 1);
32583
- for (let i = 0; i < innerCount; i++) {
32584
- stackupLayers.push({
32585
- layer: innerLayerNames[i],
32586
- copperThickness: 0.035,
32587
- dielectricThickness: dielectricPerLayer,
32588
- dielectricEr: 4.5,
32589
- material: "FR4"
32590
- });
32591
- }
32592
- }
32593
- stackupLayers.push({
32594
- layer: "BCu",
32638
+ assertSupportedCopperCount(layerCount);
32639
+ const copperNames = copperLayerNames(layerCount);
32640
+ const dielectricPerLayer = layerCount > 1 ? thickness / (layerCount - 1) : thickness;
32641
+ const stackupLayers = copperNames.map((layer, i) => i === 0 ? { layer, copperThickness: 0.035 } : {
32642
+ layer,
32595
32643
  copperThickness: 0.035,
32596
- dielectricThickness: layerCount >= 4 ? thickness / (layerCount - 1) : thickness,
32644
+ dielectricThickness: dielectricPerLayer,
32597
32645
  dielectricEr: 4.5,
32598
32646
  material: "FR4"
32599
32647
  });
@@ -41728,6 +41776,23 @@ var init_CHANGELOG = __esm({
41728
41776
  "kernel"
41729
41777
  ]
41730
41778
  },
41779
+ {
41780
+ id: "2026-10-17-pcb-layer-coverage",
41781
+ version: "0.10.0",
41782
+ date: "2026-10-17",
41783
+ category: "fix",
41784
+ title: "Inner copper beyond In2Cu renders on 6\u201310 layer boards",
41785
+ summary: "Layer colours, toggles, dielectric slabs and copper Z now derive from the board stackup, so In3Cu\u2013In8Cu draw and toggle; new boards up to 10 layers get valid layer names; MCP accepts In7/In8.",
41786
+ features: [
41787
+ "pcb",
41788
+ "electronics",
41789
+ "layers"
41790
+ ],
41791
+ mcpTools: [
41792
+ "get_copper",
41793
+ "render_stackup"
41794
+ ]
41795
+ },
41731
41796
  {
41732
41797
  id: "2026-10-17-pcb-32-copper-layers",
41733
41798
  version: "0.10.0",
@@ -49597,6 +49662,7 @@ var init_dist3 = __esm({
49597
49662
  init_logger();
49598
49663
  init_changelog();
49599
49664
  init_sketch_constraint_persist();
49665
+ init_pcb_layers();
49600
49666
  }
49601
49667
  });
49602
49668
 
@@ -54610,7 +54676,7 @@ var init_registry_dispatch = __esm({
54610
54676
 
54611
54677
  // src/tools/pcb-layers.ts
54612
54678
  var INNER_COPPER, PCB_LAYERS, COPPER_STACK;
54613
- var init_pcb_layers = __esm({
54679
+ var init_pcb_layers2 = __esm({
54614
54680
  "src/tools/pcb-layers.ts"() {
54615
54681
  "use strict";
54616
54682
  INNER_COPPER = Array.from({ length: 30 }, (_, i) => `In${i + 1}Cu`);
@@ -54741,7 +54807,7 @@ var VALID_LAYERS;
54741
54807
  var init_pcb_validate = __esm({
54742
54808
  "src/tools/pcb-validate.ts"() {
54743
54809
  "use strict";
54744
- init_pcb_layers();
54810
+ init_pcb_layers2();
54745
54811
  VALID_LAYERS = new Set(PCB_LAYERS);
54746
54812
  }
54747
54813
  });
@@ -62201,7 +62267,7 @@ function ecadUnverifiable(check2, outcome) {
62201
62267
  isError: true
62202
62268
  };
62203
62269
  }
62204
- function isCopperLayer(layer) {
62270
+ function isCopperLayer2(layer) {
62205
62271
  return COPPER_LAYER_SET.has(layer);
62206
62272
  }
62207
62273
  function suggestLayer(name) {
@@ -62226,7 +62292,7 @@ function validateLayer(raw) {
62226
62292
  function validateCopperLayer(raw) {
62227
62293
  const res = validateLayer(raw);
62228
62294
  if ("error" in res) return res;
62229
- if (!isCopperLayer(res.layer)) {
62295
+ if (!isCopperLayer2(res.layer)) {
62230
62296
  return {
62231
62297
  error: `layer '${res.layer}' is not a copper layer; copper layers: ${COPPER_LAYERS.join(", ")}`
62232
62298
  };
@@ -66442,7 +66508,7 @@ function searchFootprints(args) {
66442
66508
  };
66443
66509
  }
66444
66510
  function padCopperLayers(pad) {
66445
- return pad.layers.filter((l) => isCopperLayer(l));
66511
+ return pad.layers.filter((l) => isCopperLayer2(l));
66446
66512
  }
66447
66513
  function getPadPositions(args) {
66448
66514
  const ctx = resolveDocInput(args);
@@ -66987,7 +67053,7 @@ async function setStackup(args) {
66987
67053
  if (copperOz != null) {
66988
67054
  const t2 = round33(copperOz * OZ_TO_MM);
66989
67055
  for (const l of stackup) {
66990
- if (isCopperLayer(l.layer)) l.copperThickness = t2;
67056
+ if (isCopperLayer2(l.layer)) l.copperThickness = t2;
66991
67057
  }
66992
67058
  }
66993
67059
  for (const ov of perLayer ?? []) {
@@ -66999,7 +67065,7 @@ async function setStackup(args) {
66999
67065
  const layerName = layerRes.layer;
67000
67066
  let entry = stackup.find((l) => l.layer === layerName);
67001
67067
  if (!entry) {
67002
- if (!isCopperLayer(layerName)) {
67068
+ if (!isCopperLayer2(layerName)) {
67003
67069
  return fail2(`cannot create non-copper layer "${layerName}" \u2014 only copper layers are auto-added`);
67004
67070
  }
67005
67071
  entry = { layer: layerName };
@@ -70379,7 +70445,7 @@ var init_ecad2 = __esm({
70379
70445
  init_em_claims();
70380
70446
  init_enclosure();
70381
70447
  init_pcb_validate();
70382
- init_pcb_layers();
70448
+ init_pcb_layers2();
70383
70449
  init_ecad_diff();
70384
70450
  init_artifact_store();
70385
70451
  init_remote();
@@ -73823,9 +73889,7 @@ async function renderStackup(args) {
73823
73889
  isError: true
73824
73890
  };
73825
73891
  }
73826
- const declared = new Set(pcb.stackup.layers.map((l) => String(l.layer)));
73827
- const present = COPPER_LAYERS2.filter((l) => declared.has(l));
73828
- const copper = present.length > 0 ? [...present] : ["FCu", "BCu"];
73892
+ const copper = boardCopperLayers(pcb);
73829
73893
  const pcbJson = JSON.stringify(pcb);
73830
73894
  const content = [];
73831
73895
  const index = [];
@@ -73892,7 +73956,7 @@ async function renderStackup(args) {
73892
73956
  });
73893
73957
  return withRenderAssets({ content }, assets);
73894
73958
  }
73895
- var renderViewSchema, SVG_SCALE, DEFAULT_WIDTH_PX, MAX_NODES, MAX_PATTERN_INSTANCES, MAX_RENDER_TRIANGLES, MAX_RASTER_SVG_BYTES, MAX_INLINE_SVG_BYTES, renderPcbSchema, PCB_MARGIN_MM, RATSNEST_COLOR, renderRatsnestSchema, COPPER_LAYERS2, renderStackupSchema, toolDefs24;
73959
+ var renderViewSchema, SVG_SCALE, DEFAULT_WIDTH_PX, MAX_NODES, MAX_PATTERN_INSTANCES, MAX_RENDER_TRIANGLES, MAX_RASTER_SVG_BYTES, MAX_INLINE_SVG_BYTES, renderPcbSchema, PCB_MARGIN_MM, RATSNEST_COLOR, renderRatsnestSchema, renderStackupSchema, toolDefs24;
73896
73960
  var init_render2 = __esm({
73897
73961
  "src/tools/render.ts"() {
73898
73962
  "use strict";
@@ -73903,7 +73967,6 @@ var init_render2 = __esm({
73903
73967
  init_tool_def();
73904
73968
  init_render_assets();
73905
73969
  init_arg_coerce();
73906
- init_pcb_layers();
73907
73970
  init_pose();
73908
73971
  renderViewSchema = {
73909
73972
  type: "object",
@@ -74042,7 +74105,6 @@ var init_render2 = __esm({
74042
74105
  },
74043
74106
  required: ["document_id"]
74044
74107
  };
74045
- COPPER_LAYERS2 = COPPER_STACK;
74046
74108
  renderStackupSchema = {
74047
74109
  type: "object",
74048
74110
  properties: {
@@ -84633,8 +84695,8 @@ var init_server3 = __esm({
84633
84695
  init_order_feed();
84634
84696
  init_animate();
84635
84697
  PKG_VERSION = (() => {
84636
- if ("0.10.0-main.94") {
84637
- return "0.10.0-main.94";
84698
+ if ("0.10.0-main.95") {
84699
+ return "0.10.0-main.95";
84638
84700
  }
84639
84701
  try {
84640
84702
  const req = createRequire2(import.meta.url);
@@ -84643,8 +84705,8 @@ var init_server3 = __esm({
84643
84705
  return "0.0.0";
84644
84706
  }
84645
84707
  })();
84646
- BUILD_SHA = "6176496f3a4b9477437d5eec85aea4bc40cde13c";
84647
- BUILD_TIME = "2026-10-17T18:45:10.765Z";
84708
+ BUILD_SHA = "2182e0fa666586bfac3ebff40ad17af91836bf97";
84709
+ BUILD_TIME = "2026-10-17T19:27:56.972Z";
84648
84710
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
84649
84711
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
84650
84712
  INSTANCE_ID = randomUUID7().slice(0, 8);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcad/mcp",
3
- "version": "0.10.0-main.94",
3
+ "version": "0.10.0-main.95",
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": "6176496f3a4b9477437d5eec85aea4bc40cde13c",
23
- "builtAt": "2026-10-17T18:45:10.765Z"
22
+ "sha": "2182e0fa666586bfac3ebff40ad17af91836bf97",
23
+ "builtAt": "2026-10-17T19:27:56.972Z"
24
24
  }
25
25
  }
Binary file