@vcad/mcp 0.10.0-main.130 → 0.10.0-main.132

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 +275 -90
  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 86e01dfe3474a2c82f179c81edd92f1efa97340b at 2026-10-21T16:21:11.937Z. Source: https://github.com/ecto/vcad
9
+ Built from 362c46b798588ed58f200c9d529b3d11b2b2ff73 at 2026-10-21T17:31:51.205Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -10867,6 +10867,173 @@ var init_delta = __esm({
10867
10867
  }
10868
10868
  });
10869
10869
 
10870
+ // ../engine/dist/engine-host.js
10871
+ function handleEngineRequest(host, req) {
10872
+ try {
10873
+ let envelope;
10874
+ let bytes;
10875
+ switch (req.op) {
10876
+ case "init":
10877
+ host.engine?.free();
10878
+ host.engine = req.replica !== void 0 && host.Engine.withReplica ? host.Engine.withReplica(req.replica) : new host.Engine();
10879
+ envelope = host.engine.stateEnvelope();
10880
+ break;
10881
+ case "load":
10882
+ host.engine?.free();
10883
+ host.engine = host.Engine.load(req.bytes);
10884
+ envelope = host.engine.stateEnvelope();
10885
+ break;
10886
+ default: {
10887
+ const engine2 = host.engine;
10888
+ if (!engine2)
10889
+ return { ok: false, message: "engine not initialized" };
10890
+ if (req.op === "apply")
10891
+ envelope = engine2.applyDelta(JSON.stringify(req.command));
10892
+ else if (req.op === "applyTool")
10893
+ envelope = engine2.applyToolDelta(req.tool, JSON.stringify(req.args));
10894
+ else if (req.op === "state")
10895
+ envelope = engine2.stateEnvelope();
10896
+ else
10897
+ bytes = engine2.save();
10898
+ }
10899
+ }
10900
+ const engine = host.engine;
10901
+ return {
10902
+ ok: true,
10903
+ envelope,
10904
+ bytes,
10905
+ hash: engine.stateHash(),
10906
+ canUndo: engine.can_undo(),
10907
+ canRedo: engine.can_redo()
10908
+ };
10909
+ } catch (e) {
10910
+ return { ok: false, message: e instanceof Error ? e.message : String(e) };
10911
+ }
10912
+ }
10913
+ function inProcessTransport(Engine2) {
10914
+ const host = { Engine: Engine2, engine: null };
10915
+ return {
10916
+ request: async (req) => handleEngineRequest(host, req),
10917
+ dispose: () => {
10918
+ host.engine?.free();
10919
+ host.engine = null;
10920
+ }
10921
+ };
10922
+ }
10923
+ function workerTransport(worker) {
10924
+ let next = 0;
10925
+ const pending2 = /* @__PURE__ */ new Map();
10926
+ worker.addEventListener("message", (e) => {
10927
+ const { id, response } = e.data;
10928
+ pending2.get(id)?.(response);
10929
+ pending2.delete(id);
10930
+ });
10931
+ return {
10932
+ request: (req) => new Promise((resolve7) => {
10933
+ const id = next++;
10934
+ pending2.set(id, resolve7);
10935
+ worker.postMessage({ id, req });
10936
+ }),
10937
+ dispose: () => worker.terminate()
10938
+ };
10939
+ }
10940
+ var EngineHostError, DocumentEngineClient;
10941
+ var init_engine_host = __esm({
10942
+ "../engine/dist/engine-host.js"() {
10943
+ "use strict";
10944
+ init_delta();
10945
+ EngineHostError = class extends Error {
10946
+ constructor(message) {
10947
+ super(message);
10948
+ this.name = "EngineHostError";
10949
+ }
10950
+ };
10951
+ DocumentEngineClient = class {
10952
+ transport;
10953
+ view = null;
10954
+ queue = Promise.resolve();
10955
+ flags = { hash: "", canUndo: false, canRedo: false };
10956
+ constructor(transport) {
10957
+ this.transport = transport;
10958
+ }
10959
+ /** The current view (null before `init`/`load`). */
10960
+ get state() {
10961
+ return this.view;
10962
+ }
10963
+ get stateHash() {
10964
+ return this.flags.hash;
10965
+ }
10966
+ get canUndo() {
10967
+ return this.flags.canUndo;
10968
+ }
10969
+ get canRedo() {
10970
+ return this.flags.canRedo;
10971
+ }
10972
+ /** Start an empty document. */
10973
+ init(replica) {
10974
+ return this.full({ op: "init", replica });
10975
+ }
10976
+ /** Restore a `save()` snapshot. */
10977
+ load(bytes) {
10978
+ return this.full({ op: "load", bytes });
10979
+ }
10980
+ /** Re-read the whole state (resynchronizes the view). */
10981
+ refresh() {
10982
+ return this.full({ op: "state" });
10983
+ }
10984
+ /** Apply a command; rejects with `EngineRefusal` when the engine refuses. */
10985
+ apply(command) {
10986
+ return this.delta({ op: "apply", command });
10987
+ }
10988
+ /** Lower and apply an AI tool call. */
10989
+ applyTool(tool, args) {
10990
+ return this.delta({ op: "applyTool", tool, args });
10991
+ }
10992
+ /** Snapshot the engine (document + history). */
10993
+ save() {
10994
+ return this.enqueue(async () => {
10995
+ const r = this.check(await this.transport.request({ op: "save" }));
10996
+ return r.bytes ?? new Uint8Array();
10997
+ });
10998
+ }
10999
+ dispose() {
11000
+ this.transport.dispose();
11001
+ this.view = null;
11002
+ }
11003
+ full(req) {
11004
+ return this.enqueue(async () => {
11005
+ const r = this.check(await this.transport.request(req));
11006
+ this.view = stateFromEnvelope(r.envelope);
11007
+ return this.view;
11008
+ });
11009
+ }
11010
+ delta(req) {
11011
+ return this.enqueue(async () => {
11012
+ const base = this.view;
11013
+ if (!base)
11014
+ throw new EngineHostError("engine not initialized");
11015
+ const r = this.check(await this.transport.request(req));
11016
+ const delta = parseDeltaEnvelope(r.envelope);
11017
+ const { state, changes } = applyEngineDelta(base, delta);
11018
+ this.view = state;
11019
+ return { state, changes, createdFeatureId: delta.createdFeatureId, warnings: delta.warnings };
11020
+ });
11021
+ }
11022
+ check(r) {
11023
+ if (!r.ok)
11024
+ throw new EngineHostError(r.message);
11025
+ this.flags = { hash: r.hash, canUndo: r.canUndo, canRedo: r.canRedo };
11026
+ return r;
11027
+ }
11028
+ enqueue(f) {
11029
+ const run = this.queue.then(f, f);
11030
+ this.queue = run.catch(() => void 0);
11031
+ return run;
11032
+ }
11033
+ };
11034
+ }
11035
+ });
11036
+
10870
11037
  // ../engine/dist/sequence.js
10871
11038
  function requireWasm2() {
10872
11039
  const mod = getKernelWasmSync();
@@ -12023,7 +12190,9 @@ __export(dist_exports, {
12023
12190
  DEFAULT_NESTING_PARAMS: () => DEFAULT_NESTING_PARAMS,
12024
12191
  DEFAULT_SHOP_PROFILE: () => DEFAULT_SHOP_PROFILE,
12025
12192
  DependencyGraph: () => DependencyGraph,
12193
+ DocumentEngineClient: () => DocumentEngineClient,
12026
12194
  Engine: () => Engine,
12195
+ EngineHostError: () => EngineHostError,
12027
12196
  EngineRefusal: () => EngineRefusal,
12028
12197
  ExpressionEvalError: () => EvalError,
12029
12198
  ExpressionParseError: () => ParseError,
@@ -12055,6 +12224,7 @@ __export(dist_exports, {
12055
12224
  computeRatsnest: () => computeRatsnest,
12056
12225
  connectorsFromPcb: () => connectorsFromPcb,
12057
12226
  createCircuitSim: () => createCircuitSim,
12227
+ createEngineWorker: () => createEngineWorker,
12058
12228
  critiqueRoute: () => critiqueRoute,
12059
12229
  decimateMeshGpu: () => decimateMeshGpu2,
12060
12230
  defaultParamsFor: () => defaultParamsFor,
@@ -12081,8 +12251,10 @@ __export(dist_exports, {
12081
12251
  getKernelWasmSync: () => getKernelWasmSync,
12082
12252
  getPcbDfmPack: () => getPcbDfmPack,
12083
12253
  getRayTracer: () => getRayTracer,
12254
+ handleEngineRequest: () => handleEngineRequest,
12084
12255
  hashCsgOp: () => hashCsgOp,
12085
12256
  homogenizeMaterial: () => homogenizeMaterial,
12257
+ inProcessTransport: () => inProcessTransport,
12086
12258
  initializeGpu: () => initializeGpu,
12087
12259
  initializeRayTracer: () => initializeRayTracer,
12088
12260
  inspectMolecule: () => inspectMolecule,
@@ -12150,8 +12322,12 @@ __export(dist_exports, {
12150
12322
  tryRunDrc: () => tryRunDrc,
12151
12323
  verifyReceipt: () => verifyReceipt,
12152
12324
  verifySubstitution: () => verifySubstitution,
12325
+ workerTransport: () => workerTransport,
12153
12326
  writeXyz: () => writeXyz
12154
12327
  });
12328
+ function createEngineWorker() {
12329
+ return new Worker(new URL("./engine-worker.js", import.meta.url), { type: "module" });
12330
+ }
12155
12331
  var SCENE_CACHE_MAX, Engine;
12156
12332
  var init_dist = __esm({
12157
12333
  "../engine/dist/index.js"() {
@@ -12168,6 +12344,7 @@ var init_dist = __esm({
12168
12344
  init_diff();
12169
12345
  init_solid_cache();
12170
12346
  init_delta();
12347
+ init_engine_host();
12171
12348
  init_mesh_cache();
12172
12349
  init_dependency_graph();
12173
12350
  init_evaluate();
@@ -12315,6 +12492,7 @@ var init_dist = __esm({
12315
12492
  evaluateDocument: wasmModule7.evaluateDocument,
12316
12493
  evalVcadSource: wasmModule7.evalVcadSource,
12317
12494
  evalVcadSourceWithModules: wasmModule7.evalVcadSourceWithModules,
12495
+ evalLoonDocument: wasmModule7.evalLoonDocument,
12318
12496
  evalVcadSourceParametric: wasmModule7.evalVcadSourceParametric,
12319
12497
  documentParameterGradient: wasmModule7.documentParameterGradient,
12320
12498
  documentSensitivities: wasmModule7.documentSensitivities,
@@ -13217,6 +13395,22 @@ var init_dist = __esm({
13217
13395
  * With an empty map this is exactly {@link evalVcadSource}. Returns null
13218
13396
  * if the kernel doesn't support module-aware loon evaluation.
13219
13397
  */
13398
+ /**
13399
+ * Evaluate loon source to a session document stamped with its provenance
13400
+ * (`doc.source`: program, modules, origin dir/file, SHA-256), in the kernel.
13401
+ * Null on kernels predating the export.
13402
+ */
13403
+ evalLoonDocument(source, modules, origin = {}) {
13404
+ if (typeof this.kernel.evalLoonDocument !== "function")
13405
+ return null;
13406
+ const doc = JSON.parse(this.kernel.evalLoonDocument(source, JSON.stringify(modules), origin.baseDir, origin.path));
13407
+ if (doc.source) {
13408
+ doc.source.diverged ??= false;
13409
+ doc.source.diverged_by ??= [];
13410
+ doc.source.modules ??= {};
13411
+ }
13412
+ return doc;
13413
+ }
13220
13414
  evalVcadSourceWithModules(source, modules) {
13221
13415
  if (!Object.keys(modules).length)
13222
13416
  return this.evalVcadSource(source);
@@ -41509,6 +41703,18 @@ var init_CHANGELOG = __esm({
41509
41703
  "cli"
41510
41704
  ]
41511
41705
  },
41706
+ {
41707
+ id: "2026-10-21-photoreal-cyclorama",
41708
+ version: "0.10.0",
41709
+ date: "2026-10-21",
41710
+ category: "feat",
41711
+ title: "Seamless cyclorama backdrop for photoreal renders",
41712
+ summary: "--backdrop cyclorama (vcad render --cyclorama) puts the subject on a matte floor that curves into a back wall, with no horizon line or edge in frame.",
41713
+ features: [
41714
+ "photoreal",
41715
+ "render"
41716
+ ]
41717
+ },
41512
41718
  {
41513
41719
  id: "2026-10-21-mac-sim-teardown-race",
41514
41720
  version: "0.10.0",
@@ -51528,79 +51734,8 @@ var init_loon_assets = __esm({
51528
51734
  }
51529
51735
  });
51530
51736
 
51531
- // src/tools/source-provenance.ts
51532
- import { createHash } from "node:crypto";
51533
- import { readFileSync as readFileSync3 } from "node:fs";
51534
- function sourceHash(text) {
51535
- return createHash("sha256").update(text, "utf8").digest("hex");
51536
- }
51537
- function attachLoonSource(doc, { text, modules, base_dir, path }) {
51538
- const source = {
51539
- language: "loon",
51540
- text,
51541
- modules: modules && Object.keys(modules).length ? { ...modules } : {},
51542
- hash: sourceHash(text),
51543
- diverged: false,
51544
- diverged_by: []
51545
- };
51546
- if (base_dir) source.base_dir = base_dir;
51547
- if (path) source.path = path;
51548
- doc.source = source;
51549
- }
51550
- function markSourceDiverged(documentId, tool) {
51551
- const src = documents.get(documentId)?.source;
51552
- if (!src) return false;
51553
- const firstTime = !src.diverged;
51554
- src.diverged = true;
51555
- const by = src.diverged_by ??= [];
51556
- if (by[by.length - 1] !== tool) by.push(tool);
51557
- if (by.length > MAX_DIVERGED_BY) by.splice(0, by.length - MAX_DIVERGED_BY);
51558
- return firstTime;
51559
- }
51560
- function sourceStatus(doc) {
51561
- const src = doc?.source;
51562
- if (!src) return { source_stale: false };
51563
- const path = src.path;
51564
- if (path) {
51565
- let onDisk = null;
51566
- try {
51567
- onDisk = readFileSync3(path, "utf8");
51568
- } catch {
51569
- return {
51570
- source_stale: true,
51571
- source_path: path,
51572
- reason: `The source file ${path} can no longer be read \u2014 this session is no longer backed by the file it was loaded from.`
51573
- };
51574
- }
51575
- if (sourceHash(onDisk) !== src.hash) {
51576
- return {
51577
- source_stale: true,
51578
- source_path: path,
51579
- reason: `${path} changed on disk since this session was evaluated from it \u2014 the session's geometry is from the OLD source. Re-load the file to pick up the edits.`
51580
- };
51581
- }
51582
- }
51583
- if (src.diverged) {
51584
- const by = src.diverged_by ?? [];
51585
- return {
51586
- source_stale: true,
51587
- ...path ? { source_path: path } : {},
51588
- reason: `This session has been edited directly (${by.join(", ") || "mutation"}), and those edits cannot round-trip back to loon. The stored source describes the document's ORIGIN, not its current state` + (path ? ` \u2014 saving would not reproduce ${path}, and re-evaluating ${path} would discard the edits.` : `.`)
51589
- };
51590
- }
51591
- return { source_stale: false, ...path ? { source_path: path } : {} };
51592
- }
51593
- var MAX_DIVERGED_BY;
51594
- var init_source_provenance = __esm({
51595
- "src/tools/source-provenance.ts"() {
51596
- "use strict";
51597
- init_session_core();
51598
- MAX_DIVERGED_BY = 8;
51599
- }
51600
- });
51601
-
51602
51737
  // src/tools/loon.ts
51603
- import { readFileSync as readFileSync4 } from "node:fs";
51738
+ import { readFileSync as readFileSync3 } from "node:fs";
51604
51739
  import { delimiter, isAbsolute as isAbsolute3, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
51605
51740
  function composeLoonProgram(input) {
51606
51741
  const { source, use_loons, loons } = input;
@@ -51626,7 +51761,7 @@ function readModule(base, name) {
51626
51761
  const file = resolve2(join2(root, ...name.split(".")) + ext);
51627
51762
  if (file !== root && !file.startsWith(root + sep2)) continue;
51628
51763
  try {
51629
- return readFileSync4(file, "utf8");
51764
+ return readFileSync3(file, "utf8");
51630
51765
  } catch {
51631
51766
  }
51632
51767
  }
@@ -51693,11 +51828,10 @@ function evalCadLoon(input, engine) {
51693
51828
  const modules = composeLoonModules(input);
51694
51829
  let doc;
51695
51830
  try {
51696
- doc = engine.evalVcadSourceWithModules(source, modules);
51831
+ doc = engine.evalLoonDocument(source, modules, { baseDir: base_dir });
51697
51832
  } catch (e) {
51698
51833
  throw explainEvalError(e, parsed, missingModules(source, modules));
51699
51834
  }
51700
- if (doc) attachLoonSource(doc, { text: source, modules, base_dir });
51701
51835
  if (!doc) {
51702
51836
  const text2 = Object.keys(modules).length ? "Error: this kernel build cannot resolve loon modules ([use ...]) \u2014 update the kernel, or inline the modules into `source`" : "Error: Loon evaluation not supported by this engine build";
51703
51837
  return { result: { content: [{ type: "text", text: text2 }] }, doc: null };
@@ -51771,7 +51905,6 @@ var init_loon = __esm({
51771
51905
  init_session_core();
51772
51906
  init_loon_assets();
51773
51907
  init_remote();
51774
- init_source_provenance();
51775
51908
  init_tool_def();
51776
51909
  createCadLoonSchema = {
51777
51910
  type: "object",
@@ -52427,7 +52560,7 @@ var init_session_store = __esm({
52427
52560
  });
52428
52561
 
52429
52562
  // src/tools/artifact-store.ts
52430
- import { createHash as createHash2, randomBytes } from "node:crypto";
52563
+ import { createHash, randomBytes } from "node:crypto";
52431
52564
  function ttlMs() {
52432
52565
  const raw = process.env.MCP_ARTIFACT_TTL_MS;
52433
52566
  const n = raw ? parseInt(raw, 10) : NaN;
@@ -52523,7 +52656,7 @@ function storeArtifact(files) {
52523
52656
  const manifest = stored.map((f) => ({
52524
52657
  file: f.name,
52525
52658
  bytes: f.buf.length,
52526
- sha256: createHash2("sha256").update(f.buf).digest("hex")
52659
+ sha256: createHash("sha256").update(f.buf).digest("hex")
52527
52660
  }));
52528
52661
  const bytes = stored.reduce((n, f) => n + f.buf.length, 0);
52529
52662
  const expiresAt = now + ttlMs();
@@ -52658,7 +52791,7 @@ async function loadDurable(id) {
52658
52791
  manifest: Array.isArray(row.manifest) ? row.manifest : files.map((f) => ({
52659
52792
  file: f.name,
52660
52793
  bytes: f.buf.length,
52661
- sha256: createHash2("sha256").update(f.buf).digest("hex")
52794
+ sha256: createHash("sha256").update(f.buf).digest("hex")
52662
52795
  })),
52663
52796
  bytes: typeof row.bytes === "number" ? row.bytes : files.reduce((n, f) => n + f.buf.length, 0),
52664
52797
  createdAt: row.created_at ? Date.parse(row.created_at) : Date.now(),
@@ -52718,6 +52851,64 @@ var init_artifact_store = __esm({
52718
52851
  }
52719
52852
  });
52720
52853
 
52854
+ // src/tools/source-provenance.ts
52855
+ import { createHash as createHash2 } from "node:crypto";
52856
+ import { readFileSync as readFileSync4 } from "node:fs";
52857
+ function sourceHash(text) {
52858
+ return createHash2("sha256").update(text, "utf8").digest("hex");
52859
+ }
52860
+ function markSourceDiverged(documentId, tool) {
52861
+ const src = documents.get(documentId)?.source;
52862
+ if (!src) return false;
52863
+ const firstTime = !src.diverged;
52864
+ src.diverged = true;
52865
+ const by = src.diverged_by ??= [];
52866
+ if (by[by.length - 1] !== tool) by.push(tool);
52867
+ if (by.length > MAX_DIVERGED_BY) by.splice(0, by.length - MAX_DIVERGED_BY);
52868
+ return firstTime;
52869
+ }
52870
+ function sourceStatus(doc) {
52871
+ const src = doc?.source;
52872
+ if (!src) return { source_stale: false };
52873
+ const path = src.path;
52874
+ if (path) {
52875
+ let onDisk = null;
52876
+ try {
52877
+ onDisk = readFileSync4(path, "utf8");
52878
+ } catch {
52879
+ return {
52880
+ source_stale: true,
52881
+ source_path: path,
52882
+ reason: `The source file ${path} can no longer be read \u2014 this session is no longer backed by the file it was loaded from.`
52883
+ };
52884
+ }
52885
+ if (sourceHash(onDisk) !== src.hash) {
52886
+ return {
52887
+ source_stale: true,
52888
+ source_path: path,
52889
+ reason: `${path} changed on disk since this session was evaluated from it \u2014 the session's geometry is from the OLD source. Re-load the file to pick up the edits.`
52890
+ };
52891
+ }
52892
+ }
52893
+ if (src.diverged) {
52894
+ const by = src.diverged_by ?? [];
52895
+ return {
52896
+ source_stale: true,
52897
+ ...path ? { source_path: path } : {},
52898
+ reason: `This session has been edited directly (${by.join(", ") || "mutation"}), and those edits cannot round-trip back to loon. The stored source describes the document's ORIGIN, not its current state` + (path ? ` \u2014 saving would not reproduce ${path}, and re-evaluating ${path} would discard the edits.` : `.`)
52899
+ };
52900
+ }
52901
+ return { source_stale: false, ...path ? { source_path: path } : {} };
52902
+ }
52903
+ var MAX_DIVERGED_BY;
52904
+ var init_source_provenance = __esm({
52905
+ "src/tools/source-provenance.ts"() {
52906
+ "use strict";
52907
+ init_session_core();
52908
+ MAX_DIVERGED_BY = 8;
52909
+ }
52910
+ });
52911
+
52721
52912
  // src/tools/session.ts
52722
52913
  import { writeFileSync as writeFileSync2, readFileSync as readFileSync5 } from "node:fs";
52723
52914
  import { dirname, resolve as resolve3 } from "node:path";
@@ -53034,18 +53225,12 @@ async function loadDocumentFromPath(path, store, engine) {
53034
53225
  const modules = composeLoonModules({ source: raw, base_dir: baseDir });
53035
53226
  let doc;
53036
53227
  try {
53037
- doc = engine.evalVcadSourceWithModules(raw, modules) ?? null;
53228
+ doc = engine.evalLoonDocument(raw, modules, { baseDir, path: abs });
53038
53229
  } catch (e) {
53039
53230
  return fail2(`Loon evaluation of ${abs} failed: ${e.message}`);
53040
53231
  }
53041
53232
  if (!doc) return fail2(`Loon evaluation of ${abs} produced no document.`);
53042
53233
  const imports = assetNote(resolveLoonAssets(doc, { base_dir: baseDir }, engine));
53043
- attachLoonSource(doc, {
53044
- text: raw,
53045
- modules,
53046
- base_dir: baseDir,
53047
- path: abs
53048
- });
53049
53234
  const id = registerSession(doc);
53050
53235
  return {
53051
53236
  content: [
@@ -86876,8 +87061,8 @@ var init_server3 = __esm({
86876
87061
  init_order_feed();
86877
87062
  init_animate();
86878
87063
  PKG_VERSION = (() => {
86879
- if ("0.10.0-main.130") {
86880
- return "0.10.0-main.130";
87064
+ if ("0.10.0-main.132") {
87065
+ return "0.10.0-main.132";
86881
87066
  }
86882
87067
  try {
86883
87068
  const req = createRequire2(import.meta.url);
@@ -86886,8 +87071,8 @@ var init_server3 = __esm({
86886
87071
  return "0.0.0";
86887
87072
  }
86888
87073
  })();
86889
- BUILD_SHA = "86e01dfe3474a2c82f179c81edd92f1efa97340b";
86890
- BUILD_TIME = "2026-10-21T16:21:11.937Z";
87074
+ BUILD_SHA = "362c46b798588ed58f200c9d529b3d11b2b2ff73";
87075
+ BUILD_TIME = "2026-10-21T17:31:51.205Z";
86891
87076
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
86892
87077
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
86893
87078
  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.130",
3
+ "version": "0.10.0-main.132",
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": "86e01dfe3474a2c82f179c81edd92f1efa97340b",
23
- "builtAt": "2026-10-21T16:21:11.937Z"
22
+ "sha": "362c46b798588ed58f200c9d529b3d11b2b2ff73",
23
+ "builtAt": "2026-10-21T17:31:51.205Z"
24
24
  }
25
25
  }