forgecad 0.1.1 → 0.1.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 (41) hide show
  1. package/dist/assets/{evalWorker-DuS4V-H5.js → evalWorker-1m873KWd.js} +107 -107
  2. package/dist/assets/{index-d60dJDhX.js → index-Dvz3nSDc.js} +342 -326
  3. package/dist/assets/{manifold-DEOPQqeC.js → manifold-C38sUiKu.js} +1 -1
  4. package/dist/assets/{manifold-cL7A7HeM.js → manifold-Dk2u-lhj.js} +1 -1
  5. package/dist/assets/{manifold-DbvY5u9x.js → manifold-rOWQW9fU.js} +1 -1
  6. package/dist/assets/{reportWorker-GZVKtf9S.js → reportWorker-Cj587shw.js} +129 -129
  7. package/dist/index.html +1 -1
  8. package/dist-cli/forgecad.js +204 -19
  9. package/dist-skill/SKILL.md +31 -4561
  10. package/dist-skill/docs/API/README.md +24 -0
  11. package/dist-skill/docs/API/guides/modeling-recipes.md +246 -0
  12. package/dist-skill/docs/API/internals/compiler.md +300 -0
  13. package/dist-skill/docs/API/internals/manifold.md +7 -0
  14. package/dist-skill/docs/API/model-building/README.md +31 -0
  15. package/dist-skill/docs/API/model-building/assembly.md +205 -0
  16. package/dist-skill/docs/API/model-building/coordinate-system.md +43 -0
  17. package/dist-skill/docs/API/model-building/entities.md +282 -0
  18. package/dist-skill/docs/API/model-building/geometry-conventions.md +104 -0
  19. package/dist-skill/docs/API/model-building/positioning.md +170 -0
  20. package/dist-skill/docs/API/model-building/reference.md +1936 -0
  21. package/dist-skill/docs/API/model-building/sheet-metal.md +180 -0
  22. package/dist-skill/docs/API/model-building/sketch-anchor.md +32 -0
  23. package/dist-skill/docs/API/model-building/sketch-booleans.md +101 -0
  24. package/dist-skill/docs/API/model-building/sketch-core.md +68 -0
  25. package/dist-skill/docs/API/model-building/sketch-extrude.md +57 -0
  26. package/dist-skill/docs/API/model-building/sketch-on-face.md +98 -0
  27. package/dist-skill/docs/API/model-building/sketch-operations.md +92 -0
  28. package/dist-skill/docs/API/model-building/sketch-path.md +70 -0
  29. package/dist-skill/docs/API/model-building/sketch-primitives.md +104 -0
  30. package/dist-skill/docs/API/model-building/sketch-transforms.md +60 -0
  31. package/dist-skill/docs/API/output/bom.md +53 -0
  32. package/dist-skill/docs/API/output/brep-export.md +82 -0
  33. package/dist-skill/docs/API/output/dimensions.md +62 -0
  34. package/dist-skill/docs/API/runtime/viewport.md +229 -0
  35. package/dist-skill/docs/CLI.md +672 -0
  36. package/dist-skill/docs/CODING.md +345 -0
  37. package/dist-skill/docs/PROGRAM-LEAD.md +180 -0
  38. package/dist-skill/docs/VISION.md +77 -0
  39. package/examples/api/import-group-assembly.forge.js +34 -0
  40. package/examples/api/import-group-source.forge.js +35 -0
  41. package/package.json +1 -1
@@ -0,0 +1,345 @@
1
+ # ForgeCAD Coding Guidelines
2
+
3
+ ## Development Workflow
4
+
5
+ ### Building & Running
6
+ ```bash
7
+ npm install # Install dependencies
8
+ npm link # Install the local forgecad binary
9
+ forgecad studio # Start the browser studio (localhost:5173)
10
+ npm run build # Production build
11
+ npm run preview # Preview production build
12
+ ```
13
+
14
+ ### CLI Tools
15
+ ```bash
16
+ forgecad export svg examples/frame.sketch.js # Export sketch to SVG (Node, no browser)
17
+ forgecad render examples/cup.forge.js # Render to PNG (Puppeteer + Chrome)
18
+ ```
19
+
20
+ See [CLI.md](CLI.md) for full CLI documentation.
21
+
22
+ ### Project Structure
23
+ ```
24
+ src/
25
+ ├── forge/ # Core geometry engine (shared by browser + CLI)
26
+ │ ├── kernel.ts # Manifold WASM wrapper, Shape class, primitives
27
+ │ ├── headless.ts # Single entry point for all contexts (browser + Node CLI)
28
+ │ ├── index.ts # Browser entry point (re-exports from headless.ts)
29
+ │ ├── runner.ts # Script sandbox — executes user scripts and resolves imported .svg assets
30
+ │ ├── params.ts # Parameter system (param() → UI sliders)
31
+ │ ├── library.ts # Part library (lib.boltHole, lib.pipe, etc.)
32
+ │ ├── section.ts # Plane intersection / projection
33
+ │ ├── meshToGeometry.ts # Manifold mesh → Three.js BufferGeometry
34
+ │ ├── sceneBuilder.ts # Three.js scene setup (shared with CLI renderer)
35
+ │ └── sketch/ # 2D sketch system
36
+ │ ├── core.ts # Sketch class
37
+ │ ├── primitives.ts # rect, circle2d, polygon, ngon, etc.
38
+ │ ├── transforms.ts # translate, rotate, scale, mirror
39
+ │ ├── booleans.ts # add, subtract, intersect, union2d, hull2d
40
+ │ ├── operations.ts # offset, hull, simplify, warp
41
+ │ ├── extrude.ts # extrude, revolve (2D → 3D)
42
+ │ ├── path.ts # PathBuilder, stroke
43
+ │ ├── anchor.ts # attachTo positioning
44
+ │ ├── constraints.ts # Constraint solver (18 types)
45
+ │ ├── entities.ts # Point2D, Line2D, Circle2D, Rectangle2D, Constraint helpers
46
+ │ ├── topology.ts # TrackedShape, face/edge naming
47
+ │ ├── patterns.ts # linearPattern, circularPattern, mirrorCopy
48
+ │ ├── fillets.ts # filletEdge, chamferEdge
49
+ │ ├── arcBridge.ts # arcBridgeBetweenRects
50
+ │ └── index.ts # Re-exports everything
51
+ ├── components/ # React UI components
52
+ │ ├── Viewport.tsx # 3D viewport (Three.js + R3F)
53
+ │ ├── CodeEditor.tsx # Monaco editor with ForgeCAD types
54
+ │ ├── FileExplorer.tsx # Project file tree
55
+ │ ├── ViewPanel.tsx # Render mode, views, object settings
56
+ │ ├── ParamPanel.tsx # Parameter sliders
57
+ │ └── ExportPanel.tsx # STL export
58
+ ├── store/
59
+ │ └── forgeStore.ts # Zustand global state
60
+ ├── App.tsx # Main application shell
61
+ └── main.tsx # React entry point
62
+
63
+ cli/
64
+ ├── forgecad.ts # Top-level CLI entrypoint and command routing
65
+ ├── forge-svg.ts # SVG export (uses real engine via headless.ts)
66
+ ├── forge-render.mjs # PNG render launcher (Puppeteer)
67
+ ├── render.ts # Headless render entry (loaded in browser by Puppeteer)
68
+ └── render.html # HTML shell for headless render
69
+
70
+ examples/ # Example scripts
71
+ ├── *.forge.js # 3D part examples
72
+ └── *.sketch.js # 2D sketch examples
73
+ ```
74
+
75
+ ## Coding Standards
76
+
77
+ ### Minimal Implementation
78
+ Write only the code needed to solve the problem. No verbose implementations, no speculative features.
79
+
80
+ ## Domain Localization Standard (Required)
81
+
82
+ This standard is package-wide for any new user-facing concept or API family.
83
+
84
+ ### Contract
85
+ - Each concept family must have a clear primary home in both code and docs.
86
+ - Extend the module that already owns the mental model instead of scattering helpers across unrelated files.
87
+ - When a feature spans multiple layers, pick one domain owner and make the other layers mirror that owner.
88
+ - Keep related runtime code, examples, checks, and docs close to the same domain name whenever practical.
89
+
90
+ ### Examples
91
+ - Assembly and kinematics live under `src/forge/assembly.ts` and `docs/permanent/API/model-building/assembly.md`.
92
+ - Sketch constraints live under `src/forge/sketch/constraints.ts` and the sketch/entity API docs.
93
+ - Transform/placement helpers should stay grouped with transform and positioning surfaces, not reappear as ad-hoc helpers in unrelated modules.
94
+
95
+ ### Enforcement
96
+ - Before adding a new API, state which domain owns it.
97
+ - If a concept currently has no clean home, create one instead of spreading the first implementation across multiple files.
98
+
99
+ ## Backend Compiler Standard (Required)
100
+
101
+ This standard is package-wide for any geometry feature that affects runtime lowering, exact export, or backend capability routing.
102
+
103
+ Read [API/internals/compiler.md](API/internals/compiler.md) before changing this area.
104
+ For large multi-agent migrations or architecture programs, also read [PROGRAM-LEAD.md](PROGRAM-LEAD.md).
105
+
106
+ ### Contract
107
+ - Forge semantic intent comes first. Backends are lowerers, not the authoring model.
108
+ - Scene-level capability routing must stay centralized. Do not re-derive export/runtime policy ad hoc in unrelated modules.
109
+ - Public feature APIs must not hide backend-specific behavior directly in their callsites. Backend code belongs in the lowerers.
110
+ - New backend limitations must surface as diagnostics, not silent fallback or silent exactness loss.
111
+
112
+ ### Enforcement
113
+ - If a feature is compile-covered, update the canonical compile graph and the scene compiler.
114
+ - If a feature is not yet dual-lowered, add explicit unsupported diagnostics for the missing backend rather than bypassing the compiler.
115
+ - Any geometry feature change must update invariant coverage and the living backend-compiler tracker.
116
+
117
+ ## Multi-Agent Program Standard (Required For Large Migrations)
118
+
119
+ For work that spans multiple agent branches or staged dependency waves, the Program Lead role in [PROGRAM-LEAD.md](PROGRAM-LEAD.md) is the default operating model.
120
+
121
+ Use it when:
122
+
123
+ - one missing foundation blocks several feature lanes
124
+ - multiple agents need isolated tasks with dependency ordering
125
+ - the repo needs a living task graph and capability tracker to stay truthful
126
+
127
+ The key rule is simple:
128
+
129
+ - solve the deepest shared prerequisite first
130
+ - only then open the parallel wave that builds on top of it
131
+
132
+ ### TypeScript
133
+ - Use explicit types for function parameters and return values
134
+ - Avoid `any` - use `unknown` or proper types
135
+ - Prefer interfaces for object shapes
136
+
137
+ ### React Components
138
+ - Functional components only
139
+ - Inline styles for simplicity (no CSS files unless necessary)
140
+ - Extract reusable logic to custom hooks or store actions
141
+
142
+ ### State Management
143
+ - All global state lives in `forgeStore.ts`
144
+ - Use Zustand selectors to prevent unnecessary re-renders
145
+ - Keep actions pure and synchronous where possible
146
+
147
+ ## Frame Composition Standard (Required)
148
+
149
+ This standard is package-wide for any code that composes transforms (`Transform`, joints, assemblies, kinematic helpers).
150
+
151
+ ### Contract
152
+ - `A.mul(B)` means **apply A, then B**
153
+ - Use `composeChain(...)` for 3+ composed transforms instead of manual `.mul()` chains
154
+ - In assembly/kinematics, always express composition in this canonical order:
155
+ - `local -> childBase -> jointMotion -> jointFrame -> parentWorld`
156
+
157
+ ### Why this is mandatory
158
+ Transform order bugs can produce geometry that "looks valid" but is globally wrong (detached mechanism segments, drifting pivots, mirrored motion paths) and often pass casual visual checks.
159
+
160
+ ### 5-Why (2026-02 Assembly disconnect incident)
161
+ 1. Why were arm segments disconnected?
162
+ Because child world transforms were composed in the wrong order in `assembly.solve()`.
163
+ 2. Why was order wrong?
164
+ Because `.mul()` chain semantics (apply self, then other) were interpreted inconsistently with matrix notation.
165
+ 3. Why was that ambiguity possible?
166
+ Because there was no single canonical frame equation documented and enforced in code review.
167
+ 4. Why didn’t tests catch it immediately?
168
+ Because there was no invariant test comparing assembly-solved frame origins against an analytic kinematic oracle.
169
+ 5. Why no invariant test existed?
170
+ Because we had feature-level example checks, but no package-wide transform convention gate.
171
+
172
+ Root cause: **missing, enforced transform/frame composition contract across code + tests.**
173
+
174
+ ### Enforcement
175
+ - Any change touching transforms, joints, or assembly solving must run:
176
+ - `forgecad check transforms`
177
+ - If the change affects user-facing geometry behavior, also run:
178
+ - `forgecad run <affected-example>`
179
+
180
+ ## Editor Declaration Parity Standard (Required)
181
+
182
+ This standard is package-wide for any user-facing API exposed to scripts.
183
+
184
+ ### Contract
185
+ - Runtime API and editor declarations must ship together:
186
+ - Runtime surface: `src/forge/*` exports + `src/forge/runner.ts` sandbox bindings
187
+ - Editor surface: `src/components/CodeEditor.tsx` `FORGE_TYPES`
188
+ - Docs surface: `docs/permanent/API/**/*.md`
189
+ - If an important feature is missing from editor declarations, you must either:
190
+ - implement declarations in the same change, or
191
+ - create a tracked task in `tasks/` that explicitly names the missing surface and scope.
192
+
193
+ ### Enforcement
194
+ - Before merge, verify new/changed script APIs are present in all three surfaces above.
195
+ - Do not ship runtime-only features without either declaration parity or a tracking task.
196
+
197
+ ## Script API Contract Standard (Required)
198
+
199
+ This standard is package-wide for any API exposed to user scripts.
200
+
201
+ ### Contract
202
+ - Collection-shaped script APIs must accept the intuitive collection forms the docs advertise:
203
+ - variadic operands when the operation naturally works on many inputs
204
+ - a single array of operands when that keeps call sites composable
205
+ - Method syntax and function syntax must mirror each other for the same operation family.
206
+ - User-facing APIs must not silently ignore extra arguments. Unsupported arity or operand types must throw a direct runtime error with the API name in the message.
207
+ - If a future API needs configuration, do not smuggle it in as an ambiguous trailing object on an operand list. Use a distinct helper or a clearly named options-bearing API.
208
+
209
+ ### Enforcement
210
+ - Any change to user-facing script APIs must run:
211
+ - `forgecad check api`
212
+ - If the change also affects transforms, dimensions, placement refs, or geometry semantics, run the relevant existing invariant checks too.
213
+
214
+ ## Git Workflow
215
+
216
+ ### Commit Every Major Change
217
+ Each logical unit of work should be a separate commit:
218
+
219
+ ```bash
220
+ git add <files>
221
+ git commit -m "Add file explorer panel"
222
+ ```
223
+
224
+ ### Commit Message Format
225
+ ```
226
+ <verb> <what>
227
+
228
+ Examples:
229
+ - Add file explorer panel
230
+ - Fix measure mode toggle
231
+ - Update parameter slider styling
232
+ - Remove unused imports
233
+ ```
234
+
235
+ Use present tense verbs: Add, Fix, Update, Remove, Refactor
236
+
237
+ ### What Counts as "Major"
238
+ - New feature or component
239
+ - Bug fix
240
+ - Refactoring that changes structure
241
+ - Performance improvement
242
+ - Breaking API change
243
+
244
+ ### What to Commit Together
245
+ - Related files for a single feature
246
+ - Tests with the code they test
247
+ - Documentation with the feature it describes
248
+
249
+ ### Example Workflow
250
+ ```bash
251
+ # Feature: Add file explorer
252
+ git add src/components/FileExplorer.tsx
253
+ git add src/store/forgeStore.ts
254
+ git add src/App.tsx
255
+ git commit -m "Add file explorer panel"
256
+
257
+ # Next feature: Add keyboard shortcuts
258
+ git add src/hooks/useKeyboard.ts
259
+ git add src/App.tsx
260
+ git commit -m "Add keyboard shortcuts for file operations"
261
+ ```
262
+
263
+ ## Testing
264
+
265
+ ### Manual Testing Checklist
266
+ Before committing UI changes:
267
+ - [ ] Test in browser at localhost:5173
268
+ - [ ] Check console for errors
269
+ - [ ] Verify responsive behavior
270
+ - [ ] Test with example scripts
271
+
272
+ ### Integration Testing
273
+ - Load example files and verify they render
274
+ - Test parameter sliders update geometry
275
+ - Verify STL export produces valid files
276
+ - Check measure mode calculates correctly
277
+
278
+ ## Code Review
279
+
280
+ ### Self-Review Before Commit
281
+ 1. Remove console.logs and debug code
282
+ 2. Check for unused imports
283
+ 3. Verify TypeScript has no errors
284
+ 4. Test the change works as intended
285
+ 5. Read the diff - does it make sense?
286
+
287
+ ### What to Look For
288
+ - Does this solve the problem with minimal code?
289
+ - Are there edge cases not handled?
290
+ - Is the code readable without comments?
291
+ - Does it follow existing patterns?
292
+
293
+ ## Performance
294
+
295
+ ### Geometry Operations
296
+ - Manifold operations are expensive - minimize boolean ops
297
+ - Cache geometry results when parameters don't change
298
+ - Use debouncing for real-time updates (already implemented)
299
+
300
+ ### React Rendering
301
+ - Use Zustand selectors to prevent unnecessary re-renders
302
+ - Memoize expensive computations with `useMemo`
303
+ - Keep component tree shallow
304
+
305
+ ## Common Patterns
306
+
307
+ ### Adding a New Sketch Primitive
308
+ 1. Add function to `src/forge/sketch/primitives.ts`
309
+ 2. It's auto-exported via `sketch/index.ts` → `headless.ts` → `index.ts`
310
+ 3. Add it to the sandbox in `src/forge/runner.ts` (both the `new Function()` args and the call)
311
+ 4. Add TypeScript hints in `src/components/CodeEditor.tsx` (`FORGE_TYPES`)
312
+ 5. Update `docs/permanent/API/model-building/sketch-primitives.md`
313
+ 6. Commit: "Add [primitive] sketch primitive"
314
+
315
+ ### Adding a New 3D Primitive
316
+ 1. Add function to `src/forge/kernel.ts`
317
+ 2. Export from `headless.ts`
318
+ 3. Add to runner sandbox in `src/forge/runner.ts`
319
+ 4. Add TypeScript hints in `src/components/CodeEditor.tsx`
320
+ 5. Update `docs/permanent/API/model-building/reference.md`
321
+ 6. Commit: "Add [primitive] 3D primitive"
322
+
323
+ ### Adding a New CLI Command
324
+ 1. Create `cli/your-command.ts`
325
+ 2. Import from `../src/forge/headless`
326
+ 3. Call `await init()` then use `runScript()`
327
+ 4. Add script to `package.json`
328
+ 5. Update `docs/permanent/CLI.md`
329
+ 6. Commit: "Add [command] CLI command"
330
+
331
+ ### Adding UI State
332
+ 1. Add to `src/store/forgeStore.ts` interface
333
+ 2. Add initial value and actions
334
+ 3. Wire up to component
335
+ 4. Commit: "Add [feature] UI state"
336
+
337
+ ### Adding a Component
338
+ 1. Create in `src/components/`
339
+ 2. Import and use in `App.tsx` or parent
340
+ 3. Commit: "Add [Component] component"
341
+
342
+ ### Key Architecture Rule: Single Source of Truth
343
+ All geometry logic lives in `src/forge/`. CLI tools import from `src/forge/headless.ts`.
344
+ **Never** duplicate forge logic in CLI scripts. If you need something in CLI, make sure
345
+ it's exported from `headless.ts` and import it.
@@ -0,0 +1,180 @@
1
+ # Program Lead Role
2
+
3
+ This document formalizes the reusable role Forge uses for large architectural projects that involve multiple agent branches and staged dependency waves.
4
+
5
+ Use this role when the work is too deep or too cross-cutting to split safely into ad hoc feature tickets.
6
+
7
+ ## Role Name
8
+
9
+ Program Lead
10
+
11
+ Short version:
12
+
13
+ - owns the architectural through-line
14
+ - decides what must be solved before parallelization
15
+ - turns the program into explicit tasks, waves, and merge rules
16
+ - reviews landed work for truthfulness, scope, and regression safety
17
+
18
+ This is not a people-manager role. It is a technical integration and program-shaping role.
19
+
20
+ ## Mission
21
+
22
+ Keep multi-agent technical work coherent.
23
+
24
+ The Program Lead protects three things:
25
+
26
+ 1. one clear source of truth for architecture
27
+ 2. honest task decomposition with real dependency boundaries
28
+ 3. a repo state that tells the truth about what is landed, supported, blocked, and next
29
+
30
+ If those three drift apart, the program stops scaling.
31
+
32
+ ## Responsibilities
33
+
34
+ ### 1. Identify the deepest prerequisite
35
+
36
+ Before parallelizing, find the one core problem everything else depends on.
37
+
38
+ Examples:
39
+
40
+ - shared query/reference backbone
41
+ - topology-rewrite propagation
42
+ - backend-neutral compile graph
43
+
44
+ The Program Lead should prefer foundation before breadth. If several features all feel blocked by the same missing layer, that missing layer becomes the next core lane.
45
+
46
+ ### 2. Shape the work into waves
47
+
48
+ Every program should have:
49
+
50
+ - one current core lane
51
+ - one parallel wave that becomes safe after that lane lands
52
+ - one follow-on wave that depends on the first parallel wave
53
+ - one closeout lane for corpus, docs, and capability truthfulness
54
+
55
+ The Program Lead owns that wave plan and updates it as the repo changes.
56
+
57
+ ### 3. Write explicit task contracts
58
+
59
+ Each task should define:
60
+
61
+ - problem definition
62
+ - description
63
+ - requirements
64
+ - isolation rule
65
+ - dependencies
66
+ - parallelization notes
67
+ - status log
68
+
69
+ The point is not bureaucracy. The point is merge safety and honest scope.
70
+
71
+ ### 4. Own the integration seam
72
+
73
+ Agents should build feature logic in isolated modules first.
74
+
75
+ The Program Lead owns:
76
+
77
+ - the shared branch
78
+ - the thin shared-file integration seams
79
+ - the sequencing of merges when multiple tasks touch central compiler files
80
+
81
+ ### 5. Review landed work before opening the next wave
82
+
83
+ Before the next wave starts, the Program Lead reviews:
84
+
85
+ - implementation against task scope
86
+ - tests and regression coverage
87
+ - docs and task/tracker truthfulness
88
+ - hidden capability inflation
89
+
90
+ The Program Lead should explicitly say whether the program should move forward or not.
91
+
92
+ ### 6. Keep capability claims honest
93
+
94
+ The Program Lead is responsible for making sure docs do not overstate support.
95
+
96
+ If the implementation only supports a defended subset, the docs must say so.
97
+
98
+ ### 7. Maintain the living docs
99
+
100
+ At minimum, the Program Lead keeps these current:
101
+
102
+ - temporary program README
103
+ - mission tracker
104
+ - task graph
105
+ - task files
106
+ - permanent architecture docs when contracts change
107
+
108
+ ## Operating Rules
109
+
110
+ ### One branch of truth
111
+
112
+ - Keep one program branch as the integration branch.
113
+ - Agent branches should merge into that branch, not bypass it.
114
+ - Reviews and go/no-go decisions should happen against that branch, not stale side worktrees.
115
+
116
+ ### One architectural center
117
+
118
+ - Do not let each task invent its own local semantic model.
119
+ - If several tasks need the same concept, the Program Lead should create or demand a shared contract first.
120
+
121
+ ### Explicit unsupported is good
122
+
123
+ - Unsupported or ambiguous cases should be recorded in diagnostics and docs.
124
+ - Silent fallback is program debt.
125
+
126
+ ### Foundation before convenience
127
+
128
+ - Do not widen feature breadth by bypassing a missing architectural layer.
129
+ - If a feature needs a missing core layer, stop and create the layer task.
130
+
131
+ ### Close each wave honestly
132
+
133
+ Before moving on:
134
+
135
+ - regression coverage must exist
136
+ - docs must match reality
137
+ - task graph must reflect the new queue
138
+
139
+ ## Expected Outputs
140
+
141
+ For a healthy multi-agent program, the Program Lead should leave behind:
142
+
143
+ - a readable explainer
144
+ - a living mission tracker
145
+ - a dependency graph
146
+ - scoped task files
147
+ - regression expectations
148
+ - explicit next-step guidance after each review
149
+
150
+ ## Anti-Patterns
151
+
152
+ These are warning signs that the Program Lead should stop and correct:
153
+
154
+ - "just start all the feature tasks"
155
+ - "we can clean the tracker later"
156
+ - "this branch probably has the latest state"
157
+ - "the snapshot changed, it is probably fine"
158
+ - "let's add one shortcut in this feature instead of solving the shared layer"
159
+
160
+ ## Success Criteria
161
+
162
+ The role is working if:
163
+
164
+ - agents can work in parallel without constant semantic collisions
165
+ - merges are mostly thin and predictable
166
+ - tasks describe real isolated work instead of vague ambition
167
+ - docs tell a new contributor where the program really is
168
+ - the next wave opens only when the previous wave actually earned it
169
+
170
+ ## Default Hand-off Pattern
171
+
172
+ For each review checkpoint, the Program Lead should answer:
173
+
174
+ 1. What landed?
175
+ 2. What is still missing?
176
+ 3. Is there any blocker to moving forward?
177
+ 4. Which tasks can start now?
178
+ 5. Which tasks must still wait?
179
+
180
+ That hand-off pattern should be reusable across projects, not just ForgeCAD.
@@ -0,0 +1,77 @@
1
+ # ForgeCAD — What It Is and Where It's Going
2
+
3
+ ## The Relationship with Manifold
4
+
5
+ [Manifold](https://github.com/elalish/manifold) is a geometry kernel. It does boolean operations on triangle meshes, extrusion, revolution, smoothing, and SDF level sets. It's fast, correct, and runs in WASM. Think of it as the engine block.
6
+
7
+ ForgeCAD is the car built around that engine. Manifold doesn't know what a "rectangle with named sides" is. It doesn't know what a "constraint" is. It doesn't have parameters, sliders, a code editor, or file imports. It gives you raw mesh operations — you give it polygons and get back polygons.
8
+
9
+ Every serious CAD system has this split:
10
+ - Fusion360 uses Parasolid/ACIS as its kernel
11
+ - FreeCAD uses OpenCascade
12
+ - ForgeCAD uses Manifold
13
+
14
+ The kernel is not the product. The modeling layer on top is.
15
+
16
+ ## What ForgeCAD Adds Over Manifold
17
+
18
+ ### Already built
19
+ - **Constraint solver** — 18 constraint types (coincident, parallel, perpendicular, tangent, equal, symmetric, concentric, collinear, distance, length, angle, radius, diameter, hDistance, vDistance, fixed, horizontal, vertical) with iterative relaxation solver. Detects under/over/fully-constrained states. Live constraint editing in the UI.
20
+ - **Named 2D entities** — `Rectangle2D`, `Circle2D`, `Line2D`, `Point2D` with semantic access (`.side('top')`, `.vertex('bottom-left')`, `.pointAtAngle(90)`)
21
+ - **Topology tracking** — `TrackedShape` preserves face/edge names through extrusion and translation. `shape.face('top')`, `shape.edge('vert-bl')`, `shape.rotateAroundEdge('top-bottom', 90)`.
22
+ - **Sketch primitives** — `roundedRect`, `slot`, `star`, `ngon`, `ellipse`, `polygon`, path builder with stroke
23
+ - **Patterns** — `linearPattern`, `circularPattern`, `mirrorCopy` for 3D shape arrays
24
+ - **Fillets & chamfers** — `filletCorners()` for selective 2D polygon corners, plus `filletEdge()` / `chamferEdge()` for vertical 3D edges using topology references
25
+ - **Arc bridge** — `arcBridgeBetweenRects()` for smooth arc surfaces between rectangular areas (e.g., laptop hinges)
26
+ - **Parameters** — `param()` creates live UI sliders, code re-executes on change
27
+ - **Multi-file** — `importSketch()`, `importPart()` with circular import detection, folder support
28
+ - **Code-as-format** — plain JS/TS files, version-controllable, LLM-writable
29
+ - **3D smoothing** — `smoothOut()` + `refine()` / `refineToLength()` / `refineToTolerance()` for edge rounding
30
+ - **3D advanced ops** — `hull3d()` (convex hull of shapes + points), `levelSet()` (SDF-based shapes), `warp()`, `split()`, `splitByPlane()`, `trimByPlane()`
31
+ - **Sketch on face** — `sketch.onFace(body, face, ...)` places a 2D sketch on canonical or tracked planar faces and extrudes from that face normal
32
+ - **Part library** — bolt holes, counterbores, tubes, pipes, hex nuts, rounded boxes, brackets, hole patterns, threaded bolts/nuts (real helical threads via SDF levelSet)
33
+ - **Colors** — `.color('#ff0000')` on both Shape and Sketch, preserved through transforms and booleans
34
+ - **CLI tools** — SVG export (pure Node), PNG render (Puppeteer), all sharing the same engine via `headless.ts`
35
+ - **Measurement tool** — Click-to-measure with vertex/edge/face snapping, draggable markers
36
+ - **File management** — File explorer with folders, drag-and-drop, rename, create/delete, unsaved change indicators
37
+ - **View controls** — Render modes (solid/wireframe/overlay), projection (perspective/orthographic), named views (front/back/left/right/top/bottom/iso), fit-to-view, zoom-to-selection
38
+ - **STL export** — Binary STL export from the browser UI
39
+ - **Cut planes** — `cutPlane()` defines named section planes for inspection. Viewport sectioning uses `trimByPlane()` for capped solids, with GPU clipping fallback on trim failures
40
+
41
+ ### Gaps to close (Fusion360 parity)
42
+
43
+ | Feature | What it does | Why it matters | Difficulty |
44
+ |---------|-------------|----------------|------------|
45
+ | Arc entity | First-class arc in constraint system | Needed for fillet results to participate in constraints | Medium |
46
+ | Shell operation | Hollow a solid with wall thickness | Enclosures, cases, containers | Medium |
47
+ | Per-edge 3D fillet | Round specific edges by exact radius | The #1 most-used Fusion360 operation | Very Hard (mesh kernel) |
48
+ | Trim/extend | Cut or extend sketch entities at intersections | Complex sketch editing | Medium |
49
+ | Splines | B-spline curves in sketches | Organic shapes | Medium |
50
+ | Loft | Blend between multiple cross-section profiles | Transition shapes, aerodynamic forms | Hard |
51
+ | Thread/helix | Helical sweep for threads, springs | Mechanical fasteners | Medium (threads done via SDF, general helix sweep still missing) |
52
+
53
+ ### What we deliberately skip
54
+ - **History tree / timeline** — code IS the history. You read it top to bottom. No need for a separate feature tree when the script is the tree.
55
+ - **Direct modeling** — push/pull faces interactively. Not relevant for code-first CAD.
56
+ - **Full GUI-style assembly mate solving** — Forge now supports code-level assembly graphs (`assembly()`, revolute/prismatic/fixed joints, collision checks, BOM metadata), but not full interactive face-mate workflows like Fusion's assembly workspace.
57
+ - **Photorealistic rendering** — not a rendering tool. Basic viewport materials are sufficient. Export to STL for slicing or external renderers.
58
+
59
+ ## The Code-First Bet
60
+
61
+ The thesis: parametric CAD expressed as code is strictly more powerful than GUI-based CAD for certain workflows:
62
+
63
+ 1. **LLM generation** — an AI can write and modify `.forge.js` files. It can't click buttons in Fusion360.
64
+ 2. **Version control** — git diff on a `.forge.js` file shows exactly what changed. Fusion360 files are opaque blobs.
65
+ 3. **Composition** — import a part, transform it, array it, subtract it. All in code. No manual assembly.
66
+ 4. **Parametric by default** — every `param()` is a slider. No extra work to make something parametric.
67
+ 5. **Extensibility** — if you need a new primitive, write a function. No plugin SDK needed.
68
+
69
+ This doesn't replace Fusion360 for everything. Interactive sketching, direct face manipulation, complex surfacing — those are better with a GUI. But for parametric parts, enclosures, mechanical components, and especially for AI-assisted design, code-first wins.
70
+
71
+ ## Technical Direction
72
+
73
+ - **Keep Manifold as the kernel.** It's actively maintained, fast, and handles the hard geometry problems. Don't reimplement CSG.
74
+ - **Build the parametric layer.** Constraints, named entities, topology tracking, sketch operations — this is where ForgeCAD's value lives.
75
+ - **Expose Manifold's power.** Things like `smoothOut`, `refine`, `levelSet` (SDF), `warp` — make them accessible from user scripts with clean APIs.
76
+ - **Stay extensible.** Users should be able to define new primitives, new operations, new patterns inside their scripts. The API should be a toolkit, not a cage.
77
+ - **Make Forge semantics own the backends.** Manifold and CadQuery/OCCT should be lowerers for the same Forge modeling system, not competing authoring models. See [API/internals/compiler.md](API/internals/compiler.md).
@@ -0,0 +1,34 @@
1
+ // import-group-assembly.forge.js
2
+ // Demonstrates importGroup(): bring in a multipart component and work on
3
+ // the whole group or individual named children separately.
4
+
5
+ // --- Import the full assembly as a ShapeGroup ---
6
+ const bracketAssembly = importGroup("api/import-group-source.forge.js");
7
+
8
+ // Place it using a named reference (same API as importPart)
9
+ const placed = bracketAssembly.placeReference("mountCenter", [0, 0, 0]);
10
+
11
+ // --- Access individual children by name ---
12
+ // Each child is a Shape/TrackedShape/ShapeGroup you can manipulate independently.
13
+ const leftBracket = placed.child("Bracket Left");
14
+ const rightBracket = placed.child("Bracket Right");
15
+ const dowel = placed.child("Dowel");
16
+
17
+ // Make a highlight copy of the left bracket for visualisation
18
+ const highlight = leftBracket.color('#ff4444');
19
+
20
+ // --- A second instance, shifted and with overridden params ---
21
+ const secondAssembly = importGroup("api/import-group-source.forge.js", {
22
+ "Height": 60,
23
+ "Width": 80,
24
+ }).translate(150, 0, 0);
25
+
26
+ return [
27
+ // Show the first assembly as individual named parts
28
+ { name: "Left Bracket (highlight)", shape: highlight },
29
+ { name: "Right Bracket", shape: rightBracket },
30
+ { name: "Dowel", shape: dowel },
31
+
32
+ // Show the second (translated) assembly as a group
33
+ { name: "Second Assembly", shape: secondAssembly },
34
+ ];
@@ -0,0 +1,35 @@
1
+ // import-group-source.forge.js
2
+ // A multipart bracket assembly exported as a named ShapeGroup.
3
+ // Import with: importGroup("api/import-group-source.forge.js")
4
+
5
+ const thickness = param("Thickness", 4, { min: 2, max: 8, unit: "mm" });
6
+ const height = param("Height", 40, { min: 20, max: 80, unit: "mm" });
7
+ const width = param("Width", 60, { min: 40, max: 120, unit: "mm" });
8
+
9
+ // Left bracket
10
+ const leftBracket = box(thickness, width, height)
11
+ .color('#5b7c8d');
12
+
13
+ // Right bracket — mirror of left
14
+ const rightBracket = box(thickness, width, height)
15
+ .translate(width + thickness, 0, 0)
16
+ .color('#5b7c8d');
17
+
18
+ // Connecting dowel — runs along Y axis between the two brackets
19
+ const dowel = cylinder(width, 3)
20
+ .rotate(90, 0, 0)
21
+ .translate(width / 2 + thickness, width, height / 2)
22
+ .color('#d38b4d');
23
+
24
+ return group(
25
+ { name: "Bracket Left", shape: leftBracket },
26
+ { name: "Bracket Right", shape: rightBracket },
27
+ { name: "Dowel", shape: dowel },
28
+ ).withReferences({
29
+ points: {
30
+ // Semantic mount point at the center of the left face
31
+ mountCenter: [0, width / 2, height / 2],
32
+ // Top-center of the full assembly
33
+ topCenter: [width / 2 + thickness, width / 2, height],
34
+ },
35
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgecad",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Code-first parametric CAD for JavaScript/TypeScript, in the browser and CLI.",
5
5
  "license": "BUSL-1.1",
6
6
  "type": "module",