Parametric CAD for agent-built, manufacturable parts inside Nimbalyst.
Replicad CAD turns *.replicad.ts files into live, editable 3D models with a real OpenCascade B-rep kernel behind them. Build brackets, enclosures, fixtures, adapters, gears, and imported-part mounts with TypeScript instead of dragging sketches by hand, then export clean STEP, STL, 3MF, or OBJ files for CAM, printing, or sharing.
The extension is built around a tight write → preview → measure → correct loop:
- model with the full Replicad TypeScript API over OpenCascade.js,
- tune dimensions through a generated Customizer panel,
- inspect multi-view screenshots, geometry metrics, and printability warnings,
- import vendor STEP files and fit new parts around measured geometry,
- hand the same tools to Nimbalyst agents so they can see and repair the parts they generate.
Unlike mesh-only or simple CSG tools, this gives you the CAD operations people actually need: fillets, chamfers, booleans, shelling, lofts, sweeps, STEP import, and manufacturing-grade exports.
See replicad-extension-design.md for the full design rationale.
- Install Replicad CAD from the Nimbalyst marketplace, or install a local
.nimextpackage from a release build. - Open a workspace that contains a
*.replicad.tsfile, or copy one of the models fromsamples/. - Edit the model code. The preview recompiles automatically after edits and parameter changes.
- Use the Customizer panel to adjust exported parameters without rewriting code.
- Export the result from the editor menu, or ask an agent to use
replicad.export_modelfor STEP, STL, 3MF, or OBJ output.
For a fast first test, open samples/motor-cradle.replicad.ts. It imports a vendor STEP asset, measures it, and builds a cradle around the measured part.
Models are raw Replicad TypeScript, *.replicad.ts. A model's default export (or a main export) returns geometry:
import { drawRoundedRectangle, drawCircle } from 'replicad';
export const defaultParams = { width: 40, depth: 30, height: 12, fillet: 3 };
export default function main({ width, depth, height, fillet }) {
return drawRoundedRectangle(width, depth, fillet).sketchOnPlane().extrude(height);
}A model may return:
- a single Replicad 3D shape,
- an array of shapes, or
- an array of
{ shape, name, color, opacity }descriptors (multi-part models).
Export defaultParams (and optionally a richer parameterDefinitions descriptor with kind, min/max/step, group, and enum options) to drive the model from the Customizer panel and from the AI tools.
The only module a model may import is 'replicad'. STEP assets in the project are reachable through an injected imported("<filename>") helper. Place vendor parts anywhere in the workspace, then reference them by filename from your model or ask an agent to discover them with replicad.get_project.
drawText / sketchText work out of the box — the worker ships a built-in default font (Roboto). To use a different typeface, encode a .ttf/.otf with npm run font:encode path/to/font.ttf and drop the resulting *.ttf.b64 sidecar anywhere in your project; the first one found overrides the default. (A base64 sidecar is required because the editor's filesystem reader is text-only.)
A three-pane custom editor for *.replicad.ts:
- Code (Monaco, TypeScript) on the left,
- Live B-rep preview (Three.js) in the middle — recompiles on edit and on parameter changes,
- Customizer parameter panel on the right (numbers, booleans, enums, vectors, grouped sections),
- Export menu for STEP, STL, 3MF, and OBJ output.
Typical workflow:
- Write or paste a Replicad model.
- Export
defaultParamsfor the dimensions you expect to tune. - Click Compile if you want to force a rebuild immediately.
- Rotate and zoom the preview to check fit and features.
- Use Wireframe to inspect internal edges and generated topology.
- Export a manufacturing file when the model is ready.
Exported *.stl and *.obj files open in a read-only mesh viewer with orbit controls, wireframe toggle, bounding-box dimensions, triangle count, and watertightness.
Nimbalyst agents can use the same kernel pipeline as the editor. That matters: the agent is not guessing from text alone; it can compile the model, see rendered views, measure the shape, check overhangs and bed fit, then revise the code.
| Tool | Purpose |
|---|---|
replicad.get_project |
Project model: modules, runnable roots, parameters, STEP assets, conventions. |
replicad.compile_preview |
Compile a model (with parameter overrides) → diagnostics, resolved params, geometry metrics. |
replicad.inspect_model |
The see-correct tool: multi-view montage image + metrics + printability report. |
replicad.import_step |
Import/inspect a vendor STEP part so the agent can mate/cut against it. |
replicad.export_model |
Write manufacturable exports (STEP/STL/OBJ) to disk. |
Good agent prompts are concrete about the part, constraints, and output format:
Create a parametric wall bracket for a 25 mm tube. Use two countersunk M4 holes, round every outside edge, inspect it for printability, then export STEP and STL.
Open motor-cradle.replicad.ts, measure the imported motor STEP, increase the clearance by 0.2 mm, verify the bolt pattern, and export a watertight STL.
The samples/ folder is a self-contained workspace; each file is a parametric model that exercises a different kernel feature.
| Model | Demonstrates |
|---|---|
bracket |
Fillet + chamfer, a bolt-hole grid, grouped Customizer params. |
enclosure |
Shelling, multi-shape output with colors. |
hex-standoff |
An enum parameter driving a dimension table (parametric hardware). |
planetary-gear |
The draw() pen API, involute tooth math, a meshing gear train. |
knob |
Revolving a 2D half-section into a solid; a D-shaped shaft bore. |
threaded-jar |
A helical thread swept along a helix (sketchHelix + sweepSketch), mating jar + lid. |
motor-cradle |
Importing a vendor STEP, measuring it, and fitting a mount to the measured geometry. |
cantilever-overhang |
A deliberate overhang so inspect_model's printability check fires; toggle support to fix it. |
duct-adapter |
Lofting a square profile into a round one (loftWith) for a hollow square-to-round duct. |
twisted-vase |
A twist extrude (extrude with twistAngle), shelled into a fluted planter. |
heart-keychain |
A custom outline from drawParametricFunction extruded into a tag. |
nameplate |
3D text via drawText using the built-in font; emboss or engrave on a plate. |
The motor-cradle STEP asset lives in samples/assets/ and can be regenerated with node temptests/gen-stepper-step.mjs.
Optional .nimbalyst/replicad.yml at the workspace root documents roots, units, material, and the printer profile (printerNozzle, printerBed) that seeds the printability checks. See samples/.nimbalyst/replicad.yml.
Example:
units: mm
material: PLA
printerNozzle: 0.4
printerBed:
x: 220
y: 220
z: 250
roots:
- samples/motor-cradle.replicad.ts- Two-bundle, Blob-URL build. Two Vite invocations emit a single inlined main bundle (
dist/index.js) and a single inlined worker bundle (dist/replicad.worker.js). The loader installs the main bundle through a Blob URL, so neither can rely on relative chunk imports. - wasm-as-base64-text handoff. The ~10.8 MB OCCT wasm is not bundled. The build emits it as
dist/replicad.wasm.b64; the client reads it as text and posts it to the worker atinit, which decodes it intoModule.wasmBinary. The default text font (dist/replicad.font.b64) rides along the same way — same reason: the SDK filesystem reader is text-only and can't return binary. - Kernel worker. Hosts OpenCascade.js (the
with_exceptionsOCCT build, so kernel failures throw catchable JS errors instead of aborting the wasm) plus Replicad. Each compile transpiles the user's*.replicad.tswith Sucrase — pure-JS, so there is no second wasm to hand off and the live-edit loop stays tight — runs it against the kernel, and returns an indexed mesh, metrics, and on-demand exports. - Request-ID protocol, serialized compiles, single reused kernel instance.
deactivate()terminates the worker (the Blob URL and decoded wasm leak otherwise).
Design note: the design doc suggested esbuild-wasm/swc for transpilation; this build uses Sucrase instead to avoid a second wasm payload in the worker. The contract (transpile-on-compile, no separate build step) is unchanged.
For extension development:
npm install
npm run build # main bundle + worker bundle + wasm + font base64 emit
npm run typechecknpm run build runs four steps: vite build (main), vite build --config vite.worker.config.ts (worker), node scripts/emit-wasm-b64.mjs (wasm → base64 text), and node scripts/emit-font-b64.mjs (default font → base64 text).
Set NIMBALYST_BUILD_SOURCEMAPS=1 when you need local production source maps. Release builds omit them by default so marketplace packages do not ship source.
Create a public .nimext artifact for GitHub releases or marketplace review:
npm run package:nimextThis writes release/com.nimbalyst.replicad-<version>.nimext and a matching SHA-256 file. The package contains only manifest.json, built dist/ assets, the README, changelog, license/docs, and marketplace screenshots. Marketplace screenshots are generated from the manifest's marketplace.screenshots entry, which opens samples/motor-cradle.replicad.ts in Nimbalyst.