forgecad 0.6.3 → 0.7.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.
- package/README.md +2 -11
- package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-DAu1C1ST.js} +250 -151
- package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
- package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-Gc_BCdqC.js} +269 -143
- package/dist/assets/EditorApp-D9bJvtf7.js +11338 -0
- package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-DG1-oUSV.css} +459 -87
- package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-CEO8XbV8.js} +2 -4
- package/dist/assets/LandingPage-CdCuEOdC.js +451 -0
- package/dist/assets/PricingPage-BSrxu6d7.js +232 -0
- package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-FUCSIRq6.js} +129 -5
- package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-KoR0SNKq.js} +6770 -2914
- package/dist/assets/{index-2hfs_ub0.css → index-CyVd1D4D.css} +227 -53
- package/dist/assets/{Viewport-CoB46f5R.js → index-wTEK39at.js} +31385 -6439
- package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
- package/dist/assets/{manifold-CqNMHHKO.js → manifold-B1sGWdYk.js} +4 -3
- package/dist/assets/{manifold-Cce9wRFz.js → manifold-D7o0N50J.js} +1 -1
- package/dist/assets/{manifold-D6BeHIOo.js → manifold-G5sBaXzi.js} +1 -1
- package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-DYcRHhv9.js} +6798 -3341
- package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
- package/dist/docs-raw/generated/assembly.md +691 -112
- package/dist/docs-raw/generated/concepts.md +1225 -1400
- package/dist/docs-raw/generated/core.md +464 -1412
- package/dist/docs-raw/generated/curves.md +593 -117
- package/dist/docs-raw/generated/lib.md +38 -748
- package/dist/docs-raw/generated/output.md +139 -245
- package/dist/docs-raw/generated/sheet-metal.md +473 -21
- package/dist/docs-raw/generated/sketch.md +553 -349
- package/dist/docs-raw/generated/viewport.md +345 -303
- package/dist/docs-raw/generated/wood.md +104 -0
- package/dist/index.html +2 -2
- package/dist/sitemap.xml +6 -6
- package/dist-cli/chunk-PZ5AY32C.js +10 -0
- package/dist-cli/chunk-PZ5AY32C.js.map +1 -0
- package/dist-cli/forgecad.js +9435 -5407
- package/dist-cli/forgecad.js.map +1 -0
- package/dist-cli/solver-FV7TJZGI.js +365 -0
- package/dist-cli/solver-FV7TJZGI.js.map +1 -0
- package/dist-skill/CONTEXT.md +3186 -7145
- package/dist-skill/SKILL-dev.md +21 -63
- package/dist-skill/SKILL.md +12 -56
- package/dist-skill/docs/API/core/concepts.md +16 -98
- package/dist-skill/docs/CLI/export.md +91 -0
- package/dist-skill/docs/CLI/projects.md +107 -0
- package/dist-skill/docs/CLI/studio_publishing.md +52 -0
- package/dist-skill/docs/CLI/validation.md +66 -0
- package/dist-skill/docs/generated/assembly.md +691 -112
- package/dist-skill/docs/generated/core.md +464 -1412
- package/dist-skill/docs/generated/curves.md +593 -117
- package/dist-skill/docs/generated/lib.md +38 -748
- package/dist-skill/docs/generated/output.md +139 -245
- package/dist-skill/docs/generated/sheet-metal.md +473 -21
- package/dist-skill/docs/generated/sketch.md +553 -349
- package/dist-skill/docs/generated/viewport.md +345 -303
- package/dist-skill/docs/generated/wood.md +104 -0
- package/dist-skill/docs/guides/coordinate-system.md +11 -17
- package/dist-skill/docs/guides/geometry-conventions.md +13 -70
- package/dist-skill/docs/guides/modeling-recipes.md +22 -195
- package/dist-skill/docs/guides/positioning.md +88 -147
- package/dist-skill/docs-dev/API/core/concepts.md +51 -0
- package/dist-skill/docs-dev/API/core/sdf-advanced.md +92 -0
- package/dist-skill/docs-dev/API/core/sdf-primitives.md +58 -0
- package/dist-skill/docs-dev/API/core/sdf-workflow.md +42 -0
- package/dist-skill/docs-dev/CLI/export.md +91 -0
- package/dist-skill/docs-dev/CLI/projects.md +107 -0
- package/dist-skill/docs-dev/CLI/studio_publishing.md +52 -0
- package/dist-skill/docs-dev/CLI/validation.md +66 -0
- package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
- package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
- package/dist-skill/{docs → docs-dev}/coding.md +1 -3
- package/dist-skill/docs-dev/generated/assembly.md +771 -0
- package/dist-skill/docs-dev/generated/core.md +775 -0
- package/dist-skill/docs-dev/generated/curves.md +688 -0
- package/dist-skill/docs-dev/generated/lib.md +50 -0
- package/dist-skill/docs-dev/generated/output.md +234 -0
- package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
- package/dist-skill/docs-dev/generated/sketch.md +801 -0
- package/dist-skill/docs-dev/generated/viewport.md +486 -0
- package/dist-skill/docs-dev/generated/wood.md +104 -0
- package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
- package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
- package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
- package/dist-skill/docs-dev/guides/positioning.md +151 -0
- package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
- package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
- package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
- package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
- package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
- package/examples/api/attachTo-basics.forge.js +5 -5
- package/examples/api/boolean-operations.forge.js +3 -3
- package/examples/api/bounding-box-visualizer.forge.js +2 -2
- package/examples/api/clone-duplicate.forge.js +1 -1
- package/examples/api/colors-union-vs-array.forge.js +6 -6
- package/examples/api/connector-assembly.forge.js +4 -4
- package/examples/api/connector-basics.forge.js +2 -2
- package/examples/api/extrude-options.forge.js +4 -10
- package/examples/api/feature-created-faces.forge.js +6 -10
- package/examples/api/fillet-showcase.forge.js +1 -1
- package/examples/api/folded-service-panel-cover.forge.js +2 -2
- package/examples/api/group-test.forge.js +1 -1
- package/examples/api/group-vs-union.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +4 -0
- package/examples/api/js-module-pillars.js +1 -1
- package/examples/api/js-module-scene.js +2 -2
- package/examples/api/mesh-import-slats.forge.js +1 -1
- package/examples/api/pointAlong-orientation.forge.js +1 -1
- package/examples/api/profile-2020-b-slot6.forge.js +0 -1
- package/examples/api/route-perimeter-flange.forge.js +1 -1
- package/examples/api/sdf-rover-demo.forge.js +10 -10
- package/examples/api/sketch-on-face-demo.forge.js +2 -2
- package/examples/api/sketch-regions.forge.js +4 -4
- package/examples/api/transition-curves.forge.js +1 -1
- package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
- package/examples/api/variable-sweep-test.forge.js +2 -2
- package/examples/api/wood-joinery.forge.js +60 -0
- package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
- package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
- package/examples/experiments/drone-arm.forge.js +53 -0
- package/examples/furniture/adjustable-table.forge.js +2 -2
- package/examples/furniture/bathroom.forge.js +11 -11
- package/examples/furniture/chair.forge.js +1 -1
- package/examples/generative/crystal-growth.forge.js +2 -2
- package/examples/generative/frost-spires.forge.js +3 -3
- package/examples/generative/golden-spiral-tower.forge.js +3 -3
- package/examples/mechanical/3d-printer.forge.js +28 -28
- package/examples/mechanical/5-finger-robot-hand.forge.js +15 -15
- package/examples/mechanical/airplane-propeller.forge.js +2 -2
- package/examples/mechanical/fillet-enclosure.forge.js +1 -1
- package/examples/mechanical/headphone-hanger-v2.forge.js +2 -2
- package/examples/mechanical/robot_hand.forge.js +15 -15
- package/examples/mechanical/robot_hand_2.forge.js +9 -9
- package/examples/products/bottle.forge.js +1 -1
- package/examples/products/chess-set.forge.js +19 -19
- package/examples/products/classical-piano.forge.js +11 -11
- package/examples/products/clock.forge.js +12 -12
- package/examples/products/iphone.forge.js +8 -8
- package/examples/products/laptop.forge.js +15 -15
- package/examples/products/liquid-soap-dispenser.forge.js +18 -18
- package/examples/products/origami-fish.forge.js +8 -6
- package/examples/products/spiderman-cake.forge.js +4 -4
- package/examples/toolbox/bolted-joint.forge.js +2 -2
- package/package.json +7 -4
- package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
- package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
- package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
- package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
- package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
- package/dist/assets/index-1CYp3zUp.js +0 -1455
- package/dist/docs-raw/CLI.md +0 -865
- package/dist-skill/docs/API/API.md +0 -1666
- package/dist-skill/docs/API/README.md +0 -37
- package/dist-skill/docs/API/assembly/assembly.md +0 -617
- package/dist-skill/docs/API/core/edge-queries.md +0 -130
- package/dist-skill/docs/API/core/parameters.md +0 -122
- package/dist-skill/docs/API/core/reserved-terms.md +0 -137
- package/dist-skill/docs/API/core/sdf.md +0 -326
- package/dist-skill/docs/API/core/skill-cli.md +0 -194
- package/dist-skill/docs/API/core/skill-guide.md +0 -205
- package/dist-skill/docs/API/core/specs.md +0 -186
- package/dist-skill/docs/API/core/topology.md +0 -372
- package/dist-skill/docs/API/entities.md +0 -268
- package/dist-skill/docs/API/output/bom.md +0 -58
- package/dist-skill/docs/API/output/brep-export.md +0 -87
- package/dist-skill/docs/API/output/dimensions.md +0 -67
- package/dist-skill/docs/API/output/export.md +0 -110
- package/dist-skill/docs/API/output/gcode.md +0 -195
- package/dist-skill/docs/API/runtime/viewport.md +0 -420
- package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
- package/dist-skill/docs/API/sketch/anchor.md +0 -37
- package/dist-skill/docs/API/sketch/booleans.md +0 -91
- package/dist-skill/docs/API/sketch/core.md +0 -73
- package/dist-skill/docs/API/sketch/extrude.md +0 -62
- package/dist-skill/docs/API/sketch/on-face.md +0 -104
- package/dist-skill/docs/API/sketch/operations.md +0 -78
- package/dist-skill/docs/API/sketch/path.md +0 -75
- package/dist-skill/docs/API/sketch/primitives.md +0 -146
- package/dist-skill/docs/API/sketch/regions.md +0 -80
- package/dist-skill/docs/API/sketch/text.md +0 -108
- package/dist-skill/docs/API/sketch/transforms.md +0 -65
- package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
- package/dist-skill/docs/CLI.md +0 -865
- package/dist-skill/docs/INDEX.md +0 -94
- package/dist-skill/docs/RELEASING.md +0 -55
- package/dist-skill/docs/cli-monetization.md +0 -111
- package/dist-skill/docs/deployment.md +0 -281
- package/dist-skill/docs/generated/concepts.md +0 -2112
- package/dist-skill/docs/internals/shape-from-slices.md +0 -152
- package/dist-skill/docs/platform/admin.md +0 -45
- package/dist-skill/docs/platform/architecture.md +0 -79
- package/dist-skill/docs/platform/auth.md +0 -110
- package/dist-skill/docs/platform/email.md +0 -67
- package/dist-skill/docs/platform/projects.md +0 -111
- package/dist-skill/docs/platform/sharing.md +0 -90
- package/dist-skill/docs/runbook.md +0 -345
package/dist-skill/docs/CLI.md
DELETED
|
@@ -1,865 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
skill-group: cli
|
|
3
|
-
skill-order: 1
|
|
4
|
-
skill-tiers: [standard]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# ForgeCAD CLI
|
|
8
|
-
|
|
9
|
-
## Architecture
|
|
10
|
-
|
|
11
|
-
All CLI tools share the **same forge engine** as the browser UI. There is one source of truth for geometry logic — no code duplication. See [CODING.md → Project Structure](CODING.md#project-structure) for the full source tree.
|
|
12
|
-
|
|
13
|
-
**Browser** imports via `src/forge/index.ts` → re-exports from `headless.ts`.
|
|
14
|
-
**CLI tools** import directly from `src/forge/headless.ts`.
|
|
15
|
-
|
|
16
|
-
The key function is `runScript(code, fileName, allFiles)` — it wraps user code in a `Function()` sandbox with the entire forge API injected, and transpiles project files so standard JS `import` / `export` / `require(...)` work for shared utility modules. CLI scripts just call `init()` + `runScript()` and work with the results.
|
|
17
|
-
|
|
18
|
-
## When to use what
|
|
19
|
-
|
|
20
|
-
ForgeCAD has two overlapping interfaces. Use the right one for each context.
|
|
21
|
-
|
|
22
|
-
| Context | Use | Avoid |
|
|
23
|
-
|---------|-----|-------|
|
|
24
|
-
| **Using ForgeCAD as a tool** | `forgecad *` commands | `npm run *` |
|
|
25
|
-
| **Developing ForgeCAD itself** | `npm run dev` (live reload), `npm run build` (prod) | — |
|
|
26
|
-
| **CI / publishing** | `npm run build && npm run test` | forgecad CLI (not installed in CI) |
|
|
27
|
-
| **AI agents in this repo** | `forgecad *` commands only | `npm run build`, `npm run build:cli` |
|
|
28
|
-
|
|
29
|
-
The CLI is always available after `npm install` — no explicit build step needed.
|
|
30
|
-
|
|
31
|
-
### Dev server vs production server
|
|
32
|
-
|
|
33
|
-
| Command | What it does | Requires |
|
|
34
|
-
|---------|-------------|---------|
|
|
35
|
-
| `forgecad dev [path]` | Vite dev server, live reload | nothing beyond `npm install` |
|
|
36
|
-
| `forgecad studio [path]` | Fast static server for the production build | `dist/` built via `npm run build` |
|
|
37
|
-
| `npm run dev` | Same as `forgecad dev` — standard JS project entry point | nothing |
|
|
38
|
-
|
|
39
|
-
Use `forgecad dev` during active development of forge scripts. Use `forgecad studio` to verify the production build or serve it to others.
|
|
40
|
-
|
|
41
|
-
## Install
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npm install -g forgecad
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
For developers working on ForgeCAD itself:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm install
|
|
51
|
-
npm link
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
The npm package ships a minified JS bundle (`cli.js`) — no source maps. A compiled native binary build script exists (`npm run build:binary`) for future Homebrew distribution but is not the primary channel.
|
|
55
|
-
|
|
56
|
-
## Licensing
|
|
57
|
-
|
|
58
|
-
Some commands require a ForgeCAD Pro license. Free-tier commands work without any key.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
forgecad license # Show current license status
|
|
62
|
-
forgecad license activate <key> # Activate a license key
|
|
63
|
-
forgecad license deactivate # Remove license from this machine
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
| Tier | What's included |
|
|
67
|
-
|------|----------------|
|
|
68
|
-
| **Free** | dev, studio, run, render, export stl/3mf/svg, all checks, debug |
|
|
69
|
-
| **Pro** | export step/brep, render-hq, capture gif/mp4, gcode, report, cutting-layout, sdf, urdf, sketch-pdf |
|
|
70
|
-
|
|
71
|
-
Pro commands show a `[Pro]` badge in `forgecad help` and display a clear upgrade message when invoked without a license.
|
|
72
|
-
|
|
73
|
-
See [cli-monetization.md](project/cli-monetization.md) for the full monetization strategy.
|
|
74
|
-
|
|
75
|
-
### Shell Autocomplete
|
|
76
|
-
|
|
77
|
-
ForgeCAD now ships shell completion scripts in the usual modern-tool style:
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
forgecad completion bash
|
|
81
|
-
forgecad completion zsh
|
|
82
|
-
forgecad completion fish
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Quick install:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# bash
|
|
89
|
-
echo 'source <(forgecad completion bash)' >> ~/.bashrc
|
|
90
|
-
|
|
91
|
-
# zsh
|
|
92
|
-
mkdir -p ~/.zsh/completions
|
|
93
|
-
forgecad completion zsh > ~/.zsh/completions/_forgecad
|
|
94
|
-
echo 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrc
|
|
95
|
-
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
|
|
96
|
-
|
|
97
|
-
# fish
|
|
98
|
-
mkdir -p ~/.config/fish/completions
|
|
99
|
-
forgecad completion fish > ~/.config/fish/completions/forgecad.fish
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
The completions are contextual:
|
|
103
|
-
|
|
104
|
-
- nested subcommands such as `forgecad notebook view` and `forgecad export step`
|
|
105
|
-
- command-specific flags and common enum values
|
|
106
|
-
- ForgeCAD file suggestions where a command expects `.forge.js` or `.forge-notebook.json`
|
|
107
|
-
|
|
108
|
-
## Available Commands
|
|
109
|
-
|
|
110
|
-
### Authentication & Account
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
forgecad login # Interactive email/password login
|
|
114
|
-
forgecad login --server http://localhost:5174 # Login to local dev server
|
|
115
|
-
forgecad logout # Clear stored credentials
|
|
116
|
-
forgecad whoami # Show user, server, and license status
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Credentials are stored in `~/.forgecad/auth.json`.
|
|
120
|
-
|
|
121
|
-
### Project Management
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
# Create and sync
|
|
125
|
-
forgecad project init "My Project" # Create on server + link current directory
|
|
126
|
-
forgecad project init "My Project" --slug my-project --visibility public
|
|
127
|
-
forgecad project clone my-project # Download into ./my-project/
|
|
128
|
-
forgecad project push [--force] # Upload local changes
|
|
129
|
-
forgecad project pull [--force] # Download remote changes
|
|
130
|
-
forgecad project status # Show local vs remote diff
|
|
131
|
-
|
|
132
|
-
# Inspect and modify
|
|
133
|
-
forgecad project list # List all your projects
|
|
134
|
-
forgecad project info # Show current project details (name, visibility, files, URL)
|
|
135
|
-
forgecad project rename "New Name" # Rename the project
|
|
136
|
-
forgecad project set-visibility public # Change visibility (private|shared|public)
|
|
137
|
-
forgecad project delete [--force] # Permanently delete project and all files
|
|
138
|
-
forgecad project open # Open in browser
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Projects are stored on forgecad.io. Local projects are linked to their remote counterpart via `forgecad.json`.
|
|
142
|
-
|
|
143
|
-
### File Management (Remote)
|
|
144
|
-
|
|
145
|
-
Operate directly on remote project files without the push/pull cycle:
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
forgecad file list [path] # List remote files (optional path prefix filter)
|
|
149
|
-
forgecad file read <path> # Print file contents to stdout
|
|
150
|
-
forgecad file save <path> # Upload local file to remote (same relative path)
|
|
151
|
-
forgecad file save <path> --content "code here" # Save inline content
|
|
152
|
-
cat model.forge.js | forgecad file save model.forge.js --stdin # Pipe content from stdin
|
|
153
|
-
forgecad file delete <path> [--force] # Delete remote file
|
|
154
|
-
forgecad file rename <old> <new> # Rename or move a remote file
|
|
155
|
-
forgecad file mkdir <path> # Create a remote directory
|
|
156
|
-
forgecad file copy <source-slug> <path> [--dest <dest-path>] # Copy from another project
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
These commands require the current directory to be an initialized ForgeCAD project (has `forgecad.json`).
|
|
160
|
-
|
|
161
|
-
### Member Management
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
forgecad project members # List project members
|
|
165
|
-
forgecad project add-member alice@example.com # Add as editor (default)
|
|
166
|
-
forgecad project add-member bob@example.com --role viewer
|
|
167
|
-
forgecad project remove-member alice@example.com
|
|
168
|
-
forgecad project set-role bob@example.com editor
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Roles: **owner** (full control, manage members), **editor** (read/write files), **viewer** (read-only).
|
|
172
|
-
|
|
173
|
-
### Publishing & Sharing
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
forgecad publish model.forge.js --title "My Model" # Publish model, get shareable URL
|
|
177
|
-
forgecad publish model.forge.js --no-sync # Publish without auto-pushing project
|
|
178
|
-
forgecad shares list # List all published models with URLs
|
|
179
|
-
forgecad shares delete <share-id> [--force] # Unpublish a shared model
|
|
180
|
-
forgecad link <gist-url-or-id> # Generate share link from GitHub Gist
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
Published models are viewable at `forgecad.io/m/<shareId>`. Shares are **live references** to project files — they always reflect the current version, not a frozen snapshot. Publishing requires being inside a project directory. The project is auto-synced first (unless `--no-sync`).
|
|
184
|
-
|
|
185
|
-
### New File from Template
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
forgecad new mypart # Part template (default)
|
|
189
|
-
forgecad new bracket --template sketch # Constrained sketch template
|
|
190
|
-
forgecad new robot --template assembly # Multi-part assembly template
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Studio & Dev Server
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# Development — Vite dev server, live reload, no build needed
|
|
197
|
-
forgecad dev
|
|
198
|
-
forgecad dev ~/cad/gearbox
|
|
199
|
-
forgecad dev --blank --port 4173
|
|
200
|
-
|
|
201
|
-
# Production — static server, requires dist/ (npm run build)
|
|
202
|
-
forgecad studio
|
|
203
|
-
forgecad studio ~/cad/gearbox
|
|
204
|
-
forgecad studio --blank --port 4173
|
|
205
|
-
|
|
206
|
-
# Web / embeddable mode — always dev server, no filesystem
|
|
207
|
-
forgecad web
|
|
208
|
-
forgecad web --open
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
Both `forgecad dev` and `forgecad studio` accept the same options:
|
|
212
|
-
- `--blank` — open without any project folder
|
|
213
|
-
- `--port <n>` — bind to a specific port (default: 5173)
|
|
214
|
-
- `--host [host]` — expose on the network
|
|
215
|
-
- `--open` — open a browser tab automatically
|
|
216
|
-
- `--strict-port` — fail if the port is already in use
|
|
217
|
-
|
|
218
|
-
`forgecad open` is an alias for `forgecad studio`.
|
|
219
|
-
|
|
220
|
-
### Notebook Cells (server-backed)
|
|
221
|
-
|
|
222
|
-
Forge notebooks live in `.forge-notebook.json` files and behave like lightweight Jupyter notebooks for ForgeCAD code cells.
|
|
223
|
-
|
|
224
|
-
The browser and CLI both use the Vite server for notebook execution. The CLI does not run Forge locally for notebook cells; it auto-starts or reuses the Forge server, sends the cell code, then prints the returned output summary.
|
|
225
|
-
|
|
226
|
-
Append a new code cell and run it immediately in one command:
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
forgecad notebook examples/demo.forge-notebook.json --code "show(box(40, 20, 10));"
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
If the target notebook file does not exist yet, append mode auto-creates it first with the default ForgeCAD notebook structure, then adds the new cell.
|
|
233
|
-
|
|
234
|
-
Or pipe a larger cell in through stdin:
|
|
235
|
-
|
|
236
|
-
```bash
|
|
237
|
-
cat /tmp/cell.js | forgecad notebook examples/demo.forge-notebook.json
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
Re-run the last preview cell, or a specific cell id:
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
forgecad notebook examples/demo.forge-notebook.json
|
|
244
|
-
forgecad notebook run examples/demo.forge-notebook.json <cell-id>
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
View the notebook in the terminal without dumping raw JSON:
|
|
248
|
-
|
|
249
|
-
```bash
|
|
250
|
-
forgecad notebook view examples/demo.forge-notebook.json
|
|
251
|
-
forgecad notebook view examples/demo.forge-notebook.json preview
|
|
252
|
-
forgecad notebook view examples/demo.forge-notebook.json 2
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
`view` is local-only. It parses the notebook JSON and renders notebook metadata, numbered source lines, and stored outputs for each cell. The optional selector accepts a 1-based cell number, an exact cell id, or `preview`.
|
|
256
|
-
|
|
257
|
-
`run`/`view` expect the notebook file to already exist. Auto-creation only applies to append flows (`--code`, `--file`, stdin, or the explicit `append` subcommand).
|
|
258
|
-
|
|
259
|
-
Export a notebook into a plain `.forge.js` script:
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
forgecad notebook export examples/demo.forge-notebook.json
|
|
263
|
-
forgecad notebook export examples/demo.forge-notebook.json out/demo-from-notebook.forge.js
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
If you already have a Forge server running, point the CLI at it:
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
forgecad notebook examples/demo.forge-notebook.json --server http://localhost:5173 --code "show(box(40, 20, 10));"
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Notebook paths are resolved from the shell working directory before the CLI calls the server, so the server's opened project root does not add an extra path prefix.
|
|
273
|
-
|
|
274
|
-
Notebook cell behavior:
|
|
275
|
-
|
|
276
|
-
- Cells share state top-to-bottom
|
|
277
|
-
- `show(value)` pins the geometry that should stay visible in the viewport
|
|
278
|
-
- A trailing expression is also treated as the cell value
|
|
279
|
-
- Cell outputs are written back into the notebook JSON, similar to Jupyter
|
|
280
|
-
|
|
281
|
-
For the `forgecad` entrypoints below, passing a `.forge-notebook.json` uses that notebook's preview cell. That means you can inspect with `view`, validate with `run`, and render or capture the current preview without exporting first.
|
|
282
|
-
|
|
283
|
-
### Script Validation
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
forgecad run examples/cup.forge.js
|
|
287
|
-
forgecad run examples/api/notebook-iteration.forge-notebook.json
|
|
288
|
-
forgecad run examples/cup.forge.js --debug-imports
|
|
289
|
-
forgecad run examples/cup.forge.js --param "Wall Thickness=3"
|
|
290
|
-
forgecad run examples/cup.forge.js --param "Show Lid=0"
|
|
291
|
-
forgecad run examples/cup.forge.js --param "Pan Style=wok"
|
|
292
|
-
forgecad run examples/constraints/06-complex-spectrogram.forge.js --solver-debug-out tmp/spectrogram-debug
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
Runs a `.forge.js` or notebook preview cell in the real runtime and prints object stats, diagnostics, and execution time.
|
|
296
|
-
|
|
297
|
-
`--param "Key=Value"` overrides script parameters for that run. It supports:
|
|
298
|
-
|
|
299
|
-
- numeric `param()` values such as `"Wall Thickness=3"`
|
|
300
|
-
- boolean `boolParam()` values using `1` or `0`
|
|
301
|
-
- string `choiceParam()` values using the displayed label, such as `"Pan Style=wok"`
|
|
302
|
-
|
|
303
|
-
`--debug-imports` adds an import trace (source file, target file, overrides, return type, success/error phase), useful when debugging `require()` import behavior.
|
|
304
|
-
|
|
305
|
-
`--solver-debug-out <dir>` enables the Rust planner's constructive transcript and SVG snapshots for every solved sketch in that run, then writes a reusable artifact bundle to disk:
|
|
306
|
-
|
|
307
|
-
- `README.md` summary at the output root
|
|
308
|
-
- one subdirectory per sketch
|
|
309
|
-
- `constructive-transcript.md` with the step-by-step planner story
|
|
310
|
-
- `svg/*.svg` snapshots keyed to transcript steps
|
|
311
|
-
|
|
312
|
-
### SVG Export (no browser needed)
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
forgecad export svg examples/constraints/01-fully-constrained-rect.forge.js [output.svg]
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
Runs a sketch `.forge.js` script in Node.js using the real forge engine and outputs SVG. No browser, no Puppeteer — pure Node.
|
|
319
|
-
|
|
320
|
-
**How it works:** Initializes the Manifold WASM kernel, runs the script through `runScript()`, extracts the Sketch result, converts polygons to SVG paths.
|
|
321
|
-
|
|
322
|
-
### STEP / BREP Export (exact subset, Python + CadQuery)
|
|
323
|
-
|
|
324
|
-
```bash
|
|
325
|
-
forgecad export step examples/api/brep-exportable.forge.js
|
|
326
|
-
forgecad export brep examples/api/brep-exportable.forge.js
|
|
327
|
-
|
|
328
|
-
# Optional overrides:
|
|
329
|
-
forgecad export step examples/api/brep-exportable.forge.js --output out/demo.step
|
|
330
|
-
forgecad export step examples/api/brep-exportable.forge.js --python 3.11
|
|
331
|
-
forgecad export step examples/api/brep-exportable.forge.js --uv /custom/path/to/uv
|
|
332
|
-
forgecad export step examples/chess-set.forge.js --allow-faceted
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
This exporter is `uv`-first. `cli/forge-brep-export.py` carries inline dependency metadata, so `uv run` provisions CadQuery automatically for the exporter environment.
|
|
336
|
-
|
|
337
|
-
By default this exporter is exact-subset only. It does **not** silently convert arbitrary triangle meshes back into fake BREP. Instead, Forge lowers compile-covered geometry into the `cadquery-occt` compiler target and exports that exact subset through CadQuery/OpenCascade.
|
|
338
|
-
|
|
339
|
-
If you pass `--allow-faceted`, unsupported closed mesh solids are exported as explicit faceted OCCT solids. This keeps mesh-heavy designs exportable to STEP/BREP, but that fallback is tessellation-driven rather than exact replay.
|
|
340
|
-
|
|
341
|
-
The maintained feature matrix lives in [`docs/permanent/API/output/brep-export.md`](API/output/brep-export.md).
|
|
342
|
-
|
|
343
|
-
If any returned solid object falls outside the exact subset, the CLI fails with a reason instead of silently exporting degraded geometry. When a scene mixes solids and 2D sketches, the exact solids export and the sketch-only objects are skipped with a warning.
|
|
344
|
-
|
|
345
|
-
With `--allow-faceted`, mesh-solid blockers that still lack an exact replay plan are exported as faceted solids instead of failing. The CLI prints which objects used the fallback.
|
|
346
|
-
|
|
347
|
-
For coverage runs across many examples, use the `uv` matrix scripts:
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
uv run scripts/brep/matrix.py --format step examples
|
|
351
|
-
uv run scripts/brep/matrix.py --format brep examples
|
|
352
|
-
uv run scripts/brep/rerun_failures.py tmp/brep-matrix-step-20260306T120000Z.json
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
These scripts use the repo-local `.venv-brep/.venv/bin/python` by default, run exports through a bounded parallel worker pool, and write JSON reports under `tmp/`.
|
|
356
|
-
|
|
357
|
-
### G-code Toolpath Export
|
|
358
|
-
|
|
359
|
-
```bash
|
|
360
|
-
forgecad export gcode examples/gcode/parametric-vase.forge.js
|
|
361
|
-
forgecad export gcode examples/gcode/parametric-vase.forge.js --output out/vase.gcode
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
Exports a G-code toolpath script directly to `.gcode` for FDM 3D printing. The script must return a `GCodeBuilder` instance (created via the `gcode()` factory function).
|
|
365
|
-
|
|
366
|
-
This is a **toolpath scripting API**, not a slicer. You define print movements directly in code — enabling parametric vases, mathematical surfaces, non-planar paths, and other geometries that conventional slicers cannot produce.
|
|
367
|
-
|
|
368
|
-
**How it works:** Initializes the forge kernel, runs the script, extracts the `GCodeBuilder` result, and writes the generated G-code text to disk. Prints segment count, estimated time, filament usage, and bounding box.
|
|
369
|
-
|
|
370
|
-
**Options:**
|
|
371
|
-
- `--output <path>` / `-o <path>` — Output file path (default: replaces `.forge.js` with `.gcode`)
|
|
372
|
-
|
|
373
|
-
**Demo scripts:**
|
|
374
|
-
- `examples/gcode/parametric-vase.forge.js` — Sine-wave modulated continuous spiral vase
|
|
375
|
-
- `examples/gcode/spiral-tower.forge.js` — Twisted hexagonal polygon tower
|
|
376
|
-
- `examples/gcode/math-surface.forge.js` — Non-planar bowl with wave rim
|
|
377
|
-
- `examples/gcode/lissajous-vase.forge.js` — Lissajous curve vase with morphing profile
|
|
378
|
-
|
|
379
|
-
Preview these scripts in ForgeCAD's interactive viewport. The current `forgecad render` CLI expects shape outputs and does not render `GCodeBuilder` scenes yet.
|
|
380
|
-
|
|
381
|
-
See [`docs/permanent/API/output/gcode.md`](API/output/gcode.md) for the dedicated G-code mode guide and full `GCodeBuilder` API reference.
|
|
382
|
-
|
|
383
|
-
### SDF Robot Export (Gazebo package)
|
|
384
|
-
|
|
385
|
-
```bash
|
|
386
|
-
forgecad export sdf examples/api/sdf-rover-demo.forge.js
|
|
387
|
-
|
|
388
|
-
# Optional output directory:
|
|
389
|
-
forgecad export sdf examples/api/sdf-rover-demo.forge.js --output out/forge_scout
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
This exporter writes a Gazebo-friendly package workspace:
|
|
393
|
-
|
|
394
|
-
- `models/<model-name>/model.sdf`
|
|
395
|
-
- `models/<model-name>/model.config`
|
|
396
|
-
- `models/<model-name>/meshes/*.stl`
|
|
397
|
-
- `worlds/<world-name>.sdf` when the script requests a demo world
|
|
398
|
-
- `manifest.json` with topic names, link/joint mappings, and exporter warnings
|
|
399
|
-
|
|
400
|
-
The script must call `robotExport({...})` with an `assembly(...)` graph. The exporter uses the declared parts + joints directly; it does **not** try to infer a robot from flattened scene meshes.
|
|
401
|
-
|
|
402
|
-
When `world.generateDemoWorld` and `world.keyboardTeleop.enabled` are on, the exported world includes both:
|
|
403
|
-
|
|
404
|
-
- Gazebo's GUI `KeyPublisher` plugin
|
|
405
|
-
- server-side `TriggeredPublisher` bindings that map arrow keys to the diff-drive `cmd_vel` topic
|
|
406
|
-
|
|
407
|
-
Recommended launch flow:
|
|
408
|
-
|
|
409
|
-
```bash
|
|
410
|
-
export GZ_SIM_RESOURCE_PATH="$PWD/out/forge_scout/models${GZ_SIM_RESOURCE_PATH:+:$GZ_SIM_RESOURCE_PATH}"
|
|
411
|
-
|
|
412
|
-
# Terminal 1: server
|
|
413
|
-
gz sim -s -r out/forge_scout/worlds/forge_scout_trial.sdf
|
|
414
|
-
|
|
415
|
-
# Terminal 2: GUI client using the same world layout
|
|
416
|
-
gz sim -g out/forge_scout/worlds/forge_scout_trial.sdf
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
Notes:
|
|
420
|
-
|
|
421
|
-
- On macOS, use the split `-s` / `-g` flow above. `gz sim <world.sdf>` is not supported there.
|
|
422
|
-
- Click the 3D view so it has keyboard focus, then use `W` / `X` for forward / reverse, `A` / `D` to rotate, `Q` / `E` / `Z` / `C` for diagonals, and `S` or `Space` to stop.
|
|
423
|
-
- For older exports created before the GUI plugin was added, load `Key Publisher` manually from the Gazebo GUI plugins menu.
|
|
424
|
-
|
|
425
|
-
Current behavior:
|
|
426
|
-
|
|
427
|
-
- Per-link geometry is exported as STL mesh assets
|
|
428
|
-
- Collision geometry reuses the same mesh unless `collision: 'none'` is set on a link
|
|
429
|
-
- Link mass comes from `massKg`, else `densityKgM3 * volume`, else a default density
|
|
430
|
-
- Inertia is an approximate box fit based on link bounds
|
|
431
|
-
- Coupled joints are currently rejected
|
|
432
|
-
- Parts without geometry are currently rejected
|
|
433
|
-
|
|
434
|
-
### PNG Render (requires Chrome)
|
|
435
|
-
|
|
436
|
-
```bash
|
|
437
|
-
forgecad render examples/cup.forge.js [output.png]
|
|
438
|
-
forgecad render examples/api/notebook-iteration.forge-notebook.json [output.png]
|
|
439
|
-
forgecad render examples/cup.forge.js out/scene.png --scene '{"camera":{"projectionMode":"perspective","position":[200,-160,120],"target":[0,0,20],"up":[0,0,1]},"objects":{"obj-2":{"visible":false},"obj-3":{"opacity":0.35}}}'
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
Renders 3D shapes to PNG images from multiple camera angles. Uses Puppeteer to launch headless Chrome with WebGL for Three.js rendering.
|
|
443
|
-
|
|
444
|
-
When the input is a notebook, `forgecad render` renders the notebook's preview cell.
|
|
445
|
-
|
|
446
|
-
**How it works:**
|
|
447
|
-
1. `cli/forge-render.mjs` — Node launcher script. Auto-starts Vite dev server if not running, launches Puppeteer.
|
|
448
|
-
2. `cli/render.html` + `cli/render.ts` — Loaded in the browser by Puppeteer. Imports from `src/forge/headless.ts`, runs the script, builds a Three.js scene, renders from multiple angles.
|
|
449
|
-
3. Screenshots are captured as base64 PNG and saved to disk.
|
|
450
|
-
|
|
451
|
-
**Environment variables:**
|
|
452
|
-
|
|
453
|
-
| Variable | Default | Description |
|
|
454
|
-
|----------|---------|-------------|
|
|
455
|
-
| `FORGE_ANGLES` | `front,side,top,iso` | Camera angles to render |
|
|
456
|
-
| `FORGE_SIZE` | `1024` | Image size in pixels |
|
|
457
|
-
| `FORGE_PORT` | `5173` | Vite dev server port |
|
|
458
|
-
| `CHROME_PATH` | Auto-detected | Chrome/Chromium executable path |
|
|
459
|
-
|
|
460
|
-
**CLI options:**
|
|
461
|
-
- `--angles <front,side,top,iso>` — standard angles to render
|
|
462
|
-
- `--size <px>` — output size override
|
|
463
|
-
- `--port <n>` — Vite port override
|
|
464
|
-
- `--camera <spec>` — exact camera pose, e.g. `proj=perspective;pos=120,80,120;target=0,0,0;up=0,0,1`
|
|
465
|
-
- `--scene <json>` — full scene state copied from the viewport, including camera plus object visibility/opacity/color overrides
|
|
466
|
-
- `--background <color>` — background override
|
|
467
|
-
- `--chrome-path <path>` — Chrome executable path override
|
|
468
|
-
|
|
469
|
-
**Camera angles:** `front` (−Y), `back` (+Y), `side` (+X), `top` (+Z), `iso` (diagonal)
|
|
470
|
-
|
|
471
|
-
### Animated Capture (GIF or MP4, requires Chrome)
|
|
472
|
-
|
|
473
|
-
```bash
|
|
474
|
-
forgecad capture gif examples/cup.forge.js [output.gif]
|
|
475
|
-
forgecad capture mp4 examples/cup.forge.js [output.mp4]
|
|
476
|
-
forgecad capture gif examples/api/notebook-assembly-debug.forge-notebook.json --list
|
|
477
|
-
forgecad capture mp4 examples/api/runtime-joints-view.forge.js out/step.mp4 --capture animation --animation Step
|
|
478
|
-
forgecad capture gif examples/3d-printer.forge.js out/section.gif --cut-plane "Front Section"
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
Creates high-quality animated captures from the real Forge viewport renderer:
|
|
482
|
-
- Orbit captures with optional wireframe pass
|
|
483
|
-
- Fixed-camera animation captures for `jointsView()` clips
|
|
484
|
-
- Named cut-plane captures
|
|
485
|
-
- Exact camera replay via `--camera`
|
|
486
|
-
- Full viewport scene replay via `--scene`
|
|
487
|
-
|
|
488
|
-
When the input is a notebook, `forgecad capture gif` / `forgecad capture mp4` capture the notebook's preview cell.
|
|
489
|
-
|
|
490
|
-
**How it works:**
|
|
491
|
-
1. Auto-starts (or reuses) the Vite dev server.
|
|
492
|
-
2. Loads `cli/render.html` in headless Chrome.
|
|
493
|
-
3. Runs the script once, then captures frames from the same scene while applying the selected animation, cut planes, and camera pose.
|
|
494
|
-
4. Encodes with `ffmpeg` when available:
|
|
495
|
-
- GIF: palettegen/paletteuse for much better colors
|
|
496
|
-
- MP4: H.264 via `libx264`
|
|
497
|
-
5. Falls back to the pure-JS GIF encoder only when `ffmpeg` is unavailable.
|
|
498
|
-
|
|
499
|
-
**Options:**
|
|
500
|
-
- `--format <gif|mp4>` — output format
|
|
501
|
-
- `--capture <orbit|animation>` — moving orbit camera or fixed animation camera
|
|
502
|
-
- `--animation <name>` — select one `jointsView()` clip
|
|
503
|
-
- `--animation-loops <n>` — repeat the chosen clip
|
|
504
|
-
- `--cut-plane <name>` — enable a named cut plane (repeatable)
|
|
505
|
-
- `--camera <spec>` — exact camera pose, e.g. `proj=perspective;pos=120,80,120;target=0,0,0;up=0,0,1`
|
|
506
|
-
- `--scene <json>` — full scene state copied from the viewport, including camera plus object visibility/opacity/color overrides
|
|
507
|
-
- `--render-mode <solid|wireframe>` — primary render mode
|
|
508
|
-
- `--wireframe-pass` / `--no-wireframe-pass` — enable/disable the extra wireframe pass (off by default)
|
|
509
|
-
- `--size <px>` — output frame resolution (default `960`)
|
|
510
|
-
- `--pixel-ratio <n>` — render supersampling factor (default `2`)
|
|
511
|
-
- `--fps <n>` — capture frame rate (default `24`)
|
|
512
|
-
- `--frames-per-turn <n>` — frames per full orbit pass (default `100`)
|
|
513
|
-
- `--hold-frames <n>` — freeze frames before each pass (default `6`)
|
|
514
|
-
- `--pitch <deg>` — orbit elevation override
|
|
515
|
-
- `--background <color>` — background color (default `#252526`)
|
|
516
|
-
- `--quality <default|live|high>` — Forge geometry quality preset for export (default `high`)
|
|
517
|
-
- `--encoder <auto|ffmpeg|js>` — GIF encoder strategy
|
|
518
|
-
- `--crf <n>` — MP4 quality for `libx264` (default `18`)
|
|
519
|
-
- `--list` — print the script's available animation clips and cut planes
|
|
520
|
-
- `--port <n>` — Vite port (default `5173`)
|
|
521
|
-
- `--chrome-path <path>` — Chrome executable path override
|
|
522
|
-
- `--ffmpeg-path <path>` — ffmpeg executable path override
|
|
523
|
-
|
|
524
|
-
**Environment variables:**
|
|
525
|
-
- `FORGE_CAPTURE_SIZE`
|
|
526
|
-
- `FORGE_CAPTURE_PIXEL_RATIO`
|
|
527
|
-
- `FORGE_CAPTURE_FPS`
|
|
528
|
-
- `FORGE_CAPTURE_FRAMES_PER_TURN`
|
|
529
|
-
- `FORGE_CAPTURE_HOLD_FRAMES`
|
|
530
|
-
- `FORGE_CAPTURE_PITCH_DEG`
|
|
531
|
-
- `FORGE_CAPTURE_BACKGROUND`
|
|
532
|
-
- `FORGE_CAPTURE_QUALITY`
|
|
533
|
-
- `FORGE_CAPTURE_ANIMATION_LOOPS`
|
|
534
|
-
- `FORGE_CAPTURE_CRF`
|
|
535
|
-
- `FFMPEG_PATH`
|
|
536
|
-
- Legacy `FORGE_GIF_*` vars are still honored as fallbacks
|
|
537
|
-
- `FORGE_PORT`
|
|
538
|
-
- `CHROME_PATH`
|
|
539
|
-
|
|
540
|
-
**UI scene handoff:**
|
|
541
|
-
- The View Panel exposes a `Camera` section.
|
|
542
|
-
- Use `Copy CLI --scene` to grab the current viewport framing plus per-object scene overrides and paste it directly into `render`, `capture gif`, or `capture mp4`.
|
|
543
|
-
|
|
544
|
-
### PDF Report (2D drawing pack)
|
|
545
|
-
|
|
546
|
-
```bash
|
|
547
|
-
forgecad export report examples/cup.forge.js [output.pdf]
|
|
548
|
-
forgecad export report examples/cup.forge.js [output.pdf] --dim-angle-tol 18
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
Generates a searchable-text PDF report with multiple projected drawing views:
|
|
552
|
-
- Bill of Materials page (auto-summed from script `bom()` entries)
|
|
553
|
-
- Combined model page (front/right/top/isometric)
|
|
554
|
-
- Disassembled component pages (same view set per unique component geometry; repeated identical items collapse into one page)
|
|
555
|
-
- Auto-generated detail continuation pages for elongated/high-detail views (separate pages, not overlayed)
|
|
556
|
-
- `dim()` annotations included per view only when their axis aligns with that view's projection plane axes
|
|
557
|
-
|
|
558
|
-
BOM aggregation rules:
|
|
559
|
-
- Each `bom(quantity, description, { unit })` call contributes one raw entry
|
|
560
|
-
- Report export groups by `key` (if provided) else by normalized `description + unit`
|
|
561
|
-
- Quantities are summed per group and rendered as line items in the BOM table
|
|
562
|
-
|
|
563
|
-
Component dimension ownership for disassembled pages:
|
|
564
|
-
- Preferred: explicit binding via `dim(..., { component: \"Part Name\" })`
|
|
565
|
-
- Imported-part ownership: `dim(..., { currentComponent: true })` to pin to the owning returned component instance (no bbox heuristic)
|
|
566
|
-
- Other-component ownership: `dim(..., { component: \"Tabletop\" })`
|
|
567
|
-
- If multiple owners are bound (e.g. `currentComponent: true` plus another component), it is treated as shared and stays on the overview page
|
|
568
|
-
- Fallback: automatic ownership only when both dimension endpoints are unambiguously inside exactly one returned component bounding box
|
|
569
|
-
- Ambiguous dimensions are intentionally skipped for disassembled pages
|
|
570
|
-
|
|
571
|
-
Optional report flag:
|
|
572
|
-
- `--dim-angle-tol <degrees>`: include dimensions whose projected direction is within this many degrees of the nearest view axis (default: `12`)
|
|
573
|
-
|
|
574
|
-
### STL Export (from browser)
|
|
575
|
-
|
|
576
|
-
STL export is available in the browser UI via the Export panel. Binary STL format.
|
|
577
|
-
|
|
578
|
-
### Parameter Validation
|
|
579
|
-
|
|
580
|
-
```bash
|
|
581
|
-
forgecad check params examples/shoe-rack-doors.forge.js [--samples 10]
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
Samples each parameter across its range and checks for runtime errors, degenerate geometry (volume ≈ 0), and new collisions between parts. Skips intra-group collisions when assembly groups are used.
|
|
585
|
-
|
|
586
|
-
**Options:**
|
|
587
|
-
- `--samples N` — Number of sample points per parameter (default: 8)
|
|
588
|
-
|
|
589
|
-
**Output example:**
|
|
590
|
-
```
|
|
591
|
-
✓ Baseline: 6 objects, 12 params
|
|
592
|
-
✓ Checked 91 parameter samples (8 per param)
|
|
593
|
-
|
|
594
|
-
⚠ Found 8 issues across 4 parameters:
|
|
595
|
-
|
|
596
|
-
Parameter "Bottom Left Door":
|
|
597
|
-
💥 New collision at values: -120.0, -102.9
|
|
598
|
-
Bottom Left Door ∩ Frame (shared vol: 2561.9mm³)
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
### Transform/Assembly Invariant Check
|
|
602
|
-
|
|
603
|
-
```bash
|
|
604
|
-
forgecad check transforms
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
Runs fast math-level invariants to catch transform order and frame composition regressions before they leak into examples.
|
|
608
|
-
|
|
609
|
-
### Compiler Snapshot Check
|
|
610
|
-
|
|
611
|
-
```bash
|
|
612
|
-
forgecad check compiler
|
|
613
|
-
forgecad check compiler --case segmented-runtime-hints
|
|
614
|
-
forgecad check compiler --update
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
Runs curated compiler regression cases and compares them against committed snapshots.
|
|
618
|
-
This is a unit-style invariant check, not just a debugger convenience.
|
|
619
|
-
The ordinary multi-feature part corpus lives in [`examples/compiler-corpus/README.md`](../../examples/compiler-corpus/README.md).
|
|
620
|
-
|
|
621
|
-
Each snapshot records:
|
|
622
|
-
- Forge compile plans
|
|
623
|
-
- CadQuery/OCCT lowerings
|
|
624
|
-
- export routing decisions
|
|
625
|
-
- quantized runtime Manifold mesh summaries
|
|
626
|
-
- quantized compiler-lowered Manifold mesh summaries
|
|
627
|
-
|
|
628
|
-
This check also fails if:
|
|
629
|
-
- a plan-covered shape or sketch no longer matches its compiler-lowered runtime output
|
|
630
|
-
- export manifests drift away from the per-object compiler routing decisions
|
|
631
|
-
- exact/faceted support claims stop matching the lowered artifacts and diagnostics
|
|
632
|
-
|
|
633
|
-
### Query Propagation Snapshot Check
|
|
634
|
-
|
|
635
|
-
```bash
|
|
636
|
-
forgecad check query-propagation
|
|
637
|
-
forgecad check query-propagation --update
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
Runs focused topology-rewrite query-propagation snapshots without dumping the
|
|
641
|
-
entire compiler scene. This keeps supported, ambiguous, and intentionally
|
|
642
|
-
unsupported rewrite semantics reviewable as the propagation layer evolves.
|
|
643
|
-
|
|
644
|
-
Each snapshot records:
|
|
645
|
-
- the propagated shape objects that actually carry topology-rewrite metadata
|
|
646
|
-
- exact versus faceted routing outcomes for those objects
|
|
647
|
-
- deterministic rewrite-operation ordering
|
|
648
|
-
- preserved and created query summaries
|
|
649
|
-
- explicit ambiguity/unsupported diagnostic codes
|
|
650
|
-
|
|
651
|
-
This check also fails if:
|
|
652
|
-
- a defended propagation case loses the expected preserved or created query shape
|
|
653
|
-
- a known unsupported rewrite stops reporting its explicit diagnostic boundary
|
|
654
|
-
- a multi-feature corpus part stops surfacing the expected rewrite ordering
|
|
655
|
-
|
|
656
|
-
### Example Architecture Gate
|
|
657
|
-
|
|
658
|
-
```bash
|
|
659
|
-
forgecad check examples
|
|
660
|
-
forgecad check examples --family api-parts --family compiler-corpus
|
|
661
|
-
forgecad check examples --example examples/api/brep-exportable.forge.js
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
Runs the checked example manifest for the entire `examples/` tree.
|
|
665
|
-
|
|
666
|
-
The manifest currently lives in `cli/example-manifest/` and covers every:
|
|
667
|
-
|
|
668
|
-
- `.forge.js`
|
|
669
|
-
- `.forge-notebook.json`
|
|
670
|
-
|
|
671
|
-
The command always verifies manifest coverage first, so it fails if:
|
|
672
|
-
|
|
673
|
-
- a new example file was added without classification
|
|
674
|
-
- a checked manifest entry points at a missing file
|
|
675
|
-
- an example's assigned validation path fails
|
|
676
|
-
- a `part` example's declared route expectation no longer matches the compiler report
|
|
677
|
-
|
|
678
|
-
Current example classes:
|
|
679
|
-
|
|
680
|
-
- `part`: runtime execution plus optional exact/faceted route assertions on the selected primary shapes
|
|
681
|
-
- `assembly`: runtime solve + scene emission, not exact-route parity
|
|
682
|
-
- `runtime-scene`: viewport/report/runtime examples that still need to execute successfully
|
|
683
|
-
- `sketch`: sketch payload validation via the sketch export path
|
|
684
|
-
- `notebook`: preview-cell validation for `.forge-notebook.json`
|
|
685
|
-
- `experimental`: temporary fenced examples that still have to run
|
|
686
|
-
|
|
687
|
-
The gate dispatches by declared validation path, not just by class label:
|
|
688
|
-
|
|
689
|
-
- `part-runtime`: execute and then enforce any declared exact/faceted route contract
|
|
690
|
-
- `assembly-runtime`: execute and validate solved-scene/assembly-owned runtime behavior
|
|
691
|
-
- `runtime-scene`: execute as a viewport/report/runtime scene without treating it as part-route evidence
|
|
692
|
-
- `sketch-svg`: render returned sketch payloads through the sketch SVG path
|
|
693
|
-
- `notebook-preview`: materialize and execute the notebook preview cell
|
|
694
|
-
- `experimental-runtime`: execute only, while the example stays outside the active architecture claim
|
|
695
|
-
|
|
696
|
-
For non-part entries, the manifest can also pin specific runtime surfaces that
|
|
697
|
-
must remain available to repo checks, such as BOM entries, cut planes,
|
|
698
|
-
`jointsView()` controls, grouped scene structure, or collected
|
|
699
|
-
`robotExport(...)` data.
|
|
700
|
-
|
|
701
|
-
Current part route states:
|
|
702
|
-
|
|
703
|
-
- `exact`: selected primary shapes must stay on the exact compiler route
|
|
704
|
-
- `faceted`: exact must stay blocked and allow-faceted must succeed with diagnostics
|
|
705
|
-
- `holdout`: runtime-checked, but intentionally outside the exact-route claim because the example still mixes route outcomes or depends on a documented unsupported capability; this is a temporary recovery state and should normally trend back to zero
|
|
706
|
-
|
|
707
|
-
Successful runs also print the current temporary fence list, including each
|
|
708
|
-
remaining `holdout` or `experimental` entry's blocker and follow-up task, so
|
|
709
|
-
the command output can be used directly in a phase-entry review.
|
|
710
|
-
|
|
711
|
-
Use `--family` when a task owns only one manifest lane, and `--example` when you
|
|
712
|
-
want to debug a single checked artifact.
|
|
713
|
-
|
|
714
|
-
### Invariant Test Suite
|
|
715
|
-
|
|
716
|
-
```bash
|
|
717
|
-
forgecad check suite
|
|
718
|
-
npm test
|
|
719
|
-
npm run test:examples
|
|
720
|
-
npm run test:compiler
|
|
721
|
-
npm run test:compiler:update
|
|
722
|
-
npm run test:query-propagation
|
|
723
|
-
npm run test:query-propagation:update
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
ForgeCAD's current unit-test surface is assertion-based CLI checks, not a separate Vitest/Jest harness.
|
|
727
|
-
|
|
728
|
-
The important entrypoints are:
|
|
729
|
-
- `npm test` runs the repo invariant suite (`transforms`, `dimensions`, `placement`, `js-modules`, `brep`, `compiler`, `query-propagation`, `examples`, `api`)
|
|
730
|
-
- `npm run test:examples` runs the example architecture gate across the checked `examples/` manifest
|
|
731
|
-
- `npm run test:compiler` runs just the compiler snapshot/invariant suite
|
|
732
|
-
- `npm run test:compiler:update` refreshes committed compiler snapshots after an intentional change
|
|
733
|
-
- `npm run test:query-propagation` runs the focused topology-rewrite query-propagation snapshots
|
|
734
|
-
- `npm run test:query-propagation:update` refreshes those query-propagation snapshots after an intentional change
|
|
735
|
-
- `forgecad check suite` is the CLI equivalent of the invariant suite runner
|
|
736
|
-
|
|
737
|
-
### Dimension Propagation Invariant Check
|
|
738
|
-
|
|
739
|
-
```bash
|
|
740
|
-
forgecad check dimensions
|
|
741
|
-
```
|
|
742
|
-
|
|
743
|
-
Runs shape-level invariants for dimension metadata propagation across:
|
|
744
|
-
- transform APIs (`translate`, `rotate`, `transform`, `scale`, `mirror`, `rotateAround`)
|
|
745
|
-
- copy/style APIs (`clone`, `color`, `setColor`)
|
|
746
|
-
- boolean APIs (`add/subtract/intersect`, plus `union/difference/intersection`)
|
|
747
|
-
- import runtime path (`require(...).color(...).translate(...)`)
|
|
748
|
-
|
|
749
|
-
### Dimension Debugger
|
|
750
|
-
|
|
751
|
-
```bash
|
|
752
|
-
forgecad debug dimensions /path/to/file.forge.js [--all]
|
|
753
|
-
forgecad debug dimensions /path/to/file.forge.js [--all] [--dim-angle-tol 12]
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
Prints:
|
|
757
|
-
- total object count
|
|
758
|
-
- total dimension count
|
|
759
|
-
- per-view visibility counts (`front/right/top/iso`) using report angle tolerance
|
|
760
|
-
- report ownership routing (`combined` vs `component:<name>`) per dimension
|
|
761
|
-
- per-object approximate dimension ownership (both endpoints inside object bbox)
|
|
762
|
-
- a dimension coordinate list (first 20 by default, `--all` for full dump)
|
|
763
|
-
|
|
764
|
-
### Compiler Debugger
|
|
765
|
-
|
|
766
|
-
```bash
|
|
767
|
-
forgecad debug compiler /path/to/file.forge.js
|
|
768
|
-
forgecad debug compiler /path/to/file.forge.js --compact
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
Prints JSON for the current script's compiler state, including:
|
|
772
|
-
- per-object compile plans
|
|
773
|
-
- CadQuery/OCCT lowering diagnostics and lowered plans
|
|
774
|
-
- faceted fallback eligibility
|
|
775
|
-
- runtime Manifold summaries
|
|
776
|
-
- compiler-lowered Manifold summaries
|
|
777
|
-
|
|
778
|
-
### Local Branch Cleanup
|
|
779
|
-
|
|
780
|
-
```bash
|
|
781
|
-
uv run cli/forge-prune-local-branches.py
|
|
782
|
-
uv run cli/forge-prune-local-branches.py --dry-run
|
|
783
|
-
uv run cli/forge-prune-local-branches.py --base mainline
|
|
784
|
-
```
|
|
785
|
-
|
|
786
|
-
This is a `uv`-backed Python utility for repository housekeeping. It finds local branches with no matching remote branch that are already merged into the selected base ref, shows them in a Rich terminal UI, then prompts one by one before deleting anything.
|
|
787
|
-
|
|
788
|
-
Behavior:
|
|
789
|
-
- Deletes with `git branch -d`, not force-delete
|
|
790
|
-
- Removes linked worktrees first when the branch is checked out in a secondary worktree
|
|
791
|
-
- Requires an explicit `force` choice if one of those linked worktrees is dirty
|
|
792
|
-
- Refuses to touch the current worktree, the primary worktree, or prunable/missing worktree entries
|
|
793
|
-
- `--path` lets you point at any location inside the target repository
|
|
794
|
-
|
|
795
|
-
## Adding New CLI Commands
|
|
796
|
-
|
|
797
|
-
1. Create or extend a module under `cli/`
|
|
798
|
-
2. Import from `../src/forge/headless`
|
|
799
|
-
3. Call `await init()` to load the WASM kernel
|
|
800
|
-
4. Use `runScript(code, fileName, allFiles)` to execute user scripts
|
|
801
|
-
5. Register the new subcommand in `cli/forgecad.ts`
|
|
802
|
-
|
|
803
|
-
### Minimal Example
|
|
804
|
-
|
|
805
|
-
```typescript
|
|
806
|
-
#!/usr/bin/env node
|
|
807
|
-
import { readFileSync } from 'fs';
|
|
808
|
-
import { init, runScript } from '../src/forge/headless';
|
|
809
|
-
|
|
810
|
-
const code = readFileSync(process.argv[2], 'utf-8');
|
|
811
|
-
|
|
812
|
-
await init();
|
|
813
|
-
const result = runScript(code, 'main.forge.js', {});
|
|
814
|
-
|
|
815
|
-
if (result.error) {
|
|
816
|
-
console.error(result.error);
|
|
817
|
-
process.exit(1);
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
for (const obj of result.objects) {
|
|
821
|
-
if (obj.shape) {
|
|
822
|
-
console.log(`${obj.name}: volume=${obj.shape.volume().toFixed(1)}mm³`);
|
|
823
|
-
}
|
|
824
|
-
if (obj.sketch) {
|
|
825
|
-
console.log(`${obj.name}: area=${obj.sketch.area().toFixed(1)}mm²`);
|
|
826
|
-
}
|
|
827
|
-
if (obj.toolpath) {
|
|
828
|
-
console.log(`${obj.name}: ${obj.toolpath.segments.length} G-code segments`);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
```
|
|
832
|
-
|
|
833
|
-
### Cross-file imports
|
|
834
|
-
|
|
835
|
-
When running scripts that use `require()` / `importSvgSketch()` or plain JS module imports, pass all project files (or at least all files reachable by imports), keyed by project-relative path. This supports root-relative and relative imports, utility `.js` modules, and `.svg` assets (`./assets/logo.svg`):
|
|
836
|
-
|
|
837
|
-
```typescript
|
|
838
|
-
import { readdirSync, readFileSync } from 'fs';
|
|
839
|
-
|
|
840
|
-
const allFiles: Record<string, string> = {};
|
|
841
|
-
for (const f of readdirSync(scriptDir)) {
|
|
842
|
-
if (f.endsWith('.forge.js') || f.endsWith('.js') || f.endsWith('.svg')) {
|
|
843
|
-
allFiles[f] = readFileSync(join(scriptDir, f), 'utf-8');
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
const result = runScript(code, 'main.forge.js', allFiles);
|
|
848
|
-
```
|
|
849
|
-
|
|
850
|
-
For utility modules that want explicit ForgeCAD imports instead of globals, use the virtual runtime module:
|
|
851
|
-
|
|
852
|
-
```javascript
|
|
853
|
-
import { box, union } from "forgecad";
|
|
854
|
-
```
|
|
855
|
-
|
|
856
|
-
Use `require("./file.forge.js", { Param: value })` for model/sketch files when you want ForgeCAD-specific behavior like param override scopes. Use `importSvgSketch()` for SVG assets.
|
|
857
|
-
|
|
858
|
-
## Dependencies
|
|
859
|
-
|
|
860
|
-
| Package | Purpose | Context |
|
|
861
|
-
|---------|---------|---------|
|
|
862
|
-
| `forgecad` | Installable CLI binary (`forgecad ...`) | Runtime package |
|
|
863
|
-
| `puppeteer-core` | Headless Chrome for PNG/GIF/MP4 rendering | Runtime dependency |
|
|
864
|
-
| `manifold-3d` | Geometry kernel (WASM) | Works in both Node and browser |
|
|
865
|
-
| `three` | 3D rendering (used by render.ts) | Loaded in browser context by Puppeteer |
|