cyclecad 3.2.0 → 3.4.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.
Files changed (65) hide show
  1. package/DOCKER-SETUP-VERIFICATION.md +399 -0
  2. package/DOCKER-TESTING.md +463 -0
  3. package/FUSION360_MODULES.md +478 -0
  4. package/FUSION_MODULES_README.md +352 -0
  5. package/INTEGRATION_SNIPPETS.md +608 -0
  6. package/KILLER-FEATURES-DELIVERY.md +469 -0
  7. package/MODULES_SUMMARY.txt +337 -0
  8. package/QUICK_REFERENCE.txt +298 -0
  9. package/README-DOCKER-TESTING.txt +438 -0
  10. package/app/index.html +23 -10
  11. package/app/js/fusion-help.json +1808 -0
  12. package/app/js/help-module-v3.js +1096 -0
  13. package/app/js/killer-features-help.json +395 -0
  14. package/app/js/killer-features.js +1508 -0
  15. package/app/js/modules/fusion-assembly.js +842 -0
  16. package/app/js/modules/fusion-cam.js +785 -0
  17. package/app/js/modules/fusion-data.js +814 -0
  18. package/app/js/modules/fusion-drawing.js +844 -0
  19. package/app/js/modules/fusion-inspection.js +756 -0
  20. package/app/js/modules/fusion-render.js +774 -0
  21. package/app/js/modules/fusion-simulation.js +986 -0
  22. package/app/js/modules/fusion-sketch.js +1044 -0
  23. package/app/js/modules/fusion-solid.js +1095 -0
  24. package/app/js/modules/fusion-surface.js +949 -0
  25. package/app/tests/FUSION_TEST_SUITE.md +266 -0
  26. package/app/tests/README.md +77 -0
  27. package/app/tests/TESTING-CHECKLIST.md +177 -0
  28. package/app/tests/TEST_SUITE_SUMMARY.txt +236 -0
  29. package/app/tests/brep-live-test.html +848 -0
  30. package/app/tests/docker-integration-test.html +811 -0
  31. package/app/tests/fusion-all-tests.html +670 -0
  32. package/app/tests/fusion-assembly-tests.html +461 -0
  33. package/app/tests/fusion-cam-tests.html +421 -0
  34. package/app/tests/fusion-simulation-tests.html +421 -0
  35. package/app/tests/fusion-sketch-tests.html +613 -0
  36. package/app/tests/fusion-solid-tests.html +529 -0
  37. package/app/tests/index.html +453 -0
  38. package/app/tests/killer-features-test.html +509 -0
  39. package/app/tests/run-tests.html +874 -0
  40. package/app/tests/step-import-live-test.html +1115 -0
  41. package/app/tests/test-agent-v3.html +93 -696
  42. package/architecture-dashboard.html +1970 -0
  43. package/docs/API-REFERENCE.md +1423 -0
  44. package/docs/BREP-LIVE-TEST-GUIDE.md +453 -0
  45. package/docs/DEVELOPER-GUIDE-v3.md +795 -0
  46. package/docs/DOCKER-QUICK-TEST.md +376 -0
  47. package/docs/FUSION-FEATURES-GUIDE.md +2513 -0
  48. package/docs/FUSION-TUTORIAL.md +1203 -0
  49. package/docs/INFRASTRUCTURE-GUIDE-INDEX.md +327 -0
  50. package/docs/KEYBOARD-SHORTCUTS.md +402 -0
  51. package/docs/KILLER-FEATURES-INTEGRATION.md +412 -0
  52. package/docs/KILLER-FEATURES-SUMMARY.md +424 -0
  53. package/docs/KILLER-FEATURES-TUTORIAL.md +784 -0
  54. package/docs/KILLER-FEATURES.md +562 -0
  55. package/docs/QUICK-REFERENCE.md +282 -0
  56. package/docs/README-v3-DOCS.md +274 -0
  57. package/docs/TUTORIAL-v3.md +1190 -0
  58. package/docs/architecture-dashboard.html +1970 -0
  59. package/docs/architecture-v3.html +1038 -0
  60. package/linkedin-post-v3.md +58 -0
  61. package/package.json +1 -1
  62. package/scripts/dev-setup.sh +338 -0
  63. package/scripts/docker-health-check.sh +159 -0
  64. package/scripts/integration-test.sh +311 -0
  65. package/scripts/test-docker.sh +515 -0
@@ -0,0 +1,1423 @@
1
+ # cycleCAD Agent API Reference
2
+
3
+ Complete documentation of the cycleCAD API for AI agents, external tools, and programmatic access.
4
+
5
+ ---
6
+
7
+ ## TABLE OF CONTENTS
8
+
9
+ 1. [Overview](#overview)
10
+ 2. [Authentication and Setup](#authentication-and-setup)
11
+ 3. [Shape Namespace](#shape-namespace)
12
+ 4. [Feature Namespace](#feature-namespace)
13
+ 5. [Assembly Namespace](#assembly-namespace)
14
+ 6. [Render Namespace](#render-namespace)
15
+ 7. [Validate Namespace](#validate-namespace)
16
+ 8. [Simulate Namespace](#simulate-namespace)
17
+ 9. [CAM Namespace](#cam-namespace)
18
+ 10. [Drawing Namespace](#drawing-namespace)
19
+ 11. [Data Namespace](#data-namespace)
20
+ 12. [Error Handling](#error-handling)
21
+ 13. [Code Examples](#code-examples)
22
+
23
+ ---
24
+
25
+ ## OVERVIEW
26
+
27
+ ### API Style
28
+ - **Protocol**: JSON-RPC 2.0 over HTTP/WebSocket
29
+ - **Base URL**: `https://cyclecad.com/api/v1/` or `ws://cyclecad-local:8787`
30
+ - **Authentication**: API key in header or token in body
31
+ - **Content-Type**: `application/json`
32
+
33
+ ### Request Format
34
+ ```json
35
+ {
36
+ "jsonrpc": "2.0",
37
+ "method": "shape.cylinder",
38
+ "params": {
39
+ "diameter": 50,
40
+ "height": 80,
41
+ "sketch_plane": "XY"
42
+ },
43
+ "id": 1
44
+ }
45
+ ```
46
+
47
+ ### Response Format
48
+ ```json
49
+ {
50
+ "jsonrpc": "2.0",
51
+ "result": {
52
+ "status": "success",
53
+ "body_id": "body_001",
54
+ "geometry": {
55
+ "volume": 157079.6,
56
+ "mass": 423.92,
57
+ "bbox": { "min": [-25, -25, 0], "max": [25, 25, 80] }
58
+ }
59
+ },
60
+ "id": 1
61
+ }
62
+ ```
63
+
64
+ ### Error Response
65
+ ```json
66
+ {
67
+ "jsonrpc": "2.0",
68
+ "error": {
69
+ "code": -32602,
70
+ "message": "Invalid parameters",
71
+ "data": {
72
+ "field": "diameter",
73
+ "reason": "must be > 0"
74
+ }
75
+ },
76
+ "id": 1
77
+ }
78
+ ```
79
+
80
+ ---
81
+
82
+ ## AUTHENTICATION AND SETUP
83
+
84
+ ### Initialize Session
85
+ ```
86
+ POST /auth/init
87
+ ```
88
+
89
+ **Request:**
90
+ ```json
91
+ {
92
+ "api_key": "sk_live_abc123xyz"
93
+ }
94
+ ```
95
+
96
+ **Response:**
97
+ ```json
98
+ {
99
+ "status": "success",
100
+ "session_id": "sess_123xyz",
101
+ "token": "bearer_token_xyz",
102
+ "expires_in": 3600
103
+ }
104
+ ```
105
+
106
+ ### Get API Schema
107
+ ```
108
+ GET /schema
109
+ ```
110
+
111
+ Returns complete schema for all methods, parameters, and return values.
112
+
113
+ **Response:**
114
+ ```json
115
+ {
116
+ "version": "1.0",
117
+ "namespaces": [
118
+ {
119
+ "name": "shape",
120
+ "methods": [
121
+ {
122
+ "name": "cylinder",
123
+ "description": "Create 3D cylinder",
124
+ "params": {...},
125
+ "returns": {...}
126
+ }
127
+ ]
128
+ }
129
+ ]
130
+ }
131
+ ```
132
+
133
+ ---
134
+
135
+ ## SHAPE NAMESPACE
136
+
137
+ Geometric primitives and basic shape creation.
138
+
139
+ ### shape.cylinder
140
+ **Create 3D cylinder**
141
+
142
+ **Parameters:**
143
+ - `diameter` (number, required): Cylinder diameter in mm
144
+ - `height` (number, required): Cylinder height in mm
145
+ - `center` (object, optional): Center point {x, y, z}, default [0,0,0]
146
+ - `name` (string, optional): Feature name, default "Cylinder"
147
+
148
+ **Returns:**
149
+ ```json
150
+ {
151
+ "body_id": "body_001",
152
+ "feature_id": "cylinder_001",
153
+ "geometry": {
154
+ "volume": 157079.6,
155
+ "surface_area": 7853.98,
156
+ "mass": 423.92,
157
+ "bbox": { "min": [-25, -25, 0], "max": [25, 25, 80] }
158
+ }
159
+ }
160
+ ```
161
+
162
+ **Example:**
163
+ ```javascript
164
+ const result = await cyclecad.execute({
165
+ method: "shape.cylinder",
166
+ params: {
167
+ diameter: 50,
168
+ height: 80,
169
+ center: [0, 0, 0],
170
+ name: "Main Shaft"
171
+ }
172
+ });
173
+ // Result: body_id = "body_001"
174
+ ```
175
+
176
+ ---
177
+
178
+ ### shape.box
179
+ **Create rectangular box**
180
+
181
+ **Parameters:**
182
+ - `width` (number, required): Width (X) in mm
183
+ - `height` (number, required): Height (Z) in mm
184
+ - `depth` (number, required): Depth (Y) in mm
185
+ - `center` (object, optional): Center point {x, y, z}
186
+ - `name` (string, optional): Feature name
187
+
188
+ **Returns:** Same as cylinder (body_id, geometry, etc.)
189
+
190
+ **Example:**
191
+ ```javascript
192
+ const box = await cyclecad.execute({
193
+ method: "shape.box",
194
+ params: {
195
+ width: 100,
196
+ height: 50,
197
+ depth: 75
198
+ }
199
+ });
200
+ ```
201
+
202
+ ---
203
+
204
+ ### shape.sphere
205
+ **Create sphere**
206
+
207
+ **Parameters:**
208
+ - `diameter` (number, required): Sphere diameter in mm
209
+ - `center` (object, optional): Center point {x, y, z}
210
+ - `name` (string, optional): Feature name
211
+
212
+ **Returns:** Body geometry with volume, surface area, etc.
213
+
214
+ ---
215
+
216
+ ### shape.cone
217
+ **Create cone**
218
+
219
+ **Parameters:**
220
+ - `base_diameter` (number, required): Base diameter in mm
221
+ - `height` (number, required): Cone height in mm
222
+ - `apex_offset` (number, optional): Offset from center (creates truncated cone)
223
+ - `center` (object, optional): Base center point
224
+ - `name` (string, optional): Feature name
225
+
226
+ **Returns:** Body geometry
227
+
228
+ ---
229
+
230
+ ### shape.torus
231
+ **Create torus (donut)**
232
+
233
+ **Parameters:**
234
+ - `outer_diameter` (number, required): Outer diameter in mm
235
+ - `tube_diameter` (number, required): Tube diameter in mm
236
+ - `center` (object, optional): Center point {x, y, z}
237
+ - `name` (string, optional): Feature name
238
+
239
+ **Returns:** Body geometry
240
+
241
+ ---
242
+
243
+ ### shape.wedge
244
+ **Create wedge/triangular prism**
245
+
246
+ **Parameters:**
247
+ - `width` (number, required): Width in mm
248
+ - `height` (number, required): Height in mm
249
+ - `depth` (number, required): Depth in mm
250
+ - `angle` (number, required): Taper angle in degrees
251
+ - `center` (object, optional): Center point
252
+ - `name` (string, optional): Feature name
253
+
254
+ **Returns:** Body geometry
255
+
256
+ ---
257
+
258
+ ## FEATURE NAMESPACE
259
+
260
+ Operations that modify or add to existing bodies.
261
+
262
+ ### feature.extrude
263
+ **Extrude a sketch profile**
264
+
265
+ **Parameters:**
266
+ - `sketch_id` (string, required): ID of 2D sketch to extrude
267
+ - `distance` (number, required): Extrusion distance in mm
268
+ - `direction` (string, optional): "up", "down", "symmetric", default "up"
269
+ - `angle` (number, optional): Draft angle in degrees
270
+ - `name` (string, optional): Feature name
271
+
272
+ **Returns:**
273
+ ```json
274
+ {
275
+ "feature_id": "extrude_001",
276
+ "body_id": "body_001",
277
+ "geometry": { "volume": 50000, "mass": 135 }
278
+ }
279
+ ```
280
+
281
+ **Example:**
282
+ ```javascript
283
+ const sketch = await cyclecad.execute({
284
+ method: "sketch.rectangle",
285
+ params: { width: 50, height: 75 }
286
+ });
287
+
288
+ const extrude = await cyclecad.execute({
289
+ method: "feature.extrude",
290
+ params: {
291
+ sketch_id: sketch.sketch_id,
292
+ distance: 50,
293
+ direction: "up"
294
+ }
295
+ });
296
+ ```
297
+
298
+ ---
299
+
300
+ ### feature.revolve
301
+ **Revolve a profile around an axis**
302
+
303
+ **Parameters:**
304
+ - `sketch_id` (string, required): Sketch profile ID
305
+ - `axis_id` (string, required): Axis edge/line ID
306
+ - `angle` (number, optional): Rotation angle, default 360
307
+ - `name` (string, optional): Feature name
308
+
309
+ **Returns:** Feature with body_id and geometry
310
+
311
+ ---
312
+
313
+ ### feature.sweep
314
+ **Sweep a profile along a path**
315
+
316
+ **Parameters:**
317
+ - `profile_id` (string, required): Profile sketch ID
318
+ - `path_id` (string, required): Path curve/edge ID
319
+ - `twist_angle` (number, optional): Twist in degrees
320
+ - `scale_end` (number, optional): Scale at path end (1.0 = no scale)
321
+ - `name` (string, optional): Feature name
322
+
323
+ **Returns:** Feature with geometry
324
+
325
+ ---
326
+
327
+ ### feature.loft
328
+ **Loft between multiple profiles**
329
+
330
+ **Parameters:**
331
+ - `profiles` (array, required): Array of sketch IDs [profile1, profile2, ...]
332
+ - `continuity` (string, optional): "positional", "tangent", "curvature", default "tangent"
333
+ - `name` (string, optional): Feature name
334
+
335
+ **Returns:** Feature with geometry
336
+
337
+ ---
338
+
339
+ ### feature.fillet
340
+ **Round edges on a body**
341
+
342
+ **Parameters:**
343
+ - `body_id` (string, required): Body to fillet
344
+ - `edges` (array, required): Array of edge IDs to fillet
345
+ - `radius` (number, required): Fillet radius in mm
346
+ - `name` (string, optional): Feature name
347
+
348
+ **Returns:** Feature with updated geometry
349
+
350
+ **Example:**
351
+ ```javascript
352
+ const fillet = await cyclecad.execute({
353
+ method: "feature.fillet",
354
+ params: {
355
+ body_id: "body_001",
356
+ edges: ["edge_001", "edge_002", "edge_003", "edge_004"],
357
+ radius: 5,
358
+ name: "Top Edge Fillet"
359
+ }
360
+ });
361
+ ```
362
+
363
+ ---
364
+
365
+ ### feature.chamfer
366
+ **Bevel edges on a body**
367
+
368
+ **Parameters:**
369
+ - `body_id` (string, required): Body to chamfer
370
+ - `edges` (array, required): Array of edge IDs
371
+ - `distance` (number, optional): Chamfer distance in mm
372
+ - `angle` (number, optional): Chamfer angle in degrees
373
+ - `name` (string, optional): Feature name
374
+
375
+ **Returns:** Feature with updated geometry
376
+
377
+ ---
378
+
379
+ ### feature.shell
380
+ **Make body hollow with uniform wall thickness**
381
+
382
+ **Parameters:**
383
+ - `body_id` (string, required): Body to shell
384
+ - `faces_to_remove` (array, optional): Face IDs to remove (open shell)
385
+ - `thickness` (number, required): Wall thickness in mm
386
+ - `name` (string, optional): Feature name
387
+
388
+ **Returns:** Feature with hollow geometry
389
+
390
+ ---
391
+
392
+ ### feature.draft
393
+ **Apply draft angle to faces**
394
+
395
+ **Parameters:**
396
+ - `body_id` (string, required): Body to draft
397
+ - `faces` (array, required): Array of face IDs
398
+ - `angle` (number, required): Draft angle in degrees
399
+ - `pull_direction` (object, optional): Direction vector {x, y, z}
400
+ - `name` (string, optional): Feature name
401
+
402
+ **Returns:** Feature with updated geometry
403
+
404
+ ---
405
+
406
+ ### feature.pattern_rectangular
407
+ **Create rectangular array of feature**
408
+
409
+ **Parameters:**
410
+ - `feature_id` (string, required): Feature to pattern (extrude, hole, etc.)
411
+ - `x_count` (number, required): Number of columns
412
+ - `y_count` (number, required): Number of rows
413
+ - `x_spacing` (number, required): Distance between features (X)
414
+ - `y_spacing` (number, required): Distance between features (Y)
415
+ - `name` (string, optional): Feature name
416
+
417
+ **Returns:** Pattern feature with all instances
418
+
419
+ **Example:**
420
+ ```javascript
421
+ const pattern = await cyclecad.execute({
422
+ method: "feature.pattern_rectangular",
423
+ params: {
424
+ feature_id: "hole_001",
425
+ x_count: 3,
426
+ y_count: 2,
427
+ x_spacing: 30,
428
+ y_spacing: 25,
429
+ name: "Bolt Hole Pattern"
430
+ }
431
+ });
432
+ // Result: 6 holes total (3 × 2 grid)
433
+ ```
434
+
435
+ ---
436
+
437
+ ### feature.pattern_circular
438
+ **Create circular array of feature**
439
+
440
+ **Parameters:**
441
+ - `feature_id` (string, required): Feature to pattern
442
+ - `axis_id` (string, optional): Rotation axis (default Z)
443
+ - `count` (number, required): Total number of instances
444
+ - `angle` (number, optional): Total rotation angle, default 360
445
+ - `name` (string, optional): Feature name
446
+
447
+ **Returns:** Pattern feature with instances
448
+
449
+ ---
450
+
451
+ ### feature.mirror
452
+ **Mirror a feature across a plane**
453
+
454
+ **Parameters:**
455
+ - `feature_id` (string, required): Feature to mirror
456
+ - `plane` (string, required): Mirror plane ("XY", "YZ", "XZ", or plane_id)
457
+ - `name` (string, optional): Feature name
458
+
459
+ **Returns:** Mirrored feature
460
+
461
+ ---
462
+
463
+ ### feature.boolean_union
464
+ **Combine two bodies**
465
+
466
+ **Parameters:**
467
+ - `body1_id` (string, required): First body
468
+ - `body2_id` (string, required): Second body
469
+ - `name` (string, optional): Feature name
470
+
471
+ **Returns:** New body with merged geometry
472
+
473
+ ---
474
+
475
+ ### feature.boolean_cut
476
+ **Subtract one body from another**
477
+
478
+ **Parameters:**
479
+ - `target_id` (string, required): Body to keep
480
+ - `tool_id` (string, required): Body to subtract
481
+ - `name` (string, optional): Feature name
482
+
483
+ **Returns:** New body with subtracted geometry
484
+
485
+ ---
486
+
487
+ ### feature.boolean_intersect
488
+ **Keep only overlapping volume**
489
+
490
+ **Parameters:**
491
+ - `body1_id` (string, required): First body
492
+ - `body2_id` (string, required): Second body
493
+ - `name` (string, optional): Feature name
494
+
495
+ **Returns:** New body with intersection only
496
+
497
+ ---
498
+
499
+ ## ASSEMBLY NAMESPACE
500
+
501
+ Multi-part assembly operations and constraints.
502
+
503
+ ### assembly.insert_component
504
+ **Add part to assembly**
505
+
506
+ **Parameters:**
507
+ - `part_id` (string, required): Part to insert
508
+ - `position` (object, optional): Position {x, y, z}
509
+ - `rotation` (object, optional): Rotation {x, y, z} in degrees
510
+ - `name` (string, optional): Component name
511
+
512
+ **Returns:**
513
+ ```json
514
+ {
515
+ "component_id": "comp_001",
516
+ "assembly_id": "assembly_001",
517
+ "position": [0, 0, 0],
518
+ "rotation": [0, 0, 0]
519
+ }
520
+ ```
521
+
522
+ ---
523
+
524
+ ### assembly.joint_rigid
525
+ **Lock two components in fixed position**
526
+
527
+ **Parameters:**
528
+ - `component1_id` (string, required): First component
529
+ - `component2_id` (string, required): Second component
530
+ - `face1_id` (string, optional): Face on first component
531
+ - `face2_id` (string, optional): Face on second component
532
+
533
+ **Returns:**
534
+ ```json
535
+ {
536
+ "joint_id": "joint_rigid_001",
537
+ "type": "rigid",
538
+ "components": ["comp_001", "comp_002"]
539
+ }
540
+ ```
541
+
542
+ ---
543
+
544
+ ### assembly.joint_revolute
545
+ **Allow rotation around axis (hinge)**
546
+
547
+ **Parameters:**
548
+ - `component1_id` (string, required): First component
549
+ - `component2_id` (string, required): Second component
550
+ - `axis_id` (string, required): Rotation axis (edge or line)
551
+ - `angle_min` (number, optional): Minimum angle in degrees
552
+ - `angle_max` (number, optional): Maximum angle in degrees
553
+
554
+ **Returns:** Joint with type "revolute" and angle limits
555
+
556
+ ---
557
+
558
+ ### assembly.joint_slider
559
+ **Allow translation along axis**
560
+
561
+ **Parameters:**
562
+ - `component1_id` (string, required): First component
563
+ - `component2_id` (string, required): Second component
564
+ - `axis_id` (string, required): Sliding axis
565
+ - `distance_min` (number, optional): Minimum distance
566
+ - `distance_max` (number, optional): Maximum distance
567
+
568
+ **Returns:** Joint with type "slider"
569
+
570
+ ---
571
+
572
+ ### assembly.joint_ball
573
+ **Allow rotation in all directions (ball-and-socket)**
574
+
575
+ **Parameters:**
576
+ - `component1_id` (string, required): First component
577
+ - `component2_id` (string, required): Second component
578
+ - `point_id` (string, required): Ball center point
579
+ - `cone_angle` (number, optional): Rotation limit cone angle
580
+
581
+ **Returns:** Joint with type "ball"
582
+
583
+ ---
584
+
585
+ ### assembly.joint_planar
586
+ **Lock planes together (allow translation in plane)**
587
+
588
+ **Parameters:**
589
+ - `component1_id` (string, required): First component
590
+ - `component2_id` (string, required): Second component
591
+ - `plane1_id` (string, required): Plane on first component
592
+ - `plane2_id` (string, required): Plane on second component
593
+
594
+ **Returns:** Joint with type "planar"
595
+
596
+ ---
597
+
598
+ ### assembly.joint_cylinder
599
+ **Allow rotation and translation around same axis**
600
+
601
+ **Parameters:**
602
+ - `component1_id` (string, required): First component
603
+ - `component2_id` (string, required): Second component
604
+ - `axis_id` (string, required): Cylinder axis
605
+
606
+ **Returns:** Joint with type "cylinder"
607
+
608
+ ---
609
+
610
+ ### assembly.check_collision
611
+ **Detect interference between components**
612
+
613
+ **Parameters:**
614
+ - `assembly_id` (string, required): Assembly to check
615
+ - `component1_id` (string, optional): First component (null = all)
616
+ - `component2_id` (string, optional): Second component (null = all)
617
+
618
+ **Returns:**
619
+ ```json
620
+ {
621
+ "collisions": [
622
+ {
623
+ "component1": "comp_001",
624
+ "component2": "comp_002",
625
+ "volume": 125.4,
626
+ "overlap_points": [...]
627
+ }
628
+ ],
629
+ "collision_count": 1
630
+ }
631
+ ```
632
+
633
+ ---
634
+
635
+ ## RENDER NAMESPACE
636
+
637
+ Visualization, materials, lighting, and animation.
638
+
639
+ ### render.apply_material
640
+ **Assign material to surface**
641
+
642
+ **Parameters:**
643
+ - `body_id` (string, required): Body to apply material
644
+ - `material` (string, required): Material name ("steel", "aluminum", "plastic", etc.)
645
+ - `color` (string, optional): Hex color code "#FF0000"
646
+ - `metalness` (number, optional): 0-1, default 0.5
647
+ - `roughness` (number, optional): 0-1, default 0.5
648
+
649
+ **Returns:**
650
+ ```json
651
+ {
652
+ "body_id": "body_001",
653
+ "material": "steel",
654
+ "properties": {
655
+ "color": "#555555",
656
+ "metalness": 0.8,
657
+ "roughness": 0.3
658
+ }
659
+ }
660
+ ```
661
+
662
+ ---
663
+
664
+ ### render.studio_lighting
665
+ **Set up professional 3-point lighting**
666
+
667
+ **Parameters:**
668
+ - `key_light` (object): {intensity, position: {x, y, z}, color}
669
+ - `fill_light` (object): {intensity, position, color}
670
+ - `back_light` (object): {intensity, position, color}
671
+
672
+ **Returns:** Lighting configuration
673
+
674
+ ---
675
+
676
+ ### render.environment
677
+ **Set background HDRI and reflections**
678
+
679
+ **Parameters:**
680
+ - `hdri_name` (string, required): HDRI map name ("studio", "outdoor", "industrial")
681
+ - `rotation` (number, optional): Rotation in degrees
682
+ - `intensity` (number, optional): 0-2, default 1.0
683
+
684
+ **Returns:** Environment configuration
685
+
686
+ ---
687
+
688
+ ### render.turntable
689
+ **Create auto-rotating animation**
690
+
691
+ **Parameters:**
692
+ - `body_id` (string, required): Body to rotate
693
+ - `speed_rpm` (number, optional): Rotation speed, default 30
694
+ - `duration_seconds` (number, optional): Total duration, default 10
695
+ - `camera_height` (number, optional): Camera height (0-1), default 0.5
696
+
697
+ **Returns:**
698
+ ```json
699
+ {
700
+ "animation_id": "anim_turntable_001",
701
+ "duration": 10,
702
+ "format": "mp4",
703
+ "file_url": "https://..."
704
+ }
705
+ ```
706
+
707
+ ---
708
+
709
+ ### render.storyboard
710
+ **Create keyframe-based animation**
711
+
712
+ **Parameters:**
713
+ - `keyframes` (array, required): Array of {time: seconds, position: {x, y, z}, rotation: {x, y, z}, visibility: bool}
714
+ - `duration_seconds` (number, optional): Total duration
715
+ - `camera_path` (array, optional): Array of camera positions
716
+
717
+ **Returns:** Animation with rendering progress and URL
718
+
719
+ ---
720
+
721
+ ### render.snapshot
722
+ **Capture 3D view as image**
723
+
724
+ **Parameters:**
725
+ - `body_id` (string, required): Body to capture
726
+ - `resolution` (string, optional): "1080p", "4K", custom WIDTHxHEIGHT
727
+ - `format` (string, optional): "png", "jpg", default "png"
728
+ - `background` (string, optional): "transparent", "white", "black", hex color
729
+
730
+ **Returns:**
731
+ ```json
732
+ {
733
+ "image_url": "https://...",
734
+ "resolution": "1920x1080",
735
+ "format": "png"
736
+ }
737
+ ```
738
+
739
+ ---
740
+
741
+ ## VALIDATE NAMESPACE
742
+
743
+ Design review and manufacturability analysis.
744
+
745
+ ### validate.design_review
746
+ **Analyze design for quality**
747
+
748
+ **Parameters:**
749
+ - `body_id` (string, required): Body to analyze
750
+ - `checks` (array, optional): ["sharp_edges", "thin_walls", "undercuts", "stress", "cost"]
751
+
752
+ **Returns:**
753
+ ```json
754
+ {
755
+ "score": "A",
756
+ "analysis": {
757
+ "sharp_edges": { "count": 3, "severity": "low" },
758
+ "thin_walls": { "min_thickness": 1.2, "severity": "medium" },
759
+ "undercuts": { "count": 1, "severity": "high" },
760
+ "estimated_cost": 45.50,
761
+ "estimated_weight": 0.65
762
+ },
763
+ "recommendations": ["Add 0.5mm fillet to top edges", "Increase wall thickness to 2mm"]
764
+ }
765
+ ```
766
+
767
+ ---
768
+
769
+ ### validate.manufacturability
770
+ **Check for injection molding or machining**
771
+
772
+ **Parameters:**
773
+ - `body_id` (string, required): Body to check
774
+ - `process` (string, required): "injection_molding", "machining", "3d_printing"
775
+
776
+ **Returns:**
777
+ ```json
778
+ {
779
+ "process": "injection_molding",
780
+ "feasibility": "excellent",
781
+ "issues": [],
782
+ "recommendations": ["Add 2-5° draft angle to side faces"],
783
+ "estimated_cost": 45.50,
784
+ "estimated_time": "45 minutes"
785
+ }
786
+ ```
787
+
788
+ ---
789
+
790
+ ### validate.stress_estimate
791
+ **Quick stress analysis**
792
+
793
+ **Parameters:**
794
+ - `body_id` (string, required): Body to analyze
795
+ - `material` (string, required): Material name ("steel", "aluminum", etc.)
796
+ - `load_force` (number, required): Applied force in Newtons
797
+ - `load_point` (object, optional): Point of force application {x, y, z}
798
+
799
+ **Returns:**
800
+ ```json
801
+ {
802
+ "max_stress_mpa": 245.3,
803
+ "safety_factor": 2.1,
804
+ "result": "PASS",
805
+ "note": "Safe for static load"
806
+ }
807
+ ```
808
+
809
+ ---
810
+
811
+ ### validate.weight_estimate
812
+ **Calculate approximate mass**
813
+
814
+ **Parameters:**
815
+ - `body_id` (string, required): Body to weigh
816
+ - `material` (string, required): Material ("steel" = 7850 kg/m³, "aluminum" = 2700 kg/m³, etc.)
817
+
818
+ **Returns:**
819
+ ```json
820
+ {
821
+ "volume": 0.0001234,
822
+ "material": "steel",
823
+ "density": 7850,
824
+ "weight_kg": 0.969,
825
+ "weight_lbs": 2.14
826
+ }
827
+ ```
828
+
829
+ ---
830
+
831
+ ## SIMULATE NAMESPACE
832
+
833
+ Structural, thermal, and modal analysis.
834
+
835
+ ### simulate.stress
836
+ **Static stress analysis**
837
+
838
+ **Parameters:**
839
+ - `body_id` (string, required): Body to simulate
840
+ - `material` (string, required): Material ("steel", "aluminum", etc.)
841
+ - `loads` (array, required): [{face_id, force_vector: {x, y, z}}, ...]
842
+ - `constraints` (array, required): [{face_id, type: "fixed"}, ...]
843
+ - `mesh_quality` (string, optional): "coarse", "medium", "fine", default "medium"
844
+
845
+ **Returns:**
846
+ ```json
847
+ {
848
+ "simulation_id": "sim_stress_001",
849
+ "max_stress_mpa": 245.3,
850
+ "max_deflection_mm": 0.45,
851
+ "safety_factor": 2.1,
852
+ "status": "complete",
853
+ "results_url": "https://..."
854
+ }
855
+ ```
856
+
857
+ ---
858
+
859
+ ### simulate.thermal
860
+ **Heat transfer analysis**
861
+
862
+ **Parameters:**
863
+ - `body_id` (string, required): Body to simulate
864
+ - `material` (string, required): Material with thermal properties
865
+ - `heat_sources` (array, required): [{face_id, heat_flux_w_per_m2}, ...]
866
+ - `boundary_conditions` (array, required): [{face_id, temperature_c}, ...]
867
+ - `duration_seconds` (number, optional): For transient analysis
868
+
869
+ **Returns:**
870
+ ```json
871
+ {
872
+ "simulation_id": "sim_thermal_001",
873
+ "max_temperature_c": 125.4,
874
+ "min_temperature_c": 25.0,
875
+ "steady_state": true,
876
+ "status": "complete"
877
+ }
878
+ ```
879
+
880
+ ---
881
+
882
+ ### simulate.modal
883
+ **Natural frequency and vibration analysis**
884
+
885
+ **Parameters:**
886
+ - `body_id` (string, required): Body to analyze
887
+ - `material` (string, required): Material with density
888
+ - `constraints` (array, required): [{face_id, type: "fixed"}, ...]
889
+ - `modes_count` (number, optional): Number of modes to find, default 5
890
+
891
+ **Returns:**
892
+ ```json
893
+ {
894
+ "simulation_id": "sim_modal_001",
895
+ "modes": [
896
+ { "mode": 1, "frequency_hz": 123.4, "shape": "bending_x" },
897
+ { "mode": 2, "frequency_hz": 156.7, "shape": "bending_y" },
898
+ { "mode": 3, "frequency_hz": 234.5, "shape": "torsion" }
899
+ ],
900
+ "status": "complete"
901
+ }
902
+ ```
903
+
904
+ ---
905
+
906
+ ## CAM NAMESPACE
907
+
908
+ Manufacturing tool paths and CNC code generation.
909
+
910
+ ### cam.setup
911
+ **Define machining parameters**
912
+
913
+ **Parameters:**
914
+ - `body_id` (string, required): Body to machine
915
+ - `stock_type` (string, required): "box", "cylinder", custom
916
+ - `stock_dimensions` (object, required): {length, width, height} in mm
917
+ - `machine_type` (string, required): "mill_3axis", "mill_4axis", "lathe", "laser", "waterjet"
918
+
919
+ **Returns:**
920
+ ```json
921
+ {
922
+ "setup_id": "cam_setup_001",
923
+ "machine": "mill_3axis",
924
+ "stock_volume": 50000,
925
+ "available_tools": ["endmill_10", "ballmill_8", "drill_5"]
926
+ }
927
+ ```
928
+
929
+ ---
930
+
931
+ ### cam.contour_2d
932
+ **Mill outer profile of 2D sketch**
933
+
934
+ **Parameters:**
935
+ - `sketch_id` (string, required): 2D sketch outline
936
+ - `tool_id` (string, required): Tool from library
937
+ - `depth_per_pass` (number, required): Cut depth per pass in mm
938
+ - `climb_or_conventional` (string, optional): "climb", "conventional", default "climb"
939
+
940
+ **Returns:**
941
+ ```json
942
+ {
943
+ "toolpath_id": "tp_contour_001",
944
+ "passes": 3,
945
+ "estimated_time_minutes": 12.5,
946
+ "total_distance_mm": 2450
947
+ }
948
+ ```
949
+
950
+ ---
951
+
952
+ ### cam.pocket_2d
953
+ **Mill enclosed area to depth**
954
+
955
+ **Parameters:**
956
+ - `sketch_id` (string, required): Closed profile to pocket
957
+ - `tool_id` (string, required): Cutting tool
958
+ - `depth` (number, required): Pocket depth in mm
959
+ - `depth_per_pass` (number, required): Cut depth per pass
960
+
961
+ **Returns:** Toolpath with passes and time estimate
962
+
963
+ ---
964
+
965
+ ### cam.roughing_3d
966
+ **Remove bulk material quickly**
967
+
968
+ **Parameters:**
969
+ - `body_id` (string, required): Body to rough
970
+ - `tool_id` (string, required): Roughing tool (large diameter)
971
+ - `step_down` (number, required): Vertical step in mm
972
+ - `step_over` (number, optional): Horizontal spacing in mm
973
+
974
+ **Returns:** 3D toolpath with path points and time estimate
975
+
976
+ ---
977
+
978
+ ### cam.finishing_3d
979
+ **Fine cuts for surface quality**
980
+
981
+ **Parameters:**
982
+ - `body_id` (string, required): Body to finish
983
+ - `tool_id` (string, required): Finishing tool (ball mill or fine endmill)
984
+ - `step_down` (number, required): Vertical step in mm
985
+ - `step_over` (number, optional): Small horizontal spacing
986
+
987
+ **Returns:** 3D toolpath optimized for surface finish
988
+
989
+ ---
990
+
991
+ ### cam.export_gcode
992
+ **Generate CNC machine code**
993
+
994
+ **Parameters:**
995
+ - `toolpath_id` (string, required): Toolpath to export
996
+ - `post_processor` (string, required): "fanuc", "haas", "siemens", "mach3"
997
+ - `safe_z_height` (number, optional): Rapid traverse height in mm
998
+
999
+ **Returns:**
1000
+ ```json
1001
+ {
1002
+ "gcode_url": "https://...",
1003
+ "file_size_bytes": 125400,
1004
+ "lines": 8523,
1005
+ "estimated_time_minutes": 45.5
1006
+ }
1007
+ ```
1008
+
1009
+ ---
1010
+
1011
+ ## DRAWING NAMESPACE
1012
+
1013
+ Engineering drawing creation and annotation.
1014
+
1015
+ ### drawing.new_sheet
1016
+ **Create 2D drawing sheet**
1017
+
1018
+ **Parameters:**
1019
+ - `body_id` (string, required): Body to draw
1020
+ - `sheet_size` (string, optional): "A4", "A3", "Letter", "Ledger", default "A4"
1021
+ - `scale` (string, optional): "1:1", "1:2", "1:10", default "1:1"
1022
+
1023
+ **Returns:**
1024
+ ```json
1025
+ {
1026
+ "drawing_id": "dwg_001",
1027
+ "sheet_id": "sheet_001",
1028
+ "sheet_size": "A4",
1029
+ "scale": "1:1"
1030
+ }
1031
+ ```
1032
+
1033
+ ---
1034
+
1035
+ ### drawing.orthographic_view
1036
+ **Add orthographic projection to drawing**
1037
+
1038
+ **Parameters:**
1039
+ - `drawing_id` (string, required): Drawing to add to
1040
+ - `view_type` (string, required): "front", "top", "right", "left", "back", "bottom", "isometric"
1041
+ - `position` (object, required): {x, y} on sheet in mm
1042
+
1043
+ **Returns:**
1044
+ ```json
1045
+ {
1046
+ "view_id": "view_front_001",
1047
+ "type": "orthographic",
1048
+ "projection": "front",
1049
+ "position": [50, 100]
1050
+ }
1051
+ ```
1052
+
1053
+ ---
1054
+
1055
+ ### drawing.section_view
1056
+ **Add cross-section to drawing**
1057
+
1058
+ **Parameters:**
1059
+ - `drawing_id` (string, required): Drawing to add to
1060
+ - `cutting_plane` (object, required): {point: {x, y, z}, normal: {x, y, z}}
1061
+ - `position` (object, required): {x, y} on sheet
1062
+
1063
+ **Returns:** Section view with cross-section geometry
1064
+
1065
+ ---
1066
+
1067
+ ### drawing.dimension_auto
1068
+ **Automatically add dimensions from 3D constraints**
1069
+
1070
+ **Parameters:**
1071
+ - `view_id` (string, required): View to dimension
1072
+ - `placement` (string, optional): "inside", "outside", default "outside"
1073
+
1074
+ **Returns:**
1075
+ ```json
1076
+ {
1077
+ "dimensions_added": 15,
1078
+ "redundant_dimensions": 2,
1079
+ "notes": ["Consider removing redundant width dimensions"]
1080
+ }
1081
+ ```
1082
+
1083
+ ---
1084
+
1085
+ ### drawing.dimension_manual
1086
+ **Add custom dimension to view**
1087
+
1088
+ **Parameters:**
1089
+ - `view_id` (string, required): View to dimension
1090
+ - `element1_id` (string, required): First element (edge or point)
1091
+ - `element2_id` (string, optional): Second element (for distance)
1092
+ - `value` (string, optional): Dimension text (e.g., "50.00", "Ø25", "R10")
1093
+ - `position` (object, required): {x, y} on sheet
1094
+
1095
+ **Returns:** Dimension object with ID and properties
1096
+
1097
+ ---
1098
+
1099
+ ### drawing.gdt_add
1100
+ **Add geometric tolerance frame**
1101
+
1102
+ **Parameters:**
1103
+ - `view_id` (string, required): View to add GD&T to
1104
+ - `control_type` (string, required): "position", "flatness", "perpendicular", "runout", "profile", "angularity"
1105
+ - `tolerance_value` (number, required): Tolerance in mm
1106
+ - `primary_datum` (string, optional): Primary datum reference
1107
+ - `secondary_datum` (string, optional): Secondary datum
1108
+ - `tertiary_datum` (string, optional): Tertiary datum
1109
+ - `position` (object, required): {x, y} on sheet
1110
+
1111
+ **Returns:** GD&T control frame object
1112
+
1113
+ ---
1114
+
1115
+ ### drawing.export_pdf
1116
+ **Export drawing as PDF**
1117
+
1118
+ **Parameters:**
1119
+ - `drawing_id` (string, required): Drawing to export
1120
+ - `include_sheets` (array, optional): Sheet IDs (null = all)
1121
+
1122
+ **Returns:**
1123
+ ```json
1124
+ {
1125
+ "pdf_url": "https://...",
1126
+ "file_size_bytes": 250000,
1127
+ "pages": 1
1128
+ }
1129
+ ```
1130
+
1131
+ ---
1132
+
1133
+ ## DATA NAMESPACE
1134
+
1135
+ Version control, import/export, and collaboration.
1136
+
1137
+ ### data.save_version
1138
+ **Create design checkpoint**
1139
+
1140
+ **Parameters:**
1141
+ - `project_id` (string, required): Project to version
1142
+ - `version_name` (string, required): Version label ("v1.0", "prototype", "final")
1143
+ - `description` (string, optional): Change notes
1144
+
1145
+ **Returns:**
1146
+ ```json
1147
+ {
1148
+ "version_id": "v_001",
1149
+ "timestamp": "2024-03-26T10:30:00Z",
1150
+ "version_name": "v1.0",
1151
+ "size_mb": 2.5
1152
+ }
1153
+ ```
1154
+
1155
+ ---
1156
+
1157
+ ### data.restore_version
1158
+ **Revert to previous version**
1159
+
1160
+ **Parameters:**
1161
+ - `version_id` (string, required): Version to restore to
1162
+
1163
+ **Returns:**
1164
+ ```json
1165
+ {
1166
+ "status": "success",
1167
+ "timestamp": "2024-03-26T10:30:00Z",
1168
+ "note": "Design restored to v1.0"
1169
+ }
1170
+ ```
1171
+
1172
+ ---
1173
+
1174
+ ### data.import_step
1175
+ **Load STEP file**
1176
+
1177
+ **Parameters:**
1178
+ - `file_path` (string, required): Path to .STEP or .STP file
1179
+ - `action` (string, optional): "new_part", "add_to_assembly", default "new_part"
1180
+
1181
+ **Returns:**
1182
+ ```json
1183
+ {
1184
+ "part_id": "part_imported_001",
1185
+ "body_count": 3,
1186
+ "geometry": { "volume": 50000, "mass": 135 }
1187
+ }
1188
+ ```
1189
+
1190
+ ---
1191
+
1192
+ ### data.export_step
1193
+ **Save as STEP file**
1194
+
1195
+ **Parameters:**
1196
+ - `body_id` (string, required): Body to export
1197
+ - `file_path` (string, required): Output path
1198
+
1199
+ **Returns:**
1200
+ ```json
1201
+ {
1202
+ "file_url": "https://...",
1203
+ "file_size_bytes": 125000,
1204
+ "format": "STEP"
1205
+ }
1206
+ ```
1207
+
1208
+ ---
1209
+
1210
+ ### data.export_stl
1211
+ **Save as STL for 3D printing**
1212
+
1213
+ **Parameters:**
1214
+ - `body_id` (string, required): Body to export
1215
+ - `resolution` (string, optional): "coarse", "normal", "fine", default "normal"
1216
+ - `format` (string, optional): "ascii", "binary", default "binary"
1217
+
1218
+ **Returns:**
1219
+ ```json
1220
+ {
1221
+ "file_url": "https://...",
1222
+ "file_size_bytes": 250000,
1223
+ "triangles": 45000
1224
+ }
1225
+ ```
1226
+
1227
+ ---
1228
+
1229
+ ### data.export_dxf
1230
+ **Save 2D sketch as DXF**
1231
+
1232
+ **Parameters:**
1233
+ - `sketch_id` (string, required): Sketch to export
1234
+ - `scale` (string, optional): "1:1", "1:2", etc.
1235
+
1236
+ **Returns:**
1237
+ ```json
1238
+ {
1239
+ "file_url": "https://...",
1240
+ "format": "DXF",
1241
+ "layers": ["geometry", "dimensions", "text"]
1242
+ }
1243
+ ```
1244
+
1245
+ ---
1246
+
1247
+ ## ERROR HANDLING
1248
+
1249
+ ### Error Codes
1250
+
1251
+ | Code | HTTP Status | Meaning |
1252
+ |------|-------------|---------|
1253
+ | -32600 | 400 | Invalid Request |
1254
+ | -32601 | 404 | Method not found |
1255
+ | -32602 | 400 | Invalid parameters |
1256
+ | -32603 | 500 | Internal error |
1257
+ | -32000 | 400 | Server error (custom) |
1258
+ | -32001 | 409 | Conflict (e.g., body doesn't exist) |
1259
+ | -32002 | 422 | Validation failed |
1260
+
1261
+ ### Error Response Example
1262
+ ```json
1263
+ {
1264
+ "jsonrpc": "2.0",
1265
+ "error": {
1266
+ "code": -32602,
1267
+ "message": "Invalid parameter: diameter",
1268
+ "data": {
1269
+ "field": "diameter",
1270
+ "value": -10,
1271
+ "reason": "must be > 0"
1272
+ }
1273
+ },
1274
+ "id": 1
1275
+ }
1276
+ ```
1277
+
1278
+ ### Common Errors
1279
+
1280
+ **Invalid Body ID:**
1281
+ ```
1282
+ Error: Body 'body_999' not found
1283
+ Code: -32001
1284
+ ```
1285
+
1286
+ **Invalid Geometry:**
1287
+ ```
1288
+ Error: Self-intersecting geometry detected
1289
+ Code: -32002
1290
+ ```
1291
+
1292
+ **Operation Failed:**
1293
+ ```
1294
+ Error: Fillet failed - radius too large for geometry
1295
+ Code: -32000
1296
+ ```
1297
+
1298
+ ---
1299
+
1300
+ ## CODE EXAMPLES
1301
+
1302
+ ### Example 1: Create a Simple Box with Fillets
1303
+
1304
+ ```javascript
1305
+ const cyclecad = require('cyclecad-api');
1306
+
1307
+ async function createBox() {
1308
+ // Create sketch
1309
+ const sketch = await cyclecad.execute({
1310
+ method: "sketch.rectangle",
1311
+ params: { width: 100, height: 75 }
1312
+ });
1313
+
1314
+ // Extrude to 3D
1315
+ const extrude = await cyclecad.execute({
1316
+ method: "feature.extrude",
1317
+ params: {
1318
+ sketch_id: sketch.sketch_id,
1319
+ distance: 50
1320
+ }
1321
+ });
1322
+
1323
+ // Get edges for filleting
1324
+ const edges = extrude.geometry.edges.filter(e => e.position === "top");
1325
+
1326
+ // Add fillet
1327
+ const fillet = await cyclecad.execute({
1328
+ method: "feature.fillet",
1329
+ params: {
1330
+ body_id: extrude.body_id,
1331
+ edges: edges.map(e => e.id),
1332
+ radius: 5
1333
+ }
1334
+ });
1335
+
1336
+ return fillet;
1337
+ }
1338
+
1339
+ createBox().then(result => console.log(result));
1340
+ ```
1341
+
1342
+ ---
1343
+
1344
+ ### Example 2: Create Assembly with Moving Joint
1345
+
1346
+ ```javascript
1347
+ async function createMechanism() {
1348
+ // Insert base
1349
+ const base = await cyclecad.execute({
1350
+ method: "assembly.insert_component",
1351
+ params: {
1352
+ part_id: "base_plate",
1353
+ position: [0, 0, 0]
1354
+ }
1355
+ });
1356
+
1357
+ // Insert lever
1358
+ const lever = await cyclecad.execute({
1359
+ method: "assembly.insert_component",
1360
+ params: {
1361
+ part_id: "lever_arm",
1362
+ position: [50, 0, 20]
1363
+ }
1364
+ });
1365
+
1366
+ // Create hinge joint
1367
+ const joint = await cyclecad.execute({
1368
+ method: "assembly.joint_revolute",
1369
+ params: {
1370
+ component1_id: base.component_id,
1371
+ component2_id: lever.component_id,
1372
+ axis_id: "edge_hinge",
1373
+ angle_min: -90,
1374
+ angle_max: 90
1375
+ }
1376
+ });
1377
+
1378
+ return { base, lever, joint };
1379
+ }
1380
+ ```
1381
+
1382
+ ---
1383
+
1384
+ ### Example 3: Design Review and Export
1385
+
1386
+ ```javascript
1387
+ async function reviewAndExport() {
1388
+ const body_id = "body_001";
1389
+
1390
+ // Run design review
1391
+ const review = await cyclecad.execute({
1392
+ method: "validate.design_review",
1393
+ params: {
1394
+ body_id: body_id,
1395
+ checks: ["sharp_edges", "thin_walls", "undercuts", "stress", "cost"]
1396
+ }
1397
+ });
1398
+
1399
+ console.log(`Design Score: ${review.score}`);
1400
+ console.log(`Issues: ${review.analysis.sharp_edges.count} sharp edges`);
1401
+
1402
+ // If issues found, show recommendations
1403
+ if (review.recommendations.length > 0) {
1404
+ console.log("Recommendations:");
1405
+ review.recommendations.forEach(r => console.log("- " + r));
1406
+ }
1407
+
1408
+ // Export to STEP for manufacturing
1409
+ const step = await cyclecad.execute({
1410
+ method: "data.export_step",
1411
+ params: {
1412
+ body_id: body_id,
1413
+ file_path: "/exports/final_design.stp"
1414
+ }
1415
+ });
1416
+
1417
+ return { review, step };
1418
+ }
1419
+ ```
1420
+
1421
+ ---
1422
+
1423
+ End of API Reference