@vcad/mcp 0.10.0-main.126 → 0.10.0-main.128

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 +156 -66
  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 cf7237b3fa4de3ec9ddd2eccbd0f33b802ea1089 at 2026-10-21T14:05:09.525Z. Source: https://github.com/ecto/vcad
9
+ Built from cb926fa0eb538b57dde7e948d6f98ffa3e66b1ee at 2026-10-21T15:04:03.835Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -10798,6 +10798,75 @@ var init_diff = __esm({
10798
10798
  }
10799
10799
  });
10800
10800
 
10801
+ // ../engine/dist/delta.js
10802
+ function stateFromEnvelope(json) {
10803
+ const env = typeof json === "string" ? JSON.parse(json) : json;
10804
+ if (!env.ok || !env.result)
10805
+ throw new EngineRefusal(env.error);
10806
+ return { document: env.result.document, parts: env.result.parts };
10807
+ }
10808
+ function parseDeltaEnvelope(json) {
10809
+ const env = typeof json === "string" ? JSON.parse(json) : json;
10810
+ if (!env.ok || !env.result)
10811
+ throw new EngineRefusal(env.error);
10812
+ return env.result;
10813
+ }
10814
+ function applyDocumentDelta(doc, delta) {
10815
+ const out = { ...doc };
10816
+ for (const key3 of delta.removedFields)
10817
+ delete out[key3];
10818
+ for (const [key3, value] of Object.entries(delta.fields))
10819
+ out[key3] = value;
10820
+ for (const [key3, patch] of Object.entries(delta.maps)) {
10821
+ const prev = out[key3];
10822
+ const map = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...prev } : {};
10823
+ for (const k of patch.remove)
10824
+ delete map[k];
10825
+ for (const [k, v] of Object.entries(patch.set))
10826
+ map[k] = v;
10827
+ out[key3] = map;
10828
+ }
10829
+ return out;
10830
+ }
10831
+ function applyPartsDelta(parts, delta) {
10832
+ const order = delta.order ?? parts.map((p) => p.id);
10833
+ const byId = new Map(parts.map((p) => [p.id, p]));
10834
+ for (const p of [...delta.added, ...delta.updated])
10835
+ byId.set(p.id, p);
10836
+ for (const id of delta.removed)
10837
+ byId.delete(id);
10838
+ return order.flatMap((id) => {
10839
+ const p = byId.get(id);
10840
+ return p ? [p] : [];
10841
+ });
10842
+ }
10843
+ function applyEngineDelta(state, delta) {
10844
+ return {
10845
+ state: {
10846
+ document: applyDocumentDelta(state.document, delta.document),
10847
+ parts: applyPartsDelta(state.parts, delta.parts)
10848
+ },
10849
+ changes: {
10850
+ rebuild: [...delta.parts.added, ...delta.parts.updated].map((p) => p.id),
10851
+ removed: [...delta.parts.removed]
10852
+ }
10853
+ };
10854
+ }
10855
+ var EngineRefusal;
10856
+ var init_delta = __esm({
10857
+ "../engine/dist/delta.js"() {
10858
+ "use strict";
10859
+ EngineRefusal = class extends Error {
10860
+ error;
10861
+ constructor(error2) {
10862
+ super(error2.message);
10863
+ this.error = error2;
10864
+ this.name = "EngineRefusal";
10865
+ }
10866
+ };
10867
+ }
10868
+ });
10869
+
10801
10870
  // ../engine/dist/sequence.js
10802
10871
  function requireWasm2() {
10803
10872
  const mod = getKernelWasmSync();
@@ -11955,6 +12024,7 @@ __export(dist_exports, {
11955
12024
  DEFAULT_SHOP_PROFILE: () => DEFAULT_SHOP_PROFILE,
11956
12025
  DependencyGraph: () => DependencyGraph,
11957
12026
  Engine: () => Engine,
12027
+ EngineRefusal: () => EngineRefusal,
11958
12028
  ExpressionEvalError: () => EvalError,
11959
12029
  ExpressionParseError: () => ParseError,
11960
12030
  MdEnv: () => MdEnv,
@@ -11963,7 +12033,10 @@ __export(dist_exports, {
11963
12033
  SolidCache: () => SolidCache,
11964
12034
  airgapFluxDensity: () => airgapFluxDensity,
11965
12035
  airgapSolve: () => airgapSolve,
12036
+ applyDocumentDelta: () => applyDocumentDelta,
12037
+ applyEngineDelta: () => applyEngineDelta,
11966
12038
  applyForwardKinematics: () => applyForwardKinematics,
12039
+ applyPartsDelta: () => applyPartsDelta,
11967
12040
  buildMoleculeReceipt: () => buildReceipt2,
11968
12041
  buildPartDocument: () => buildPartDocument,
11969
12042
  buildReceipt: () => buildReceipt,
@@ -12033,6 +12106,7 @@ __export(dist_exports, {
12033
12106
  parseAltiumPcbDoc: () => parseAltiumPcbDoc2,
12034
12107
  parseAltiumPcbLib: () => parseAltiumPcbLib2,
12035
12108
  parseBindingKey: () => parseBindingKey,
12109
+ parseDeltaEnvelope: () => parseDeltaEnvelope,
12036
12110
  parseEagleBrd: () => parseEagleBrd2,
12037
12111
  parseExpression: () => parse,
12038
12112
  parseKicadPcb: () => parseKicadPcb2,
@@ -12066,6 +12140,7 @@ __export(dist_exports, {
12066
12140
  semanticDiff: () => semanticDiff,
12067
12141
  solveDesignConstraints: () => solveDesignConstraints2,
12068
12142
  solveForwardKinematics: () => solveForwardKinematics2,
12143
+ stateFromEnvelope: () => stateFromEnvelope,
12069
12144
  threeWayMerge: () => threeWayMerge,
12070
12145
  toWorld: () => toWorld,
12071
12146
  transformMesh: () => transformMesh,
@@ -12092,6 +12167,7 @@ var init_dist = __esm({
12092
12167
  init_gpu();
12093
12168
  init_diff();
12094
12169
  init_solid_cache();
12170
+ init_delta();
12095
12171
  init_mesh_cache();
12096
12172
  init_dependency_graph();
12097
12173
  init_evaluate();
@@ -12220,6 +12296,8 @@ var init_dist = __esm({
12220
12296
  importStepBufferWithReport: wasmModule7.importStepBufferWithReport,
12221
12297
  documentToStepBuffer: wasmModule7.documentToStepBuffer,
12222
12298
  registerStepSource: wasmModule7.registerStepSource,
12299
+ stepImportDocument: wasmModule7.stepImportDocument,
12300
+ importStepMeshDocument: wasmModule7.importStepMeshDocument,
12223
12301
  stepSourceRegistered: wasmModule7.stepSourceRegistered,
12224
12302
  unregisterStepSource: wasmModule7.unregisterStepSource,
12225
12303
  inspectDocumentFaces: wasmModule7.inspectDocumentFaces,
@@ -12774,6 +12852,28 @@ var init_dist = __esm({
12774
12852
  summary: result.summary
12775
12853
  };
12776
12854
  }
12855
+ /**
12856
+ * Build the document for a B-rep STEP import: one lazy `step_import` root
12857
+ * per solid index of the file registered under `path`, named `partName`
12858
+ * (or `partName_N` for several), in `material` (`vcad_eval::step_doc`).
12859
+ */
12860
+ stepImportDocument(path, solidIndices, partName, material) {
12861
+ if (typeof this.kernel.stepImportDocument !== "function") {
12862
+ throw new Error("stepImportDocument is not available - rebuild the kernel WASM");
12863
+ }
12864
+ return JSON.parse(this.kernel.stepImportDocument(path, Uint32Array.from(solidIndices), partName, material));
12865
+ }
12866
+ /**
12867
+ * Tessellated STEP import straight to a document (one `ImportedMesh` root
12868
+ * per body), built in the kernel. Throws when the file has no geometry.
12869
+ */
12870
+ importStepMeshDocument(data, partName, material, source) {
12871
+ if (typeof this.kernel.importStepMeshDocument !== "function") {
12872
+ throw new Error("importStepMeshDocument is not available - rebuild the kernel WASM");
12873
+ }
12874
+ const r = this.kernel.importStepMeshDocument(new Uint8Array(data), partName, material, source);
12875
+ return { ...r, document: JSON.parse(r.document) };
12876
+ }
12777
12877
  /**
12778
12878
  * Register STEP file contents so `step_import` nodes resolve to B-rep.
12779
12879
  *
@@ -41371,6 +41471,19 @@ var init_CHANGELOG = __esm({
41371
41471
  "render"
41372
41472
  ]
41373
41473
  },
41474
+ {
41475
+ id: "2026-10-21-photoreal-focus-dist",
41476
+ version: "0.10.0",
41477
+ date: "2026-10-21",
41478
+ category: "feat",
41479
+ title: "Depth of field controls for photoreal renders",
41480
+ summary: "--focus-dist sets the thin-lens plane of focus in vcad-render; vcad render --photoreal gains --aperture, --focus-dist and --focus-part.",
41481
+ features: [
41482
+ "photoreal",
41483
+ "render",
41484
+ "cli"
41485
+ ]
41486
+ },
41374
41487
  {
41375
41488
  id: "2026-10-21-mac-sim-teardown-race",
41376
41489
  version: "0.10.0",
@@ -41395,6 +41508,20 @@ var init_CHANGELOG = __esm({
41395
41508
  "file-io"
41396
41509
  ]
41397
41510
  },
41511
+ {
41512
+ id: "2026-10-21-mac-exports-photoreal",
41513
+ version: "0.10.0",
41514
+ date: "2026-10-21",
41515
+ category: "feat",
41516
+ title: "Mac app exports STEP and GLB, renders photoreal",
41517
+ summary: "File \u25B8 Export now writes STL, STEP and GLB with the CLI's writers, and File \u25B8 Render Photoreal\u2026 path-traces the current view with progress and cancel, no external binary.",
41518
+ features: [
41519
+ "desktop",
41520
+ "mac",
41521
+ "export",
41522
+ "photoreal"
41523
+ ]
41524
+ },
41398
41525
  {
41399
41526
  id: "2026-10-21-mac-app-updates",
41400
41527
  version: "0.10.0",
@@ -41460,6 +41587,18 @@ var init_CHANGELOG = __esm({
41460
41587
  "ai"
41461
41588
  ]
41462
41589
  },
41590
+ {
41591
+ id: "2026-10-21-agent-nested-create",
41592
+ version: "0.10.0",
41593
+ date: "2026-10-21",
41594
+ category: "fix",
41595
+ title: "Agent accepts nested create calls",
41596
+ summary: "The Agent's create tool now accepts the nested argument shape models naturally emit, and repeat requests reuse the endpoint's prompt cache.",
41597
+ features: [
41598
+ "desktop",
41599
+ "agent"
41600
+ ]
41601
+ },
41463
41602
  {
41464
41603
  id: "2026-10-20-vendor-verified-power-imu-footprints",
41465
41604
  version: "0.10.0",
@@ -81056,30 +81195,6 @@ function readStepInput(input) {
81056
81195
  }
81057
81196
  return { bytes: readFileSync7(filepath), diskPath: resolve5(filepath) };
81058
81197
  }
81059
- function defaultMaterials() {
81060
- return {
81061
- steel: {
81062
- name: "Steel",
81063
- color: [0.6, 0.6, 0.65],
81064
- metallic: 0.9,
81065
- roughness: 0.3,
81066
- density: 7850
81067
- },
81068
- aluminum: {
81069
- name: "Aluminum",
81070
- color: [0.8, 0.8, 0.85],
81071
- metallic: 0.9,
81072
- roughness: 0.2,
81073
- density: 2700
81074
- },
81075
- default: {
81076
- name: "Default",
81077
- color: [0.8, 0.8, 0.8],
81078
- metallic: 0,
81079
- roughness: 0.5
81080
- }
81081
- };
81082
- }
81083
81198
  function skippedFaceSummary(report, warnings) {
81084
81199
  const skipped = report.reduce((sum, s) => sum + s.skipped_faces.length, 0);
81085
81200
  if (skipped === 0) return {};
@@ -81108,36 +81223,18 @@ function importStep(input, engine) {
81108
81223
  /\.(step|stp)$/i.test(sourceLabel) ? sourceLabel.slice(-5) : ""
81109
81224
  );
81110
81225
  const partMaterial = material ?? "steel";
81111
- const doc = createDocument();
81112
- doc.materials = defaultMaterials();
81113
- const addRoot = (nodeId, nodeName, op) => {
81114
- doc.nodes[String(nodeId)] = { id: nodeId, name: nodeName, op };
81115
- doc.roots.push({ root: nodeId, material: partMaterial });
81116
- doc.part_materials[nodeName] = partMaterial;
81117
- };
81226
+ let doc;
81118
81227
  let summary;
81119
81228
  if (as_mesh) {
81120
- const { meshes, report, summary: importWarnings } = engine.importStepWithReport(arrayBuffer);
81121
- if (meshes.length === 0) {
81122
- throw new Error("No geometry found in STEP file");
81123
- }
81124
- meshes.forEach((mesh, i) => {
81125
- const op = {
81126
- type: "ImportedMesh",
81127
- positions: Array.from(mesh.positions),
81128
- indices: Array.from(mesh.indices),
81129
- normals: mesh.normals ? Array.from(mesh.normals) : void 0,
81130
- source: sourceLabel
81131
- };
81132
- addRoot(i + 1, meshes.length === 1 ? partName : `${partName}_${i + 1}`, op);
81133
- });
81229
+ const imported = engine.importStepMeshDocument(arrayBuffer, partName, partMaterial, sourceLabel);
81230
+ doc = imported.document;
81134
81231
  summary = {
81135
81232
  representation: "mesh",
81136
- bodies: meshes.length,
81137
- total_triangles: meshes.reduce((sum, m) => sum + m.indices.length / 3, 0),
81138
- total_vertices: meshes.reduce((sum, m) => sum + m.positions.length / 3, 0),
81233
+ bodies: imported.bodies,
81234
+ total_triangles: imported.triangles,
81235
+ total_vertices: imported.vertices,
81139
81236
  note: "Imported as triangle meshes: no analytic faces, and these parts cannot be exported to STEP. Drop `as_mesh` for a B-rep import.",
81140
- ...skippedFaceSummary(report, importWarnings)
81237
+ ...skippedFaceSummary(imported.report, imported.summary)
81141
81238
  };
81142
81239
  } else {
81143
81240
  const label = basename(sourceLabel).replace(/[^\w.-]/g, "_") || "import.step";
@@ -81151,18 +81248,12 @@ function importStep(input, engine) {
81151
81248
  if (registered.solids.length === 0) {
81152
81249
  throw new Error("No geometry found in STEP file");
81153
81250
  }
81154
- registered.solids.forEach((solid, i) => {
81155
- const op = {
81156
- type: "step_import",
81157
- path,
81158
- ...solid.index === 0 ? {} : { solid_index: solid.index }
81159
- };
81160
- addRoot(
81161
- i + 1,
81162
- registered.solids.length === 1 ? partName : `${partName}_${i + 1}`,
81163
- op
81164
- );
81165
- });
81251
+ doc = engine.stepImportDocument(
81252
+ path,
81253
+ registered.solids.map((solid) => solid.index),
81254
+ partName,
81255
+ partMaterial
81256
+ );
81166
81257
  const meshOnly = registered.solids.filter((s) => s.faces === 0);
81167
81258
  summary = {
81168
81259
  representation: "brep",
@@ -81228,7 +81319,6 @@ var MAX_STEP_BYTES, STEP_CACHE_DIR, importStepSchema, toolDefs46;
81228
81319
  var init_import = __esm({
81229
81320
  "src/tools/import.ts"() {
81230
81321
  "use strict";
81231
- init_dist2();
81232
81322
  init_safe_path();
81233
81323
  init_remote();
81234
81324
  init_artifact_store();
@@ -86915,8 +87005,8 @@ var init_server3 = __esm({
86915
87005
  init_order_feed();
86916
87006
  init_animate();
86917
87007
  PKG_VERSION = (() => {
86918
- if ("0.10.0-main.126") {
86919
- return "0.10.0-main.126";
87008
+ if ("0.10.0-main.128") {
87009
+ return "0.10.0-main.128";
86920
87010
  }
86921
87011
  try {
86922
87012
  const req = createRequire2(import.meta.url);
@@ -86925,8 +87015,8 @@ var init_server3 = __esm({
86925
87015
  return "0.0.0";
86926
87016
  }
86927
87017
  })();
86928
- BUILD_SHA = "cf7237b3fa4de3ec9ddd2eccbd0f33b802ea1089";
86929
- BUILD_TIME = "2026-10-21T14:05:09.525Z";
87018
+ BUILD_SHA = "cb926fa0eb538b57dde7e948d6f98ffa3e66b1ee";
87019
+ BUILD_TIME = "2026-10-21T15:04:03.835Z";
86930
87020
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
86931
87021
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
86932
87022
  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.126",
3
+ "version": "0.10.0-main.128",
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": "cf7237b3fa4de3ec9ddd2eccbd0f33b802ea1089",
23
- "builtAt": "2026-10-21T14:05:09.525Z"
22
+ "sha": "cb926fa0eb538b57dde7e948d6f98ffa3e66b1ee",
23
+ "builtAt": "2026-10-21T15:04:03.835Z"
24
24
  }
25
25
  }