forgecad 0.10.4 → 0.11.0

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 (121) hide show
  1. package/dist/assets/{AdminPage-B3L3W1Uo.js → AdminPage-B1nIvqLS.js} +1 -1
  2. package/dist/assets/{BenchmarkPage-DXKVXMrJ.js → BenchmarkPage-YZJbw5nd.js} +2 -2
  3. package/dist/assets/{BlogPage-B7BWxOCg.js → BlogPage-DIWRApKS.js} +1 -1
  4. package/dist/assets/{DocsPage-BPGGwht1.js → DocsPage-ClL6X1hR.js} +8 -22
  5. package/dist/assets/EditorApp-CYBDvSyT.js +17067 -0
  6. package/dist/assets/{EmbedViewer-DygByZS2.js → EmbedViewer-Dmfu_LIw.js} +2 -2
  7. package/dist/assets/{LandingPageProofDriven-BoVE7JGY.js → LandingPageProofDriven-XYTiYxfM.js} +2 -2
  8. package/dist/assets/{LegalPage-Din8wv8d.js → LegalPage-D5Z3CscF.js} +2 -2
  9. package/dist/assets/{PricingPage-C2PMzmDc.js → PricingPage-BP4lIGio.js} +2 -2
  10. package/dist/assets/{SettingsPage-BlJDCRe8.js → SettingsPage-D3bcPBsC.js} +1 -1
  11. package/dist/assets/{app-BsRYSfxY.js → app-BKjogwIZ.js} +3288 -512
  12. package/dist/assets/{backendInit-6C0DLgH0.js → backendInit-6a9-ilom.js} +80498 -74979
  13. package/dist/assets/cli/{render-XXol_ET7.js → render-CMNudGb0.js} +1264 -113
  14. package/dist/assets/{constructionHistoryWorker-cTHWRJEi.js → constructionHistoryWorker-BuZgc606.js} +8369 -6839
  15. package/dist/assets/{evalWorker-BssDYW9u.js → evalWorker-DQ82ueGu.js} +45438 -39996
  16. package/dist/assets/{forgecad_geometry-CZ_IfuvA.js → forgecad_geometry-D8rWX7nQ.js} +1 -1
  17. package/dist/assets/{forgecad_geometry_bg-C3rQHfwg.wasm → forgecad_geometry_bg-ObqfqjJT.wasm} +0 -0
  18. package/dist/assets/{inspectWorker-ymhBV4Ll.js → inspectWorker-Cuby2qfT.js} +4899 -1303
  19. package/dist/assets/{jointPose-B0blBj9A.js → jointPose-CFql5I-u.js} +1 -1
  20. package/dist/assets/{landing-proof-driven-Cpf-MIbI.css → landing-proof-driven-_u4v_xQb.css} +2 -2
  21. package/dist/assets/{manifold-CYlIm-M6.js → manifold-02pmr7O7.js} +2 -2
  22. package/dist/assets/{manifold-B_7QXpGB.js → manifold-C6KU0oII.js} +1 -1
  23. package/dist/assets/{manifold-CNShmpEJ.js → manifold-P1yF3GKn.js} +1 -1
  24. package/dist/assets/{reportWorker-Cb5eyM7D.js → reportWorker-kg065BVL.js} +76583 -65731
  25. package/dist/cli/render.html +1 -1
  26. package/dist/docs/index.html +2 -2
  27. package/dist/docs-raw/AI/usage.md +6 -8
  28. package/dist/docs-raw/CLI.md +14 -12
  29. package/dist/docs-raw/component-model.md +28 -9
  30. package/dist/docs-raw/generated/assembly.md +76 -3
  31. package/dist/docs-raw/generated/concepts.md +43 -7
  32. package/dist/docs-raw/generated/core.md +399 -73
  33. package/dist/docs-raw/generated/curves.md +357 -6
  34. package/dist/docs-raw/generated/runtime-names.md +12 -12
  35. package/dist/docs-raw/generated/sketch.md +16 -3
  36. package/dist/docs-raw/guides/inspection-bundles.md +5 -3
  37. package/dist/docs-raw/guides/structural-fea.md +235 -0
  38. package/dist/docs-raw/skills/forgecad-build-model.md +70 -147
  39. package/dist/docs-raw/skills/forgecad-image-prompt.md +1 -1
  40. package/dist/docs-raw/skills/forgecad-project-sync.md +3 -3
  41. package/dist/docs-raw/skills/forgecad-reconstruct-cad-file.md +2 -2
  42. package/dist/docs-raw/skills/forgecad-reconstruct-from-images.md +4 -5
  43. package/dist/docs-raw/skills/forgecad.md +4 -1
  44. package/dist/docs-raw/skills/index.md +1 -5
  45. package/dist/docs-raw/welcome.md +3 -4
  46. package/dist/index.html +1 -1
  47. package/dist/llms.txt +1 -2
  48. package/dist/sitemap.xml +15 -15
  49. package/dist-cli/{check-compiler-4RPB6SB5.js → check-compiler-UJWUEIDC.js} +1 -1
  50. package/dist-cli/{check-query-propagation-KN3DFQTX.js → check-query-propagation-O2EPDJSY.js} +1 -1
  51. package/dist-cli/{chunk-UHBRMYA6.js → chunk-MNDROM7T.js} +78926 -73392
  52. package/dist-cli/forgecad.js +6306 -1061
  53. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  54. package/dist-skill/CONTEXT.md +1257 -110
  55. package/dist-skill/SKILL.md +4 -1
  56. package/dist-skill/docs/API/core/concepts.md +31 -4
  57. package/dist-skill/docs/CLI.md +14 -12
  58. package/dist-skill/docs/generated/assembly.md +73 -3
  59. package/dist-skill/docs/generated/core.md +395 -74
  60. package/dist-skill/docs/generated/curves.md +356 -6
  61. package/dist-skill/docs/generated/runtime-names.md +12 -12
  62. package/dist-skill/docs/generated/sketch.md +16 -3
  63. package/dist-skill/docs/guides/inspection-bundles.md +5 -3
  64. package/dist-skill/docs/guides/manual-parameters.md +130 -0
  65. package/dist-skill/docs/guides/structural-fea.md +235 -0
  66. package/dist-skill/library/README.md +0 -4
  67. package/dist-skill/library/forgecad-build-model/SKILL.md +57 -150
  68. package/dist-skill/library/forgecad-build-model/references/inspection-feedback.md +58 -0
  69. package/dist-skill/library/forgecad-build-model/references/module-contracts.md +53 -0
  70. package/dist-skill/library/forgecad-build-model/references/parameter-controls.md +22 -0
  71. package/dist-skill/library/forgecad-build-model/references/readiness-review.md +43 -0
  72. package/dist-skill/library/forgecad-build-model/references/simulation-feedback.md +49 -0
  73. package/dist-skill/library/forgecad-build-model/references/stage-1-design-intent.md +21 -0
  74. package/dist-skill/library/forgecad-build-model/references/stage-2-architecture-plan.md +23 -0
  75. package/dist-skill/library/forgecad-build-model/references/stage-3-build-slices.md +39 -0
  76. package/dist-skill/library/forgecad-build-model/references/stage-4-feedback-iteration.md +24 -0
  77. package/dist-skill/library/forgecad-build-model/references/stage-5-readiness-package.md +34 -0
  78. package/dist-skill/library/forgecad-image-prompt/SKILL.md +1 -1
  79. package/dist-skill/library/forgecad-project-sync/SKILL.md +3 -3
  80. package/dist-skill/library/forgecad-reconstruct-cad-file/SKILL.md +2 -2
  81. package/dist-skill/library/forgecad-reconstruct-from-images/SKILL.md +4 -5
  82. package/dist-skill/website/skills/forgecad-build-model.md +70 -147
  83. package/dist-skill/website/skills/forgecad-image-prompt.md +1 -1
  84. package/dist-skill/website/skills/forgecad-project-sync.md +3 -3
  85. package/dist-skill/website/skills/forgecad-reconstruct-cad-file.md +2 -2
  86. package/dist-skill/website/skills/forgecad-reconstruct-from-images.md +4 -5
  87. package/dist-skill/website/skills/forgecad.md +4 -1
  88. package/dist-skill/website/skills/index.md +1 -5
  89. package/examples/analysis/structural-stress-fea.forge.js +19 -0
  90. package/examples/api/blend-full-round.forge.js +37 -0
  91. package/examples/api/blend-variable-radius.forge.js +51 -0
  92. package/examples/api/curve-project-and-intersect.forge.js +59 -0
  93. package/examples/api/extrude-up-to-face.forge.js +47 -0
  94. package/examples/api/param-path2d.forge.js +65 -0
  95. package/examples/api/param-placement2d.forge.js +80 -0
  96. package/examples/api/param-spline2d-g-continuity.forge.js +57 -0
  97. package/examples/api/spoon-full-tang-handle.forge.js +188 -0
  98. package/examples/api/surface-boundarynet-dished-bowl.forge.js +63 -0
  99. package/examples/api/surface-fill-interior-constraints.forge.js +59 -0
  100. package/examples/api/surface-variable-thickness-panel.forge.js +62 -0
  101. package/examples/mechanical/airplane-propeller.forge.js +81 -28
  102. package/package.json +5 -2
  103. package/dist/assets/EditorApp-BWUGCdD5.js +0 -16610
  104. package/dist/docs-raw/skills/forgecad-design-spec.md +0 -145
  105. package/dist/docs-raw/skills/forgecad-grade-model.md +0 -84
  106. package/dist/docs-raw/skills/forgecad-inspect-model.md +0 -80
  107. package/dist/docs-raw/skills/forgecad-verify-mujoco.md +0 -78
  108. package/dist-skill/library/forgecad-design-spec/SKILL.md +0 -132
  109. package/dist-skill/library/forgecad-design-spec/references/default-profiles.md +0 -99
  110. package/dist-skill/library/forgecad-design-spec/references/master-prompt.md +0 -73
  111. package/dist-skill/library/forgecad-grade-model/SKILL.md +0 -72
  112. package/dist-skill/library/forgecad-grade-model/agents/openai.yaml +0 -4
  113. package/dist-skill/library/forgecad-inspect-model/SKILL.md +0 -68
  114. package/dist-skill/library/forgecad-verify-mujoco/SKILL.md +0 -66
  115. package/dist-skill/website/skills/forgecad-design-spec.md +0 -145
  116. package/dist-skill/website/skills/forgecad-grade-model.md +0 -84
  117. package/dist-skill/website/skills/forgecad-inspect-model.md +0 -80
  118. package/dist-skill/website/skills/forgecad-verify-mujoco.md +0 -78
  119. /package/dist/assets/{landing-proof-driven-BxZZh5r5.js → landing-proof-driven-DNPRKL_p.js} +0 -0
  120. /package/dist-skill/library/{forgecad-verify-mujoco → forgecad-build-model}/scripts/mujoco_verify.py +0 -0
  121. /package/dist-skill/library/{forgecad-inspect-model → forgecad-build-model/scripts}/summarize_manifest.py +0 -0
@@ -0,0 +1,59 @@
1
+ /**
2
+ * n-sided filled surface pulled onto interior features with `Surface.Fill`.
3
+ *
4
+ * `Surface.Fill` already fills any closed loop of n >= 3 boundary curves
5
+ * (energy-minimizing constrained fill on the OCCT backend). Two optional fields
6
+ * shape the INTERIOR of that fill without changing the rim:
7
+ *
8
+ * - `through` — interior constraint curves the surface must pass through. They
9
+ * are NOT part of the boundary loop; they pull the fill onto an internal
10
+ * feature line (here, a raised diagonal spine/crease).
11
+ * - `points` — isolated interior points the surface must interpolate (here, a
12
+ * single pinned bump lifted above the rim plane).
13
+ *
14
+ * The result is an open sheet, so `.thicken()` turns it into a thin solid.
15
+ * (Interior constraints require the default OCCT exact backend.)
16
+ */
17
+
18
+ scene({
19
+ camera: { position: [120, -150, 110], target: [25, 25, 6], fov: 32 },
20
+ environment: { preset: 'studio' },
21
+ });
22
+
23
+ // A near-planar pentagon rim at z = 0 (five corners, five exact edges).
24
+ const corners = [
25
+ [0, 0, 0],
26
+ [50, 0, 0],
27
+ [62, 38, 0],
28
+ [25, 60, 0],
29
+ [-12, 38, 0],
30
+ ];
31
+
32
+ function edge(a, b) {
33
+ return Curve.Fit([corners[a], corners[b]]);
34
+ }
35
+
36
+ const boundaries = [
37
+ { name: 'a', curve: edge(0, 1) },
38
+ { name: 'b', curve: edge(1, 2) },
39
+ { name: 'c', curve: edge(2, 3) },
40
+ { name: 'd', curve: edge(3, 4) },
41
+ { name: 'e', curve: edge(4, 0) },
42
+ ];
43
+
44
+ // Interior crease the fill must ride over: a raised diagonal spine.
45
+ const spine = Curve.Fit([
46
+ [8, 8, 3],
47
+ [28, 30, 7],
48
+ [50, 48, 3],
49
+ ]);
50
+
51
+ const skin = Surface.Fill({
52
+ boundaries,
53
+ through: [{ curve: spine }], // pull the fill onto the internal feature line
54
+ points: [[22, 14, 6]], // pin an interior bump above the rim plane
55
+ }).thicken(1.2);
56
+
57
+ skin.color('#bcd0d8');
58
+
59
+ return skin;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Variable-thickness surface panel.
3
+ *
4
+ * `Surface.Net()` builds the carrier sheet. `Thickness.grid()` defines a scalar
5
+ * UV wall field, so the panel can be thin at one edge, thicker through the load
6
+ * path, and locally reinforced near one corner without hand-offset geometry.
7
+ */
8
+
9
+ scene({
10
+ background: { top: '#eef4f7', bottom: '#f9fbfd' },
11
+ camera: { position: [150, -190, 92], target: [0, 0, 8], fov: 34 },
12
+ environment: { preset: 'studio', intensity: 0.25, background: false },
13
+ ground: { visible: true, color: '#d6dde3', height: -5, receiveShadow: true },
14
+ });
15
+
16
+ const panelWidth = param('Panel Width', 128);
17
+ const panelDepth = param('Panel Depth', 82);
18
+ const crownHeight = param('Crown Height', 15);
19
+
20
+ const uCount = 6;
21
+ const vCount = 5;
22
+ const panelCage = [];
23
+
24
+ for (let i = 0; i <= uCount; i++) {
25
+ const u = i / uCount;
26
+ const x = (u - 0.5) * panelWidth;
27
+ const row = [];
28
+
29
+ for (let j = 0; j <= vCount; j++) {
30
+ const v = j / vCount;
31
+ const y = (v - 0.5) * panelDepth;
32
+ const xProfile = 1 - (2 * u - 1) ** 2;
33
+ const yProfile = 1 - 0.42 * (2 * v - 1) ** 2;
34
+ const diagonalBias = 2.8 * u * (1 - v);
35
+ row.push([x, y, crownHeight * xProfile * yProfile + diagonalBias]);
36
+ }
37
+
38
+ panelCage.push(row);
39
+ }
40
+
41
+ const panel = Surface.Net()
42
+ .cage(panelCage)
43
+ .degree(3, 3)
44
+ .thickenInsideBy(
45
+ Thickness.grid(
46
+ [
47
+ [1.1, 1.3, 1.5],
48
+ [1.8, 2.4, 2.9],
49
+ [2.8, 3.5, 4.2],
50
+ ],
51
+ { easing: 'easeInOut' },
52
+ ),
53
+ { resolution: 56 },
54
+ )
55
+ .color('#5c8fb5')
56
+ .material({ roughness: 0.62, metalness: 0.04, clearcoat: 0.12 });
57
+
58
+ verify.notEmpty('Variable-thickness panel produces solid geometry', panel);
59
+ verify.volumeApprox('Variable thickness stays in the expected volume range', panel, panelWidth * panelDepth * 2.55, 6000);
60
+ verify.physicalComponentCount('Variable-thickness panel is one connected component', 1);
61
+
62
+ return [{ name: 'Variable Thickness Panel', shape: panel }];
@@ -16,6 +16,13 @@
16
16
  //
17
17
  // Thickness: 24% at root (structural) → 6% at tip (aerodynamic)
18
18
  // Camber: 4% at root → 1.5% at tip (Cl margin at low-speed root)
19
+ //
20
+ // Skin: The blade is lofted through the closed airfoil sections with
21
+ // Shape.fromSlices — an ordered slice loft that keeps a smooth
22
+ // section-to-section correspondence, so the blade reads class-A
23
+ // (no spanwise faceting) even on the default Manifold backend.
24
+ // Run with `--backend truck` (or occt) for an exact kernel-native
25
+ // NURBS solid — preferred for STEP export.
19
26
 
20
27
  // ─── Design Parameters ──────────────────────────────────────────
21
28
  const diameter = Param.number("Diameter", 1900, { min: 1200, max: 2600, unit: "mm" });
@@ -171,49 +178,98 @@ function camberAt(rNorm) {
171
178
  // - Zero pitch → chord along tangential (Y in world)
172
179
  // - Positive β → leading edge tilts toward thrust axis (+Z)
173
180
 
174
- const NUM_STATIONS = 24;
175
- const NACA_PTS = 40; // points per airfoil surface (80 total outline)
181
+ const NUM_STATIONS = 28; // a few more stations than the old loft for a smoother span
182
+ const NACA_PTS = 48; // points per airfoil surface (96 total outline)
176
183
  const CAMBER_POS = 0.4; // max camber at 40% chord (standard for props)
177
184
  const rRoot = rHub * 0.55; // blade shank starts inside the spinner
178
185
 
179
- // Airfoil section at a given normalized span position (clamped to the
180
- // aerodynamic range the shank inside the spinner reuses the hub section).
181
- function bladeSection(rNorm, r) {
186
+ // Airfoil section as a 2D point list (before it becomes a Sketch), already
187
+ // rotated for twist. The buried shank can blend toward a fuller, rounder cuff:
188
+ // rNorm normalized span for the aerodynamic distributions
189
+ // r — true radius (drives the BEMT twist)
190
+ // fatten — root-cuff blend 0..1: 0 = pure airfoil, 1 = fully rounded fat
191
+ // shank. Pulls each outline point toward an enclosing ellipse so the
192
+ // blade meets the spinner with a beefy, non-spindly junction instead
193
+ // of necking down to a thin stalk (the old root-quality defect).
194
+ function bladeSectionPoints(rNorm, r, fatten) {
182
195
  const chord = chordAt(rNorm);
183
196
  const thick = thicknessRatioAt(rNorm);
184
197
  const camber = camberAt(rNorm);
185
198
  const twist = twistAt(Math.max(r, rHub));
186
199
 
187
200
  let pts = nacaPoints(camber, CAMBER_POS, thick, chord, NACA_PTS);
188
- pts = rotate2D(pts, 90 + twist); // 90° aligns chord with tangential, +twist adds pitch
189
- return polygon(pts);
201
+
202
+ if (fatten > 0) {
203
+ // Blend toward an enclosing ellipse centered at the quarter-chord origin —
204
+ // fills the thin airfoil into a fuller shank without changing the point
205
+ // count or ordering, so the loft keeps a clean ordered correspondence.
206
+ const exA = chord * 0.34; // half-length along chord
207
+ const exB = Math.max(chord * thick * 0.62, chord * 0.16); // half-thickness, floored fat
208
+ pts = pts.map(([x, y]) => {
209
+ const ang = Math.atan2(y, x);
210
+ const ex = exA * Math.cos(ang);
211
+ const ey = exB * Math.sin(ang);
212
+ return [x + (ex - x) * fatten, y + (ey - y) * fatten];
213
+ });
214
+ }
215
+
216
+ // 90° aligns chord with the tangential direction; +twist adds pitch.
217
+ return rotate2D(pts, 90 + twist);
190
218
  }
191
219
 
192
- const profiles = [];
193
- const heights = [];
220
+ function bladeSection(rNorm, r, fatten) {
221
+ return polygon(bladeSectionPoints(rNorm, r, fatten || 0));
222
+ }
194
223
 
195
- // Shank stations buried inside the spinner a constant hub section carries
196
- // the blade to a structural attachment instead of floating at the hub surface.
197
- for (const r of [rRoot, rHub * 0.92]) {
198
- profiles.push(bladeSection(0, rHub));
199
- heights.push(r);
224
+ // Ordered station list: span coordinate (world X, radial in the disk) + the
225
+ // closed airfoil section's points. Sections sit perpendicular to X, so the
226
+ // blade extends radially with no post-loft rotation.
227
+ const stationX = [];
228
+ const stationPoints = [];
229
+
230
+ // Two buried shank stations inside the spinner: the deepest is a fully round
231
+ // cuff, the next blends back toward the airfoil so the aero blade grows
232
+ // smoothly out of the shank instead of pinching at the hub.
233
+ const shankStations = [
234
+ { x: rRoot, fatten: 1.0 },
235
+ { x: rHub * 0.86, fatten: 0.55 },
236
+ ];
237
+ for (const { x, fatten } of shankStations) {
238
+ stationX.push(x);
239
+ stationPoints.push(bladeSectionPoints(0, rHub, fatten));
200
240
  }
201
241
 
202
242
  // Aerodynamic stations from the hub surface to the tip. Cosine spacing
203
243
  // clusters stations at the root (where the BEMT twist gradient is steepest)
204
- // and at the tip (where the planform rounds off).
244
+ // and at the tip (where the planform rounds off). A light residual cuff on the
245
+ // first aero stations avoids a sudden chord/thickness step at the hub line.
205
246
  for (let i = 0; i <= NUM_STATIONS; i++) {
206
- const rNorm = 0.5 - 0.5 * Math.cos(Math.PI * i / NUM_STATIONS);
207
- const r = rHub + rNorm * (R - rHub);
208
- profiles.push(bladeSection(rNorm, r));
209
- heights.push(r);
247
+ const rNorm = 0.5 - 0.5 * Math.cos(Math.PI * i / NUM_STATIONS);
248
+ const r = rHub + rNorm * (R - rHub);
249
+ const fatten = rNorm < 0.06 ? 0.25 * (1 - rNorm / 0.06) : 0;
250
+ stationX.push(r);
251
+ stationPoints.push(bladeSectionPoints(rNorm, r, fatten));
210
252
  }
211
253
 
212
- // Loft all profiles into a smooth blade solid
213
- const bladeRaw = loft(profiles, heights, { edgeLength: meshRes });
214
-
215
- // Rotate blade from Z-axis (span) to X-axis (radial in propeller disk)
216
- const blade = bladeRaw.rotateY(90);
254
+ // Loft the closed sections into a smooth blade solid. Shape.fromSlices keeps an
255
+ // ordered, smooth section-to-section correspondence (no SDF faceting). On the
256
+ // default Manifold backend edgeLength tunes the mesh; the truck/occt kernel
257
+ // ignores it and builds an exact NURBS solid.
258
+ const blade = Shape.fromSlices(
259
+ stationX.map((x, i) => Shape.slicePerpendicularToX(x, polygon(stationPoints[i]))),
260
+ { edgeLength: meshRes },
261
+ );
262
+
263
+ // Blade-shaped cutouts through the spinner: the same ordered sections grown
264
+ // ~5% for running clearance, lofted the same exact way so the cut tracks the
265
+ // blade skin (keeping the span direction exact).
266
+ const CLEARANCE = 1.05;
267
+ const bladeCutout = Shape.fromSlices(
268
+ stationX.map((x, i) => Shape.slicePerpendicularToX(
269
+ x, polygon(stationPoints[i].map(([px, py]) => [px * CLEARANCE, py * CLEARANCE])),
270
+ )),
271
+ { edgeLength: meshRes },
272
+ );
217
273
 
218
274
  // ─── Spinner / Hub ──────────────────────────────────────────────
219
275
  //
@@ -269,10 +325,7 @@ const hubBarrel = cylinder(spinnerLen * 0.5, rHub * 0.62)
269
325
 
270
326
  const bladeAssembly = union(allBlades, hubBarrel);
271
327
 
272
- // Blade-shaped cutouts through the spinner with a small running
273
- // clearance: the blade cross-section is grown in chord and thickness
274
- // (x/y before the radial rotation), keeping the span direction exact.
275
- const bladeCutout = bladeRaw.scale([1.04, 1.04, 1]).rotateY(90);
328
+ // Pattern the blade-shaped cutouts (defined with the blade above) around the disk.
276
329
  const spinnerCutouts = circularPattern(bladeCutout, numBlades);
277
330
 
278
331
  // ─── Optional: Airfoil Section Visualization ────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgecad",
3
- "version": "0.10.4",
3
+ "version": "0.11.0",
4
4
  "description": "Code-first parametric CAD for JavaScript/TypeScript, in the browser and CLI.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://forgecad.io",
@@ -44,6 +44,9 @@
44
44
  "export": {
45
45
  "description": "Export Forge models to manufacturing, simulation, and exchange formats."
46
46
  },
47
+ "fea": {
48
+ "description": "Run, inspect, render, compare, and check structural FEA studies."
49
+ },
47
50
  "inspect": {
48
51
  "description": "Inspect ForgeCAD models with targeted visual, physical, and manufacturing evidence."
49
52
  },
@@ -112,7 +115,7 @@
112
115
  "dev:cli": "npm run build:solver:if-missing && npm run build:geometry:if-missing && tsup cli/forgecad.ts --format esm --platform node --target node20 --out-dir dist-cli --sourcemap --external typescript && node scripts/copy-cli-assets.mjs dist-cli",
113
116
  "build:cli": "npm run build:solver:if-missing && npm run build:geometry:if-missing && tsup cli/forgecad.ts --format esm --platform node --target node20 --out-dir dist-cli --clean --external typescript && node scripts/copy-cli-assets.mjs dist-cli",
114
117
  "build:native-occt": "node scripts/build-native-occt.mjs",
115
- "build:backend": "npm run build:native-occt && tsup apps/backend/src/server.ts apps/backend/src/nativeOcctWorker.ts --format esm --platform node --target node20 --out-dir dist-backend --clean --sourcemap",
118
+ "build:backend": "npm run build:geometry:if-missing && npm run build:native-occt && tsup apps/backend/src/server.ts apps/backend/src/nativeOcctWorker.ts --format esm --platform node --target node20 --out-dir dist-backend --clean --sourcemap && node scripts/copy-wasm-assets.mjs dist-backend",
116
119
  "build:binary": "node scripts/build-binary.mjs",
117
120
  "build:binary:all": "node scripts/build-binary.mjs --all",
118
121
  "bundle:offline": "node scripts/build-install-bundle.mjs",