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 |
@@ -12,6 +12,24 @@ const width = param("Width", 50, { min: 20, max: 100, unit: "mm" });
12
12
  return box(width, 30, 10);
13
13
  ```
14
14
 
15
+ ## Injected Runtime Names
16
+
17
+ ForgeCAD API functions and classes are injected into every `.forge.js` script. Use them directly; do not import or destructure ForgeCAD API names from helper files.
18
+
19
+ ```javascript
20
+ // BAD — `bom` and `bomToCsv` are already built-in runtime names.
21
+ const { bom, bomToCsv } = require("./bom.js");
22
+
23
+ // GOOD — use the built-in directly.
24
+ bom(4, "M4 bolt");
25
+
26
+ // GOOD — keep project helpers under their own local name.
27
+ const bomHelpers = require("./bom.js");
28
+ bomHelpers.addFasteners(...);
29
+ ```
30
+
31
+ Top-level declarations such as `const bom = ...`, `let scene = ...`, or `class Shape {}` collide with the injected runtime names. If you need a local helper, choose a project-specific name like `projectBom`, `sceneConfig`, or `makeShape`.
32
+
15
33
  ## Execution Model
16
34
 
17
35
  - Scripts re-execute on every parameter change (400ms debounce)
@@ -24,6 +42,8 @@ Top-level assembly scripts can return an unsolved `Assembly` directly; ForgeCAD
24
42
 
25
43
  A script can return a plain object whose values include renderable geometry alongside non-renderable metadata. All renderable entries (Shape, Sketch, ShapeGroup, Assembly, SolvedAssembly, SdfShape, or Array of named objects) are rendered; non-renderable entries are silently skipped. This is useful for multi-file projects where a part needs to publish interface data (bolt positions, dimensions) to other files:
26
44
 
45
+ When importing project files, include the full extension in every relative path: `require('./motor-mount.forge.js')` for model files and `require('./helpers.js')` for plain helper modules. ForgeCAD resolves project imports by exact path and does not infer `.forge.js` or `.js` from `require('./motor-mount')`.
46
+
27
47
  ```javascript
28
48
  // motor-mount.forge.js — renders standalone, exports metadata via require()
29
49
  const holePositions = [[17, 15], [-29, 15], [17, -15], [-29, -15]];
@@ -75,6 +95,12 @@ Shapes carry semantic face labels through their lifecycle. The flow is:
75
95
 
76
96
  You resolve labels to geometry with `.face(name)` or `.face(query)` — see the Shape class docs for the full query API. Operations like `.pocket()`, `.boss()`, `.hole()`, and `faceProfile()` all consume face references.
77
97
 
98
+ ## Text vs Viewport Labels
99
+
100
+ Use `text2d()` only when the letters are part of the model: raised text, engraving, cut labels, serial plates, exported markings, or geometry that should survive into STL/STEP output. `text2d()` builds filled sketch geometry from font outlines, so it can make exact/OCCT workflows slower.
101
+
102
+ Use `Viewport.label(text, [x, y, z], options)` when the goal is to explain the model in the viewport. Render labels are annotations only: they do not create meshes, do not export, do not enter the B-rep path, and do not add face labels.
103
+
78
104
  ## SDF Modeling
79
105
 
80
106
  For organic shapes, smooth blending, TPMS lattices, and surface deformations. Return `SdfShape` values directly, or return a plain object/array tree of SDF leaves, for native raymarch preview. Use `.toShape()` or `toShape(...)` only when you need mesh-backed CAD/export behavior. See [sdf-primitives.md](sdf-primitives.md).
@@ -5,7 +5,7 @@ skill-order: 1
5
5
 
6
6
  # ForgeCAD CLI
7
7
 
8
- Run, export, render, and publish `.forge.js` models from your terminal. Core workflows are included with a free ForgeCAD account; advanced exports and rendering are Pro.
8
+ Create projects, open local studios, run, inspect, export, publish, and sync `.forge.js` models from your terminal. Core workflows are included with a free ForgeCAD account; advanced exports and rendering are Pro.
9
9
 
10
10
  ## Quick Start
11
11
 
@@ -13,36 +13,44 @@ Run, export, render, and publish `.forge.js` models from your terminal. Core wor
13
13
  # 1. Install
14
14
  npm install -g forgecad
15
15
 
16
- # 2. Sign in and clone a hosted project
16
+ # 2. Sign in and create a dedicated project folder
17
17
  forgecad login
18
- forgecad project clone start-here
19
- cd start-here
18
+ mkdir spool-adapter
19
+ cd spool-adapter
20
+ forgecad project init "Spool Adapter" --visibility private
20
21
 
21
- # 3. Run it
22
- forgecad run 00-start-here.forge.js
22
+ # 3. Create a first model file
23
+ forgecad new adapter --template part
23
24
 
24
- # 4. Open the editor (live reload)
25
- forgecad dev .
25
+ # 4. Open the local editor
26
+ forgecad studio .
26
27
 
27
- # 5. Export
28
- forgecad export stl 00-start-here.forge.js
28
+ # 5. Validate, export, and push to the browser
29
+ forgecad run adapter.forge.js
30
+ forgecad export stl adapter.forge.js
31
+ forgecad project push
32
+ forgecad project open
29
33
  ```
30
34
 
31
- Most CLI commands require a ForgeCAD account. Use `forgecad login` for email/password accounts, `forgecad login --token` for GitHub/Google web-auth accounts, or `FORGECAD_TOKEN=fc_pat_... forgecad <command>` for CI/CD.
35
+ Most CLI commands require a ForgeCAD account. Use `forgecad login` for email/password accounts, `forgecad login --token` for GitHub/Google web-auth accounts, or `FORGECAD_TOKEN=fc_pat_... forgecad <command>` for CI/CD. `forgecad studio` always requires an explicit project path; use `.` for the current project.
36
+
37
+ You can also start from the hosted starter project with `forgecad project clone start-here`, then `cd start-here` and `forgecad studio .`.
32
38
 
33
39
  ## Editor
34
40
 
35
- ForgeCAD includes a local editor with live reload. Edit a `.forge.js` file, save, and the 3D view updates instantly — parameters become interactive sliders.
41
+ ForgeCAD includes a local editor. Open it around a dedicated project folder, edit a `.forge.js` file, save, and the 3D view updates — parameters become interactive sliders.
36
42
 
37
43
  | Command | Description |
38
44
  |---------|-------------|
39
- | `dev <project-path> [project-path ...]` | Start the Vite dev server with live reload. No build step required — the preferred way to run ForgeCAD during active development. |
40
- | `studio <project-path> [project-path ...]` | Serve the production build of the studio (requires dist/ — run `npm run build` first). |
45
+ | `studio <project-path> [project-path ...]` | Open the installed local editor around one or more project folders. |
46
+ | `dev <project-path> [project-path ...]` | Start the Vite dev server for ForgeCAD source development. |
41
47
  | `web` | Start a local dev server in web/playground mode (no filesystem, localStorage only). |
42
48
  | `open <project-path> [project-path ...]` | Alias for `forgecad studio`. |
43
49
 
50
+ `forgecad studio <project-path>` is the normal installed-CLI command for users. `forgecad dev <project-path>` starts the Vite dev server and is mainly for ForgeCAD source development.
51
+
44
52
  <details>
45
- <summary>Common flags for dev / studio</summary>
53
+ <summary>Common flags for studio / dev</summary>
46
54
 
47
55
  | Option | Description |
48
56
  |--------|-------------|
@@ -79,7 +87,7 @@ The primary validation command. Runs your script with the real geometry kernel (
79
87
 
80
88
  Intra-group pairs (same assembly group) and mock-to-mock pairs are skipped. If a part passes through a boolean-subtracted hole, no collision is reported — the material is gone.
81
89
 
82
- **Spatial analysis** — reports directional relationships and gap distances between nearby objects (e.g. `bracket is ABOVE base (gap: 5mm)`). When no issues are found: `(no collisions, all objects well-separated)`.
90
+ **Spatial analysis** — reports directional relationships and gap distances between nearby objects (e.g. `bracket is ABOVE base (gap: 5mm)`). Exact pairwise collision intersections run by default only for bounded scenes; use `--spatial exact` for exhaustive collision checks or `--spatial off` to skip this section.
83
91
 
84
92
  **Physical connectivity** — pass `--connectivity` to list physically connected components across visible objects. Overlapping or touching bboxes are joined within `--connectivity-tolerance` (default `0.05` model units); use collision inspection for exact positive-volume overlaps. This helps answer whether the model is one continuous assembly or several separate islands.
85
93
 
@@ -93,6 +101,7 @@ forgecad run examples/cup.forge.js --focus
93
101
  forgecad run examples/cup.forge.js --focus bracket,hinge
94
102
  forgecad run examples/cup.forge.js --hide "wall,bolt"
95
103
  forgecad run examples/cup.forge.js --connectivity
104
+ forgecad run examples/cup.forge.js --journeys
96
105
  forgecad run examples/cup.forge.js --backend occt
97
106
  forgecad run examples/cup.forge.js --debug-imports
98
107
  forgecad run examples/cup.forge.js -p "Wall Thickness=3" -p "Body Height=200"
@@ -126,7 +135,7 @@ Render a Forge scene to PNG using the real viewport renderer.
126
135
 
127
136
  Launches a headless Chrome instance, renders the scene with the same WebGL viewport as the editor, and saves a PNG. The output path defaults to `<script-name>.png` next to the input file.
128
137
 
129
- Use `--focus` to isolate specific parts (hides everything else) or `--hide` to remove clutter like mock objects. The `--camera` flag accepts named views (`front`, `top`, `iso`), `azimuth:elevation` angles, or an exact `proj/pos/target/up/fov` camera spec — pass it multiple times to render several viewpoints in one run.
138
+ Use `--focus` to isolate specific parts (hides everything else) or `--hide` to remove clutter like mock objects. The `--view` flag selects a named camera declared in `scene({ views })`. The `--camera` flag accepts built-in views (`front`, `top`, `iso`), `azimuth:elevation` angles, or an exact `proj/pos/target/up/fov` camera spec — pass `--camera` multiple times to render several viewpoints in one run.
130
139
 
131
140
  Use `--edges=<off|thin|bold>` to control the edge overlay. For a pure wireframe look, use `render wireframe` instead.
132
141
 
@@ -137,6 +146,7 @@ forgecad render 3d examples/cup.forge.js
137
146
  forgecad render 3d examples/cup.forge.js --focus
138
147
  forgecad render 3d examples/cup.forge.js --focus bracket
139
148
  forgecad render 3d examples/cup.forge.js --hide "wall,bolt"
149
+ forgecad render 3d model.forge.js --view hero
140
150
  forgecad render 3d model.forge.js --camera 45:30
141
151
  forgecad render 3d model.forge.js --camera "proj=perspective;pos=200,-160,120;target=0,0,20;up=0,0,1;fov=38"
142
152
  forgecad render 3d model.forge.js --camera front --camera side
@@ -234,6 +244,7 @@ forgecad render section examples/furniture/01-table.forge.js out/bold.svg --edge
234
244
  | `--focus <names>` | Focus: no arg hides mocks; comma-separated names shows only those |
235
245
  | `--hide <names>` | Hide comma-separated object names |
236
246
  | `--camera <front\|back\|side\|right\|top\|iso\|az:el\|az:el:dist\|spec>` | Camera preset, spherical (az:el), or full spec such as `proj=perspective;pos=x,y,z;target=x,y,z;up=x,y,z;fov=45`. Repeatable. |
247
+ | `--view <name>` | Named camera view declared by the model with scene({ views }) |
237
248
  | `--size <px>` | Image size in pixels |
238
249
  | `--scene <json>` | Viewport scene state JSON |
239
250
  | `--background <color>` | Canvas background override |
@@ -292,22 +303,22 @@ forgecad render section examples/furniture/01-table.forge.js out/bold.svg --edge
292
303
 
293
304
  ## Export
294
305
 
295
- Export to every format you need. Account-included formats work after login; advanced formats are Pro.
306
+ Export to every format you need. Export actions are free to run; production outputs carry commercial-use guidance.
296
307
 
297
308
  | Command | Format | Use case |
298
309
  |---------|--------|----------|
299
- | `cut-list` **\[Pro\]** | Terminal | Grouped sheet-material cut list from `sheetStock()` |
310
+ | `cut-list` **\[Production\]** | Terminal | Grouped sheet-material cut list from `sheetStock()` |
300
311
  | `export svg` | SVG | 2D vector output from sketches |
301
- | `export sketch-pdf` **\[Pro\]** | PDF | Sketch with dimensions and constraints |
302
- | `export step` **\[Pro\]** | STEP | CAD interchange (exact geometry) |
303
- | `export brep` **\[Pro\]** | BREP | Boundary representation |
312
+ | `export sketch-pdf` **\[Production\]** | PDF | Sketch with dimensions and constraints |
313
+ | `export step` **\[Production\]** | STEP | CAD interchange (exact geometry) |
314
+ | `export brep` **\[Production\]** | BREP | Boundary representation |
304
315
  | `export 3mf` | 3MF | 3D printing (color, multi-part) |
305
316
  | `export stl` | STL | 3D printing |
306
- | `export gcode` **\[Pro\]** | G-code | Toolpath (scripted, not sliced) |
307
- | `export sdf` **\[Pro\]** | SDF package | Gazebo robot simulation |
308
- | `export urdf` **\[Pro\]** | URDF package | ROS / PyBullet / MuJoCo |
309
- | `export report` **\[Pro\]** | PDF report | Multi-view report with BOM and dimensions |
310
- | `export cutting-layout` **\[Pro\]** | PDF | Sheet cutting layout with cut sequence |
317
+ | `export gcode` **\[Production\]** | G-code | Toolpath (scripted, not sliced) |
318
+ | `export sdf` **\[Production\]** | SDF package | Gazebo robot simulation |
319
+ | `export urdf` **\[Production\]** | URDF package | ROS / PyBullet / MuJoCo |
320
+ | `export report` **\[Production\]** | PDF report | Multi-view report with BOM and dimensions |
321
+ | `export cutting-layout` **\[Production\]** | PDF | Sheet cutting layout with cut sequence |
311
322
  | `link` | URL | Generate a ForgeCAD share link from a GitHub Gist URL or ID and copy it to clipboard. |
312
323
 
313
324
  ```bash
@@ -351,22 +362,32 @@ forgecad export sdf rover.forge.js --output out/forge_scout
351
362
 
352
363
  ## Projects & Publishing
353
364
 
354
- ForgeCAD has a hosted platform at [forgecad.io](https://forgecad.io). The CLI connects your local files to it.
365
+ ForgeCAD has a hosted platform at [forgecad.io](https://forgecad.io). The CLI connects a dedicated local project folder to it.
366
+
367
+ A project is a local folder linked to the hosted app by `forgecad.json`. Use `forgecad project clone <slug>` to download an existing hosted project into a local folder, or run `forgecad project init` inside a folder that should become a new ForgeCAD project. Open local projects with `forgecad studio <project-path>`.
355
368
 
356
- A project is a local folder linked to the hosted app by `.forgecad/project.json`. Use `forgecad project clone <slug>` to download an existing hosted project into a local folder, or run `forgecad project init` inside a folder that should become a ForgeCAD project. Open local projects with `forgecad studio <project-path> [project-path ...]`.
369
+ Keep the project root small and intentional. Do not run the editor from `~`, downloads, desktop, or a huge source tree. ForgeCAD scans project files such as `.forge.js`, `.js`, and `.svg`; broad roots make local workflows and AI-agent context slow and confusing.
357
370
 
358
371
  ### Get started
359
372
 
360
373
  ```bash
361
374
  forgecad login
362
- forgecad project clone start-here
363
-
364
- # or initialize the current folder as a new project:
375
+ mkdir spool-adapter
376
+ cd spool-adapter
365
377
  forgecad project init "Spool Adapter"
378
+ forgecad new adapter --template part
379
+ forgecad studio .
380
+
381
+ # or clone an existing hosted project:
382
+ forgecad project clone start-here
383
+ cd start-here
384
+ forgecad studio .
366
385
  ```
367
386
 
368
387
  `forgecad login` prompts for email/password. If your account was created through GitHub or Google, create an API token in Settings > API Tokens and run `forgecad login --token`; it prompts securely when the token is omitted. Use `FORGECAD_TOKEN=fc_pat_...` instead for CI/CD and one-off automation. See [Platform authentication](platform/auth.md#cli-auth-for-oauth-accounts) for details.
369
388
 
389
+ `forgecad project init` creates the remote project, writes `forgecad.json`, pushes any existing local source files, and records server file IDs. `forgecad project push` syncs an already initialized project; it does not create a remote project from an arbitrary folder.
390
+
370
391
  ### Sync
371
392
 
372
393
  ```bash
@@ -457,7 +478,7 @@ Shares are live references — always the current version, not a snapshot.
457
478
 
458
479
  ## AI Integration
459
480
 
460
- ForgeCAD files are plain JavaScript. AI coding agents write and iterate on them directly. The CLI closes the loop. See [AI Usage](AI/usage.md) for approved models, Codex/Claude Code setup, installable skills, and completion criteria.
481
+ ForgeCAD files are plain JavaScript. AI coding agents should work inside an initialized project folder, write and iterate on local files, and use the CLI for evidence. See [AI Usage](AI/usage.md) for approved models, project-first setup, installable skills, quality prompts, and completion criteria.
461
482
 
462
483
  ```bash
463
484
  # Install the full public ForgeCAD skill library
@@ -542,11 +563,11 @@ forgecad check params path/to/model.forge.js --samples 12
542
563
 
543
564
  ### Licensing
544
565
 
545
- Core CLI workflows are included with a free account. Advanced exports and rendering are Pro.
566
+ The CLI is free for core workflows and exports. Production outputs are free to run; Pro covers commercial use. High-value render and capture tools require Pro.
546
567
 
547
- | Free | Pro |
548
- |------|-----|
549
- | `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `check params`, `check suite` | `render hq`, `capture gif`, `capture mp4`, `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export sdf`, `export urdf`, `export report`, `export cutting-layout` |
568
+ | Free | Production outputs | Pro |
569
+ |------|--------------------|-----|
570
+ | `run`, `dev`, `studio`, `render 3d`, `export stl`, `export 3mf`, `export svg`, `check params`, `check suite` | `cut-list`, `export sketch-pdf`, `export step`, `export brep`, `export gcode`, `export sdf`, `export urdf`, `export report`, `export cutting-layout` are free to run; Pro covers commercial use. | `render hq`, `capture gif`, `capture mp4` |
550
571
 
551
572
  ```bash
552
573
  forgecad license # Check signed-in account status
@@ -414,6 +414,8 @@ coalesceEdges(segments: EdgeSegment[], tolerance?: number): EdgeSegment[]
414
414
 
415
415
  When importing a `.forge.js` file, the return value is what the script returns. If the script returns a metadata object (e.g. `{ shape: myShape, bolts: {...} }`), the caller receives the full object — renderable values and metadata together.
416
416
 
417
+ **Path rule:** Always include the file extension in relative imports: use `require("./part.forge.js")` for model files and `require("./helpers.js")` for plain helper modules. ForgeCAD does not apply Node-style extension inference, so `require("./part")` will not find `part.forge.js` or `part.js`.
418
+
417
419
  **Parameter scoping:** Parameters declared in required files are automatically namespaced with a `"filename#N / "` prefix (e.g. `"bracket.forge.js#1 / Width"`). This prevents collisions when multiple files declare same-named params. Each file's params appear as separate sliders.
418
420
 
419
421
  **Parameter overrides:** When passing overrides, use the bare param name (not the scoped name). Overrides are type-checked — unrecognized keys throw an error with typo suggestions.