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

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 +29 -184
  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 cb926fa0eb538b57dde7e948d6f98ffa3e66b1ee at 2026-10-21T15:04:03.835Z. Source: https://github.com/ecto/vcad
9
+ Built from c0f41c513a664c5cad95f6b53a04977718e67e65 at 2026-10-21T15:14:39.035Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -12304,6 +12304,7 @@ var init_dist = __esm({
12304
12304
  importUrdfBuffer: wasmModule7.importUrdfBuffer,
12305
12305
  importUrdfBufferWithOptions: wasmModule7.importUrdfBufferWithOptions,
12306
12306
  urdfCommentedFloatingJoint: wasmModule7.urdfCommentedFloatingJoint,
12307
+ buildSheetMetalDocument: wasmModule7.buildSheetMetalDocument,
12307
12308
  inlineMeshImports: wasmModule7.inlineMeshImports,
12308
12309
  exportProjectedViewToDxf: wasmModule7.exportProjectedViewToDxf,
12309
12310
  offsetSectionMesh: wasmModule7.offsetSectionMesh,
@@ -12967,6 +12968,17 @@ var init_dist = __esm({
12967
12968
  * a commented-out floating joint means the author expected the simulator
12968
12969
  * to supply the free base.
12969
12970
  */
12971
+ /**
12972
+ * Build a sheet-metal document (base flange + ordered flanges, hems, jogs,
12973
+ * bend relief) from a `sheet_metal_create` request, in the kernel
12974
+ * (`vcad_eval::sheet_build`). Throws on malformed input.
12975
+ */
12976
+ buildSheetMetalDocument(args) {
12977
+ if (typeof this.kernel.buildSheetMetalDocument !== "function") {
12978
+ throw new Error("sheet-metal document builder not available - rebuild the kernel WASM");
12979
+ }
12980
+ return JSON.parse(this.kernel.buildSheetMetalDocument(JSON.stringify(args)));
12981
+ }
12970
12982
  /**
12971
12983
  * Inline STL meshes into `doc` in place: each `MeshImport` node keyed in
12972
12984
  * `meshes` (node id -> STL bytes) becomes an `ImportedMesh` (metres -> mm,
@@ -41508,6 +41520,18 @@ var init_CHANGELOG = __esm({
41508
41520
  "file-io"
41509
41521
  ]
41510
41522
  },
41523
+ {
41524
+ id: "2026-10-21-mac-labs-toggle",
41525
+ version: "0.10.0",
41526
+ date: "2026-10-21",
41527
+ category: "feat",
41528
+ title: "Labs toggle for in-development Mac workspaces",
41529
+ summary: "Electronics, Manufacture (CNC Studio) and simulation in the Mac app now sit behind Settings \u25B8 Labs, off by default, so the default app is Design plus Agent.",
41530
+ features: [
41531
+ "desktop",
41532
+ "settings"
41533
+ ]
41534
+ },
41511
41535
  {
41512
41536
  id: "2026-10-21-mac-exports-photoreal",
41513
41537
  version: "0.10.0",
@@ -79822,154 +79846,6 @@ var init_dfm2 = __esm({
79822
79846
  });
79823
79847
 
79824
79848
  // src/tools/sheet-metal.ts
79825
- function buildSheetMetalDoc(base, flanges, hems, jogs, bendRelief) {
79826
- const doc = createDocument();
79827
- const nodes = {};
79828
- const shopProfile = base.shop_profile !== void 0 ? { shop_profile: base.shop_profile } : {};
79829
- const engravings = base.engravings !== void 0 && base.engravings.length > 0 ? { engravings: base.engravings } : {};
79830
- const baseNode = base.outline !== void 0 ? {
79831
- id: 0,
79832
- name: "Base flange (polygon)",
79833
- op: {
79834
- type: "SheetMetalBaseFlangePolygon",
79835
- outline: base.outline,
79836
- holes: base.holes,
79837
- thickness: base.thickness,
79838
- material: base.material,
79839
- ...shopProfile,
79840
- ...engravings
79841
- }
79842
- } : {
79843
- id: 0,
79844
- name: "Base flange",
79845
- op: {
79846
- type: "SheetMetalBaseFlangeRect",
79847
- width: base.width ?? 0,
79848
- depth: base.depth ?? 0,
79849
- thickness: base.thickness,
79850
- material: base.material,
79851
- ...shopProfile,
79852
- ...engravings
79853
- }
79854
- };
79855
- nodes["0"] = baseNode;
79856
- let parent = 0;
79857
- let nextId3 = 1;
79858
- flanges.forEach((f) => {
79859
- const id = nextId3++;
79860
- nodes[String(id)] = {
79861
- id,
79862
- name: `Edge flange ${id}`,
79863
- op: {
79864
- type: "SheetMetalEdgeFlange",
79865
- parent,
79866
- panel_id: f.panel_id ?? 0,
79867
- edge_index: f.edge_index,
79868
- length: f.length,
79869
- angle: f.angle ?? Math.PI / 2,
79870
- // Omit radius when unspecified — the kernel defaults to thickness,
79871
- // or the shop's fixed radius under a shop profile.
79872
- ...f.radius !== void 0 ? { radius: f.radius } : {},
79873
- direction: f.direction ?? "Up",
79874
- ...f.manual_k !== void 0 ? { manual_k: f.manual_k } : {}
79875
- }
79876
- };
79877
- parent = id;
79878
- });
79879
- hems.forEach((h) => {
79880
- const id = nextId3++;
79881
- nodes[String(id)] = {
79882
- id,
79883
- name: `Hem ${id}`,
79884
- op: {
79885
- type: "SheetMetalHem",
79886
- parent,
79887
- panel_id: h.panel_id ?? 0,
79888
- edge_index: h.edge_index,
79889
- kind: h.kind ?? "Closed",
79890
- length: h.length,
79891
- gap: h.gap ?? 0,
79892
- direction: h.direction ?? "Up"
79893
- }
79894
- };
79895
- parent = id;
79896
- });
79897
- jogs.forEach((j) => {
79898
- const id = nextId3++;
79899
- nodes[String(id)] = {
79900
- id,
79901
- name: `Jog ${id}`,
79902
- op: {
79903
- type: "SheetMetalJog",
79904
- parent,
79905
- panel_id: j.panel_id ?? 0,
79906
- edge_index: j.edge_index,
79907
- offset: j.offset,
79908
- length: j.length,
79909
- ...j.radius !== void 0 ? { radius: j.radius } : {},
79910
- direction: j.direction ?? "Up"
79911
- }
79912
- };
79913
- parent = id;
79914
- });
79915
- if (bendRelief) {
79916
- const id = nextId3++;
79917
- nodes[String(id)] = {
79918
- id,
79919
- name: "Bend relief",
79920
- op: {
79921
- type: "SheetMetalBendRelief",
79922
- parent,
79923
- ...bendRelief.width_mm !== void 0 ? { width: bendRelief.width_mm } : {},
79924
- ...bendRelief.depth_mm !== void 0 ? { depth: bendRelief.depth_mm } : {}
79925
- }
79926
- };
79927
- parent = id;
79928
- }
79929
- doc.nodes = nodes;
79930
- doc.roots = [{ root: parent, material: "default" }];
79931
- return doc;
79932
- }
79933
- function normaliseEngravings(raw) {
79934
- return raw.map((e, i) => {
79935
- const o = e ?? {};
79936
- if (o.type === "Text" || o.type === void 0 && typeof o.text === "string") {
79937
- if (typeof o.text !== "string" || o.text.length === 0) {
79938
- throw new Error(`engravings[${i}]: Text needs a non-empty \`text\``);
79939
- }
79940
- const height = Number(o.height);
79941
- if (!(height > 0)) {
79942
- throw new Error(`engravings[${i}]: Text needs \`height\` > 0 (cap height, mm)`);
79943
- }
79944
- return {
79945
- type: "Text",
79946
- text: o.text,
79947
- x: Number(o.x ?? 0),
79948
- y: Number(o.y ?? 0),
79949
- height,
79950
- angle: Number(o.angle ?? 0)
79951
- };
79952
- }
79953
- if (o.type === "Polyline" || Array.isArray(o.points)) {
79954
- const points = Array.isArray(o.points) ? o.points.map((p) => {
79955
- if (Array.isArray(p) && p.length >= 2)
79956
- return { x: Number(p[0]), y: Number(p[1]) };
79957
- if (p && typeof p === "object" && "x" in p && "y" in p) {
79958
- const q2 = p;
79959
- return { x: Number(q2.x), y: Number(q2.y) };
79960
- }
79961
- return null;
79962
- }).filter((p) => p !== null) : [];
79963
- if (points.length < 2) {
79964
- throw new Error(`engravings[${i}]: Polyline needs >= 2 points`);
79965
- }
79966
- return { type: "Polyline", points };
79967
- }
79968
- throw new Error(
79969
- `engravings[${i}]: expected {type: "Text", text, x, y, height} or {type: "Polyline", points}`
79970
- );
79971
- });
79972
- }
79973
79849
  function renderedOf(engine, doc) {
79974
79850
  const scene = engine.evaluate(doc);
79975
79851
  for (const part of scene.parts) {
@@ -79989,37 +79865,7 @@ function textResult13(payload) {
79989
79865
  };
79990
79866
  }
79991
79867
  function sheetMetalCreate(input, engine) {
79992
- const a = input ?? {};
79993
- const normalisePoint = (p) => {
79994
- if (Array.isArray(p) && p.length >= 2)
79995
- return { x: Number(p[0]), y: Number(p[1]) };
79996
- if (p && typeof p === "object" && "x" in p && "y" in p) {
79997
- const o = p;
79998
- return { x: Number(o.x), y: Number(o.y) };
79999
- }
80000
- return null;
80001
- };
80002
- const normaliseLoop = (loop) => {
80003
- if (!Array.isArray(loop)) return [];
80004
- return loop.map(normalisePoint).filter((p) => p !== null);
80005
- };
80006
- const outline = Array.isArray(a.outline) ? normaliseLoop(a.outline) : void 0;
80007
- const holes = Array.isArray(a.holes) ? a.holes.map(normaliseLoop) : void 0;
80008
- const base = {
80009
- width: Number(a.width),
80010
- depth: Number(a.depth),
80011
- thickness: Number(a.thickness),
80012
- material: typeof a.material === "string" ? a.material : "al-soft",
80013
- outline,
80014
- holes,
80015
- ...typeof a.shop_profile === "string" && a.shop_profile.length > 0 ? { shop_profile: a.shop_profile } : {},
80016
- ...Array.isArray(a.engravings) ? { engravings: normaliseEngravings(a.engravings) } : {}
80017
- };
80018
- const flanges = Array.isArray(a.flanges) ? a.flanges : [];
80019
- const hems = Array.isArray(a.hems) ? a.hems : [];
80020
- const jogs = Array.isArray(a.jogs) ? a.jogs : [];
80021
- const bendRelief = a.bend_relief === true ? {} : a.bend_relief && typeof a.bend_relief === "object" ? a.bend_relief : void 0;
80022
- const doc = buildSheetMetalDoc(base, flanges, hems, jogs, bendRelief);
79868
+ const doc = engine.buildSheetMetalDocument(input ?? {});
80023
79869
  const rendered = renderedOf(engine, doc);
80024
79870
  const documentId = registerSession(doc);
80025
79871
  const errors = rendered.violations.filter(
@@ -80287,7 +80133,6 @@ var sheetMetalCreateSchema, sheetMetalUnfoldSchema, sheetMetalMaterialsSchema, s
80287
80133
  var init_sheet_metal2 = __esm({
80288
80134
  "src/tools/sheet-metal.ts"() {
80289
80135
  "use strict";
80290
- init_dist2();
80291
80136
  init_session2();
80292
80137
  init_tool_def();
80293
80138
  sheetMetalCreateSchema = {
@@ -87005,8 +86850,8 @@ var init_server3 = __esm({
87005
86850
  init_order_feed();
87006
86851
  init_animate();
87007
86852
  PKG_VERSION = (() => {
87008
- if ("0.10.0-main.128") {
87009
- return "0.10.0-main.128";
86853
+ if ("0.10.0-main.129") {
86854
+ return "0.10.0-main.129";
87010
86855
  }
87011
86856
  try {
87012
86857
  const req = createRequire2(import.meta.url);
@@ -87015,8 +86860,8 @@ var init_server3 = __esm({
87015
86860
  return "0.0.0";
87016
86861
  }
87017
86862
  })();
87018
- BUILD_SHA = "cb926fa0eb538b57dde7e948d6f98ffa3e66b1ee";
87019
- BUILD_TIME = "2026-10-21T15:04:03.835Z";
86863
+ BUILD_SHA = "c0f41c513a664c5cad95f6b53a04977718e67e65";
86864
+ BUILD_TIME = "2026-10-21T15:14:39.035Z";
87020
86865
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
87021
86866
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
87022
86867
  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.128",
3
+ "version": "0.10.0-main.129",
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": "cb926fa0eb538b57dde7e948d6f98ffa3e66b1ee",
23
- "builtAt": "2026-10-21T15:04:03.835Z"
22
+ "sha": "c0f41c513a664c5cad95f6b53a04977718e67e65",
23
+ "builtAt": "2026-10-21T15:14:39.035Z"
24
24
  }
25
25
  }