@vcad/mcp 0.9.4-main.73 → 0.9.4-main.74

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 c94448044a725e430c38faf507027d5a10b2c68d at 2026-08-17T23:42:23.328Z. Source: https://github.com/ecto/vcad
9
+ Built from cad60a705d41503617de2b556150aaeae3e893c8 at 2026-08-19T15:53:22.260Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -225,6 +225,10 @@ __export(vcad_kernel_wasm_exports, {
225
225
  op_shell: () => op_shell,
226
226
  op_sweep_helix: () => op_sweep_helix,
227
227
  op_sweep_line: () => op_sweep_line,
228
+ parseAltiumAsciiPcb: () => parseAltiumAsciiPcb,
229
+ parseAltiumPcbDoc: () => parseAltiumPcbDoc,
230
+ parseAltiumPcbLib: () => parseAltiumPcbLib,
231
+ parseEagleBrd: () => parseEagleBrd,
228
232
  parseKicadPcb: () => parseKicadPcb,
229
233
  parseVCode: () => parseVCode,
230
234
  parseVcadFile: () => parseVcadFile,
@@ -2443,6 +2447,42 @@ function op_sweep_line(profile_json, start, end, twist_angle, scale_start, scale
2443
2447
  }
2444
2448
  return Solid.__wrap(ret[0]);
2445
2449
  }
2450
+ function parseAltiumAsciiPcb(content) {
2451
+ const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2452
+ const len0 = WASM_VECTOR_LEN;
2453
+ const ret = wasm.parseAltiumAsciiPcb(ptr0, len0);
2454
+ if (ret[2]) {
2455
+ throw takeFromExternrefTable0(ret[1]);
2456
+ }
2457
+ return takeFromExternrefTable0(ret[0]);
2458
+ }
2459
+ function parseAltiumPcbDoc(bytes) {
2460
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
2461
+ const len0 = WASM_VECTOR_LEN;
2462
+ const ret = wasm.parseAltiumPcbDoc(ptr0, len0);
2463
+ if (ret[2]) {
2464
+ throw takeFromExternrefTable0(ret[1]);
2465
+ }
2466
+ return takeFromExternrefTable0(ret[0]);
2467
+ }
2468
+ function parseAltiumPcbLib(bytes) {
2469
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
2470
+ const len0 = WASM_VECTOR_LEN;
2471
+ const ret = wasm.parseAltiumPcbLib(ptr0, len0);
2472
+ if (ret[2]) {
2473
+ throw takeFromExternrefTable0(ret[1]);
2474
+ }
2475
+ return takeFromExternrefTable0(ret[0]);
2476
+ }
2477
+ function parseEagleBrd(content) {
2478
+ const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2479
+ const len0 = WASM_VECTOR_LEN;
2480
+ const ret = wasm.parseEagleBrd(ptr0, len0);
2481
+ if (ret[2]) {
2482
+ throw takeFromExternrefTable0(ret[1]);
2483
+ }
2484
+ return takeFromExternrefTable0(ret[0]);
2485
+ }
2446
2486
  function parseKicadPcb(content) {
2447
2487
  const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2448
2488
  const len0 = WASM_VECTOR_LEN;
@@ -10890,25 +10930,25 @@ function importBindings(wasm3) {
10890
10930
  parseEagleBrd: (content) => bind("parseEagleBrd")(content)
10891
10931
  };
10892
10932
  }
10893
- async function parseEagleBrd(content) {
10933
+ async function parseEagleBrd2(content) {
10894
10934
  const wasm3 = await loadEcadWasm();
10895
10935
  if (!wasm3)
10896
10936
  return null;
10897
10937
  return importBindings(wasm3).parseEagleBrd(content);
10898
10938
  }
10899
- async function parseAltiumAsciiPcb(content) {
10939
+ async function parseAltiumAsciiPcb2(content) {
10900
10940
  const wasm3 = await loadEcadWasm();
10901
10941
  if (!wasm3)
10902
10942
  return null;
10903
10943
  return importBindings(wasm3).parseAltiumAsciiPcb(content);
10904
10944
  }
10905
- async function parseAltiumPcbDoc(bytes) {
10945
+ async function parseAltiumPcbDoc2(bytes) {
10906
10946
  const wasm3 = await loadEcadWasm();
10907
10947
  if (!wasm3)
10908
10948
  return null;
10909
10949
  return importBindings(wasm3).parseAltiumPcbDoc(bytes);
10910
10950
  }
10911
- async function parseAltiumPcbLib(bytes) {
10951
+ async function parseAltiumPcbLib2(bytes) {
10912
10952
  const wasm3 = await loadEcadWasm();
10913
10953
  if (!wasm3)
10914
10954
  return null;
@@ -11759,11 +11799,11 @@ __export(dist_exports, {
11759
11799
  mountingHolesFromPcb: () => mountingHolesFromPcb,
11760
11800
  netContinuity: () => netContinuity,
11761
11801
  outlineAabb: () => outlineAabb,
11762
- parseAltiumAsciiPcb: () => parseAltiumAsciiPcb,
11763
- parseAltiumPcbDoc: () => parseAltiumPcbDoc,
11764
- parseAltiumPcbLib: () => parseAltiumPcbLib,
11802
+ parseAltiumAsciiPcb: () => parseAltiumAsciiPcb2,
11803
+ parseAltiumPcbDoc: () => parseAltiumPcbDoc2,
11804
+ parseAltiumPcbLib: () => parseAltiumPcbLib2,
11765
11805
  parseBindingKey: () => parseBindingKey,
11766
- parseEagleBrd: () => parseEagleBrd,
11806
+ parseEagleBrd: () => parseEagleBrd2,
11767
11807
  parseExpression: () => parse,
11768
11808
  parseKicadPcb: () => parseKicadPcb2,
11769
11809
  parseXyz: () => parseXyz,
@@ -41591,6 +41631,25 @@ var init_CHANGELOG = __esm({
41591
41631
  CHANGELOG_default = {
41592
41632
  $schema: "./changelog.schema.json",
41593
41633
  entries: [
41634
+ {
41635
+ id: "2026-08-19-loon-modules-and-root-cache",
41636
+ version: "0.9.4",
41637
+ date: "2026-08-19",
41638
+ category: "feat",
41639
+ title: "Loon lib path and a content-addressed evaluation cache",
41640
+ summary: "[use] modules resolve next to the file then on $VCAD_LOON_PATH, identically in vcad, vcad-render and MCP; evaluated root meshes are cached on disk keyed by expression + kernel build.",
41641
+ features: [
41642
+ "loon",
41643
+ "modules",
41644
+ "cache",
41645
+ "cli",
41646
+ "render"
41647
+ ],
41648
+ mcpTools: [
41649
+ "load_document",
41650
+ "create_cad_loon"
41651
+ ]
41652
+ },
41594
41653
  {
41595
41654
  id: "2026-08-17-altium-pcb-import",
41596
41655
  version: "0.9.4",
@@ -50177,7 +50236,7 @@ var init_source_provenance = __esm({
50177
50236
 
50178
50237
  // src/tools/loon.ts
50179
50238
  import { readFileSync as readFileSync3 } from "node:fs";
50180
- import { isAbsolute as isAbsolute2, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
50239
+ import { delimiter, isAbsolute as isAbsolute2, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
50181
50240
  function composeLoonProgram(input) {
50182
50241
  const { source, use_loons, loons } = input;
50183
50242
  const names = [
@@ -50208,12 +50267,18 @@ function readModule(base, name) {
50208
50267
  }
50209
50268
  return null;
50210
50269
  }
50270
+ function loonLibDirs(env = process.env) {
50271
+ const raw = env.VCAD_LOON_PATH;
50272
+ if (!raw) return [];
50273
+ return raw.split(delimiter).filter((d) => d.length > 0);
50274
+ }
50211
50275
  function composeLoonModules(input) {
50212
50276
  const { source, loons, modules, base_dir } = input;
50213
50277
  const map = {};
50214
50278
  for (const m of loons ?? []) map[m.name] = m.source;
50215
50279
  Object.assign(map, modules ?? {});
50216
- if (base_dir) {
50280
+ const dirs = [...base_dir ? [base_dir] : [], ...loonLibDirs()];
50281
+ if (dirs.length) {
50217
50282
  const pending2 = [
50218
50283
  ...importedNames(source),
50219
50284
  ...Object.values(map).flatMap(importedNames)
@@ -50223,7 +50288,11 @@ function composeLoonModules(input) {
50223
50288
  const name = pending2.pop();
50224
50289
  if (seen.has(name) || map[name]) continue;
50225
50290
  seen.add(name);
50226
- const src = readModule(base_dir, name);
50291
+ let src = null;
50292
+ for (const dir of dirs) {
50293
+ src = readModule(dir, name);
50294
+ if (src !== null) break;
50295
+ }
50227
50296
  if (src === null) continue;
50228
50297
  map[name] = src;
50229
50298
  pending2.push(...importedNames(src));
@@ -78728,7 +78797,7 @@ async function importAltium(input) {
78728
78797
  const binary = isCompoundFile(bytes);
78729
78798
  let pcb;
78730
78799
  try {
78731
- pcb = binary ? await parseAltiumPcbDoc(new Uint8Array(bytes)) : await parseAltiumAsciiPcb(bytes.toString("utf8"));
78800
+ pcb = binary ? await parseAltiumPcbDoc2(new Uint8Array(bytes)) : await parseAltiumAsciiPcb2(bytes.toString("utf8"));
78732
78801
  } catch (e) {
78733
78802
  return importError(
78734
78803
  `Could not parse the Altium ${binary ? "binary" : "ASCII"} .PcbDoc: ` + (e instanceof Error ? e.message : String(e))
@@ -78769,7 +78838,7 @@ async function importAltiumLibrary(input) {
78769
78838
  }
78770
78839
  let lib;
78771
78840
  try {
78772
- lib = await parseAltiumPcbLib(new Uint8Array(bytes));
78841
+ lib = await parseAltiumPcbLib2(new Uint8Array(bytes));
78773
78842
  } catch (e) {
78774
78843
  return importError(
78775
78844
  `Could not parse the Altium .PcbLib: ${e instanceof Error ? e.message : String(e)}`
@@ -78818,7 +78887,7 @@ async function importEagle(input) {
78818
78887
  }
78819
78888
  let pcb;
78820
78889
  try {
78821
- pcb = await parseEagleBrd(content);
78890
+ pcb = await parseEagleBrd2(content);
78822
78891
  } catch (e) {
78823
78892
  return importError(
78824
78893
  `Could not parse the Eagle .brd: ${e instanceof Error ? e.message : String(e)}`
@@ -83983,8 +84052,8 @@ var init_server3 = __esm({
83983
84052
  init_order_feed();
83984
84053
  init_animate();
83985
84054
  PKG_VERSION = (() => {
83986
- if ("0.9.4-main.73") {
83987
- return "0.9.4-main.73";
84055
+ if ("0.9.4-main.74") {
84056
+ return "0.9.4-main.74";
83988
84057
  }
83989
84058
  try {
83990
84059
  const req = createRequire2(import.meta.url);
@@ -83993,8 +84062,8 @@ var init_server3 = __esm({
83993
84062
  return "0.0.0";
83994
84063
  }
83995
84064
  })();
83996
- BUILD_SHA = "c94448044a725e430c38faf507027d5a10b2c68d";
83997
- BUILD_TIME = "2026-08-17T23:42:23.328Z";
84065
+ BUILD_SHA = "cad60a705d41503617de2b556150aaeae3e893c8";
84066
+ BUILD_TIME = "2026-08-19T15:53:22.260Z";
83998
84067
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
83999
84068
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
84000
84069
  INSTANCE_ID = randomUUID7().slice(0, 8);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcad/mcp",
3
- "version": "0.9.4-main.73",
3
+ "version": "0.9.4-main.74",
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": "c94448044a725e430c38faf507027d5a10b2c68d",
23
- "builtAt": "2026-08-17T23:42:23.328Z"
22
+ "sha": "cad60a705d41503617de2b556150aaeae3e893c8",
23
+ "builtAt": "2026-08-19T15:53:22.260Z"
24
24
  }
25
25
  }
Binary file