@vcad/mcp 0.10.0-main.134 → 0.10.0-main.136

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/index.mjs +124 -16
  3. package/package.json +3 -3
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 50d4e0c1c282745ef88e456dca033ceabdee9c31 at 2026-10-21T17:58:04.042Z. Source: https://github.com/ecto/vcad
9
+ Built from ef69b02e150910dd0991d12581df3a5056928986 at 2026-10-22T11:56:53.248Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -10867,18 +10867,95 @@ var init_delta = __esm({
10867
10867
  }
10868
10868
  });
10869
10869
 
10870
+ // ../engine/dist/scene-convert.js
10871
+ function wasmResultToScene(result) {
10872
+ const toMesh = (m) => ({
10873
+ positions: m.positions instanceof Float32Array ? m.positions : new Float32Array(m.positions),
10874
+ indices: m.indices instanceof Uint32Array ? m.indices : new Uint32Array(m.indices),
10875
+ normals: m.normals ? m.normals instanceof Float32Array ? m.normals : new Float32Array(m.normals) : void 0,
10876
+ faceKinds: m.faceKinds ? m.faceKinds instanceof Uint8Array ? m.faceKinds : new Uint8Array(m.faceKinds) : void 0
10877
+ });
10878
+ return {
10879
+ parts: result.parts.map((p) => ({ mesh: toMesh(p.mesh), material: p.material })),
10880
+ partDefs: result.partDefs?.map((pd) => ({ id: pd.id, mesh: toMesh(pd.mesh) })),
10881
+ instances: result.instances?.map((inst) => ({
10882
+ instanceId: inst.instance_id,
10883
+ partDefId: inst.part_def_id,
10884
+ name: inst.name,
10885
+ mesh: toMesh(inst.mesh),
10886
+ material: inst.material,
10887
+ transform: inst.transform
10888
+ })),
10889
+ clashes: result.clashes.map(toMesh),
10890
+ failures: result.failures,
10891
+ timing: result.timing
10892
+ };
10893
+ }
10894
+ function postProcessEmbroidery(scene, doc, kernel2) {
10895
+ const visibleRoots = doc.roots.filter((e) => e.visible !== false);
10896
+ let changed = false;
10897
+ const parts = scene.parts.map((p, i) => {
10898
+ if (p.mesh.positions.length === 0 && i < visibleRoots.length) {
10899
+ const emb = findEmbroideryPattern(visibleRoots[i].root, doc.nodes);
10900
+ if (emb) {
10901
+ changed = true;
10902
+ const baseMesh = embroideryPatternToMeshWithKernel(emb.pattern, kernel2);
10903
+ const mesh = transformMeshWithKernel(baseMesh, emb.transform, kernel2);
10904
+ return { mesh, material: p.material };
10905
+ }
10906
+ }
10907
+ return p;
10908
+ });
10909
+ return changed ? { ...scene, parts } : scene;
10910
+ }
10911
+ function postProcessSheetMetal(scene, doc, kernel2) {
10912
+ const visibleRoots = doc.roots.filter((e) => e.visible !== false);
10913
+ let changed = false;
10914
+ const parts = scene.parts.map((p, i) => {
10915
+ if (p.mesh.positions.length === 0 && i < visibleRoots.length) {
10916
+ try {
10917
+ const smPart = resolveSheetMetalPart(visibleRoots[i].root, doc.nodes, kernel2);
10918
+ if (smPart) {
10919
+ changed = true;
10920
+ return { ...smPart, material: p.material };
10921
+ }
10922
+ } catch (e) {
10923
+ console.warn(`[worker] sheet-metal eval failed at root[${i}]:`, e);
10924
+ }
10925
+ }
10926
+ return p;
10927
+ });
10928
+ return changed ? { ...scene, parts } : scene;
10929
+ }
10930
+ function postProcessScene(scene, doc, kernel2) {
10931
+ return postProcessSheetMetal(postProcessEmbroidery(scene, doc, kernel2), doc, kernel2);
10932
+ }
10933
+ var init_scene_convert = __esm({
10934
+ "../engine/dist/scene-convert.js"() {
10935
+ "use strict";
10936
+ init_evaluate();
10937
+ }
10938
+ });
10939
+
10870
10940
  // ../engine/dist/engine-host.js
10941
+ function resetEvaluator(host) {
10942
+ host.evaluator?.free?.();
10943
+ host.evaluator = null;
10944
+ }
10871
10945
  function handleEngineRequest(host, req) {
10872
10946
  try {
10873
10947
  let envelope;
10874
10948
  let bytes;
10949
+ let scene;
10875
10950
  switch (req.op) {
10876
10951
  case "init":
10952
+ resetEvaluator(host);
10877
10953
  host.engine?.free();
10878
10954
  host.engine = req.replica !== void 0 && host.Engine.withReplica ? host.Engine.withReplica(req.replica) : new host.Engine();
10879
10955
  envelope = host.engine.stateEnvelope();
10880
10956
  break;
10881
10957
  case "load":
10958
+ resetEvaluator(host);
10882
10959
  host.engine?.free();
10883
10960
  host.engine = host.Engine.load(req.bytes);
10884
10961
  envelope = host.engine.stateEnvelope();
@@ -10902,7 +10979,15 @@ function handleEngineRequest(host, req) {
10902
10979
  envelope = engine2.applyToolDelta(req.tool, JSON.stringify(req.args));
10903
10980
  else if (req.op === "state")
10904
10981
  envelope = engine2.stateEnvelope();
10905
- else
10982
+ else if (req.op === "evaluate") {
10983
+ if (!engine2.evaluateIncremental || !host.Evaluator) {
10984
+ return { ok: false, message: "engine host cannot evaluate (kernel too old)" };
10985
+ }
10986
+ host.evaluator ??= new host.Evaluator();
10987
+ const overlay = req.overlay ?? {};
10988
+ const hasOverlay = Object.keys(overlay.parameters ?? {}).length > 0 || Object.keys(overlay.bindings ?? {}).length > 0;
10989
+ scene = wasmResultToScene(engine2.evaluateIncremental(host.evaluator, hasOverlay ? JSON.stringify(overlay) : "", req.skipClashDetection ?? false));
10990
+ } else
10906
10991
  bytes = engine2.save();
10907
10992
  }
10908
10993
  }
@@ -10911,6 +10996,7 @@ function handleEngineRequest(host, req) {
10911
10996
  ok: true,
10912
10997
  envelope,
10913
10998
  bytes,
10999
+ scene,
10914
11000
  hash: engine.stateHash(),
10915
11001
  canUndo: engine.can_undo(),
10916
11002
  canRedo: engine.can_redo()
@@ -10919,27 +11005,29 @@ function handleEngineRequest(host, req) {
10919
11005
  return { ok: false, message: e instanceof Error ? e.message : String(e) };
10920
11006
  }
10921
11007
  }
10922
- function inProcessTransport(Engine2) {
10923
- const host = { Engine: Engine2, engine: null };
11008
+ function inProcessTransport(Engine2, Evaluator) {
11009
+ const host = { Engine: Engine2, engine: null, Evaluator };
10924
11010
  return {
10925
11011
  request: async (req) => handleEngineRequest(host, req),
10926
11012
  dispose: () => {
11013
+ resetEvaluator(host);
10927
11014
  host.engine?.free();
10928
11015
  host.engine = null;
10929
11016
  }
10930
11017
  };
10931
11018
  }
10932
- function sharedEngineTransport(getEngine) {
11019
+ function sharedEngineTransport(getEngine, Evaluator) {
10933
11020
  const ownerOnly = function() {
10934
11021
  throw new Error("shared engine: the owner constructs engines");
10935
11022
  };
11023
+ const host = { Engine: ownerOnly, engine: null, Evaluator };
10936
11024
  return {
10937
11025
  request: async (req) => {
10938
- const host = { Engine: ownerOnly, engine: getEngine() };
11026
+ host.engine = getEngine();
10939
11027
  const r = req.op === "init" || req.op === "load" ? { op: "state" } : req;
10940
11028
  return handleEngineRequest(host, r);
10941
11029
  },
10942
- dispose: () => void 0
11030
+ dispose: () => resetEvaluator(host)
10943
11031
  };
10944
11032
  }
10945
11033
  function workerTransport(worker) {
@@ -10964,6 +11052,7 @@ var init_engine_host = __esm({
10964
11052
  "../engine/dist/engine-host.js"() {
10965
11053
  "use strict";
10966
11054
  init_delta();
11055
+ init_scene_convert();
10967
11056
  EngineHostError = class extends Error {
10968
11057
  constructor(message) {
10969
11058
  super(message);
@@ -11011,6 +11100,25 @@ var init_engine_host = __esm({
11011
11100
  applyTool(tool, args) {
11012
11101
  return this.delta({ op: "applyTool", tool, args });
11013
11102
  }
11103
+ /**
11104
+ * Evaluate the hosted document where it lives (the worker, when the
11105
+ * engine is in one) through the host's incremental evaluator: the
11106
+ * document is never serialized and only what changed since the last
11107
+ * evaluation is redone. Ordered after every command already sent, so the
11108
+ * scene is of the state those commands produced. Pass `kernel` to run the
11109
+ * TS post-passes (embroidery, sheet metal) against this client's view.
11110
+ */
11111
+ evaluate(opts = {}) {
11112
+ return this.enqueue(async () => {
11113
+ const r = this.check(await this.transport.request({
11114
+ op: "evaluate",
11115
+ overlay: opts.overlay,
11116
+ skipClashDetection: opts.skipClashDetection
11117
+ }));
11118
+ const scene = r.scene;
11119
+ return opts.kernel && this.view ? postProcessScene(scene, this.view.document, opts.kernel) : scene;
11120
+ });
11121
+ }
11014
11122
  /** Snapshot the engine (document + history). */
11015
11123
  save() {
11016
11124
  return this.enqueue(async () => {
@@ -29673,10 +29781,10 @@ var init_types3 = __esm({
29673
29781
  }
29674
29782
  });
29675
29783
 
29676
- // ../../node_modules/zustand/esm/vanilla.mjs
29784
+ // ../core/node_modules/zustand/esm/vanilla.mjs
29677
29785
  var createStoreImpl, createStore;
29678
29786
  var init_vanilla = __esm({
29679
- "../../node_modules/zustand/esm/vanilla.mjs"() {
29787
+ "../core/node_modules/zustand/esm/vanilla.mjs"() {
29680
29788
  createStoreImpl = (createState) => {
29681
29789
  let state;
29682
29790
  const listeners = /* @__PURE__ */ new Set();
@@ -31127,7 +31235,7 @@ var require_react = __commonJS({
31127
31235
  }
31128
31236
  });
31129
31237
 
31130
- // ../../node_modules/zustand/esm/react.mjs
31238
+ // ../core/node_modules/zustand/esm/react.mjs
31131
31239
  function useStore(api, selector = identity) {
31132
31240
  const slice = import_react.default.useSyncExternalStore(
31133
31241
  api.subscribe,
@@ -31139,7 +31247,7 @@ function useStore(api, selector = identity) {
31139
31247
  }
31140
31248
  var import_react, identity, createImpl, create;
31141
31249
  var init_react = __esm({
31142
- "../../node_modules/zustand/esm/react.mjs"() {
31250
+ "../core/node_modules/zustand/esm/react.mjs"() {
31143
31251
  import_react = __toESM(require_react(), 1);
31144
31252
  init_vanilla();
31145
31253
  identity = (arg) => arg;
@@ -31153,9 +31261,9 @@ var init_react = __esm({
31153
31261
  }
31154
31262
  });
31155
31263
 
31156
- // ../../node_modules/zustand/esm/index.mjs
31264
+ // ../core/node_modules/zustand/esm/index.mjs
31157
31265
  var init_esm2 = __esm({
31158
- "../../node_modules/zustand/esm/index.mjs"() {
31266
+ "../core/node_modules/zustand/esm/index.mjs"() {
31159
31267
  init_vanilla();
31160
31268
  init_react();
31161
31269
  }
@@ -87171,8 +87279,8 @@ var init_server3 = __esm({
87171
87279
  init_order_feed();
87172
87280
  init_animate();
87173
87281
  PKG_VERSION = (() => {
87174
- if ("0.10.0-main.134") {
87175
- return "0.10.0-main.134";
87282
+ if ("0.10.0-main.136") {
87283
+ return "0.10.0-main.136";
87176
87284
  }
87177
87285
  try {
87178
87286
  const req = createRequire2(import.meta.url);
@@ -87181,8 +87289,8 @@ var init_server3 = __esm({
87181
87289
  return "0.0.0";
87182
87290
  }
87183
87291
  })();
87184
- BUILD_SHA = "50d4e0c1c282745ef88e456dca033ceabdee9c31";
87185
- BUILD_TIME = "2026-10-21T17:58:04.042Z";
87292
+ BUILD_SHA = "ef69b02e150910dd0991d12581df3a5056928986";
87293
+ BUILD_TIME = "2026-10-22T11:56:53.248Z";
87186
87294
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
87187
87295
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
87188
87296
  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.134",
3
+ "version": "0.10.0-main.136",
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": "50d4e0c1c282745ef88e456dca033ceabdee9c31",
23
- "builtAt": "2026-10-21T17:58:04.042Z"
22
+ "sha": "ef69b02e150910dd0991d12581df3a5056928986",
23
+ "builtAt": "2026-10-22T11:56:53.248Z"
24
24
  }
25
25
  }