forgecad 0.9.2 → 0.9.3

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 (79) hide show
  1. package/LICENSE +7 -5
  2. package/README.md +1 -1
  3. package/README.public.md +24 -2
  4. package/dist/assets/{AdminPage-Bs4PiK00.js → AdminPage-4jihcEk_.js} +1 -1
  5. package/dist/assets/{BlogPage-DVmgN0ma.js → BlogPage-BvzruKtw.js} +1 -1
  6. package/dist/assets/{DocsPage-BP6wlsBN.js → DocsPage-DHbd-WS-.js} +13 -13
  7. package/dist/assets/{EditorApp-Arw2NnGJ.js → EditorApp-C5P2rBfh.js} +433 -84
  8. package/dist/assets/{EditorApp-VY9lXx0N.css → EditorApp-DS0AIUrZ.css} +25 -0
  9. package/dist/assets/{EmbedViewer-qgQiOahL.js → EmbedViewer-B70wQwlE.js} +2 -2
  10. package/dist/assets/{LandingPageProofDriven-DvhtmWOz.js → LandingPageProofDriven-DIsYTnep.js} +1 -1
  11. package/dist/assets/{PricingPage-Ck3CP2ti.css → PricingPage-BMedqFef.css} +48 -0
  12. package/dist/assets/{PricingPage-657oLvWh.js → PricingPage-YPOr12pP.js} +34 -6
  13. package/dist/assets/{SettingsPage-wNy3_2yn.js → SettingsPage-rntoyJ3b.js} +10 -13
  14. package/dist/assets/{app-BdBoMQeO.js → app-CWucmnLZ.js} +801 -1208
  15. package/dist/assets/cli/{render-Ci3jjyT1.js → render-DZHmUySW.js} +214 -23
  16. package/dist/assets/copy-CQKQppF-.js +8 -0
  17. package/dist/assets/{evalWorker-CMCAbK8r.js → evalWorker-C3dKxi9Y.js} +1117 -95
  18. package/dist/assets/{manifold-BMn-8Vf8.js → manifold-CQ3FhfWB.js} +1 -1
  19. package/dist/assets/{manifold-jlYQ6E5R.js → manifold-CU0G1yYL.js} +1 -1
  20. package/dist/assets/{manifold-DbyILno4.js → manifold-CYWZMfjB.js} +2 -2
  21. package/dist/assets/{renderSceneState-DAnqvxSt.js → renderSceneState-BBUrnsUN.js} +1 -1
  22. package/dist/assets/{reportWorker-BcRVMHK-.js → reportWorker-BhZ7DjxQ.js} +1091 -95
  23. package/dist/assets/{sectionPlaneMath-DXJ_TdIW.js → sectionPlaneMath-BxfokaJE.js} +1091 -95
  24. package/dist/cli/render.html +1 -1
  25. package/dist/docs/index.html +2 -2
  26. package/dist/docs-raw/AI/usage.md +182 -89
  27. package/dist/docs-raw/API/core/concepts.md +26 -0
  28. package/dist/docs-raw/CLI.md +58 -37
  29. package/dist/docs-raw/INDEX.md +81 -64
  30. package/dist/docs-raw/cli-monetization.md +9 -8
  31. package/dist/docs-raw/generated/concepts.md +111 -4
  32. package/dist/docs-raw/generated/core.md +2 -0
  33. package/dist/docs-raw/generated/curves.md +480 -1
  34. package/dist/docs-raw/generated/output.md +1 -0
  35. package/dist/docs-raw/generated/sketch.md +2 -0
  36. package/dist/docs-raw/generated/viewport.md +81 -3
  37. package/dist/docs-raw/product/user-outreach-email-templates.md +159 -0
  38. package/dist/docs-raw/skills/forgecad-image-replicator.md +1 -1
  39. package/dist/docs-raw/skills/forgecad-make-a-model.md +33 -4
  40. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +1 -1
  41. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  42. package/dist/docs-raw/skills/forgecad-render-inspect.md +1 -1
  43. package/dist/docs-raw/skills/forgecad.md +2 -1
  44. package/dist/docs-raw/welcome.md +85 -137
  45. package/dist/index.html +1 -1
  46. package/dist/llms.txt +4 -3
  47. package/dist/sitemap.xml +6 -6
  48. package/dist-cli/forgecad.js +1413 -219
  49. package/dist-cli/forgecad.js.map +1 -1
  50. package/dist-skill/CONTEXT.md +594 -5
  51. package/dist-skill/SKILL-dev.md +2 -1
  52. package/dist-skill/SKILL.md +2 -1
  53. package/dist-skill/docs/API/core/concepts.md +26 -0
  54. package/dist-skill/docs/CLI.md +58 -37
  55. package/dist-skill/docs/generated/core.md +2 -0
  56. package/dist-skill/docs/generated/curves.md +480 -1
  57. package/dist-skill/docs/generated/output.md +1 -0
  58. package/dist-skill/docs/generated/sketch.md +2 -0
  59. package/dist-skill/docs/generated/viewport.md +81 -3
  60. package/dist-skill/docs-dev/API/core/concepts.md +26 -0
  61. package/dist-skill/docs-dev/CLI.md +58 -37
  62. package/dist-skill/docs-dev/generated/core.md +2 -0
  63. package/dist-skill/docs-dev/generated/curves.md +480 -1
  64. package/dist-skill/docs-dev/generated/output.md +1 -0
  65. package/dist-skill/docs-dev/generated/sketch.md +2 -0
  66. package/dist-skill/docs-dev/generated/viewport.md +81 -3
  67. package/dist-skill/library/README.md +0 -1
  68. package/dist-skill/library/forgecad-image-replicator/SKILL.md +1 -1
  69. package/dist-skill/library/forgecad-make-a-model/SKILL.md +33 -4
  70. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  71. package/dist-skill/library/forgecad-project/SKILL.md +1 -1
  72. package/dist-skill/library/forgecad-render-inspect/SKILL.md +1 -1
  73. package/examples/api/conformal-product-ribbon.forge.js +77 -0
  74. package/examples/api/render-labels.forge.js +33 -0
  75. package/examples/api/text2d-basics.forge.js +6 -3
  76. package/package.json +1 -1
  77. package/dist-skill/library/forgecad-deep-dive/SKILL.md +0 -120
  78. package/dist-skill/library/forgecad-deep-dive/agents/openai.yaml +0 -4
  79. package/dist-skill/library/forgecad-deep-dive/references/output-shape.md +0 -64
@@ -9,7 +9,7 @@ Cut planes, exploded views, joint animations, and scene configuration.
9
9
 
10
10
  ## Contents
11
11
 
12
- - [Viewport & Runtime](#viewport-runtime) — `scene`, `viewConfig`, `explodeView`, `jointsView`, `cutPlane`, `mock`, `showLabels`, `highlight`
12
+ - [Viewport & Runtime](#viewport-runtime) — `Viewport.label`, `scene`, `viewConfig`, `explodeView`, `jointsView`, `cutPlane`, `mock`, `showLabels`, `highlight`
13
13
  - [RouteBuilder](#routebuilder)
14
14
  - [route](#route)
15
15
 
@@ -17,14 +17,50 @@ Cut planes, exploded views, joint animations, and scene configuration.
17
17
 
18
18
  ### Viewport & Runtime
19
19
 
20
+ #### `Viewport.label()` — Add a render-only viewport label at a world-space point.
21
+
22
+ `Viewport.label()` is for explanatory text that helps a viewer understand the model. It does not create sketches, meshes, B-rep topology, exported text, or face labels, so it stays off the OCCT path. Use [`text2d()`](/docs/sketch#text2d) only when the letters should become manufactured geometry, such as raised lettering, engraved serial numbers, or exported nameplates.
23
+
24
+ Labels are collected during script execution and rendered by the viewport as lightweight overlay annotations. They are ignored by exports and do not appear in `objects`.
25
+
26
+ ```js
27
+ Viewport.label('Bearing bore', [0, 0, 18], {
28
+ color: '#f8fafc',
29
+ background: '#0f172acc',
30
+ offset: [0, 0, 8],
31
+ anchor: 'bottom',
32
+ });
33
+
34
+ return box(40, 30, 12);
35
+ ```
36
+
37
+ ```ts
38
+ Viewport.label(text: string, at: [ number, number, number ], options?: RenderLabelOptions): void
39
+ ```
40
+
41
+ **`RenderLabelOptions`**
42
+
43
+ | Option | Type | Description |
44
+ |--------|------|-------------|
45
+ | `color?` | `string` | Text color as any CSS color string. |
46
+ | `background?` | `string` | Background color as any CSS color string. Use `'transparent'` for no pill background. |
47
+ | `size?` | `number` | Font size in CSS pixels. Defaults to 12. |
48
+ | `offset?` | `[ number, number, number ]` | Additional world-space offset from `at`. |
49
+ | `anchor?` | `RenderLabelAnchor` | Which point of the label box is anchored to `at`. Defaults to `'center'`. |
50
+ | `alwaysOnTop?` | `boolean` | When false, the label is hidden when occluded by scene geometry. Defaults to true. |
51
+
20
52
  #### `scene()` — Configure the scene environment for the current script execution.
21
53
 
22
- Controls camera position, lighting rig, background color or gradient, atmospheric fog, environment maps, post-processing effects, and capture parameters for the `forgecad capture` command. Multiple calls merge — later values override earlier ones on a per-key basis, so you can split configuration across multiple `scene()` calls.
54
+ Controls camera position, named render views, optional model journeys, lighting rig, background color or gradient, atmospheric fog, environment maps, post-processing effects, and capture parameters for the `forgecad capture` command. Multiple calls merge — later values override earlier ones on a per-key basis, so you can split configuration across multiple `scene()` calls.
23
55
 
24
56
  When `lights` is specified, **all** default lights are removed. You must include your own ambient light or the scene will be fully dark.
25
57
 
26
58
  Setting `camera.position` overrides auto-framing — the viewport will no longer auto-fit the geometry on script reload.
27
59
 
60
+ Named render views let scripts check in repeatable cameras next to the model code. The canonical shape is `{ camera: { position, target } }`, and a direct camera shorthand `{ position, target }` is also accepted. Use the canonical shape when you may add view metadata later. Use it from the CLI with `forgecad render 3d model.forge.js --view hero`.
61
+
62
+ Model journeys let scripts check in a compact guided path through named objects. Each journey has ordered `steps`; each step can name a `focus` target by object name/tree path, provide a caption, and optionally provide an explicit camera. In the viewer, journeys are opt-in: they appear as a small Explore control and do not move the camera until the user starts them. Use `forgecad run model.forge.js --journeys` or `--journeys-json` to inspect resolved targets.
63
+
28
64
  Post-processing effects (`bloom`, `vignette`, `grain`) work in the browser viewport only. The CLI applies camera, lights, background, fog, and `toneMappingExposure` but skips shader effects.
29
65
 
30
66
  All numeric values accept `param()` expressions.
@@ -33,6 +69,22 @@ All numeric values accept `param()` expressions.
33
69
  scene({
34
70
  background: { top: '#000814', bottom: '#001d3d' },
35
71
  camera: { position: [160, -120, 100], target: [0, 0, 50], fov: 52 },
72
+ views: {
73
+ hero: {
74
+ camera: { position: [180, -140, 90], target: [0, 0, 25], up: [0, 0, 1], fov: 38 },
75
+ },
76
+ side: { position: [240, 0, 70], target: [0, 0, 25], fov: 34 },
77
+ },
78
+ journeys: {
79
+ grandTour: {
80
+ title: 'Grand Tour',
81
+ startsAt: 'overview',
82
+ steps: [
83
+ { id: 'overview', focus: 'Solar System', caption: 'Start with the whole model.' },
84
+ { id: 'earth', focus: 'Earth', caption: 'Fit and inspect Earth.' },
85
+ ],
86
+ },
87
+ },
36
88
  lights: [
37
89
  { type: 'ambient', color: '#001233', intensity: 0.08 },
38
90
  { type: 'point', position: [120, -80, 130], color: '#00f5d4', intensity: 4, distance: 400, decay: 1 },
@@ -59,12 +111,38 @@ scene(options: SceneOptions): void
59
111
  | Option | Type | Description |
60
112
  |--------|------|-------------|
61
113
  | `capture?` | `SceneCaptureConfig` | Default capture parameters for `forgecad capture` — CLI flags override these. |
62
- | `background?`, `camera?`, `lights?`, `environment?`, `fog?`, `postProcessing?`, `ground?` | | — |
114
+ | `background?`, `camera?`, `views?`, `journeys?`, `lights?`, `environment?`, `fog?`, `postProcessing?`, `ground?` | | — |
63
115
 
64
116
  `SceneBackgroundGradient`: `{ top: string, bottom: string }`
65
117
 
66
118
  **`SceneCameraConfig`**: `position?: [ number, number, number ]`, `target?: [ number, number, number ]`, `up?: [ number, number, number ]`, `fov?: number`, `type?: "perspective" | "orthographic"`
67
119
 
120
+ **`SceneJourneyConfig`**
121
+
122
+ | Option | Type | Description |
123
+ |--------|------|-------------|
124
+ | `title?` | `string` | Viewer-facing journey title. Defaults to the journey id. |
125
+ | `startsAt?` | `string` | Optional starting step id. Defaults to the first step. |
126
+ | `behavior?` | `"opt-in" \| "auto"` | Whether the viewer should offer or auto-open the journey. First slice supports opt-in. |
127
+ | `steps` | `SceneJourneyStepConfig[]` | Ordered journey spine. Branches can be added later without changing this core contract. |
128
+ | `valid?` | `boolean` | True unless any journey or step diagnostic has level "error". |
129
+ | `diagnostics?` | `SceneJourneyDiagnostic[]` | Whole-journey diagnostics, including unresolved startsAt and step target diagnostics. |
130
+
131
+ **`SceneJourneyStepConfig`**
132
+
133
+ | Option | Type | Description |
134
+ |--------|------|-------------|
135
+ | `id` | `string` | Stable step id used by viewer links and Next/Back state. |
136
+ | `title?` | `string` | Viewer-facing title. Defaults to the step id. |
137
+ | `focus?` | `string` | Object name or slash-separated tree path to focus. |
138
+ | `caption?` | `string` | Short optional viewer caption. |
139
+ | `camera?` | `SceneViewCameraConfig` | Optional explicit camera for this step. When omitted, the viewer fits `focus`. |
140
+ | `resolvedFocusId?` | `string \| null` | Resolved object id after script execution, when `focus` matched exactly one object. |
141
+ | `resolvedFocusPath?` | `string \| null` | Resolved object tree path or name after script execution. |
142
+ | `diagnostics?` | `SceneJourneyDiagnostic[]` | Resolution diagnostics for this step. |
143
+
144
+ `SceneJourneyDiagnostic`: `{ level: SceneJourneyDiagnosticLevel, message: string, stepId?: string, suggestions?: string[] }`
145
+
68
146
  **`SceneLightConfig`**
69
147
 
70
148
  | Option | Type | Description |
@@ -0,0 +1,159 @@
1
+ # User Outreach Email Templates
2
+
3
+ Use these templates for personal outreach to ForgeCAD users. They are intentionally written in a founder/operator voice: warm, specific, curious, and useful. The goal is to learn from real projects, make users feel supported, and open the door to deeper onboarding when it makes sense.
4
+
5
+ ## Shared Guidance
6
+
7
+ - Personalize the first sentence with one real signal when possible: plan tier, recent activity, project name, export type, team domain, or signup source.
8
+ - Keep the ask small. A 20-minute chat is easier to accept than a vague "feedback call."
9
+ - Do not make the user prove they are important. The default posture is: if they are using ForgeCAD, their workflow matters.
10
+ - For Pro users, make support and team onboarding explicit. They already crossed the trust line.
11
+ - For active free users, lead with curiosity. Mention Pro only as a practical fit for commercial work, not as the reason for the email.
12
+
13
+ ## Pro User Templates
14
+
15
+ ### 1. Welcome And Use Case Discovery
16
+
17
+ **Subject:** Welcome to ForgeCAD Pro
18
+
19
+ Hi {{first_name}},
20
+
21
+ I saw that you upgraded to ForgeCAD Pro. Thank you for trusting us with your work.
22
+
23
+ I wanted to reach out personally because we are still early enough that real professional use cases can directly shape the product. If you are using ForgeCAD for client work, a product, internal tooling, robotics, 3D printing, fixtures, or anything else serious, I would love to understand what you are building and where the tool should become sharper for you.
24
+
25
+ Would you be open to a 20-minute call this week or next? I can help with onboarding, answer workflow questions, and learn what would make ForgeCAD more useful for your day-to-day work.
26
+
27
+ Best,
28
+
29
+ {{sender_name}}
30
+
31
+ ### 2. Team Onboarding Exploration
32
+
33
+ **Subject:** Helping your team get further with ForgeCAD
34
+
35
+ Hi {{first_name}},
36
+
37
+ Thanks again for using ForgeCAD Pro. I wanted to check whether you are using it mostly on your own, or whether there are other people on your team who might need to work with the same models, project files, exports, or review flow.
38
+
39
+ If there is a team workflow behind your ForgeCAD use, I would be happy to help you think through the setup: local project structure, CLI usage, shared browser projects, AI-assisted modeling, exports, and any support expectations around commercial work.
40
+
41
+ Would it be useful to set up a short onboarding call? Even if you are not ready to add more people yet, it would help us understand what serious team adoption should feel like.
42
+
43
+ Best,
44
+
45
+ {{sender_name}}
46
+
47
+ ### 3. Pro Check-In After Usage
48
+
49
+ **Subject:** How is ForgeCAD Pro fitting into your work?
50
+
51
+ Hi {{first_name}},
52
+
53
+ I wanted to check in now that you have had some time with ForgeCAD Pro.
54
+
55
+ The main thing I would love to understand is: what job are you trying to get done with ForgeCAD, and where does the product currently help the most or slow you down?
56
+
57
+ If you have a real project in progress, I am happy to look at the workflow with you. A short call would help us support you better, and it would also help us decide which Pro and team features should come next.
58
+
59
+ Best,
60
+
61
+ {{sender_name}}
62
+
63
+ ## Active User Templates
64
+
65
+ ### 1. Curious Product Discovery
66
+
67
+ **Subject:** Curious what you are building with ForgeCAD
68
+
69
+ Hi {{first_name}},
70
+
71
+ I noticed you have been active in ForgeCAD recently, and I wanted to reach out personally.
72
+
73
+ We are trying to understand what people are actually building: quick 3D-printable parts, mechanical assemblies, robotics ideas, fixtures, generated geometry, design automation, or something completely different. The product gets much better when we can see the real use cases behind the activity.
74
+
75
+ Would you be open to a 20-minute chat? I would mostly like to learn what you are working on, what feels promising, and what currently gets in your way.
76
+
77
+ Best,
78
+
79
+ {{sender_name}}
80
+
81
+ ### 2. Active User With Commercial Hint
82
+
83
+ **Subject:** Learning from your ForgeCAD workflow
84
+
85
+ Hi {{first_name}},
86
+
87
+ I saw you have been using ForgeCAD and wanted to ask what kind of work you are exploring with it.
88
+
89
+ If this is personal, learning, open-source, or experimental work, I would simply love to understand the project and what would make ForgeCAD more enjoyable or capable for you. If you are using it commercially, ForgeCAD Pro may be the right fit, and I am happy to explain that too, but that is not the main reason I am writing.
90
+
91
+ The main reason is that active users teach us where the product is strong, where it is confusing, and what workflows deserve more attention.
92
+
93
+ Would you be open to a quick call?
94
+
95
+ Best,
96
+
97
+ {{sender_name}}
98
+
99
+ ### 3. High-Activity User Check-In
100
+
101
+ **Subject:** Quick ForgeCAD question
102
+
103
+ Hi {{first_name}},
104
+
105
+ I noticed you have spent real time with ForgeCAD, so I wanted to ask one direct question:
106
+
107
+ What are you trying to make with it?
108
+
109
+ We are early, and this is the stage where understanding real projects matters more than polished surveys. If ForgeCAD is helping, I would like to know why. If something is awkward, missing, or confusing, I would like to know that even more.
110
+
111
+ Would you be open to a short chat this week or next?
112
+
113
+ Best,
114
+
115
+ {{sender_name}}
116
+
117
+ ## Follow-Up Templates
118
+
119
+ ### 1. Gentle Follow-Up
120
+
121
+ **Subject:** Re: {{previous_subject}}
122
+
123
+ Hi {{first_name}},
124
+
125
+ Just wanted to follow up once in case this got buried.
126
+
127
+ I would still be very interested to hear what you are using ForgeCAD for. Even a two-sentence reply would be useful if a call is too much right now.
128
+
129
+ Best,
130
+
131
+ {{sender_name}}
132
+
133
+ ### 2. Concrete Reply Prompt
134
+
135
+ **Subject:** Re: {{previous_subject}}
136
+
137
+ Hi {{first_name}},
138
+
139
+ One quick follow-up. If a call is not convenient, could you reply with whichever of these is closest?
140
+
141
+ 1. I am using ForgeCAD for personal projects or learning.
142
+ 2. I am evaluating it for commercial work.
143
+ 3. I am trying to use it with a team.
144
+ 4. I am stuck or missing something important.
145
+
146
+ That alone would help us understand how to support you better.
147
+
148
+ Best,
149
+
150
+ {{sender_name}}
151
+
152
+ ## Placeholder Checklist
153
+
154
+ | Placeholder | Meaning |
155
+ |---|---|
156
+ | `{{first_name}}` | User first name when known, otherwise use `there` |
157
+ | `{{sender_name}}` | Founder/operator name |
158
+ | `{{previous_subject}}` | Subject line from the first outreach email |
159
+ | `{{project_signal}}` | Optional project, command, export, or activity signal for manual personalization |
@@ -59,7 +59,7 @@ Reference matching is a validation step after the object exists.
59
59
  - validation views and inspection channels
60
60
 
61
61
  4. Choose the modeling structure.
62
- Use a multi-file `main.forge.js` project when the object has distinct parts, repeated feature families, internals, purchased hardware, variants, or meaningful manufacturing assumptions. Keep dimensions, materials, part builders, hardware ghosts, and assembly helpers in neighboring plain `.js` files.
62
+ Use a multi-file `main.forge.js` project when the object has distinct parts, repeated feature families, internals, purchased hardware, variants, or meaningful manufacturing assumptions. Put renderable/importable parts and sub-assemblies in neighboring `.forge.js` files; keep only pure dimensions, materials, math helpers, and lookup tables in plain `.js` files.
63
63
 
64
64
  5. Build a coarse 3D blockout.
65
65
  Model the object, not the image. Start with the large volumes, axes, symmetry, side depth, rear form, underside, and hidden continuations. Render canonical views before doing reference-camera comparison.
@@ -20,7 +20,8 @@ All new `.forge.js` files go under the date-based directory structure:
20
20
  ```
21
21
  YYYY/MM/DD/file.forge.js — single-file model
22
22
  YYYY/MM/DD/folder/main.forge.js — multi-file project entry point
23
- YYYY/MM/DD/folder/*.js shared helpers, constants, parts, assemblies
23
+ YYYY/MM/DD/folder/parts/*.forge.js standalone/importable model parts
24
+ YYYY/MM/DD/folder/lib/*.js — pure helpers/constants only, no geometry return
24
25
  ```
25
26
 
26
27
  Use today's date for the directory. Use the user's current ForgeCAD project when one is available; otherwise use a clearly named local model folder.
@@ -30,8 +31,9 @@ Use today's date for the directory. Use the user's current ForgeCAD project when
30
31
  - Use kebab-case for file and folder names: `parametric-lego.forge.js`
31
32
  - Use descriptive names that communicate what the model is
32
33
  - For any multi-file project, name the runnable ForgeCAD entry point `main.forge.js`
33
- - If a model needs shared helpers, put them in a subfolder as plain `.js` files (not `.forge.js`)
34
- - Do not create multiple `.forge.js` files in the same project folder unless they are intentionally separate runnable models
34
+ - Put renderable/importable parts and sub-assemblies in separate `.forge.js` files when splitting is justified; each should be standalone-runnable and importable with `require('./parts/name.forge.js', params)`.
35
+ - Use plain `.js` files only for pure constants, math helpers, tables, or formatting code that does not construct and return ForgeCAD geometry.
36
+ - Do not create multiple `.forge.js` files merely for organization; split only for reusable parts, large self-contained components, or independent sub-assemblies.
35
37
 
36
38
  ### Workflow
37
39
 
@@ -39,12 +41,13 @@ Use today's date for the directory. Use the user's current ForgeCAD project when
39
41
  2. Create the directory — `mkdir -p YYYY/MM/DD/[folder]` as needed.
40
42
  3. Write the model — create the `.forge.js` file(s) following ForgeCAD conventions:
41
43
  - Declare `param()` / `boolParam()` for all tunable dimensions
42
- - If the model is split across files, use `main.forge.js` as the only primary `.forge.js` entry point and import helpers/parts from neighboring plain `.js` modules
44
+ - If the model is split across files, use `main.forge.js` as the primary entry point, import renderable parts from neighboring `.forge.js` files, and keep only pure helpers/constants in plain `.js` modules
43
45
  - When there are multiple versions of the same object, expose the version as a choice parameter and render one selected version at a time
44
46
  - Use clear variable names
45
47
  - Build any implied internal structure as real geometry, even when it will be hidden in the final view
46
48
  - Make final mating geometry physically plausible: parts may touch, clear each other, or be boolean-joined, but should not unintentionally pass through each other
47
49
  - Return the final geometry (single shape, array, or named objects array)
50
+ - Avoid expensive global edge treatment on repeated decorative geometry: do not call `fillet(shape, r)` or `chamfer(shape, r)` on every edge of large unioned/repeated parts unless the render/run loop proves it is fast enough. Prefer simpler primitive profiles, lower segment counts, or targeted edge selectors.
48
51
  4. Validate — run `forgecad run <file>` to check for errors. For multi-file projects, always validate `main.forge.js`.
49
52
  5. Verify geometry — render the result and run `forgecad render inspect` with the relevant channels for the task (see Render-Verify Loop below). For multi-file projects, render and inspect `main.forge.js`.
50
53
 
@@ -294,6 +297,32 @@ scene({
294
297
  });
295
298
  ```
296
299
 
300
+ #### Named render views
301
+
302
+ For models that need repeatable review, docs, or hero renders, declare named views inside
303
+ `scene({ views })`. The canonical form wraps each camera in `{ camera: ... }`; direct camera
304
+ shorthand is accepted by the runtime, but the wrapped form is the clearest prompt/example shape.
305
+
306
+ ```js
307
+ scene({
308
+ camera: { position: [430, -540, 340], target: [0, 30, 125], fov: 38 },
309
+ views: {
310
+ hero: {
311
+ camera: { position: [430, -540, 340], target: [0, 30, 125], up: [0, 0, 1], fov: 38 },
312
+ },
313
+ side: {
314
+ camera: { position: [700, 0, 180], target: [0, 30, 100], up: [0, 0, 1], fov: 32 },
315
+ },
316
+ },
317
+ });
318
+ ```
319
+
320
+ Render one later with:
321
+
322
+ ```bash
323
+ forgecad render 3d model.forge.js --view hero
324
+ ```
325
+
297
326
  #### Lighting principles
298
327
 
299
328
  - When `lights` is set, all defaults are replaced, so always include an ambient light or the scene goes black.
@@ -162,7 +162,7 @@ By the end of this skill, there should be:
162
162
  - purchased-part boundary
163
163
  - validation standard
164
164
  - variant-selection policy when multiple versions of the same object are requested
165
- - file-organization policy: if the implementation needs multiple files, the runnable ForgeCAD entry point must be `main.forge.js`, with helpers/parts/constants in neighboring plain `.js` modules
165
+ - file-organization policy: if the implementation needs multiple files, the runnable ForgeCAD entry point must be `main.forge.js`; renderable parts/sub-assemblies belong in neighboring `.forge.js` files, while plain `.js` files are only for pure helpers/constants
166
166
  - explicit uncertainty policy
167
167
 
168
168
  8. Emit one master prompt.
@@ -13,7 +13,7 @@ ForgeCAD project CLI workflow — creating, managing, syncing projects and files
13
13
 
14
14
  ### Overview
15
15
 
16
- **forgecad.io** is the primary platform for ForgeCAD projects. The CLI is the main way AI agents interact with it — creating projects, managing files, publishing models, and collaborating. `forgecad studio <project-path> [project-path ...]` / `forgecad dev <project-path> [project-path ...]` run the editor locally for offline work.
16
+ **forgecad.io** is the primary platform for ForgeCAD projects. The CLI is the main way AI agents interact with it — creating projects, managing files, publishing models, and collaborating. `forgecad studio <project-path> [project-path ...]` opens the installed local editor for users; `forgecad dev <project-path> [project-path ...]` is mainly for ForgeCAD source development.
17
17
 
18
18
  ### Authentication
19
19
 
@@ -43,7 +43,7 @@ Routing:
43
43
  Use `/tmp/<model-name>-inspect` by default so generated PNGs do not dirty the repo. Use a project output directory only when the user wants a persistent artifact.
44
44
 
45
45
  3. Pick the channel set.
46
- Use the table below. Prefer small targeted channel sets; the full channel set is expensive and should be reserved for an explicit stress check.
46
+ Use the table below. Prefer small targeted channel sets; broad stress checks should still list explicit channels.
47
47
 
48
48
  4. Run the command.
49
49
  In the ForgeCAD repo, prefer the built CLI when you want the current checkout:
@@ -27,7 +27,8 @@ Author or modify ForgeCAD models, sketches, assemblies, and CLI workflows. Prefe
27
27
 
28
28
  #### Import and Composition
29
29
 
30
- - `require("./file.forge.js", { Param: value })` for any model file, with optional param overrides.
30
+ - Always include the extension in relative imports: `require("./file.forge.js", { Param: value })` for model files and `require("./helpers.js")` for plain helper modules. Do not write extensionless imports such as `require("./file")`; ForgeCAD resolves project imports by exact path.
31
+ - ForgeCAD APIs are injected globals in `.forge.js` files. Use `bom()`, `box()`, `scene()`, `Shape`, etc. directly; do not destructure those names from helpers with patterns like `const { bom } = require("./bom.js")`. If a helper file is needed, import it under a project-specific name such as `const bomHelpers = require("./bom.js")`.
31
32
  - For static multi-part models, connectors + `matchTo()` are the default way to assemble touching parts.
32
33
  - Top-level scripts can return `Assembly` or `SolvedAssembly` directly. Do not call `.toGroup()` just to render an assembly; use `.toGroup()` only when you need `ShapeGroup` composition, transforms, or named-child lookup.
33
34
  - `importSvgSketch()` for SVG files (file format loader, not a module import).