@vcad/mcp 0.9.4-main.17 → 0.9.4-main.18

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 cfb504c93d13b7e0339f79b4b8863ffeb1ca83b1 at 2026-07-24T20:18:23.601Z. Source: https://github.com/ecto/vcad
9
+ Built from 48276771946e67b08cb31a66d123bdc2d7af926d at 2026-07-24T22:30:13.865Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -198,6 +198,7 @@ __export(vcad_kernel_wasm_exports, {
198
198
  isGpuAvailable: () => isGpuAvailable,
199
199
  isPhysicsAvailable: () => isPhysicsAvailable,
200
200
  isSlicerAvailable: () => isSlicerAvailable,
201
+ latticeGaugeSimulate: () => latticeGaugeSimulate,
201
202
  mesh_clearance: () => mesh_clearance,
202
203
  nestSheetMetalParts: () => nestSheetMetalParts,
203
204
  nestedSheetMetalDxf: () => nestedSheetMetalDxf,
@@ -2126,6 +2127,15 @@ function isSlicerAvailable() {
2126
2127
  const ret = wasm.isSlicerAvailable();
2127
2128
  return ret !== 0;
2128
2129
  }
2130
+ function latticeGaugeSimulate(spec_json) {
2131
+ const ptr0 = passStringToWasm0(spec_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2132
+ const len0 = WASM_VECTOR_LEN;
2133
+ const ret = wasm.latticeGaugeSimulate(ptr0, len0);
2134
+ if (ret[2]) {
2135
+ throw takeFromExternrefTable0(ret[1]);
2136
+ }
2137
+ return takeFromExternrefTable0(ret[0]);
2138
+ }
2129
2139
  function mesh_clearance(positions_a, indices_a, positions_b, indices_b) {
2130
2140
  const ptr0 = passArrayF32ToWasm0(positions_a, wasm.__wbindgen_malloc);
2131
2141
  const len0 = WASM_VECTOR_LEN;
@@ -11455,6 +11465,7 @@ var init_dist = __esm({
11455
11465
  toleranceAnalyze: wasmModule7.toleranceAnalyze,
11456
11466
  thermalSolve: wasmModule7.thermalSolve,
11457
11467
  thermalSolveTransient: wasmModule7.thermalSolveTransient,
11468
+ simulateFlow: wasmModule7.simulateFlow,
11458
11469
  documentDiff: wasmModule7.documentDiff,
11459
11470
  documentDiffApply: wasmModule7.documentDiffApply,
11460
11471
  documentMerge: wasmModule7.documentMerge,
@@ -11733,6 +11744,20 @@ var init_dist = __esm({
11733
11744
  }
11734
11745
  return fn(specJson, transientJson, paramsJson, optionsJson);
11735
11746
  }
11747
+ /**
11748
+ * Steady laminar flow solve (D3Q19 BGK lattice Boltzmann): pressure
11749
+ * drop, flow rates, mass audit, optional thermal pickup, and predicted
11750
+ * receipt claims. Per-voxel fields are only returned when
11751
+ * `includeFields` is true. Inputs are JSON strings (FlowSpec, options);
11752
+ * see `vcad-kernel-flow`.
11753
+ */
11754
+ simulateFlow(specJson, optionsJson, includeFields) {
11755
+ const fn = this.kernel.simulateFlow;
11756
+ if (typeof fn !== "function") {
11757
+ throw new Error("simulateFlow is not exported by this kernel WASM build \u2014 rebuild packages/kernel-wasm");
11758
+ }
11759
+ return fn(specJson, optionsJson, includeFields);
11760
+ }
11736
11761
  circuitFn(name) {
11737
11762
  const fn = this.kernel[name];
11738
11763
  if (typeof fn !== "function") {
@@ -40824,6 +40849,22 @@ var init_CHANGELOG = __esm({
40824
40849
  "simulate_lattice_gauge"
40825
40850
  ]
40826
40851
  },
40852
+ {
40853
+ id: "2026-07-24-flow-cfd-lbm",
40854
+ version: "0.9.4",
40855
+ date: "2026-07-24",
40856
+ category: "feat",
40857
+ title: "Laminar CFD: lattice-Boltzmann flow solver",
40858
+ summary: "New simulate_flow tool: steady laminar D3Q19 LBM on a voxel grid with pressure drop, flow rates, mass audit, thermal pickup, and predicted vcad.flow-claims/1 receipts.",
40859
+ features: [
40860
+ "flow",
40861
+ "cfd",
40862
+ "simulation"
40863
+ ],
40864
+ mcpTools: [
40865
+ "simulate_flow"
40866
+ ]
40867
+ },
40827
40868
  {
40828
40869
  id: "2026-07-23-router-post-route-legalization",
40829
40870
  version: "0.9.4",
@@ -51847,6 +51888,7 @@ var init_tool_metadata = __esm({
51847
51888
  simulate_photonics: { title: "Simulate Photonics", annotations: RO },
51848
51889
  analyze_antenna: { title: "Analyze Antenna", annotations: RO },
51849
51890
  solve_thermal: { title: "Solve Thermal", annotations: RO },
51891
+ simulate_flow: { title: "Simulate Flow", annotations: RO },
51850
51892
  analyze_structure: { title: "Analyze Structure", annotations: RO },
51851
51893
  simulate_neutron_shield: {
51852
51894
  title: "Simulate Neutron Shield",
@@ -69571,7 +69613,7 @@ var init_thermal = __esm({
69571
69613
  }
69572
69614
  });
69573
69615
 
69574
- // src/tools/circuit.ts
69616
+ // src/tools/flow.ts
69575
69617
  function textResult5(payload) {
69576
69618
  return {
69577
69619
  content: [
@@ -69582,6 +69624,207 @@ function textResult5(payload) {
69582
69624
  ]
69583
69625
  };
69584
69626
  }
69627
+ var vec32, shapeSchema2, flowSpecSchema, toolDefs30;
69628
+ var init_flow = __esm({
69629
+ "src/tools/flow.ts"() {
69630
+ "use strict";
69631
+ init_tool_def();
69632
+ vec32 = {
69633
+ type: "array",
69634
+ minItems: 3,
69635
+ maxItems: 3,
69636
+ items: { type: "number" }
69637
+ };
69638
+ shapeSchema2 = {
69639
+ type: "object",
69640
+ required: ["type"],
69641
+ description: 'Region shape: `{"type":"Box","min_mm":[..],"size_mm":[..]}` or `{"type":"Tube","axis":"Z","center_mm":[..2],"span_mm":[..2],"outer_radius_mm":..,"inner_radius_mm":..}`.',
69642
+ properties: {
69643
+ type: { type: "string", enum: ["Box", "Tube"] },
69644
+ min_mm: vec32,
69645
+ size_mm: vec32,
69646
+ axis: { type: "string", enum: ["X", "Y", "Z"] },
69647
+ center_mm: {
69648
+ type: "array",
69649
+ minItems: 2,
69650
+ maxItems: 2,
69651
+ items: { type: "number" }
69652
+ },
69653
+ span_mm: {
69654
+ type: "array",
69655
+ minItems: 2,
69656
+ maxItems: 2,
69657
+ items: { type: "number" }
69658
+ },
69659
+ outer_radius_mm: { type: "number" },
69660
+ inner_radius_mm: { type: "number" }
69661
+ }
69662
+ };
69663
+ flowSpecSchema = {
69664
+ type: "object",
69665
+ required: ["origin_mm", "size_mm", "divisions"],
69666
+ description: "Voxelized flow domain: an axis-aligned box discretized into cubic voxels (`size_mm[a]/divisions[a]` must agree across axes), painted with regions in order (`background` first, then `regions`). Units mm / kg / m / s / Pa / degC.",
69667
+ properties: {
69668
+ origin_mm: vec32,
69669
+ size_mm: vec32,
69670
+ divisions: {
69671
+ type: "array",
69672
+ minItems: 3,
69673
+ maxItems: 3,
69674
+ items: { type: "number" },
69675
+ description: "Voxel counts per axis (voxels must come out cubic; the cost knob)."
69676
+ },
69677
+ background: {
69678
+ type: "string",
69679
+ enum: ["solid", "fluid"],
69680
+ description: "What unpainted voxels are. Default solid."
69681
+ },
69682
+ regions: {
69683
+ type: "array",
69684
+ items: {
69685
+ type: "object",
69686
+ required: ["shape", "role"],
69687
+ properties: {
69688
+ shape: shapeSchema2,
69689
+ role: {
69690
+ type: "string",
69691
+ enum: ["solid", "fluid", "inlet", "outlet"]
69692
+ }
69693
+ }
69694
+ },
69695
+ description: "Painted in order; later regions override earlier ones. Inlet and outlet patches must sit on the domain boundary."
69696
+ },
69697
+ fluid: {
69698
+ type: "object",
69699
+ properties: {
69700
+ density_kg_m3: { type: "number" },
69701
+ viscosity_pa_s: { type: "number" }
69702
+ },
69703
+ description: "Fluid properties. Default water (998, 1.002e-3)."
69704
+ },
69705
+ inlet_velocity_m_s: {
69706
+ ...vec32,
69707
+ description: "Plug-flow inlet velocity vector, m/s."
69708
+ },
69709
+ outlet_gauge_pa: {
69710
+ type: "number",
69711
+ description: "Outlet gauge pressure, Pa. Default 0."
69712
+ },
69713
+ body_force_n_m3: {
69714
+ ...vec32,
69715
+ description: "Volumetric body force, N/m^3 (periodic channel drive; needs `options.u_ref_m_s`)."
69716
+ },
69717
+ periodic: {
69718
+ type: "array",
69719
+ minItems: 3,
69720
+ maxItems: 3,
69721
+ items: { type: "boolean" },
69722
+ description: "Per-axis periodic boundaries."
69723
+ },
69724
+ re_envelope: {
69725
+ type: "number",
69726
+ description: "Reynolds gate: the solve refuses Re above this (laminar only). Default 2300."
69727
+ },
69728
+ thermal: {
69729
+ type: "object",
69730
+ properties: {
69731
+ inlet_temp_c: { type: "number" },
69732
+ initial_temp_c: { type: "number" },
69733
+ wall_temp_c: { type: "number" },
69734
+ diffusivity_m2_s: { type: "number" },
69735
+ heat_capacity_j_kg_k: { type: "number" },
69736
+ buoyancy: {
69737
+ type: "object",
69738
+ properties: {
69739
+ beta_per_k: { type: "number" },
69740
+ t_ref_c: { type: "number" },
69741
+ gravity_m_s2: { type: "number" }
69742
+ }
69743
+ }
69744
+ },
69745
+ description: "Enable the advected temperature field (film-averaged conjugate seam; optional Boussinesq buoyancy, gated at Ra <= 1e8)."
69746
+ },
69747
+ hot_walls: {
69748
+ type: "array",
69749
+ items: {
69750
+ type: "object",
69751
+ required: ["shape", "temp_c"],
69752
+ properties: {
69753
+ shape: shapeSchema2,
69754
+ temp_c: { type: "number" }
69755
+ }
69756
+ },
69757
+ description: "Isothermal wall patches (Dirichlet) for thermal runs, painted over solid voxels adjacent to fluid."
69758
+ }
69759
+ }
69760
+ };
69761
+ toolDefs30 = [
69762
+ {
69763
+ name: "simulate_flow",
69764
+ pack: null,
69765
+ description: 'Steady laminar CFD on a voxel grid: D3Q19 BGK lattice Boltzmann with half-way bounce-back walls, velocity inlets, pressure outlets, and an optional advected temperature field (isothermal walls, Boussinesq buoyancy). Returns pressure drop, inlet/outlet flow rates, the mass-balance audit, max speed, and thermal pickup \u2014 as data plus `vcad.flow-claims/1` and unified-receipt claims. Predictions carry basis "predicted" and roll up Provisional until hardware is measured. Laminar only: fail-closed gates at Re <= 2300, the stable tau window, and Ra <= 1e8; weakly compressible (pressure noise O(Ma^2)); walls are voxel staircases. Per-voxel velocity/pressure/temperature fields are only returned with `include_fields: true` \u2014 they are grid-sized (voxel cap 2M). Steadiness is detected, not assumed: a run that never goes steady is an error, not a result.',
69766
+ inputSchema: {
69767
+ type: "object",
69768
+ required: ["spec"],
69769
+ properties: {
69770
+ spec: flowSpecSchema,
69771
+ options: {
69772
+ type: "object",
69773
+ properties: {
69774
+ u_ref_m_s: {
69775
+ type: "number",
69776
+ description: "Reference speed for unit scaling, m/s. Defaults to the inlet speed; body-force-driven cases must supply it."
69777
+ },
69778
+ max_steps: {
69779
+ type: "number",
69780
+ description: "Step budget before failing. Default 400000."
69781
+ },
69782
+ check_every: {
69783
+ type: "number",
69784
+ description: "Steadiness check interval, steps. Default 200."
69785
+ },
69786
+ steady_tol: {
69787
+ type: "number",
69788
+ description: "Relative L-inf velocity change per check. Default 1e-6."
69789
+ },
69790
+ ramp_steps: {
69791
+ type: "number",
69792
+ description: "Inlet velocity ramp length, steps. Default 1000."
69793
+ }
69794
+ }
69795
+ },
69796
+ include_fields: {
69797
+ type: "boolean",
69798
+ description: "Return the per-voxel velocity/pressure/temperature fields (grid-sized). Default false."
69799
+ }
69800
+ }
69801
+ },
69802
+ handler: (args, ctx) => {
69803
+ const a = args;
69804
+ const out = ctx.engine.simulateFlow(
69805
+ JSON.stringify(a.spec),
69806
+ JSON.stringify(a.options ?? {}),
69807
+ !!a.include_fields
69808
+ );
69809
+ return textResult5(out);
69810
+ },
69811
+ behavior: behavior({})
69812
+ }
69813
+ ];
69814
+ }
69815
+ });
69816
+
69817
+ // src/tools/circuit.ts
69818
+ function textResult6(payload) {
69819
+ return {
69820
+ content: [
69821
+ {
69822
+ type: "text",
69823
+ text: JSON.stringify(payload, null, 2)
69824
+ }
69825
+ ]
69826
+ };
69827
+ }
69585
69828
  function frequencyGrid(ac) {
69586
69829
  const list = ac.frequenciesHz;
69587
69830
  if (Array.isArray(list) && list.length > 0) return list;
@@ -69597,7 +69840,7 @@ function frequencyGrid(ac) {
69597
69840
  }
69598
69841
  return out;
69599
69842
  }
69600
- var deviceSchema, devicesSchema, toolDefs30;
69843
+ var deviceSchema, devicesSchema, toolDefs31;
69601
69844
  var init_circuit = __esm({
69602
69845
  "src/tools/circuit.ts"() {
69603
69846
  "use strict";
@@ -69634,7 +69877,7 @@ var init_circuit = __esm({
69634
69877
  items: deviceSchema,
69635
69878
  description: "Netlist as data. Node ids are dense integers with 0 = ground; the device's index in this array is its device id (used by sourceId / freeDevices / outNode references)."
69636
69879
  };
69637
- toolDefs30 = [
69880
+ toolDefs31 = [
69638
69881
  {
69639
69882
  name: "simulate_circuit",
69640
69883
  pack: null,
@@ -69743,7 +69986,7 @@ var init_circuit = __esm({
69743
69986
  tr.sampleEvery ?? 1
69744
69987
  );
69745
69988
  }
69746
- return textResult5(out);
69989
+ return textResult6(out);
69747
69990
  },
69748
69991
  behavior: behavior({})
69749
69992
  },
@@ -69806,7 +70049,7 @@ var init_circuit = __esm({
69806
70049
  ...typeof a.maxIters === "number" ? { maxIters: a.maxIters } : {}
69807
70050
  };
69808
70051
  const specJson = JSON.stringify({ devices: a.devices });
69809
- return textResult5(ctx.engine.circuitTune(specJson, JSON.stringify(tune)));
70052
+ return textResult6(ctx.engine.circuitTune(specJson, JSON.stringify(tune)));
69810
70053
  },
69811
70054
  behavior: behavior({})
69812
70055
  }
@@ -69815,7 +70058,7 @@ var init_circuit = __esm({
69815
70058
  });
69816
70059
 
69817
70060
  // src/tools/structure.ts
69818
- function textResult6(payload) {
70061
+ function textResult7(payload) {
69819
70062
  return {
69820
70063
  content: [
69821
70064
  {
@@ -69825,7 +70068,7 @@ function textResult6(payload) {
69825
70068
  ]
69826
70069
  };
69827
70070
  }
69828
- var regionSchema2, toolDefs31;
70071
+ var regionSchema2, toolDefs32;
69829
70072
  var init_structure = __esm({
69830
70073
  "src/tools/structure.ts"() {
69831
70074
  "use strict";
@@ -69852,7 +70095,7 @@ var init_structure = __esm({
69852
70095
  }
69853
70096
  }
69854
70097
  };
69855
- toolDefs31 = [
70098
+ toolDefs32 = [
69856
70099
  {
69857
70100
  name: "analyze_structure",
69858
70101
  pack: null,
@@ -69964,7 +70207,7 @@ var init_structure = __esm({
69964
70207
  resolved.mesh.indices
69965
70208
  );
69966
70209
  const solveMs = Math.round(performance.now() - started);
69967
- return textResult6({
70210
+ return textResult7({
69968
70211
  document_id: a.document_id,
69969
70212
  part: resolved.name ?? a.part,
69970
70213
  solve_ms: solveMs,
@@ -69978,7 +70221,7 @@ var init_structure = __esm({
69978
70221
  });
69979
70222
 
69980
70223
  // src/tools/em.ts
69981
- function textResult7(payload) {
70224
+ function textResult8(payload) {
69982
70225
  return {
69983
70226
  content: [
69984
70227
  {
@@ -69988,7 +70231,7 @@ function textResult7(payload) {
69988
70231
  ]
69989
70232
  };
69990
70233
  }
69991
- var paramValue4, rectRegion, bcSchema, electroShape, emSpecSchema, toolDefs32;
70234
+ var paramValue4, rectRegion, bcSchema, electroShape, emSpecSchema, toolDefs33;
69992
70235
  var init_em = __esm({
69993
70236
  "src/tools/em.ts"() {
69994
70237
  "use strict";
@@ -70144,7 +70387,7 @@ var init_em = __esm({
70144
70387
  }
70145
70388
  }
70146
70389
  };
70147
- toolDefs32 = [
70390
+ toolDefs33 = [
70148
70391
  {
70149
70392
  name: "simulate_em",
70150
70393
  pack: null,
@@ -70222,7 +70465,7 @@ var init_em = __esm({
70222
70465
  JSON.stringify(a.parameters ?? {}),
70223
70466
  JSON.stringify(a.options ?? {})
70224
70467
  );
70225
- return textResult7(out);
70468
+ return textResult8(out);
70226
70469
  },
70227
70470
  behavior: behavior({})
70228
70471
  }
@@ -70231,7 +70474,7 @@ var init_em = __esm({
70231
70474
  });
70232
70475
 
70233
70476
  // src/tools/antenna.ts
70234
- function textResult8(payload) {
70477
+ function textResult9(payload) {
70235
70478
  return {
70236
70479
  content: [
70237
70480
  {
@@ -70241,7 +70484,7 @@ function textResult8(payload) {
70241
70484
  ]
70242
70485
  };
70243
70486
  }
70244
- var paramValue5, pointSpec, antennaSpecSchema, toolDefs33;
70487
+ var paramValue5, pointSpec, antennaSpecSchema, toolDefs34;
70245
70488
  var init_antenna = __esm({
70246
70489
  "src/tools/antenna.ts"() {
70247
70490
  "use strict";
@@ -70290,7 +70533,7 @@ var init_antenna = __esm({
70290
70533
  feed_mm: pointSpec
70291
70534
  }
70292
70535
  };
70293
- toolDefs33 = [
70536
+ toolDefs34 = [
70294
70537
  {
70295
70538
  name: "analyze_antenna",
70296
70539
  pack: null,
@@ -70348,7 +70591,7 @@ var init_antenna = __esm({
70348
70591
  JSON.stringify(a.parameters ?? {}),
70349
70592
  JSON.stringify({ band: a.band, ...a.options })
70350
70593
  );
70351
- return textResult8(out);
70594
+ return textResult9(out);
70352
70595
  },
70353
70596
  behavior: behavior({})
70354
70597
  }
@@ -70357,7 +70600,7 @@ var init_antenna = __esm({
70357
70600
  });
70358
70601
 
70359
70602
  // src/tools/photonics.ts
70360
- function textResult9(payload) {
70603
+ function textResult10(payload) {
70361
70604
  return {
70362
70605
  content: [
70363
70606
  {
@@ -70367,7 +70610,7 @@ function textResult9(payload) {
70367
70610
  ]
70368
70611
  };
70369
70612
  }
70370
- var photonicsSpecSchema, toolDefs34;
70613
+ var photonicsSpecSchema, toolDefs35;
70371
70614
  var init_photonics = __esm({
70372
70615
  "src/tools/photonics.ts"() {
70373
70616
  "use strict";
@@ -70453,7 +70696,7 @@ var init_photonics = __esm({
70453
70696
  }
70454
70697
  }
70455
70698
  };
70456
- toolDefs34 = [
70699
+ toolDefs35 = [
70457
70700
  {
70458
70701
  name: "simulate_photonics",
70459
70702
  pack: null,
@@ -70500,7 +70743,7 @@ var init_photonics = __esm({
70500
70743
  JSON.stringify(a.spec),
70501
70744
  JSON.stringify(a.options ?? {})
70502
70745
  );
70503
- return textResult9(out);
70746
+ return textResult10(out);
70504
70747
  },
70505
70748
  behavior: behavior({})
70506
70749
  }
@@ -70509,7 +70752,7 @@ var init_photonics = __esm({
70509
70752
  });
70510
70753
 
70511
70754
  // src/tools/neutronics.ts
70512
- function textResult10(payload) {
70755
+ function textResult11(payload) {
70513
70756
  return {
70514
70757
  content: [
70515
70758
  {
@@ -70519,7 +70762,7 @@ function textResult10(payload) {
70519
70762
  ]
70520
70763
  };
70521
70764
  }
70522
- var paramValue6, shieldSpecSchema, toolDefs35;
70765
+ var paramValue6, shieldSpecSchema, toolDefs36;
70523
70766
  var init_neutronics = __esm({
70524
70767
  "src/tools/neutronics.ts"() {
70525
70768
  "use strict";
@@ -70590,7 +70833,7 @@ var init_neutronics = __esm({
70590
70833
  }
70591
70834
  }
70592
70835
  };
70593
- toolDefs35 = [
70836
+ toolDefs36 = [
70594
70837
  {
70595
70838
  name: "simulate_neutron_shield",
70596
70839
  pack: null,
@@ -70613,7 +70856,7 @@ var init_neutronics = __esm({
70613
70856
  JSON.stringify(a.spec),
70614
70857
  JSON.stringify(a.parameters ?? {})
70615
70858
  );
70616
- return textResult10(out);
70859
+ return textResult11(out);
70617
70860
  },
70618
70861
  behavior: behavior({})
70619
70862
  }
@@ -70622,7 +70865,7 @@ var init_neutronics = __esm({
70622
70865
  });
70623
70866
 
70624
70867
  // src/tools/qcd.ts
70625
- function textResult11(payload) {
70868
+ function textResult12(payload) {
70626
70869
  return {
70627
70870
  content: [
70628
70871
  {
@@ -70632,7 +70875,7 @@ function textResult11(payload) {
70632
70875
  ]
70633
70876
  };
70634
70877
  }
70635
- var simSpecSchema, toolDefs36;
70878
+ var simSpecSchema, toolDefs37;
70636
70879
  var init_qcd = __esm({
70637
70880
  "src/tools/qcd.ts"() {
70638
70881
  "use strict";
@@ -70722,7 +70965,7 @@ var init_qcd = __esm({
70722
70965
  }
70723
70966
  }
70724
70967
  };
70725
- toolDefs36 = [
70968
+ toolDefs37 = [
70726
70969
  {
70727
70970
  name: "simulate_lattice_gauge",
70728
70971
  pack: null,
@@ -70735,7 +70978,7 @@ var init_qcd = __esm({
70735
70978
  handler: (args, ctx) => {
70736
70979
  const a = args;
70737
70980
  const out = ctx.engine.latticeGaugeSimulate(JSON.stringify(a.spec));
70738
- return textResult11(out);
70981
+ return textResult12(out);
70739
70982
  },
70740
70983
  behavior: behavior({})
70741
70984
  }
@@ -70864,7 +71107,7 @@ function predictPhysicsTool(args, engine) {
70864
71107
  ]
70865
71108
  };
70866
71109
  }
70867
- var PHYSICS_DOMAIN, ORACLE, TIER_RESOLUTION, regionSchema3, predictPhysicsSchema, round52, toolDefs37;
71110
+ var PHYSICS_DOMAIN, ORACLE, TIER_RESOLUTION, regionSchema3, predictPhysicsSchema, round52, toolDefs38;
70868
71111
  var init_physics2 = __esm({
70869
71112
  "src/tools/physics.ts"() {
70870
71113
  "use strict";
@@ -70977,7 +71220,7 @@ var init_physics2 = __esm({
70977
71220
  }
70978
71221
  };
70979
71222
  round52 = (v) => Number(v.toPrecision(5));
70980
- toolDefs37 = [
71223
+ toolDefs38 = [
70981
71224
  {
70982
71225
  name: "predict_physics",
70983
71226
  pack: null,
@@ -71219,7 +71462,7 @@ function applySetParam(doc, node, path, value) {
71219
71462
  }
71220
71463
  cursor[parts[parts.length - 1]] = value;
71221
71464
  }
71222
- var lastReports, mechanicalProcessEnum, pcbProcessEnum, processEnum, dfmCheckSchema, dfmExplainSchema, dfmSuggestFixSchema, dfmApplyFixSchema, toolDefs38;
71465
+ var lastReports, mechanicalProcessEnum, pcbProcessEnum, processEnum, dfmCheckSchema, dfmExplainSchema, dfmSuggestFixSchema, dfmApplyFixSchema, toolDefs39;
71223
71466
  var init_dfm2 = __esm({
71224
71467
  "src/tools/dfm.ts"() {
71225
71468
  "use strict";
@@ -71316,7 +71559,7 @@ var init_dfm2 = __esm({
71316
71559
  },
71317
71560
  required: ["issue_id"]
71318
71561
  };
71319
- toolDefs38 = [
71562
+ toolDefs39 = [
71320
71563
  {
71321
71564
  name: "dfm_check",
71322
71565
  pack: "dfm",
@@ -71515,7 +71758,7 @@ function renderedOf(engine, doc) {
71515
71758
  "document has no sheet-metal part (evaluation produced no sheetMetal bundle)"
71516
71759
  );
71517
71760
  }
71518
- function textResult12(payload) {
71761
+ function textResult13(payload) {
71519
71762
  return {
71520
71763
  content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
71521
71764
  };
@@ -71557,7 +71800,7 @@ function sheetMetalCreate(input, engine) {
71557
71800
  const errors = rendered.violations.filter(
71558
71801
  (v) => v.severity === "Error"
71559
71802
  ).length;
71560
- return textResult12({
71803
+ return textResult13({
71561
71804
  document_id: documentId,
71562
71805
  model: rendered.model,
71563
71806
  flat: {
@@ -71573,7 +71816,7 @@ function sheetMetalUnfold(input, engine) {
71573
71816
  const doc = getSession(String(a.document_id ?? ""));
71574
71817
  const rendered = renderedOf(engine, doc);
71575
71818
  const includeDxf = a.include_dxf !== false;
71576
- return textResult12({
71819
+ return textResult13({
71577
71820
  flat_pattern: rendered.flatPattern,
71578
71821
  ...includeDxf ? { dxf: rendered.dxf } : {},
71579
71822
  note: "The DXF is a fab-ready merged silhouette: one closed exterior LWPOLYLINE plus hole loops on CUT, DASHED bend centerlines (on the allowance midline) on BEND_UP/BEND_DOWN, and any surface markings as open polylines on ENGRAVE (select the laser-marking/engraving service for that layer in the fab's UI). DXF carries no bend angles \u2014 you enter those in the fab's UI. For zero data entry, export the folded body as STEP instead (export_cad with a .step filename); bends are auto-detected by the shop, but radii/K must match their tooling at model time (use shop_profile in sheet_metal_create)."
@@ -71581,7 +71824,7 @@ function sheetMetalUnfold(input, engine) {
71581
71824
  }
71582
71825
  function sheetMetalMaterials(_input, engine) {
71583
71826
  const materials = engine.getSheetMetalMaterials();
71584
- return textResult12({
71827
+ return textResult13({
71585
71828
  materials,
71586
71829
  note: 'Pass any `name` (e.g. `"al-soft"`, `"steel-mild"`) as the `material` field of `sheet_metal_create`. Aliases like `"aluminum"`, `"stainless"`, `"6061-T6"` also resolve.'
71587
71830
  });
@@ -71590,13 +71833,13 @@ function sheetMetalBendTable(input, engine) {
71590
71833
  const a = input ?? {};
71591
71834
  if (typeof a.shop_profile === "string" && a.shop_profile.length > 0) {
71592
71835
  const catalog = engine.getSheetMetalShopCatalog(a.shop_profile);
71593
- return textResult12({
71836
+ return textResult13({
71594
71837
  catalog,
71595
71838
  note: `Published catalog for ${catalog.name} (retrieved ${catalog.retrieved}). inside_radius_mm is FIXED per material/thickness \u2014 pass shop_profile: "${catalog.id}" to sheet_metal_create and omit per-bend radius to use it.`
71596
71839
  });
71597
71840
  }
71598
71841
  const table = engine.getSheetMetalBendTable();
71599
- return textResult12({
71842
+ return textResult13({
71600
71843
  table,
71601
71844
  note: "K-factors are interpolated by closest R/t for the chosen material. To override K for a specific bend, pass `manual_k` on that flange in sheet_metal_create."
71602
71845
  });
@@ -71618,7 +71861,7 @@ function sheetMetalCheck(input, engine) {
71618
71861
  const errors = result.violations.filter(
71619
71862
  (v) => v.severity === "Error"
71620
71863
  ).length;
71621
- return textResult12({
71864
+ return textResult13({
71622
71865
  shop: result.shop,
71623
71866
  violations: result.violations,
71624
71867
  shop_ready: result.violations.length === 0,
@@ -71670,7 +71913,7 @@ function sheetMetalNest(input, engine) {
71670
71913
  footprints,
71671
71914
  params
71672
71915
  );
71673
- return textResult12({
71916
+ return textResult13({
71674
71917
  parts: footprints,
71675
71918
  result,
71676
71919
  summary: `${result.placements.length} placements across ${result.sheets_used} sheet(s); ${result.utilization_pct.toFixed(1)}% utilization${result.unplaceable.length > 0 ? `; ${result.unplaceable.length} unplaceable (oversize)` : ""}.`
@@ -71683,7 +71926,7 @@ function sheetMetalSequence3(input, engine) {
71683
71926
  if (!steps) {
71684
71927
  throw new Error("document has no sheet-metal part");
71685
71928
  }
71686
- return textResult12({
71929
+ return textResult13({
71687
71930
  count: steps.length,
71688
71931
  steps,
71689
71932
  note: "Form each bend in order. compensated_angle_rad is the angle to dial in on the brake \u2014 springs back to angle_rad once released."
@@ -71706,7 +71949,7 @@ function sheetMetalSuggestFix(input, engine) {
71706
71949
  violation: v,
71707
71950
  fix: suggestFix(v)
71708
71951
  }));
71709
- return textResult12({
71952
+ return textResult13({
71710
71953
  shop: result.shop,
71711
71954
  count: suggestions.length,
71712
71955
  suggestions,
@@ -71809,13 +72052,13 @@ function sheetMetalCost(input, engine) {
71809
72052
  if (!result) {
71810
72053
  throw new Error("document has no sheet-metal part");
71811
72054
  }
71812
- return textResult12({
72055
+ return textResult13({
71813
72056
  breakdown: result.breakdown,
71814
72057
  rates: result.rates,
71815
72058
  summary: `${result.breakdown.currency} ${result.breakdown.total_each.toFixed(2)} each @ qty ${result.breakdown.quantity} (mass ${result.breakdown.mass_kg_each.toFixed(3)} kg, ${result.breakdown.cut_length_m.toFixed(2)} m cut, ${result.breakdown.bends} bend(s)).`
71816
72059
  });
71817
72060
  }
71818
- var sheetMetalCreateSchema, sheetMetalUnfoldSchema, sheetMetalMaterialsSchema, sheetMetalBendTableSchema, sheetMetalCheckSchema, sheetMetalNestSchema, sheetMetalSequenceSchema, sheetMetalSuggestFixSchema, sheetMetalCostSchema, toolDefs39;
72061
+ var sheetMetalCreateSchema, sheetMetalUnfoldSchema, sheetMetalMaterialsSchema, sheetMetalBendTableSchema, sheetMetalCheckSchema, sheetMetalNestSchema, sheetMetalSequenceSchema, sheetMetalSuggestFixSchema, sheetMetalCostSchema, toolDefs40;
71819
72062
  var init_sheet_metal2 = __esm({
71820
72063
  "src/tools/sheet-metal.ts"() {
71821
72064
  "use strict";
@@ -72076,7 +72319,7 @@ var init_sheet_metal2 = __esm({
72076
72319
  },
72077
72320
  required: ["document_id"]
72078
72321
  };
72079
- toolDefs39 = [
72322
+ toolDefs40 = [
72080
72323
  {
72081
72324
  name: "sheet_metal_create",
72082
72325
  pack: "sheet_metal",
@@ -72321,7 +72564,7 @@ function simulateStrike(input, engine) {
72321
72564
  }
72322
72565
  return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
72323
72566
  }
72324
- var cents, MATERIAL_ALIASES, simulateStrikeSchema, round22, round4, toolDefs40;
72567
+ var cents, MATERIAL_ALIASES, simulateStrikeSchema, round22, round4, toolDefs41;
72325
72568
  var init_acoustics = __esm({
72326
72569
  "src/tools/acoustics.ts"() {
72327
72570
  "use strict";
@@ -72395,7 +72638,7 @@ var init_acoustics = __esm({
72395
72638
  };
72396
72639
  round22 = (x) => Math.round(x * 100) / 100;
72397
72640
  round4 = (x) => Math.round(x * 1e4) / 1e4;
72398
- toolDefs40 = [
72641
+ toolDefs41 = [
72399
72642
  {
72400
72643
  name: "simulate_strike",
72401
72644
  pack: "sheet_metal",
@@ -72546,7 +72789,7 @@ function importStep(input, engine) {
72546
72789
  ]
72547
72790
  };
72548
72791
  }
72549
- var MAX_STEP_BYTES, importStepSchema, toolDefs41;
72792
+ var MAX_STEP_BYTES, importStepSchema, toolDefs42;
72550
72793
  var init_import = __esm({
72551
72794
  "src/tools/import.ts"() {
72552
72795
  "use strict";
@@ -72578,7 +72821,7 @@ var init_import = __esm({
72578
72821
  }
72579
72822
  }
72580
72823
  };
72581
- toolDefs41 = [
72824
+ toolDefs42 = [
72582
72825
  {
72583
72826
  name: "import_step",
72584
72827
  pack: null,
@@ -72706,7 +72949,7 @@ function importEagle(_input) {
72706
72949
  "Eagle (.brd) import is not yet supported. Export your board from Eagle as KiCad (File > Export > KiCad .kicad_pcb) and use import_kicad instead."
72707
72950
  );
72708
72951
  }
72709
- var MAX_PCB_BYTES, importKicadSchema, importEagleSchema, toolDefs42;
72952
+ var MAX_PCB_BYTES, importKicadSchema, importEagleSchema, toolDefs43;
72710
72953
  var init_import_pcb = __esm({
72711
72954
  "src/tools/import-pcb.ts"() {
72712
72955
  "use strict";
@@ -72747,7 +72990,7 @@ var init_import_pcb = __esm({
72747
72990
  }
72748
72991
  }
72749
72992
  };
72750
- toolDefs42 = [
72993
+ toolDefs43 = [
72751
72994
  {
72752
72995
  name: "import_kicad",
72753
72996
  pack: "ecad",
@@ -72843,7 +73086,7 @@ Compressed URL param: ${encoded.length} bytes`
72843
73086
  ]
72844
73087
  };
72845
73088
  }
72846
- var openInBrowserSchema, toolDefs43;
73089
+ var openInBrowserSchema, toolDefs44;
72847
73090
  var init_share = __esm({
72848
73091
  "src/tools/share.ts"() {
72849
73092
  "use strict";
@@ -72867,7 +73110,7 @@ var init_share = __esm({
72867
73110
  }
72868
73111
  }
72869
73112
  };
72870
- toolDefs43 = [
73113
+ toolDefs44 = [
72871
73114
  {
72872
73115
  name: "open_in_browser",
72873
73116
  pack: null,
@@ -73192,7 +73435,7 @@ function batchReset(input) {
73192
73435
  };
73193
73436
  }
73194
73437
  }
73195
- var simulations, MAX_TRAJECTORY, envRecords, batchGroups, createRobotEnvSchema, gymStepSchema, gymResetSchema, gymObserveSchema, gymCloseSchema, batchCreateEnvsSchema, batchStepSchema, batchResetSchema, toolDefs44;
73438
+ var simulations, MAX_TRAJECTORY, envRecords, batchGroups, createRobotEnvSchema, gymStepSchema, gymResetSchema, gymObserveSchema, gymCloseSchema, batchCreateEnvsSchema, batchStepSchema, batchResetSchema, toolDefs45;
73196
73439
  var init_gym = __esm({
73197
73440
  "src/tools/gym.ts"() {
73198
73441
  "use strict";
@@ -73344,7 +73587,7 @@ var init_gym = __esm({
73344
73587
  },
73345
73588
  required: ["batch_id"]
73346
73589
  };
73347
- toolDefs44 = [
73590
+ toolDefs45 = [
73348
73591
  {
73349
73592
  name: "create_robot_env",
73350
73593
  pack: "physics",
@@ -73702,7 +73945,7 @@ async function renderMolecule(input) {
73702
73945
  return fail(err7);
73703
73946
  }
73704
73947
  }
73705
- var loadStructureSchema, inspectMoleculeSchema, configSchema, minimizeEnergySchema, mdRunSchema, designMaterialSchema, homogenizeMaterialSchema, renderMoleculeSchema, CPK, DEFAULT_RADIUS, toolDefs45;
73948
+ var loadStructureSchema, inspectMoleculeSchema, configSchema, minimizeEnergySchema, mdRunSchema, designMaterialSchema, homogenizeMaterialSchema, renderMoleculeSchema, CPK, DEFAULT_RADIUS, toolDefs46;
73706
73949
  var init_atoms2 = __esm({
73707
73950
  "src/tools/atoms.ts"() {
73708
73951
  "use strict";
@@ -73837,7 +74080,7 @@ var init_atoms2 = __esm({
73837
74080
  S: 1.05,
73838
74081
  P: 1.07
73839
74082
  };
73840
- toolDefs45 = [
74083
+ toolDefs46 = [
73841
74084
  {
73842
74085
  name: "load_structure",
73843
74086
  pack: "atoms",
@@ -75045,7 +75288,7 @@ function errorResult(text) {
75045
75288
  isError: true
75046
75289
  };
75047
75290
  }
75048
- var recordSimulationSchema, SVG_SCALE2, MAX_STEPS, MIN_STEPS, DEFAULT_WIDTH_PX2, MIN_WIDTH_PX, MAX_WIDTH_PX, DEFAULT_FPS, MIN_FPS, MAX_FPS, toolDefs46;
75291
+ var recordSimulationSchema, SVG_SCALE2, MAX_STEPS, MIN_STEPS, DEFAULT_WIDTH_PX2, MIN_WIDTH_PX, MAX_WIDTH_PX, DEFAULT_FPS, MIN_FPS, MAX_FPS, toolDefs47;
75049
75292
  var init_record2 = __esm({
75050
75293
  "src/tools/record.ts"() {
75051
75294
  "use strict";
@@ -75109,7 +75352,7 @@ var init_record2 = __esm({
75109
75352
  DEFAULT_FPS = 30;
75110
75353
  MIN_FPS = 1;
75111
75354
  MAX_FPS = 60;
75112
- toolDefs46 = [
75355
+ toolDefs47 = [
75113
75356
  {
75114
75357
  name: "record_simulation",
75115
75358
  pack: "physics",
@@ -75202,7 +75445,7 @@ ${text}`
75202
75445
  ]
75203
75446
  };
75204
75447
  }
75205
- var getChangelogSchema, toolDefs47;
75448
+ var getChangelogSchema, toolDefs48;
75206
75449
  var init_changelog2 = __esm({
75207
75450
  "src/tools/changelog.ts"() {
75208
75451
  "use strict";
@@ -75242,7 +75485,7 @@ var init_changelog2 = __esm({
75242
75485
  }
75243
75486
  }
75244
75487
  };
75245
- toolDefs47 = [
75488
+ toolDefs48 = [
75246
75489
  {
75247
75490
  name: "get_changelog",
75248
75491
  pack: null,
@@ -75391,7 +75634,7 @@ function getSimVersion(input) {
75391
75634
  ]
75392
75635
  };
75393
75636
  }
75394
- var getSimReplaySchema, getSimVersionSchema, toolDefs48;
75637
+ var getSimReplaySchema, getSimVersionSchema, toolDefs49;
75395
75638
  var init_sim_replay = __esm({
75396
75639
  "src/tools/sim-replay.ts"() {
75397
75640
  "use strict";
@@ -75419,7 +75662,7 @@ var init_sim_replay = __esm({
75419
75662
  },
75420
75663
  required: ["env_id"]
75421
75664
  };
75422
- toolDefs48 = [
75665
+ toolDefs49 = [
75423
75666
  {
75424
75667
  name: "get_sim_replay",
75425
75668
  pack: null,
@@ -75538,7 +75781,7 @@ async function getOrderFeed(input, store, user) {
75538
75781
  version: version2
75539
75782
  });
75540
75783
  }
75541
- var toUsd4, getOrderFeedSchema, toolDefs49;
75784
+ var toUsd4, getOrderFeedSchema, toolDefs50;
75542
75785
  var init_order_feed = __esm({
75543
75786
  "src/tools/order-feed.ts"() {
75544
75787
  "use strict";
@@ -75557,7 +75800,7 @@ var init_order_feed = __esm({
75557
75800
  },
75558
75801
  required: ["document_id"]
75559
75802
  };
75560
- toolDefs49 = [
75803
+ toolDefs50 = [
75561
75804
  {
75562
75805
  name: "get_order_feed",
75563
75806
  pack: "fabricate",
@@ -75762,7 +76005,7 @@ ${issues.map((i) => i.track >= 0 ? `track[${i.track}]: ${i.problem}` : i.problem
75762
76005
  note: "Timeline set. Preview with render_sequence, ship with export_video."
75763
76006
  });
75764
76007
  }
75765
- function vec32(v) {
76008
+ function vec33(v) {
75766
76009
  return v ? [v.x, v.y, v.z] : [0, 0, 0];
75767
76010
  }
75768
76011
  function hasParamTracks(timeline) {
@@ -75805,7 +76048,7 @@ function cameraChannels(frames) {
75805
76048
  }
75806
76049
  function explodeDirections(doc, transforms) {
75807
76050
  const ids = [...transforms.keys()];
75808
- const pts = ids.map((id) => vec32(transforms.get(id).translation));
76051
+ const pts = ids.map((id) => vec33(transforms.get(id).translation));
75809
76052
  const c = pts.reduce((acc, p) => [acc[0] + p[0], acc[1] + p[1], acc[2] + p[2]], [0, 0, 0]).map((v) => v / Math.max(1, pts.length));
75810
76053
  let extent = 0;
75811
76054
  for (const p of pts) {
@@ -75863,7 +76106,7 @@ function buildSequenceGlb(doc, timeline, frames, engine) {
75863
76106
  for (const inst of instances) {
75864
76107
  const rec = perInstance.get(inst.instanceId);
75865
76108
  const t2 = world.get(inst.instanceId) ?? inst.transform;
75866
- const translation = vec32(t2?.translation);
76109
+ const translation = vec33(t2?.translation);
75867
76110
  if (frame.explode > 0) {
75868
76111
  const d = dirs.get(inst.instanceId) ?? [0, 0, 0];
75869
76112
  translation[0] += d[0] * frame.explode;
@@ -76459,7 +76702,7 @@ ${issues.map((i) => i.problem).join("\n")}`
76459
76702
  note: "Rollout compiled to the document timeline. Preview with render_sequence, ship with export_video."
76460
76703
  });
76461
76704
  }
76462
- var MAX_FRAMES, MAX_GEO_SAMPLES, MAX_VERIFY_FRAMES, INLINE_GLB_MAX_BASE64, DEFAULT_WIDTH_PX3, MIN_WIDTH_PX2, MAX_WIDTH_PX2, SVG_SCALE3, KEYFRAMES_DESCRIPTION, animateSchema, renderSequenceSchema, CAMERA_NODE, exportVideoSchema, ffmpegAvailable, timelineFromSimulationSchema, toolDefs50;
76705
+ var MAX_FRAMES, MAX_GEO_SAMPLES, MAX_VERIFY_FRAMES, INLINE_GLB_MAX_BASE64, DEFAULT_WIDTH_PX3, MIN_WIDTH_PX2, MAX_WIDTH_PX2, SVG_SCALE3, KEYFRAMES_DESCRIPTION, animateSchema, renderSequenceSchema, CAMERA_NODE, exportVideoSchema, ffmpegAvailable, timelineFromSimulationSchema, toolDefs51;
76463
76706
  var init_animate = __esm({
76464
76707
  "src/tools/animate.ts"() {
76465
76708
  "use strict";
@@ -76611,7 +76854,7 @@ var init_animate = __esm({
76611
76854
  },
76612
76855
  required: ["env_id", "document_id"]
76613
76856
  };
76614
- toolDefs50 = [
76857
+ toolDefs51 = [
76615
76858
  {
76616
76859
  name: "animate",
76617
76860
  pack: null,
@@ -77450,6 +77693,7 @@ var init_server3 = __esm({
77450
77693
  init_particle();
77451
77694
  init_tolerance();
77452
77695
  init_thermal();
77696
+ init_flow();
77453
77697
  init_circuit();
77454
77698
  init_structure();
77455
77699
  init_em();
@@ -77475,8 +77719,8 @@ var init_server3 = __esm({
77475
77719
  init_order_feed();
77476
77720
  init_animate();
77477
77721
  PKG_VERSION = (() => {
77478
- if ("0.9.4-main.17") {
77479
- return "0.9.4-main.17";
77722
+ if ("0.9.4-main.18") {
77723
+ return "0.9.4-main.18";
77480
77724
  }
77481
77725
  try {
77482
77726
  const req = createRequire2(import.meta.url);
@@ -77485,8 +77729,8 @@ var init_server3 = __esm({
77485
77729
  return "0.0.0";
77486
77730
  }
77487
77731
  })();
77488
- BUILD_SHA = "cfb504c93d13b7e0339f79b4b8863ffeb1ca83b1";
77489
- BUILD_TIME = "2026-07-24T20:18:23.601Z";
77732
+ BUILD_SHA = "48276771946e67b08cb31a66d123bdc2d7af926d";
77733
+ BUILD_TIME = "2026-07-24T22:30:13.865Z";
77490
77734
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
77491
77735
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
77492
77736
  INSTANCE_ID = randomUUID6().slice(0, 8);
@@ -77547,8 +77791,8 @@ var init_server3 = __esm({
77547
77791
  ...toolDefs35,
77548
77792
  ...toolDefs36,
77549
77793
  ...toolDefs37,
77550
- ...toolDefs2,
77551
77794
  ...toolDefs38,
77795
+ ...toolDefs2,
77552
77796
  ...toolDefs39,
77553
77797
  ...toolDefs40,
77554
77798
  ...toolDefs41,
@@ -77558,11 +77802,12 @@ var init_server3 = __esm({
77558
77802
  ...toolDefs45,
77559
77803
  ...toolDefs46,
77560
77804
  ...toolDefs47,
77805
+ ...toolDefs48,
77561
77806
  ...toolDefs20,
77562
77807
  ...toolDefs19,
77563
- ...toolDefs48,
77564
77808
  ...toolDefs49,
77565
- ...toolDefs50
77809
+ ...toolDefs50,
77810
+ ...toolDefs51
77566
77811
  ];
77567
77812
  LIST_TOOL_ORDER = [
77568
77813
  // ── Session lifecycle ──────────────────────────────────────
@@ -77631,6 +77876,7 @@ var init_server3 = __esm({
77631
77876
  "simulate_photonics",
77632
77877
  "analyze_antenna",
77633
77878
  "solve_thermal",
77879
+ "simulate_flow",
77634
77880
  "analyze_structure",
77635
77881
  "simulate_neutron_shield",
77636
77882
  "simulate_lattice_gauge",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcad/mcp",
3
- "version": "0.9.4-main.17",
3
+ "version": "0.9.4-main.18",
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": "cfb504c93d13b7e0339f79b4b8863ffeb1ca83b1",
23
- "builtAt": "2026-07-24T20:18:23.601Z"
22
+ "sha": "48276771946e67b08cb31a66d123bdc2d7af926d",
23
+ "builtAt": "2026-07-24T22:30:13.865Z"
24
24
  }
25
25
  }
Binary file