forgecad 0.9.15 → 0.10.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 (166) hide show
  1. package/dist/assets/{AdminPage-CDyGUinA.js → AdminPage-DwYHz72L.js} +1 -1
  2. package/dist/assets/{BenchmarkPage-DfPMY_-d.js → BenchmarkPage-a9_f-1US.js} +1 -1
  3. package/dist/assets/{BlogPage-kF0fkdJT.js → BlogPage-DodHpvmf.js} +1 -1
  4. package/dist/assets/{DocsPage-B954L3YN.js → DocsPage-B5LePEuj.js} +8 -858
  5. package/dist/assets/{EditorApp-CuDLxKqL.css → EditorApp-BpjZgzk0.css} +148 -0
  6. package/dist/assets/EditorApp-QXsAISLR.js +16307 -0
  7. package/dist/assets/{EmbedViewer-C77B-TrF.js → EmbedViewer-DdEHGUMU.js} +2 -2
  8. package/dist/assets/{LandingPageProofDriven-Cr6fXMDj.js → LandingPageProofDriven-yhhOodbf.js} +2 -2
  9. package/dist/assets/{LegalPage-Dzklqmmg.js → LegalPage-5RbKRGYK.js} +1 -1
  10. package/dist/assets/{PricingPage-zWXkvlwl.js → PricingPage-E3Rma7aV.js} +1 -1
  11. package/dist/assets/{SettingsPage-Bz0of4KQ.js → SettingsPage-BJZcM97j.js} +1 -1
  12. package/dist/assets/{app-D3kDkggg.js → app-DSYrDg0V.js} +1846 -352
  13. package/dist/assets/cli/{render-DSY3mMQa.js → render-ZMHR9HkV.js} +161 -70
  14. package/dist/assets/{constructionHistoryWorker-gpDo-uH2.js → constructionHistoryWorker-AwMMWSxg.js} +1104 -349
  15. package/dist/assets/{evalWorker-CU0Ke6DP.js → evalWorker-DbNs7Dkp.js} +5155 -3772
  16. package/dist/assets/{inspectWorker-COyp8XXA.js → inspectWorker-CZsCFtQT.js} +1415 -439
  17. package/dist/assets/{targets-B9sGB5nB.js → jointPose-DO6mnXn_.js} +71 -3
  18. package/dist/assets/{manifold-DNkrUWpA.js → manifold-BGlQBBH9.js} +1 -1
  19. package/dist/assets/{manifold-BRI5prcH.js → manifold-BU-tJwQh.js} +1 -1
  20. package/dist/assets/{manifold-C-3h2M7p.js → manifold-fy2MV7K1.js} +2 -2
  21. package/dist/assets/{reportWorker-CdBz5bNg.js → reportWorker-DO6hcQbh.js} +8474 -4549
  22. package/dist/assets/{scalar-sampling-budget-wJF98aY9.js → scalar-sampling-budget-o90NSNmF.js} +5347 -3906
  23. package/dist/assets/{scanProxyWorker-B-9VbLIs.js → scanProxyWorker-2GtDLk-R.js} +19 -6
  24. package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
  25. package/dist/cli/render.html +1 -1
  26. package/dist/docs/index.html +3 -3
  27. package/dist/docs-raw/AI/usage.md +3 -1
  28. package/dist/docs-raw/CLI.md +65 -239
  29. package/dist/docs-raw/README.md +6 -0
  30. package/dist/docs-raw/component-model.md +17 -150
  31. package/dist/docs-raw/generated/assembly.md +159 -520
  32. package/dist/docs-raw/generated/concepts.md +245 -3491
  33. package/dist/docs-raw/generated/core.md +277 -1251
  34. package/dist/docs-raw/generated/curves.md +387 -1608
  35. package/dist/docs-raw/generated/legacy.md +162 -0
  36. package/dist/docs-raw/generated/lib.md +238 -112
  37. package/dist/docs-raw/generated/output.md +51 -76
  38. package/dist/docs-raw/generated/runtime-names.md +30 -22
  39. package/dist/docs-raw/generated/sdf.md +68 -284
  40. package/dist/docs-raw/generated/sheet-metal.md +68 -335
  41. package/dist/docs-raw/generated/sketch.md +240 -1161
  42. package/dist/docs-raw/generated/viewport.md +75 -316
  43. package/dist/docs-raw/generated/wood.md +21 -49
  44. package/dist/docs-raw/guides/coordinate-system.md +4 -42
  45. package/dist/docs-raw/guides/inspection-bundles.md +44 -442
  46. package/dist/docs-raw/guides/joint-design.md +18 -79
  47. package/dist/docs-raw/guides/positioning.md +21 -143
  48. package/dist/docs-raw/guides/scene-presentation.md +89 -0
  49. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
  50. package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
  51. package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
  52. package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
  53. package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
  54. package/dist/docs-raw/skills/forgecad-lld.md +19 -113
  55. package/dist/docs-raw/skills/forgecad-make-a-model.md +113 -532
  56. package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
  57. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
  58. package/dist/docs-raw/skills/forgecad-project.md +13 -129
  59. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
  60. package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
  61. package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
  62. package/dist/docs-raw/skills/forgecad.md +19 -18
  63. package/dist/docs-raw/skills/index.md +2 -0
  64. package/dist/docs-raw/welcome.md +4 -2
  65. package/dist/index.html +1 -1
  66. package/dist/llms.txt +1 -2
  67. package/dist/sitemap.xml +13 -13
  68. package/dist-cli/{check-compiler-SDX5QIXI.js → check-compiler-JTVBITCR.js} +1 -1
  69. package/dist-cli/{check-query-propagation-EAYEFT77.js → check-query-propagation-3FFLSMVN.js} +1 -1
  70. package/dist-cli/{chunk-N4O47JLF.js → chunk-OAN5T4XD.js} +5722 -4287
  71. package/dist-cli/forgecad.js +2195 -656
  72. package/dist-skill/CONTEXT.md +1778 -7912
  73. package/dist-skill/SKILL.md +15 -15
  74. package/dist-skill/docs/API/core/concepts.md +27 -157
  75. package/dist-skill/docs/CLI.md +65 -239
  76. package/dist-skill/docs/generated/assembly.md +160 -493
  77. package/dist-skill/docs/generated/core.md +277 -1251
  78. package/dist-skill/docs/generated/curves.md +387 -1609
  79. package/dist-skill/docs/generated/lib.md +238 -112
  80. package/dist-skill/docs/generated/output.md +51 -76
  81. package/dist-skill/docs/generated/runtime-names.md +16 -22
  82. package/dist-skill/docs/generated/sdf.md +68 -284
  83. package/dist-skill/docs/generated/sheet-metal.md +68 -335
  84. package/dist-skill/docs/generated/sketch.md +240 -1160
  85. package/dist-skill/docs/generated/viewport.md +75 -223
  86. package/dist-skill/docs/generated/wood.md +21 -49
  87. package/dist-skill/docs/guides/coordinate-system.md +4 -42
  88. package/dist-skill/docs/guides/inspection-bundles.md +44 -442
  89. package/dist-skill/docs/guides/joint-design.md +18 -79
  90. package/dist-skill/docs/guides/positioning.md +21 -143
  91. package/dist-skill/docs/guides/scene-presentation.md +89 -0
  92. package/dist-skill/docs/guides/surface-members.md +26 -0
  93. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
  94. package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
  95. package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
  96. package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
  97. package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
  98. package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
  99. package/dist-skill/library/forgecad-make-a-model/SKILL.md +111 -532
  100. package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
  101. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
  102. package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
  103. package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
  104. package/dist-skill/library/forgecad-project/SKILL.md +13 -131
  105. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
  106. package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
  107. package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
  108. package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
  109. package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
  110. package/dist-skill/website/skills/forgecad-component-model.md +53 -0
  111. package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
  112. package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
  113. package/dist-skill/website/skills/forgecad-lld.md +41 -0
  114. package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
  115. package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
  116. package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
  117. package/dist-skill/website/skills/forgecad-project.md +26 -0
  118. package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
  119. package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
  120. package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
  121. package/dist-skill/website/skills/forgecad.md +122 -0
  122. package/dist-skill/website/skills/index.md +26 -0
  123. package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
  124. package/examples/api/conformal-product-ribbon.forge.js +1 -1
  125. package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
  126. package/examples/api/extrude-options.forge.js +4 -2
  127. package/examples/api/field-loft-drive-tip.forge.js +40 -0
  128. package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
  129. package/examples/api/helix-basics.forge.js +2 -2
  130. package/examples/api/highlight-debug.forge.js +10 -10
  131. package/examples/api/mesh-import-slats.forge.js +1 -1
  132. package/examples/api/real-product-curves.forge.js +1 -1
  133. package/examples/api/route3d-elbow.forge.js +3 -0
  134. package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
  135. package/examples/api/sdf-shapes.forge.js +2 -5
  136. package/examples/api/sketch-rounding-strategies.forge.js +6 -6
  137. package/examples/api/surface-member-bottle-cage.forge.js +3 -3
  138. package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
  139. package/examples/api/surface-member-razor-inlay.forge.js +1 -1
  140. package/examples/api/variable-sweep-test.forge.js +4 -2
  141. package/examples/mechanical/airplane-propeller.forge.js +74 -39
  142. package/examples/nurbs-surface.forge.js +1 -1
  143. package/examples/products/iphone.forge.js +1 -1
  144. package/package.json +4 -1
  145. package/dist/assets/EditorApp-Beb-IZ0y.js +0 -14014
  146. package/dist/docs-raw/guides/geometry-conventions.md +0 -52
  147. package/dist/docs-raw/guides/modeling-recipes.md +0 -78
  148. package/dist-skill/docs/guides/geometry-conventions.md +0 -52
  149. package/dist-skill/docs/guides/modeling-recipes.md +0 -78
  150. package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
  151. package/examples/api/bolted-service-cover.forge.js +0 -17
  152. package/examples/api/cable-gland-anchor.forge.js +0 -14
  153. package/examples/api/captured-cartridge-guide.forge.js +0 -14
  154. package/examples/api/captured-linear-slide.forge.js +0 -13
  155. package/examples/api/clevis-pin-joint.forge.js +0 -13
  156. package/examples/api/datum-enclosure.forge.js +0 -16
  157. package/examples/api/hose-barb-port.forge.js +0 -14
  158. package/examples/api/knuckled-hinge-assembly.forge.js +0 -15
  159. package/examples/api/living-hinge-cover.forge.js +0 -14
  160. package/examples/api/pcb-terminal-block.forge.js +0 -22
  161. package/examples/api/pinned-lever-pivot-stack.forge.js +0 -14
  162. package/examples/api/retained-shaft-knob-stack.forge.js +0 -15
  163. package/examples/api/routed-tube-clip.forge.js +0 -15
  164. package/examples/api/seated-bearing-stack.forge.js +0 -30
  165. package/examples/api/snap-latch-cover.forge.js +0 -14
  166. package/examples/api/thumb-screw-clamp.forge.js +0 -15
@@ -1,52 +0,0 @@
1
- ---
2
- skill-group: geometry
3
- skill-order: 2
4
- ---
5
-
6
- # Geometry Conventions
7
-
8
- ForgeCAD wraps Manifold (mesh kernel) and Three.js (Y-up renderer). This doc captures convention mismatches and how ForgeCAD resolves them.
9
-
10
- ## Winding Order
11
-
12
- CCW = positive area, CW = empty in Manifold's `CrossSection`. ForgeCAD auto-fixes at all entry points:
13
- - `polygon(points)` — computes signed area (shoelace), reverses if CW
14
- - `path().close()` — same fix
15
-
16
- **Rule for new code:** Any function accepting user point arrays that creates a `CrossSection` MUST auto-fix winding.
17
-
18
- ## Coordinate System (Z-up vs Y-up)
19
-
20
- Three.js is Y-up; ForgeCAD is Z-up. Fix applied at camera level (`camera.up = (0,0,1)`) — geometry coordinates are native Z-up. Never swap Y/Z in geometry.
21
-
22
- ## Revolution Axis
23
-
24
- `Sketch.revolve()` produces a world Z-axis solid of revolution. Profile X = radial distance from the Z axis, Profile Y = world Z height after revolution. Profile should stay at X > 0 unless intentionally touching the axis.
25
-
26
- ## Boolean Winding (3D)
27
-
28
- Manifold requires consistent outward face normals. ForgeCAD only creates meshes through Manifold's own constructors, which guarantee correct normals.
29
-
30
- ## Transform Order
31
-
32
- Transforms apply left-to-right. `Sketch.rotate()`, `scale()`, and `mirror()` operate around bounding-box center. For 3D `Shape` / `ShapeGroup`, `scale()` and `mirror()` operate around bounding-box center, while `rotate()` remains origin-based unless you pass `options.pivot` or use `rotateAroundAxis(...)`.
33
-
34
- For explicit transform objects: `A.mul(B)` = apply A then B; `composeChain(A, B, C)` = A→B→C.
35
-
36
- ## Assembly Frame Composition
37
-
38
- ```ts
39
- childWorld = composeChain(childBase, jointMotion, jointFrame, parentWorld)
40
- ```
41
-
42
- Prefer `composeChain(...)` over manual `.mul(...).mul(...)` in kinematics code to avoid order mistakes.
43
-
44
- ## Summary
45
-
46
- | Convention | User sees | Kernel needs | Where we fix it |
47
- |---|---|---|---|
48
- | Winding | Any point order | CCW | `polygon()`, `path().close()` |
49
- | Up axis | Z-up | Y-up (Three.js) | `camera.up`, gizmo labels |
50
- | Revolution | "revolve this profile" | Profile X = radius, Profile Y = world Z height | Documented and regression-tested |
51
- | Face normals | Doesn't think about it | Outward-pointing | Manifold constructors |
52
- | Transform order | Left-to-right chain | Post-multiply | Native match |
@@ -1,78 +0,0 @@
1
- ---
2
- skill-group: recipes
3
- skill-order: 1
4
- ---
5
-
6
- # Modeling Recipes
7
-
8
- ## Iteration Bias
9
-
10
- - Default to a buildable first pass instead of a long proposal.
11
- - Replace a broken model wholesale when that is faster than incremental patching.
12
- - Validate early with `forgecad run <file>`.
13
-
14
- ## Common Patterns
15
-
16
- ### Hollow Shell
17
- ```javascript
18
- const innerSize = outer - 2 * wall;
19
- const outerBox = box(outer, outer, outer).placeReference('center', [0, 0, 0]);
20
- const innerBox = box(innerSize, innerSize, innerSize).placeReference('center', [0, 0, 0]);
21
- return outerBox.subtract(innerBox);
22
- ```
23
-
24
- ### Sketch-Based Twist
25
- ```javascript
26
- const outer = ngon(sides, radius);
27
- const inner = ngon(sides, radius - wall);
28
- return outer.subtract(inner).extrude(height, { twist: 45, divisions: 32 });
29
- ```
30
-
31
- ### Rounded Profiles
32
- ```javascript
33
- // All convex corners — offset trick
34
- const base = rect(50, 30).offset(-3, 'Round').offset(3, 'Round');
35
-
36
- // Selected corners only
37
- const roof = filletCorners(roofPoints, [
38
- { index: 3, radius: 19 },
39
- { index: 4, radius: 19 },
40
- { index: 5, radius: 19 },
41
- ]);
42
- ```
43
-
44
- ### Choosing the right sketch-rounding tool
45
-
46
- - `offset(-r).offset(+r)` — round every convex corner of a closed outline
47
- - `stroke(points, width, 'Round')` — centerline-based geometry (ribs, traces)
48
- - `filletCorners(points, ...)` — selective true-corner fillets on mixed profiles
49
-
50
- ## Best Practices
51
-
52
- - All dimensions in millimeters; angles in degrees.
53
- - Primitives are centered on XY, base at Z=0. Use `placeReference('center', [0,0,0])` to center on all axes.
54
- - Prefer named intermediate values over deeply nested one-liners.
55
- - `union2d`, `difference2d`, `intersection2d` batch faster than chained `.add()` / `.subtract()`.
56
-
57
- ## Debugging
58
-
59
- ```javascript
60
- console.log("Volume:", shape.volume());
61
- ```
62
-
63
- For sketch-heavy work, compare the raw profile and rounded profile side-by-side before extruding:
64
-
65
- ```javascript
66
- return [
67
- { name: "Raw", sketch: polygon(roofPoints) },
68
- { name: "Rounded", sketch: filletCorners(roofPoints, [...]).translate(120, 0) },
69
- ];
70
- ```
71
-
72
- ## Common Errors
73
-
74
- - `"Kernel not initialized"` — internal/runtime issue, reload the app
75
- - zero dimensions or self-intersecting sketches → invalid geometry
76
- - wrong variable name → `"Cannot read property of undefined"`
77
-
78
- For deeper API coverage, load the relevant generated doc group from the skill source map instead of reaching for repo examples by default.
@@ -1,52 +0,0 @@
1
- ---
2
- skill-group: geometry
3
- skill-order: 2
4
- ---
5
-
6
- # Geometry Conventions
7
-
8
- ForgeCAD wraps Manifold (mesh kernel) and Three.js (Y-up renderer). This doc captures convention mismatches and how ForgeCAD resolves them.
9
-
10
- ## Winding Order
11
-
12
- CCW = positive area, CW = empty in Manifold's `CrossSection`. ForgeCAD auto-fixes at all entry points:
13
- - `polygon(points)` — computes signed area (shoelace), reverses if CW
14
- - `path().close()` — same fix
15
-
16
- **Rule for new code:** Any function accepting user point arrays that creates a `CrossSection` MUST auto-fix winding.
17
-
18
- ## Coordinate System (Z-up vs Y-up)
19
-
20
- Three.js is Y-up; ForgeCAD is Z-up. Fix applied at camera level (`camera.up = (0,0,1)`) — geometry coordinates are native Z-up. Never swap Y/Z in geometry.
21
-
22
- ## Revolution Axis
23
-
24
- `Sketch.revolve()` produces a world Z-axis solid of revolution. Profile X = radial distance from the Z axis, Profile Y = world Z height after revolution. Profile should stay at X > 0 unless intentionally touching the axis.
25
-
26
- ## Boolean Winding (3D)
27
-
28
- Manifold requires consistent outward face normals. ForgeCAD only creates meshes through Manifold's own constructors, which guarantee correct normals.
29
-
30
- ## Transform Order
31
-
32
- Transforms apply left-to-right. `Sketch.rotate()`, `scale()`, and `mirror()` operate around bounding-box center. For 3D `Shape` / `ShapeGroup`, `scale()` and `mirror()` operate around bounding-box center, while `rotate()` remains origin-based unless you pass `options.pivot` or use `rotateAroundAxis(...)`.
33
-
34
- For explicit transform objects: `A.mul(B)` = apply A then B; `composeChain(A, B, C)` = A→B→C.
35
-
36
- ## Assembly Frame Composition
37
-
38
- ```ts
39
- childWorld = composeChain(childBase, jointMotion, jointFrame, parentWorld)
40
- ```
41
-
42
- Prefer `composeChain(...)` over manual `.mul(...).mul(...)` in kinematics code to avoid order mistakes.
43
-
44
- ## Summary
45
-
46
- | Convention | User sees | Kernel needs | Where we fix it |
47
- |---|---|---|---|
48
- | Winding | Any point order | CCW | `polygon()`, `path().close()` |
49
- | Up axis | Z-up | Y-up (Three.js) | `camera.up`, gizmo labels |
50
- | Revolution | "revolve this profile" | Profile X = radius, Profile Y = world Z height | Documented and regression-tested |
51
- | Face normals | Doesn't think about it | Outward-pointing | Manifold constructors |
52
- | Transform order | Left-to-right chain | Post-multiply | Native match |
@@ -1,78 +0,0 @@
1
- ---
2
- skill-group: recipes
3
- skill-order: 1
4
- ---
5
-
6
- # Modeling Recipes
7
-
8
- ## Iteration Bias
9
-
10
- - Default to a buildable first pass instead of a long proposal.
11
- - Replace a broken model wholesale when that is faster than incremental patching.
12
- - Validate early with `forgecad run <file>`.
13
-
14
- ## Common Patterns
15
-
16
- ### Hollow Shell
17
- ```javascript
18
- const innerSize = outer - 2 * wall;
19
- const outerBox = box(outer, outer, outer).placeReference('center', [0, 0, 0]);
20
- const innerBox = box(innerSize, innerSize, innerSize).placeReference('center', [0, 0, 0]);
21
- return outerBox.subtract(innerBox);
22
- ```
23
-
24
- ### Sketch-Based Twist
25
- ```javascript
26
- const outer = ngon(sides, radius);
27
- const inner = ngon(sides, radius - wall);
28
- return outer.subtract(inner).extrude(height, { twist: 45, divisions: 32 });
29
- ```
30
-
31
- ### Rounded Profiles
32
- ```javascript
33
- // All convex corners — offset trick
34
- const base = rect(50, 30).offset(-3, 'Round').offset(3, 'Round');
35
-
36
- // Selected corners only
37
- const roof = filletCorners(roofPoints, [
38
- { index: 3, radius: 19 },
39
- { index: 4, radius: 19 },
40
- { index: 5, radius: 19 },
41
- ]);
42
- ```
43
-
44
- ### Choosing the right sketch-rounding tool
45
-
46
- - `offset(-r).offset(+r)` — round every convex corner of a closed outline
47
- - `stroke(points, width, 'Round')` — centerline-based geometry (ribs, traces)
48
- - `filletCorners(points, ...)` — selective true-corner fillets on mixed profiles
49
-
50
- ## Best Practices
51
-
52
- - All dimensions in millimeters; angles in degrees.
53
- - Primitives are centered on XY, base at Z=0. Use `placeReference('center', [0,0,0])` to center on all axes.
54
- - Prefer named intermediate values over deeply nested one-liners.
55
- - `union2d`, `difference2d`, `intersection2d` batch faster than chained `.add()` / `.subtract()`.
56
-
57
- ## Debugging
58
-
59
- ```javascript
60
- console.log("Volume:", shape.volume());
61
- ```
62
-
63
- For sketch-heavy work, compare the raw profile and rounded profile side-by-side before extruding:
64
-
65
- ```javascript
66
- return [
67
- { name: "Raw", sketch: polygon(roofPoints) },
68
- { name: "Rounded", sketch: filletCorners(roofPoints, [...]).translate(120, 0) },
69
- ];
70
- ```
71
-
72
- ## Common Errors
73
-
74
- - `"Kernel not initialized"` — internal/runtime issue, reload the app
75
- - zero dimensions or self-intersecting sketches → invalid geometry
76
- - wrong variable name → `"Cannot read property of undefined"`
77
-
78
- For deeper API coverage, load the relevant generated doc group from the skill source map instead of reaching for repo examples by default.
@@ -1,79 +0,0 @@
1
- # Prompt Template
2
-
3
- Use this as a fill-in structure, not as fixed text.
4
-
5
- ## Block Order
6
-
7
- 1. Artifact identity
8
- 2. Mechanical / build truth
9
- 3. Material and color truth
10
- 4. Pose and shot
11
- 5. Render style
12
- 6. Negative constraints
13
-
14
- ## Skeleton
15
-
16
- ```text
17
- A [artifact identity and scale], designed as a real buildable CAD-driven object, not a fantasy concept. [Major subassemblies and mechanism truth]. [Materials, colors, finish, and visible hardware truth]. Show it in [pose / state]. [Shot, camera, background, and lighting]. It should look physically buildable and mechanically honest, with visible part boundaries and serviceable architecture. No [negative 1], no [negative 2], no [negative 3].
18
- ```
19
-
20
- ## Default Prompt Shape
21
-
22
- Use this for most first-pass prompts:
23
-
24
- - artifact identity:
25
- compact benchtop robot arm, printable gripper, modular fixture, shop tool, enclosure, etc.
26
- - mechanism truth:
27
- weighted base, exposed belt reductions, mounted motor, support shafts, guide rods, removable cover, jaw mechanism, hinge stack, etc.
28
- - materials:
29
- PETG, TPU, aluminum shaft, brass pinion, black belt, matte plastic, realistic metal
30
- - shot:
31
- front-left three-quarter view
32
- - render style:
33
- clean premium studio product render, neutral background, soft diffused lighting, crisp soft shadows
34
- - negatives:
35
- fake sleek shell, hidden mechanics, over-smoothed geometry, text, labels, humans
36
-
37
- ## Shot Suffixes
38
-
39
- Useful one-line suffixes:
40
-
41
- - `front-left three-quarter hero view, eye-level product camera`
42
- - `rear-right three-quarter view showing motor placement and belt routing`
43
- - `pure side view showing the reach silhouette and joint stack clearly`
44
- - `close-up on the wrist and end effector showing the mechanism clearly`
45
-
46
- ## Mode Swaps
47
-
48
- ### Honest Hero Render
49
-
50
- Add phrases like:
51
-
52
- - `clean premium studio product render`
53
- - `show the final artifact clearly`
54
- - `physically buildable and mechanically honest`
55
- - `visible part boundaries and serviceable architecture`
56
-
57
- ### Builder-First Mechanical Render
58
-
59
- Add phrases like:
60
-
61
- - `emphasizing how it would actually be built`
62
- - `clear visibility of interfaces, seams, and subsystem boundaries`
63
- - `serious prototype, not a polished consumer shell`
64
-
65
- ### Mild Exploded Assembly Render
66
-
67
- Add phrases like:
68
-
69
- - `major modules separated by small clean gaps`
70
- - `reveal the build logic without chaotic disassembly`
71
- - `no tiny floating fragments, no labels, no arrows`
72
-
73
- ### Workshop Prototype Realism
74
-
75
- Add phrases like:
76
-
77
- - `realistic workshop photo`
78
- - `visible print lines and honest surface texture`
79
- - `believable but uncluttered engineering bench background`
@@ -1,17 +0,0 @@
1
- // Bolted service cover: parent ledge, gasket, fused pull tabs, aligned holes, and installed screws.
2
-
3
- const cover = lib.boltedServiceCover({
4
- width: 90,
5
- depth: 56,
6
- coverThickness: 3,
7
- parentThickness: 8,
8
- ledgeWidth: 10,
9
- screwSize: 'M4',
10
- boltInset: [6, 6],
11
- });
12
-
13
- verify.equal('four retained cover screws', cover.screws.length, 4);
14
- verify.greaterThan('cover has edge margin around service opening', cover.dims.ledgeWidth, 6);
15
- verify.notColliding('cover does not collide with gasket', cover.cover, cover.gasket);
16
-
17
- return cover.parts;
@@ -1,14 +0,0 @@
1
- const anchor = lib.cableGlandAnchorAssembly({
2
- cableDiameter: 6,
3
- panelThickness: 3,
4
- panelWidth: 62,
5
- panelHeight: 44,
6
- });
7
-
8
- verify.equal('cable gland anchor has four retained parts', anchor.parts.length, 4);
9
- verify.greaterThan('panel leaves material around gland flange', anchor.dims.panelHeight - anchor.dims.flangeDiameter, 8);
10
- verify.notColliding('cable clears gland bore', anchor.cable, anchor.gland);
11
- verify.notColliding('gland clears panel hole', anchor.gland, anchor.panel);
12
- verify.clearanceBetween('gland flange is seated at panel pocket', anchor.gland, anchor.panel, 0.01, 0.2);
13
-
14
- return anchor.parts;
@@ -1,14 +0,0 @@
1
- const cassette = lib.capturedCartridgeGuideAssembly({
2
- length: 150,
3
- cartridgeLength: 72,
4
- insertion: 28,
5
- });
6
-
7
- verify.equal('cartridge guide has guide and removable cassette', cassette.parts.length, 2);
8
- verify.notColliding('cartridge clears guide rails and rear stop', cassette.cartridge, cassette.guide);
9
- verify.greaterThan('cartridge flange is captured by guide lips', cassette.dims.cartridgeWidth, cassette.dims.throatWidth);
10
- verify.lessThan('cartridge still clears inner guide width', cassette.dims.cartridgeWidth, cassette.dims.innerWidth);
11
- verify.greaterThan('cartridge body passes through the guide throat', cassette.dims.throatWidth, cassette.dims.cartridgeBodyWidth);
12
- verify.inRange('cartridge insertion stays inside travel', cassette.dims.insertion, 0, cassette.dims.maxInsertion);
13
-
14
- return cassette.parts;
@@ -1,13 +0,0 @@
1
- const slide = lib.capturedLinearSlide({
2
- length: 160,
3
- railWidth: 38,
4
- carriageLength: 52,
5
- travel: 42,
6
- });
7
-
8
- verify.equal('captured slide has rail and carriage parts', slide.parts.length, 2);
9
- verify.greaterThan('carriage is wider than the throat opening', slide.dims.carriageWidth, slide.dims.throatWidth);
10
- verify.greaterThan('slide retains usable travel', slide.dims.maxTravel, 80);
11
- verify.minClearance('carriage clears captured rail', slide.carriage, slide.rail, 0.05);
12
-
13
- return slide.parts;
@@ -1,13 +0,0 @@
1
- const clevis = lib.clevisPinJointAssembly({
2
- pinDiameter: 4,
3
- linkThickness: 6,
4
- linkArmLength: 38,
5
- earThickness: 4,
6
- });
7
-
8
- verify.equal('clevis joint has three retained parts', clevis.parts.length, 3);
9
- verify.greaterThan('link eye has material around pin bore', clevis.dims.eyeOuterRadius - clevis.dims.boreDiameter / 2, 4);
10
- verify.greaterThan('clevis gap clears the link eye', clevis.dims.clevisGap, clevis.dims.linkThickness);
11
- verify.minClearance('link eye clears clevis yoke', clevis.link, clevis.clevis, 0.05);
12
-
13
- return clevis.parts;
@@ -1,16 +0,0 @@
1
- const enclosure = lib.datumEnclosureAssembly({
2
- width: 96,
3
- depth: 64,
4
- height: 18,
5
- screwSize: 'M3',
6
- });
7
-
8
- verify.equal('datum enclosure has base gasket cover and four screws', enclosure.parts.length, 7);
9
- verify.greaterThan('internal cavity keeps usable width', enclosure.dims.innerWidth, 80);
10
- verify.greaterThan('standoff wall remains around screw envelope', enclosure.dims.standoffDiameter - enclosure.dims.threadEnvelopeDia, 4);
11
- verify.greaterThan('service port leaves top wall material', enclosure.dims.height - enclosure.dims.baseThickness - enclosure.dims.portHeight, 6);
12
- verify.notColliding('cover clears seated gasket', enclosure.cover, enclosure.gasket);
13
- verify.notColliding('first screw clears standoff thread envelope', enclosure.screws[0], enclosure.base);
14
- verify.inRange('cover stack has small seating clearance', enclosure.dims.faceClearance, 0.01, 0.08);
15
-
16
- return enclosure.parts;
@@ -1,14 +0,0 @@
1
- const hosePort = lib.hoseBarbPortAssembly({
2
- hoseInnerDiameter: 6,
3
- hoseOuterDiameter: 10,
4
- barbCount: 3,
5
- });
6
-
7
- verify.equal('hose barb port has receiver fitting hose and clamp', hosePort.parts.length, 4);
8
- verify.greaterThan('barb peaks retain nominal hose ID', hosePort.dims.barbPeakDiameter, hosePort.dims.hoseInnerDiameter);
9
- verify.greaterThan('hose has wall around installed barb envelope', hosePort.dims.hoseOuterDiameter - hosePort.dims.installedHoseBoreDiameter, 1.2);
10
- verify.notColliding('hose clears barb peaks', hosePort.hose, hosePort.fitting);
11
- verify.notColliding('clamp clears hose outside', hosePort.clamp, hosePort.hose);
12
- verify.inRange('fitting shoulder seats near boss face', hosePort.dims.faceClearance, 0.01, 0.08);
13
-
14
- return hosePort.parts;
@@ -1,15 +0,0 @@
1
- const hinge = lib.knuckledHingeAssembly({
2
- length: 70,
3
- leafLength: 28,
4
- leafThickness: 1.8,
5
- barrelOuterRadius: 3.2,
6
- pinDiameter: 2,
7
- openAngleDeg: 42,
8
- });
9
-
10
- verify.equal('hinge has two leaves and one retained pin', hinge.parts.length, 3);
11
- verify.greaterThan('barrel wall remains around pin bore', hinge.dims.barrelOuterRadius - hinge.dims.boreDiameter / 2, 1.5);
12
- verify.greaterThan('hinge has meaningful knuckle length', hinge.dims.knuckleLength, hinge.dims.pinDiameter * 2);
13
- verify.minClearance('moving leaf clears fixed leaf', hinge.movingLeaf, hinge.fixedLeaf, 0.05);
14
-
15
- return hinge.parts;
@@ -1,14 +0,0 @@
1
- const livingCover = lib.livingHingeCoverAssembly({
2
- width: 64,
3
- coverDepth: 42,
4
- fixedLeafDepth: 18,
5
- });
6
-
7
- verify.equal('living hinge cover is one molded part', livingCover.parts.length, 1);
8
- verify.equal('one-piece living hinge cover has one body', livingCover.cover.numBodies(), 1);
9
- verify.greaterThan('living hinge web is much thinner than rigid leaves', livingCover.dims.flexRatio, 3.5);
10
- verify.greaterThan('hinge web spans the full cover width', livingCover.dims.width, 60);
11
- verify.greaterThan('snap barb has positive retention height', livingCover.dims.snapBarbHeight, 1);
12
- verify.greaterThan('catch land is present on fixed leaf', livingCover.dims.catchLandDepth, 2);
13
-
14
- return livingCover.parts;
@@ -1,22 +0,0 @@
1
- const terminalStack = lib.pcbTerminalBlockAssembly({
2
- terminalCount: 5,
3
- terminalPitch: 5.08,
4
- screwSize: 'M3',
5
- });
6
-
7
- verify.equal('terminal block exposes one pin per terminal', terminalStack.pinPositions.length, terminalStack.dims.terminalCount);
8
- verify.greaterThan(
9
- 'PCB leaves mounting margin around terminal block',
10
- terminalStack.dims.boardWidth - terminalStack.dims.terminalBlockWidth,
11
- 20,
12
- );
13
- verify.notColliding('terminal pins clear PCB holes', terminalStack.terminalBlock, terminalStack.pcb);
14
- verify.notColliding('mounting screws clear PCB and standoff holes', union(...terminalStack.screws), union(terminalStack.pcb, terminalStack.backplate));
15
- verify.greaterThan(
16
- 'standoffs retain wall around screw envelopes',
17
- terminalStack.dims.standoffDiameter - terminalStack.dims.standoffThreadEnvelopeDiameter,
18
- 3,
19
- );
20
- verify.greaterThan('pin holes leave PCB web between terminals', terminalStack.dims.terminalPitch - terminalStack.dims.pinHoleDiameter, 3);
21
-
22
- return terminalStack.parts;
@@ -1,14 +0,0 @@
1
- const lever = lib.pinnedLeverAssembly({
2
- armLength: 56,
3
- armWidth: 10,
4
- leverThickness: 5,
5
- pinDiameter: 5,
6
- supportThickness: 8,
7
- });
8
-
9
- verify.equal('pinned lever stack has five retained parts', lever.parts.length, 5);
10
- verify.greaterThan('thrust washers have real thickness', lever.dims.washerThickness, 0);
11
- verify.greaterThan('pivot hub has material around the bore', lever.dims.hubRadius - lever.dims.boreDiameter / 2, 3);
12
- verify.notColliding('lower washer does not collide with support', lever.washers.lower, lever.support);
13
-
14
- return lever.parts;
@@ -1,15 +0,0 @@
1
- const trunnion = lib.retainedShaftAssembly({
2
- supportSpacing: 96,
3
- shaftDiameter: 8,
4
- supportThickness: 6,
5
- supportHeight: 42,
6
- knobDiameter: 24,
7
- knobThickness: 8,
8
- });
9
-
10
- verify.equal('retained shaft stack has seven parts', trunnion.parts.length, 7);
11
- verify.greaterThan('support cheeks leave material around bore', trunnion.dims.supportHeight - trunnion.dims.boreDiameter, 20);
12
- verify.greaterThan('shaft is long enough to retain knobs', trunnion.dims.shaftLength, trunnion.dims.supportSpacing);
13
- verify.notColliding('left washer does not collide with support cheek', trunnion.washers.left, trunnion.supports.left);
14
-
15
- return trunnion.parts;
@@ -1,15 +0,0 @@
1
- const route = lib.routedTubeClipAssembly({
2
- tubeDiameter: 6,
3
- tubeLength: 130,
4
- clipCount: 3,
5
- screwSize: 'M3',
6
- });
7
-
8
- verify.equal('tube route has three retaining clips', route.clips.length, 3);
9
- verify.equal('each retaining clip has two installed screws', route.screws.length, route.clips.length * 2);
10
- verify.notColliding('tube clears saddle clip bores', route.tube, union(...route.clips));
11
- verify.notColliding('clip screws clear panel and clip holes', union(...route.screws), union(route.panel, ...route.clips));
12
- verify.greaterThan('clip wall leaves material around tube bore', route.dims.clipWallThickness, route.dims.screwHeadDiameter);
13
- verify.greaterThan('tube bore clears tube outside diameter', route.dims.tubeBoreDiameter - route.dims.tubeDiameter, 0.3);
14
-
15
- return route.parts;
@@ -1,30 +0,0 @@
1
- const bearingStack = lib.seatedBearingAssembly({
2
- bearingOuterDiameter: 22,
3
- bearingInnerDiameter: 8,
4
- bearingWidth: 7,
5
- shaftDiameter: 7.4,
6
- housingWidth: 54,
7
- housingDepth: 42,
8
- housingThickness: 10,
9
- });
10
-
11
- verify.equal('seated bearing stack has three retained parts', bearingStack.parts.length, 3);
12
- verify.greaterThan(
13
- 'housing boss leaves material around bearing pocket',
14
- bearingStack.dims.bossOuterDiameter - bearingStack.dims.pocketDiameter,
15
- 5,
16
- );
17
- verify.greaterThan(
18
- 'bearing bore clears the shaft',
19
- bearingStack.dims.bearingInnerDiameter,
20
- bearingStack.dims.shaftDiameter + bearingStack.dims.runningClearance,
21
- );
22
- verify.clearanceBetween(
23
- 'bearing is seated in counterbore',
24
- bearingStack.bearing,
25
- bearingStack.housing,
26
- -0.01,
27
- bearingStack.dims.runningClearance + 0.1,
28
- );
29
-
30
- return bearingStack.parts;
@@ -1,14 +0,0 @@
1
- const snapCover = lib.snapLatchCoverAssembly({
2
- width: 72,
3
- depth: 44,
4
- ledgeWidth: 8,
5
- parentThickness: 6,
6
- });
7
-
8
- verify.equal('snap latch cover has receiver and cover parts', snapCover.parts.length, 2);
9
- verify.greaterThan('snap hooks tuck under catch land', snapCover.dims.hookThrow, snapCover.dims.latchThickness);
10
- verify.greaterThan('receiver leaves a usable service opening', snapCover.dims.openingWidth, 48);
11
- verify.notColliding('snap hooks clear receiver windows', snapCover.cover, snapCover.parent);
12
- verify.inRange('snap cover has small seating clearance', snapCover.dims.faceClearance, 0.01, 0.08);
13
-
14
- return snapCover.parts;
@@ -1,15 +0,0 @@
1
- // Thumb-screw clamp with a real threaded boss, captive pressure pad, and clamped workpiece.
2
- const clamp = lib.thumbScrewClampAssembly({
3
- screwSize: 'M6',
4
- workpieceThickness: 20,
5
- workpieceDepth: 50,
6
- });
7
-
8
- verify.equal('thumb screw clamp has frame workpiece and screw', clamp.parts.length, 3);
9
- verify.notColliding('thumb screw clears threaded boss bore', clamp.clampScrew, clamp.frame);
10
- verify.clearanceBetween('pressure pad is seated on workpiece', clamp.clampScrew, clamp.workpiece, -0.01, 0.05);
11
- verify.clearanceBetween('fixed anvil is seated on workpiece', clamp.frame, clamp.workpiece, -0.01, 0.05);
12
- verify.greaterThan('threaded boss leaves wall around screw envelope', clamp.dims.bossDiameter - clamp.dims.threadEnvelopeDiameter, 4);
13
- verify.greaterThan('frame depth captures the workpiece and pads', clamp.dims.frameDepth, clamp.dims.workpieceDepth);
14
-
15
- return clamp.parts;