@vcad/mcp 0.10.0-main.122 → 0.10.0-main.124
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 +1 -1
- package/index.mjs +132 -316
- package/package.json +3 -3
- package/vcad_kernel_wasm_bg.wasm +2 -2
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
|
|
9
|
+
Built from 72bb34aea80bd70051717281e832338ab01f1f3d at 2026-10-21T13:06:52.166Z. Source: https://github.com/ecto/vcad
|
package/index.mjs
CHANGED
|
@@ -31321,154 +31321,6 @@ var init_parameters_store = __esm({
|
|
|
31321
31321
|
}
|
|
31322
31322
|
});
|
|
31323
31323
|
|
|
31324
|
-
// ../core/dist/stores/ecad-sync.js
|
|
31325
|
-
function padsFromPins(pins) {
|
|
31326
|
-
const n = pins.length;
|
|
31327
|
-
const pitch = 2.54;
|
|
31328
|
-
return pins.map((pin, i) => ({
|
|
31329
|
-
number: pin.number,
|
|
31330
|
-
padType: "SMD",
|
|
31331
|
-
shape: { type: "RoundRect", width: 1.5, height: 1.5, cornerRatio: 0.25 },
|
|
31332
|
-
position: { x: (i - (n - 1) / 2) * pitch, y: 0 },
|
|
31333
|
-
layers: [...FALLBACK_PAD_LAYERS]
|
|
31334
|
-
}));
|
|
31335
|
-
}
|
|
31336
|
-
function syncSchematicToPcbData(pcb, schematic, netlist, opts) {
|
|
31337
|
-
const placeUnplaced = opts?.placeUnplaced ?? true;
|
|
31338
|
-
const next = structuredClone(pcb);
|
|
31339
|
-
let changed = false;
|
|
31340
|
-
const existingRefs = new Set(next.footprints.map((fp) => fp.ref));
|
|
31341
|
-
let added = 0;
|
|
31342
|
-
for (const comp of placeUnplaced ? schematic.components : []) {
|
|
31343
|
-
if (existingRefs.has(comp.ref))
|
|
31344
|
-
continue;
|
|
31345
|
-
let pads = [];
|
|
31346
|
-
let graphics = [];
|
|
31347
|
-
if (comp.properties?.footprintTemplate) {
|
|
31348
|
-
try {
|
|
31349
|
-
const template = JSON.parse(comp.properties.footprintTemplate);
|
|
31350
|
-
pads = template.pads ?? [];
|
|
31351
|
-
graphics = template.graphics ?? [];
|
|
31352
|
-
} catch {
|
|
31353
|
-
}
|
|
31354
|
-
}
|
|
31355
|
-
if (pads.length === 0)
|
|
31356
|
-
pads = padsFromPins(comp.pins);
|
|
31357
|
-
const fpCount = next.footprints.length;
|
|
31358
|
-
const staggerX = 10 + (fpCount + added) % 5 * 10;
|
|
31359
|
-
const staggerY = 10 + Math.floor((fpCount + added) / 5) * 10;
|
|
31360
|
-
next.footprints.push({
|
|
31361
|
-
ref: comp.ref,
|
|
31362
|
-
value: comp.value,
|
|
31363
|
-
footprintName: comp.footprintId ?? comp.ref,
|
|
31364
|
-
position: { x: staggerX, y: staggerY },
|
|
31365
|
-
pads,
|
|
31366
|
-
graphics
|
|
31367
|
-
});
|
|
31368
|
-
added++;
|
|
31369
|
-
changed = true;
|
|
31370
|
-
}
|
|
31371
|
-
if (netlist) {
|
|
31372
|
-
const padNet = /* @__PURE__ */ new Map();
|
|
31373
|
-
const netNames = /* @__PURE__ */ new Set();
|
|
31374
|
-
for (const net of netlist.nets) {
|
|
31375
|
-
netNames.add(net.name);
|
|
31376
|
-
for (const c of net.connections) {
|
|
31377
|
-
padNet.set(`${c.component_ref}:${c.pin_number}`, net.name);
|
|
31378
|
-
}
|
|
31379
|
-
}
|
|
31380
|
-
for (const fp of next.footprints) {
|
|
31381
|
-
for (const pad of fp.pads) {
|
|
31382
|
-
const wanted = padNet.get(`${fp.ref}:${pad.number}`);
|
|
31383
|
-
if (wanted !== pad.net) {
|
|
31384
|
-
if (wanted)
|
|
31385
|
-
pad.net = wanted;
|
|
31386
|
-
else
|
|
31387
|
-
delete pad.net;
|
|
31388
|
-
changed = true;
|
|
31389
|
-
}
|
|
31390
|
-
}
|
|
31391
|
-
}
|
|
31392
|
-
const known = new Set(next.nets.map((n) => n.name));
|
|
31393
|
-
for (const name of netNames) {
|
|
31394
|
-
if (!known.has(name)) {
|
|
31395
|
-
next.nets.push({ id: name, name });
|
|
31396
|
-
changed = true;
|
|
31397
|
-
}
|
|
31398
|
-
}
|
|
31399
|
-
}
|
|
31400
|
-
return { pcb: next, changed };
|
|
31401
|
-
}
|
|
31402
|
-
var FALLBACK_PAD_LAYERS;
|
|
31403
|
-
var init_ecad_sync = __esm({
|
|
31404
|
-
"../core/dist/stores/ecad-sync.js"() {
|
|
31405
|
-
"use strict";
|
|
31406
|
-
FALLBACK_PAD_LAYERS = ["FCu", "FPaste", "FMask"];
|
|
31407
|
-
}
|
|
31408
|
-
});
|
|
31409
|
-
|
|
31410
|
-
// ../core/dist/utils/pcb-layers.js
|
|
31411
|
-
function isCopperLayer(layer) {
|
|
31412
|
-
return COPPER_RE.test(layer);
|
|
31413
|
-
}
|
|
31414
|
-
function innerCopperIndex(layer) {
|
|
31415
|
-
const m = COPPER_RE.exec(layer);
|
|
31416
|
-
return m?.[2] ? Number(m[2]) : 0;
|
|
31417
|
-
}
|
|
31418
|
-
function innerCopperLayerName(n) {
|
|
31419
|
-
return `In${n}Cu`;
|
|
31420
|
-
}
|
|
31421
|
-
function copperLayerNames(count) {
|
|
31422
|
-
if (!Number.isInteger(count) || count < 1) {
|
|
31423
|
-
throw new Error(`invalid copper layer count ${count}`);
|
|
31424
|
-
}
|
|
31425
|
-
if (count === 1)
|
|
31426
|
-
return ["FCu"];
|
|
31427
|
-
const inner = Array.from({ length: count - 2 }, (_, i) => innerCopperLayerName(i + 1));
|
|
31428
|
-
return ["FCu", ...inner, "BCu"];
|
|
31429
|
-
}
|
|
31430
|
-
function assertSupportedCopperCount(count) {
|
|
31431
|
-
const ok4 = Number.isInteger(count) && count >= 1 && (count === 1 || count % 2 === 0) && count <= MAX_COPPER_LAYERS;
|
|
31432
|
-
if (!ok4) {
|
|
31433
|
-
throw new Error(`unsupported PCB layer count ${count}: expected 1 or an even number from 2 to ${MAX_COPPER_LAYERS}`);
|
|
31434
|
-
}
|
|
31435
|
-
}
|
|
31436
|
-
function copperSortKey(layer) {
|
|
31437
|
-
if (layer === "FCu")
|
|
31438
|
-
return 0;
|
|
31439
|
-
if (layer === "BCu")
|
|
31440
|
-
return Number.MAX_SAFE_INTEGER;
|
|
31441
|
-
return innerCopperIndex(layer);
|
|
31442
|
-
}
|
|
31443
|
-
function boardCopperLayers(pcb) {
|
|
31444
|
-
const seen = /* @__PURE__ */ new Set();
|
|
31445
|
-
const add = (l) => {
|
|
31446
|
-
if (l && isCopperLayer(l))
|
|
31447
|
-
seen.add(l);
|
|
31448
|
-
};
|
|
31449
|
-
for (const l of pcb?.stackup?.layers ?? [])
|
|
31450
|
-
add(l.layer);
|
|
31451
|
-
for (const t2 of pcb?.traces ?? [])
|
|
31452
|
-
add(t2.layer);
|
|
31453
|
-
for (const z of pcb?.zones ?? [])
|
|
31454
|
-
add(z.layer);
|
|
31455
|
-
for (const v of pcb?.vias ?? []) {
|
|
31456
|
-
add(v.startLayer);
|
|
31457
|
-
add(v.endLayer);
|
|
31458
|
-
}
|
|
31459
|
-
if (seen.size === 0)
|
|
31460
|
-
return ["FCu", "BCu"];
|
|
31461
|
-
return [...seen].sort((a, b) => copperSortKey(a) - copperSortKey(b));
|
|
31462
|
-
}
|
|
31463
|
-
var COPPER_RE, MAX_COPPER_LAYERS;
|
|
31464
|
-
var init_pcb_layers = __esm({
|
|
31465
|
-
"../core/dist/utils/pcb-layers.js"() {
|
|
31466
|
-
"use strict";
|
|
31467
|
-
COPPER_RE = /^(FCu|BCu|In(\d+)Cu)$/;
|
|
31468
|
-
MAX_COPPER_LAYERS = 32;
|
|
31469
|
-
}
|
|
31470
|
-
});
|
|
31471
|
-
|
|
31472
31324
|
// ../core/dist/stores/document-store.js
|
|
31473
31325
|
function crdtF64(v) {
|
|
31474
31326
|
return { F64: v };
|
|
@@ -31621,36 +31473,6 @@ function getOrCreateDrawingFeature(state) {
|
|
|
31621
31473
|
}
|
|
31622
31474
|
return "";
|
|
31623
31475
|
}
|
|
31624
|
-
function getOrCreateConstraintsFeature(state) {
|
|
31625
|
-
const engine = state._crdtEngine;
|
|
31626
|
-
if (_constraintsFeatureId)
|
|
31627
|
-
return _constraintsFeatureId;
|
|
31628
|
-
const featuresJson = engine.get_ordered_features_json();
|
|
31629
|
-
const features = JSON.parse(featuresJson);
|
|
31630
|
-
const existing = features.find((f) => f.kind === "design-constraints");
|
|
31631
|
-
if (existing) {
|
|
31632
|
-
_constraintsFeatureId = existing.id;
|
|
31633
|
-
return existing.id;
|
|
31634
|
-
}
|
|
31635
|
-
const result = applyCommand(engine, { type: "create_feature", kind: "design-constraints" });
|
|
31636
|
-
if (result.createdFeatureId) {
|
|
31637
|
-
_constraintsFeatureId = result.createdFeatureId;
|
|
31638
|
-
return result.createdFeatureId;
|
|
31639
|
-
}
|
|
31640
|
-
return "";
|
|
31641
|
-
}
|
|
31642
|
-
function setCrdtConstraints(state, constraints) {
|
|
31643
|
-
const fid = getOrCreateConstraintsFeature(state);
|
|
31644
|
-
if (!fid)
|
|
31645
|
-
return {};
|
|
31646
|
-
const result = applyCommand(state._crdtEngine, {
|
|
31647
|
-
type: "set_param",
|
|
31648
|
-
id: fid,
|
|
31649
|
-
key: "constraints",
|
|
31650
|
-
value: crdtStr(JSON.stringify(constraints))
|
|
31651
|
-
});
|
|
31652
|
-
return applyLegacyResult(result);
|
|
31653
|
-
}
|
|
31654
31476
|
function getOrCreateSchematicFeature(state) {
|
|
31655
31477
|
const engine = state._crdtEngine;
|
|
31656
31478
|
if (_schematicFeatureId)
|
|
@@ -31669,20 +31491,6 @@ function getOrCreateSchematicFeature(state) {
|
|
|
31669
31491
|
}
|
|
31670
31492
|
return "";
|
|
31671
31493
|
}
|
|
31672
|
-
function getPcbBoardFeatureId(state) {
|
|
31673
|
-
const engine = state._crdtEngine;
|
|
31674
|
-
const featuresJson = engine.get_ordered_features_json();
|
|
31675
|
-
const features = JSON.parse(featuresJson);
|
|
31676
|
-
const pcb = features.find((f) => f.kind === "pcb-board");
|
|
31677
|
-
return pcb?.id ?? "";
|
|
31678
|
-
}
|
|
31679
|
-
function setCrdtPcb(state, pcb) {
|
|
31680
|
-
const pcbFid = getPcbBoardFeatureId(state);
|
|
31681
|
-
if (!pcbFid)
|
|
31682
|
-
return {};
|
|
31683
|
-
const result = applyCommand(state._crdtEngine, { type: "set_param", id: pcbFid, key: "board", value: crdtStr(JSON.stringify(pcb)) });
|
|
31684
|
-
return applyLegacyResult(result);
|
|
31685
|
-
}
|
|
31686
31494
|
function applyEdit(get, set, tool, args) {
|
|
31687
31495
|
const engine = get()._crdtEngine;
|
|
31688
31496
|
if (!engine)
|
|
@@ -31695,23 +31503,21 @@ function applyEdit(get, set, tool, args) {
|
|
|
31695
31503
|
set(applyApiResult(envelope.result));
|
|
31696
31504
|
return true;
|
|
31697
31505
|
}
|
|
31698
|
-
function
|
|
31506
|
+
function addBoard(get, set, tool, args) {
|
|
31699
31507
|
const engine = get()._crdtEngine;
|
|
31700
31508
|
if (!engine) {
|
|
31701
31509
|
console.error("[PCB] Cannot create board: CRDT engine not initialized");
|
|
31702
31510
|
return 0;
|
|
31703
31511
|
}
|
|
31704
|
-
const
|
|
31705
|
-
|
|
31706
|
-
|
|
31707
|
-
|
|
31708
|
-
|
|
31709
|
-
const
|
|
31710
|
-
|
|
31711
|
-
const pcbPart = result.parts.find((p) => p.kind === "pcb-board");
|
|
31712
|
-
return pcbPart ? pcbPart.boardNodeId : 0;
|
|
31512
|
+
const envelope = applyToolCall(engine, tool, args);
|
|
31513
|
+
if (!envelope.ok)
|
|
31514
|
+
throw new Error(envelope.error.message);
|
|
31515
|
+
set(applyApiResult(envelope.result));
|
|
31516
|
+
const created = envelope.result.parts.find((p) => p.id === envelope.result.createdFeatureId);
|
|
31517
|
+
const board = created ?? envelope.result.parts.find((p) => p.kind === "pcb-board");
|
|
31518
|
+
return board?.boardNodeId ?? 0;
|
|
31713
31519
|
}
|
|
31714
|
-
var _sceneSettingsFeatureId, _schematicFeatureId, _analysisStudiesFeatureId, _drawingSettingsFeatureId,
|
|
31520
|
+
var _sceneSettingsFeatureId, _schematicFeatureId, _analysisStudiesFeatureId, _drawingSettingsFeatureId, useDocumentStore;
|
|
31715
31521
|
var init_document_store = __esm({
|
|
31716
31522
|
"../core/dist/stores/document-store.js"() {
|
|
31717
31523
|
"use strict";
|
|
@@ -31724,13 +31530,10 @@ var init_document_store = __esm({
|
|
|
31724
31530
|
init_types3();
|
|
31725
31531
|
init_ui_store();
|
|
31726
31532
|
init_parameters_store();
|
|
31727
|
-
init_ecad_sync();
|
|
31728
|
-
init_pcb_layers();
|
|
31729
31533
|
_sceneSettingsFeatureId = null;
|
|
31730
31534
|
_schematicFeatureId = null;
|
|
31731
31535
|
_analysisStudiesFeatureId = null;
|
|
31732
31536
|
_drawingSettingsFeatureId = null;
|
|
31733
|
-
_constraintsFeatureId = null;
|
|
31734
31537
|
useDocumentStore = create((set, get) => ({
|
|
31735
31538
|
document: createDocument(),
|
|
31736
31539
|
parts: [],
|
|
@@ -32625,43 +32428,36 @@ var init_document_store = __esm({
|
|
|
32625
32428
|
},
|
|
32626
32429
|
newDocument: (id, name) => {
|
|
32627
32430
|
const state = get();
|
|
32431
|
+
let engine = state._crdtEngine;
|
|
32432
|
+
let view = {
|
|
32433
|
+
document: createDocument(),
|
|
32434
|
+
parts: [],
|
|
32435
|
+
partIndex: /* @__PURE__ */ new Map(),
|
|
32436
|
+
consumedParts: {},
|
|
32437
|
+
nextNodeId: 1
|
|
32438
|
+
};
|
|
32628
32439
|
if (state._crdtEngineClass) {
|
|
32629
32440
|
_sceneSettingsFeatureId = null;
|
|
32630
32441
|
_schematicFeatureId = null;
|
|
32631
32442
|
_analysisStudiesFeatureId = null;
|
|
32632
32443
|
_drawingSettingsFeatureId = null;
|
|
32633
|
-
|
|
32634
|
-
|
|
32635
|
-
document:
|
|
32636
|
-
parts:
|
|
32637
|
-
partIndex: /* @__PURE__ */ new Map(),
|
|
32638
|
-
consumedParts: {},
|
|
32639
|
-
nextNodeId: 1,
|
|
32640
|
-
isDirty: false,
|
|
32641
|
-
documentId: id,
|
|
32642
|
-
documentName: name,
|
|
32643
|
-
lastSavedAt: null,
|
|
32644
|
-
isParameterDragging: false,
|
|
32645
|
-
isTransientEval: false,
|
|
32646
|
-
loonSource: null,
|
|
32647
|
-
_crdtEngine: engine
|
|
32648
|
-
});
|
|
32649
|
-
} else {
|
|
32650
|
-
set({
|
|
32651
|
-
document: createDocument(),
|
|
32652
|
-
parts: [],
|
|
32653
|
-
partIndex: /* @__PURE__ */ new Map(),
|
|
32654
|
-
consumedParts: {},
|
|
32655
|
-
nextNodeId: 1,
|
|
32656
|
-
isDirty: false,
|
|
32657
|
-
documentId: id,
|
|
32658
|
-
documentName: name,
|
|
32659
|
-
lastSavedAt: null,
|
|
32660
|
-
isParameterDragging: false,
|
|
32661
|
-
isTransientEval: false,
|
|
32662
|
-
loonSource: null
|
|
32444
|
+
engine = new state._crdtEngineClass();
|
|
32445
|
+
view = applyLegacyResult({
|
|
32446
|
+
document: JSON.parse(engine.get_document_json()),
|
|
32447
|
+
parts: JSON.parse(engine.get_parts_json())
|
|
32663
32448
|
});
|
|
32664
32449
|
}
|
|
32450
|
+
set({
|
|
32451
|
+
...view,
|
|
32452
|
+
isDirty: false,
|
|
32453
|
+
documentId: id,
|
|
32454
|
+
documentName: name,
|
|
32455
|
+
lastSavedAt: null,
|
|
32456
|
+
isParameterDragging: false,
|
|
32457
|
+
isTransientEval: false,
|
|
32458
|
+
loonSource: null,
|
|
32459
|
+
_crdtEngine: engine
|
|
32460
|
+
});
|
|
32665
32461
|
},
|
|
32666
32462
|
clearDirtyNodes: () => {
|
|
32667
32463
|
return /* @__PURE__ */ new Set();
|
|
@@ -32828,73 +32624,24 @@ var init_document_store = __esm({
|
|
|
32828
32624
|
set(applyLegacyResult(result));
|
|
32829
32625
|
},
|
|
32830
32626
|
initPcb: (options) => {
|
|
32831
|
-
|
|
32832
|
-
|
|
32833
|
-
|
|
32834
|
-
|
|
32835
|
-
|
|
32836
|
-
|
|
32837
|
-
|
|
32838
|
-
|
|
32839
|
-
const copperNames = copperLayerNames(layerCount);
|
|
32840
|
-
const dielectricPerLayer = layerCount > 1 ? thickness / (layerCount - 1) : thickness;
|
|
32841
|
-
const stackupLayers = copperNames.map((layer, i) => i === 0 ? { layer, copperThickness: 0.035 } : {
|
|
32842
|
-
layer,
|
|
32843
|
-
copperThickness: 0.035,
|
|
32844
|
-
dielectricThickness: dielectricPerLayer,
|
|
32845
|
-
dielectricEr: 4.5,
|
|
32846
|
-
material: "FR4"
|
|
32627
|
+
return addBoard(get, set, "pcb_init", {
|
|
32628
|
+
width: options?.width,
|
|
32629
|
+
height: options?.height,
|
|
32630
|
+
layers: options?.layers,
|
|
32631
|
+
thickness: options?.thickness,
|
|
32632
|
+
trace_width: options?.traceWidth,
|
|
32633
|
+
clearance: options?.clearance,
|
|
32634
|
+
name: options?.name
|
|
32847
32635
|
});
|
|
32848
|
-
const pcbBoard = {
|
|
32849
|
-
outline: {
|
|
32850
|
-
vertices: [
|
|
32851
|
-
{ x: 0, y: 0 },
|
|
32852
|
-
{ x: w, y: 0 },
|
|
32853
|
-
{ x: w, y: h },
|
|
32854
|
-
{ x: 0, y: h }
|
|
32855
|
-
],
|
|
32856
|
-
thickness
|
|
32857
|
-
},
|
|
32858
|
-
stackup: { layers: stackupLayers },
|
|
32859
|
-
nets: [],
|
|
32860
|
-
rules: {
|
|
32861
|
-
defaultRules: {
|
|
32862
|
-
name: "Default",
|
|
32863
|
-
traceWidth,
|
|
32864
|
-
clearance,
|
|
32865
|
-
viaDiameter: 0.6,
|
|
32866
|
-
viaDrill: 0.3
|
|
32867
|
-
},
|
|
32868
|
-
edgeClearance: 0.25,
|
|
32869
|
-
holeToHole: 0.25,
|
|
32870
|
-
minAnnularRing: 0.13,
|
|
32871
|
-
minDrill: 0.2,
|
|
32872
|
-
// KiCad's microvia defaults (uvia_min_drill / uvia_min_size).
|
|
32873
|
-
minMicroviaDrill: 0.1,
|
|
32874
|
-
minMicroviaDiameter: 0.2,
|
|
32875
|
-
inferredFloors: []
|
|
32876
|
-
},
|
|
32877
|
-
footprints: [],
|
|
32878
|
-
traces: [],
|
|
32879
|
-
vias: [],
|
|
32880
|
-
zones: []
|
|
32881
|
-
};
|
|
32882
|
-
return addPcbToDocument(get, set, pcbBoard, boardName2);
|
|
32883
32636
|
},
|
|
32884
32637
|
importPcb: (pcb, name) => {
|
|
32885
|
-
return
|
|
32638
|
+
return addBoard(get, set, "pcb_import", { board: pcb, name: name ?? "Imported PCB" });
|
|
32886
32639
|
},
|
|
32887
|
-
syncSchematicToPcb: (
|
|
32888
|
-
const
|
|
32889
|
-
const pcb = state.document.pcb;
|
|
32890
|
-
const schematic = state.document.schematic;
|
|
32640
|
+
syncSchematicToPcb: (_boardNodeId, netlist, opts) => {
|
|
32641
|
+
const { pcb, schematic } = get().document;
|
|
32891
32642
|
if (!pcb || !schematic)
|
|
32892
32643
|
return;
|
|
32893
|
-
|
|
32894
|
-
if (!changed)
|
|
32895
|
-
return;
|
|
32896
|
-
const patch = setCrdtPcb(state, nextPcb);
|
|
32897
|
-
set({ ...patch, isDirty: true });
|
|
32644
|
+
applyEdit(get, set, "pcb_sync_schematic", { netlist, place_unplaced: opts?.placeUnplaced });
|
|
32898
32645
|
},
|
|
32899
32646
|
moveSchematicComponent: (idx, position) => {
|
|
32900
32647
|
applyEdit(get, set, "sch_move_component", { index: idx, position: { x: position.x, y: position.y } });
|
|
@@ -32993,7 +32740,7 @@ var init_document_store = __esm({
|
|
|
32993
32740
|
const next = mergeSketchConstraints(state.document.constraints ?? [], sketchNode, session);
|
|
32994
32741
|
if (next.length === 0 && (state.document.constraints ?? []).length === 0)
|
|
32995
32742
|
return;
|
|
32996
|
-
|
|
32743
|
+
applyEdit(get, set, "set_design_constraints", { constraints: next });
|
|
32997
32744
|
},
|
|
32998
32745
|
addDesignConstraint: (constraint) => {
|
|
32999
32746
|
if (!applyEdit(get, set, "add_design_constraint", { constraint }))
|
|
@@ -33019,20 +32766,7 @@ var init_document_store = __esm({
|
|
|
33019
32766
|
const resultJson = wasm3.solveDesignConstraints(JSON.stringify(state.document), JSON.stringify(opts?.extraFixed ? { extraFixed: opts.extraFixed } : {}));
|
|
33020
32767
|
const result = JSON.parse(resultJson);
|
|
33021
32768
|
const { report } = result;
|
|
33022
|
-
|
|
33023
|
-
const movedBoard = report.groups.find((g) => g.converged && getNodePcb(result.document, g.node));
|
|
33024
|
-
if (movedBoard && (report.movedFootprints.length > 0 || report.movedVertices.length > 0)) {
|
|
33025
|
-
const pcb = getNodePcb(result.document, movedBoard.node);
|
|
33026
|
-
if (pcb)
|
|
33027
|
-
patch = setCrdtPcb(get(), structuredClone(pcb));
|
|
33028
|
-
}
|
|
33029
|
-
if (report.drivenValues.length > 0) {
|
|
33030
|
-
patch = {
|
|
33031
|
-
...patch,
|
|
33032
|
-
...setCrdtConstraints(get(), result.document.constraints ?? [])
|
|
33033
|
-
};
|
|
33034
|
-
}
|
|
33035
|
-
set({ ...patch, isDirty: true });
|
|
32769
|
+
applyEdit(get, set, "apply_design_solve", { document: result.document, report });
|
|
33036
32770
|
return report;
|
|
33037
32771
|
} catch (e) {
|
|
33038
32772
|
console.warn("[document-store] solveDesignConstraints failed:", e);
|
|
@@ -41607,6 +41341,32 @@ var init_CHANGELOG = __esm({
|
|
|
41607
41341
|
CHANGELOG_default = {
|
|
41608
41342
|
$schema: "./changelog.schema.json",
|
|
41609
41343
|
entries: [
|
|
41344
|
+
{
|
|
41345
|
+
id: "2026-10-21-planar-cap-normals",
|
|
41346
|
+
version: "0.10.0",
|
|
41347
|
+
date: "2026-10-21",
|
|
41348
|
+
category: "fix",
|
|
41349
|
+
title: "Flat faces keep exact normals in photoreal renders",
|
|
41350
|
+
summary: "The crease bake no longer smooths across flat loft caps: planar faces shade with their exact plane normal, so glass and polished caps render without streaks.",
|
|
41351
|
+
features: [
|
|
41352
|
+
"photoreal",
|
|
41353
|
+
"tessellation",
|
|
41354
|
+
"render"
|
|
41355
|
+
]
|
|
41356
|
+
},
|
|
41357
|
+
{
|
|
41358
|
+
id: "2026-10-21-mac-app-updates",
|
|
41359
|
+
version: "0.10.0",
|
|
41360
|
+
date: "2026-10-21",
|
|
41361
|
+
category: "feat",
|
|
41362
|
+
title: "Mac app checks for updates",
|
|
41363
|
+
summary: "The native Mac app checks for signed updates automatically and adds Check for Updates\u2026 to the app menu, ready for Developer ID\u2013signed, notarized releases.",
|
|
41364
|
+
features: [
|
|
41365
|
+
"desktop",
|
|
41366
|
+
"mac",
|
|
41367
|
+
"updates"
|
|
41368
|
+
]
|
|
41369
|
+
},
|
|
41610
41370
|
{
|
|
41611
41371
|
id: "2026-10-21-loon-relative-mesh-paths",
|
|
41612
41372
|
version: "0.10.0",
|
|
@@ -41620,6 +41380,19 @@ var init_CHANGELOG = __esm({
|
|
|
41620
41380
|
"cli"
|
|
41621
41381
|
]
|
|
41622
41382
|
},
|
|
41383
|
+
{
|
|
41384
|
+
id: "2026-10-21-gpu-photoreal-limits",
|
|
41385
|
+
version: "0.10.0",
|
|
41386
|
+
date: "2026-10-21",
|
|
41387
|
+
category: "fix",
|
|
41388
|
+
title: "GPU photoreal handles big meshes and driver failures",
|
|
41389
|
+
summary: "The GPU path tracer no longer refuses meshes over 1M triangles (the device's buffer limit applies instead), and a driver that loses the device now gives a clear error, with vcad render falling back to the CPU.",
|
|
41390
|
+
features: [
|
|
41391
|
+
"photoreal",
|
|
41392
|
+
"gpu",
|
|
41393
|
+
"render"
|
|
41394
|
+
]
|
|
41395
|
+
},
|
|
41623
41396
|
{
|
|
41624
41397
|
id: "2026-10-21-desktop-agent-blank-canvas",
|
|
41625
41398
|
version: "0.10.0",
|
|
@@ -50214,6 +49987,49 @@ var init_changelog = __esm({
|
|
|
50214
49987
|
}
|
|
50215
49988
|
});
|
|
50216
49989
|
|
|
49990
|
+
// ../core/dist/utils/pcb-layers.js
|
|
49991
|
+
function isCopperLayer(layer) {
|
|
49992
|
+
return COPPER_RE.test(layer);
|
|
49993
|
+
}
|
|
49994
|
+
function innerCopperIndex(layer) {
|
|
49995
|
+
const m = COPPER_RE.exec(layer);
|
|
49996
|
+
return m?.[2] ? Number(m[2]) : 0;
|
|
49997
|
+
}
|
|
49998
|
+
function copperSortKey(layer) {
|
|
49999
|
+
if (layer === "FCu")
|
|
50000
|
+
return 0;
|
|
50001
|
+
if (layer === "BCu")
|
|
50002
|
+
return Number.MAX_SAFE_INTEGER;
|
|
50003
|
+
return innerCopperIndex(layer);
|
|
50004
|
+
}
|
|
50005
|
+
function boardCopperLayers(pcb) {
|
|
50006
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50007
|
+
const add = (l) => {
|
|
50008
|
+
if (l && isCopperLayer(l))
|
|
50009
|
+
seen.add(l);
|
|
50010
|
+
};
|
|
50011
|
+
for (const l of pcb?.stackup?.layers ?? [])
|
|
50012
|
+
add(l.layer);
|
|
50013
|
+
for (const t2 of pcb?.traces ?? [])
|
|
50014
|
+
add(t2.layer);
|
|
50015
|
+
for (const z of pcb?.zones ?? [])
|
|
50016
|
+
add(z.layer);
|
|
50017
|
+
for (const v of pcb?.vias ?? []) {
|
|
50018
|
+
add(v.startLayer);
|
|
50019
|
+
add(v.endLayer);
|
|
50020
|
+
}
|
|
50021
|
+
if (seen.size === 0)
|
|
50022
|
+
return ["FCu", "BCu"];
|
|
50023
|
+
return [...seen].sort((a, b) => copperSortKey(a) - copperSortKey(b));
|
|
50024
|
+
}
|
|
50025
|
+
var COPPER_RE;
|
|
50026
|
+
var init_pcb_layers = __esm({
|
|
50027
|
+
"../core/dist/utils/pcb-layers.js"() {
|
|
50028
|
+
"use strict";
|
|
50029
|
+
COPPER_RE = /^(FCu|BCu|In(\d+)Cu)$/;
|
|
50030
|
+
}
|
|
50031
|
+
});
|
|
50032
|
+
|
|
50217
50033
|
// ../core/dist/index.js
|
|
50218
50034
|
var init_dist3 = __esm({
|
|
50219
50035
|
"../core/dist/index.js"() {
|
|
@@ -87135,8 +86951,8 @@ var init_server3 = __esm({
|
|
|
87135
86951
|
init_order_feed();
|
|
87136
86952
|
init_animate();
|
|
87137
86953
|
PKG_VERSION = (() => {
|
|
87138
|
-
if ("0.10.0-main.
|
|
87139
|
-
return "0.10.0-main.
|
|
86954
|
+
if ("0.10.0-main.124") {
|
|
86955
|
+
return "0.10.0-main.124";
|
|
87140
86956
|
}
|
|
87141
86957
|
try {
|
|
87142
86958
|
const req = createRequire2(import.meta.url);
|
|
@@ -87145,8 +86961,8 @@ var init_server3 = __esm({
|
|
|
87145
86961
|
return "0.0.0";
|
|
87146
86962
|
}
|
|
87147
86963
|
})();
|
|
87148
|
-
BUILD_SHA = "
|
|
87149
|
-
BUILD_TIME = "2026-10-
|
|
86964
|
+
BUILD_SHA = "72bb34aea80bd70051717281e832338ab01f1f3d";
|
|
86965
|
+
BUILD_TIME = "2026-10-21T13:06:52.166Z";
|
|
87150
86966
|
SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
|
|
87151
86967
|
VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
|
|
87152
86968
|
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.
|
|
3
|
+
"version": "0.10.0-main.124",
|
|
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": "
|
|
23
|
-
"builtAt": "2026-10-
|
|
22
|
+
"sha": "72bb34aea80bd70051717281e832338ab01f1f3d",
|
|
23
|
+
"builtAt": "2026-10-21T13:06:52.166Z"
|
|
24
24
|
}
|
|
25
25
|
}
|
package/vcad_kernel_wasm_bg.wasm
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/vcad_kernel_wasm_bg.wasm
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 35419240 bytes
|
|
4
|
+
sha256: dd437e1d919dd4a61ab3ba0c9f6fa0f8e01ca3f1b16c592df3b5d4045103b53e
|