cyclecad 0.2.2 → 0.3.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 (85) hide show
  1. package/API-BUILD-MANIFEST.txt +339 -0
  2. package/API-SERVER.md +535 -0
  3. package/Architecture-Deck.pptx +0 -0
  4. package/CLAUDE.md +172 -11
  5. package/CLI-BUILD-SUMMARY.md +504 -0
  6. package/CLI-INDEX.md +356 -0
  7. package/CLI-README.md +466 -0
  8. package/COLLABORATION-INTEGRATION-GUIDE.md +325 -0
  9. package/CONNECTED_FABS_GUIDE.md +612 -0
  10. package/CONNECTED_FABS_README.md +310 -0
  11. package/DELIVERABLES.md +343 -0
  12. package/DFM-ANALYZER-INTEGRATION.md +368 -0
  13. package/DFM-QUICK-START.js +253 -0
  14. package/Dockerfile +69 -0
  15. package/IMPLEMENTATION.md +327 -0
  16. package/LICENSE +31 -0
  17. package/MARKETPLACE_QUICK_REFERENCE.txt +294 -0
  18. package/MCP-INDEX.md +264 -0
  19. package/QUICKSTART-API.md +388 -0
  20. package/QUICKSTART-CLI.md +211 -0
  21. package/QUICKSTART-MCP.md +196 -0
  22. package/README-MCP.md +208 -0
  23. package/TEST-TOKEN-ENGINE.md +319 -0
  24. package/TOKEN-ENGINE-SUMMARY.md +266 -0
  25. package/TOKENS-README.md +263 -0
  26. package/TOOLS-REFERENCE.md +254 -0
  27. package/app/index.html +373 -3
  28. package/app/js/TOKEN-INTEGRATION.md +391 -0
  29. package/app/js/agent-api.js +3 -3
  30. package/app/js/ai-copilot.js +1435 -0
  31. package/app/js/cad-vr.js +917 -0
  32. package/app/js/cam-operations.js +638 -0
  33. package/app/js/cam-pipeline.js +840 -0
  34. package/app/js/collaboration-ui.js +995 -0
  35. package/app/js/collaboration.js +1116 -0
  36. package/app/js/connected-fabs-example.js +404 -0
  37. package/app/js/connected-fabs.js +1449 -0
  38. package/app/js/dfm-analyzer.js +1760 -0
  39. package/app/js/gcode-generator.js +485 -0
  40. package/app/js/gdt-training.js +1144 -0
  41. package/app/js/machine-profiles.js +534 -0
  42. package/app/js/marketplace-v2.js +766 -0
  43. package/app/js/marketplace.js +1994 -0
  44. package/app/js/material-library.js +2115 -0
  45. package/app/js/misumi-catalog.js +904 -0
  46. package/app/js/section-view.js +666 -0
  47. package/app/js/sketch-enhance.js +779 -0
  48. package/app/js/stock-manager.js +482 -0
  49. package/app/js/text-to-cad.js +806 -0
  50. package/app/js/token-dashboard.js +563 -0
  51. package/app/js/token-engine.js +743 -0
  52. package/app/js/tool-library.js +593 -0
  53. package/app/test-agent.html +1801 -0
  54. package/app/tutorials/advanced.html +1924 -0
  55. package/app/tutorials/basic.html +1160 -0
  56. package/app/tutorials/intermediate.html +1456 -0
  57. package/bin/cyclecad-cli.js +662 -0
  58. package/bin/cyclecad-mcp +2 -0
  59. package/bin/server.js +242 -0
  60. package/cycleCAD-Architecture.pptx +0 -0
  61. package/cycleCAD-Investor-Deck.pptx +0 -0
  62. package/demo-mcp.sh +60 -0
  63. package/docs/API-SERVER-SUMMARY.md +375 -0
  64. package/docs/API-SERVER.md +667 -0
  65. package/docs/CAM-EXAMPLES.md +344 -0
  66. package/docs/CAM-INTEGRATION.md +612 -0
  67. package/docs/CAM-QUICK-REFERENCE.md +199 -0
  68. package/docs/CLI-INTEGRATION.md +510 -0
  69. package/docs/CLI.md +872 -0
  70. package/docs/MARKETPLACE-API-SCHEMA.json +564 -0
  71. package/docs/MARKETPLACE-INTEGRATION.md +467 -0
  72. package/docs/MARKETPLACE-SETUP.html +439 -0
  73. package/docs/MCP-SERVER.md +403 -0
  74. package/examples/api-client-example.js +488 -0
  75. package/examples/api-client-example.py +359 -0
  76. package/examples/batch-manufacturing.txt +28 -0
  77. package/examples/batch-simple.txt +26 -0
  78. package/linkedin-post-combined.md +31 -0
  79. package/model-marketplace.html +1273 -0
  80. package/package.json +14 -3
  81. package/server/api-server.js +1120 -0
  82. package/server/mcp-server.js +1161 -0
  83. package/test-api-server.js +432 -0
  84. package/test-mcp.js +198 -0
  85. package/~$cycleCAD-Investor-Deck.pptx +0 -0
@@ -0,0 +1,1924 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>cycleCAD Advanced Tutorial</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
10
+ <style>
11
+ * {
12
+ margin: 0;
13
+ padding: 0;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ body {
18
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
19
+ background-color: #1e1e1e;
20
+ color: #e0e0e0;
21
+ line-height: 1.6;
22
+ font-size: 14px;
23
+ }
24
+
25
+ /* Header & Navigation */
26
+ .top-nav {
27
+ position: sticky;
28
+ top: 0;
29
+ z-index: 1000;
30
+ background-color: #252525;
31
+ border-bottom: 1px solid #404040;
32
+ padding: 12px 24px;
33
+ display: flex;
34
+ justify-content: space-between;
35
+ align-items: center;
36
+ }
37
+
38
+ .nav-left a {
39
+ color: #58a6ff;
40
+ text-decoration: none;
41
+ font-size: 13px;
42
+ font-weight: 500;
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 8px;
46
+ }
47
+
48
+ .nav-left a:hover {
49
+ color: #79c0ff;
50
+ }
51
+
52
+ .nav-tabs {
53
+ display: flex;
54
+ gap: 20px;
55
+ }
56
+
57
+ .nav-tabs a {
58
+ color: #a0a0a0;
59
+ text-decoration: none;
60
+ font-size: 13px;
61
+ font-weight: 500;
62
+ padding: 6px 0;
63
+ border-bottom: 2px solid transparent;
64
+ transition: all 0.2s;
65
+ }
66
+
67
+ .nav-tabs a:hover {
68
+ color: #e0e0e0;
69
+ }
70
+
71
+ .nav-tabs a.active {
72
+ color: #58a6ff;
73
+ border-bottom-color: #58a6ff;
74
+ }
75
+
76
+ /* Main Layout */
77
+ .container {
78
+ display: flex;
79
+ max-width: 1600px;
80
+ margin: 0 auto;
81
+ min-height: calc(100vh - 53px);
82
+ }
83
+
84
+ .sidebar {
85
+ width: 280px;
86
+ background-color: #252525;
87
+ border-right: 1px solid #404040;
88
+ padding: 20px;
89
+ overflow-y: auto;
90
+ max-height: calc(100vh - 53px);
91
+ position: sticky;
92
+ top: 53px;
93
+ }
94
+
95
+ .sidebar h3 {
96
+ font-size: 11px;
97
+ font-weight: 700;
98
+ text-transform: uppercase;
99
+ color: #808080;
100
+ margin-top: 16px;
101
+ margin-bottom: 10px;
102
+ letter-spacing: 0.5px;
103
+ }
104
+
105
+ .sidebar h3:first-child {
106
+ margin-top: 0;
107
+ }
108
+
109
+ .sidebar-item {
110
+ padding: 8px 12px;
111
+ margin: 4px 0;
112
+ border-radius: 4px;
113
+ font-size: 13px;
114
+ cursor: pointer;
115
+ transition: all 0.2s;
116
+ color: #a0a0a0;
117
+ }
118
+
119
+ .sidebar-item:hover {
120
+ background-color: #2d2d2d;
121
+ color: #e0e0e0;
122
+ }
123
+
124
+ .sidebar-item.active {
125
+ background-color: #58a6ff;
126
+ color: #1e1e1e;
127
+ font-weight: 600;
128
+ }
129
+
130
+ .progress-bar {
131
+ margin-top: 20px;
132
+ padding-top: 20px;
133
+ border-top: 1px solid #404040;
134
+ }
135
+
136
+ .progress-bar-label {
137
+ font-size: 11px;
138
+ font-weight: 700;
139
+ text-transform: uppercase;
140
+ color: #808080;
141
+ margin-bottom: 8px;
142
+ letter-spacing: 0.5px;
143
+ }
144
+
145
+ .progress-bar-fill {
146
+ height: 4px;
147
+ background-color: #404040;
148
+ border-radius: 2px;
149
+ overflow: hidden;
150
+ }
151
+
152
+ .progress-bar-fill-inner {
153
+ height: 100%;
154
+ background-color: #58a6ff;
155
+ transition: width 0.3s ease;
156
+ }
157
+
158
+ /* Main Content */
159
+ .content {
160
+ flex: 1;
161
+ padding: 40px 60px;
162
+ overflow-y: auto;
163
+ max-height: calc(100vh - 53px);
164
+ }
165
+
166
+ .section {
167
+ margin-bottom: 60px;
168
+ display: none;
169
+ }
170
+
171
+ .section.active {
172
+ display: block;
173
+ }
174
+
175
+ h1 {
176
+ font-size: 32px;
177
+ font-weight: 700;
178
+ margin-bottom: 12px;
179
+ color: #ffffff;
180
+ }
181
+
182
+ h2 {
183
+ font-size: 24px;
184
+ font-weight: 700;
185
+ margin-top: 40px;
186
+ margin-bottom: 16px;
187
+ color: #e0e0e0;
188
+ border-bottom: 2px solid #58a6ff;
189
+ padding-bottom: 8px;
190
+ }
191
+
192
+ h3 {
193
+ font-size: 16px;
194
+ font-weight: 600;
195
+ margin-top: 24px;
196
+ margin-bottom: 12px;
197
+ color: #e0e0e0;
198
+ }
199
+
200
+ p {
201
+ margin-bottom: 12px;
202
+ color: #c8c8c8;
203
+ }
204
+
205
+ a {
206
+ color: #58a6ff;
207
+ text-decoration: none;
208
+ }
209
+
210
+ a:hover {
211
+ text-decoration: underline;
212
+ }
213
+
214
+ /* Code Blocks */
215
+ pre {
216
+ background-color: #0d1117;
217
+ border: 1px solid #30363d;
218
+ border-radius: 6px;
219
+ padding: 16px;
220
+ overflow-x: auto;
221
+ margin: 16px 0;
222
+ font-size: 12px;
223
+ line-height: 1.5;
224
+ }
225
+
226
+ code {
227
+ font-family: 'Courier New', monospace;
228
+ color: #79c0ff;
229
+ }
230
+
231
+ pre code {
232
+ color: inherit;
233
+ }
234
+
235
+ /* Syntax highlighting */
236
+ .kw { color: #ff7b72; } /* Keywords */
237
+ .str { color: #a5d6ff; } /* Strings */
238
+ .num { color: #79c0ff; } /* Numbers */
239
+ .fn { color: #d2a8ff; } /* Functions */
240
+ .obj { color: #ffa657; } /* Objects */
241
+ .com { color: #8b949e; } /* Comments */
242
+
243
+ /* Tables */
244
+ table {
245
+ width: 100%;
246
+ border-collapse: collapse;
247
+ margin: 16px 0;
248
+ background-color: #0d1117;
249
+ border: 1px solid #30363d;
250
+ border-radius: 6px;
251
+ overflow: hidden;
252
+ }
253
+
254
+ th {
255
+ background-color: #161b22;
256
+ border-bottom: 1px solid #30363d;
257
+ padding: 12px;
258
+ text-align: left;
259
+ font-weight: 600;
260
+ color: #79c0ff;
261
+ font-size: 12px;
262
+ }
263
+
264
+ td {
265
+ padding: 12px;
266
+ border-bottom: 1px solid #30363d;
267
+ font-size: 13px;
268
+ }
269
+
270
+ tr:last-child td {
271
+ border-bottom: none;
272
+ }
273
+
274
+ /* Info Boxes */
275
+ .info-box {
276
+ border-radius: 6px;
277
+ padding: 12px 16px;
278
+ margin: 16px 0;
279
+ border-left: 4px solid;
280
+ font-size: 13px;
281
+ line-height: 1.5;
282
+ }
283
+
284
+ .pro-tip {
285
+ background-color: rgba(40, 167, 69, 0.1);
286
+ border-left-color: #28a745;
287
+ color: #d4f1d4;
288
+ }
289
+
290
+ .pro-tip strong {
291
+ color: #58ff66;
292
+ }
293
+
294
+ .warning {
295
+ background-color: rgba(255, 193, 7, 0.1);
296
+ border-left-color: #ffc107;
297
+ color: #fff9e6;
298
+ }
299
+
300
+ .warning strong {
301
+ color: #ffd700;
302
+ }
303
+
304
+ .advanced-note {
305
+ background-color: rgba(156, 39, 176, 0.1);
306
+ border-left-color: #9c27b0;
307
+ color: #e8d5f2;
308
+ }
309
+
310
+ .advanced-note strong {
311
+ color: #d487ff;
312
+ }
313
+
314
+ /* Lists */
315
+ ul, ol {
316
+ margin: 16px 0 16px 24px;
317
+ }
318
+
319
+ li {
320
+ margin-bottom: 8px;
321
+ color: #c8c8c8;
322
+ }
323
+
324
+ /* Diagrams */
325
+ .diagram {
326
+ background-color: #0d1117;
327
+ border: 1px solid #30363d;
328
+ border-radius: 6px;
329
+ padding: 16px;
330
+ margin: 16px 0;
331
+ font-family: 'Courier New', monospace;
332
+ font-size: 12px;
333
+ line-height: 1.4;
334
+ color: #79c0ff;
335
+ white-space: pre;
336
+ overflow-x: auto;
337
+ }
338
+
339
+ /* Footer */
340
+ .footer {
341
+ margin-top: 80px;
342
+ padding-top: 24px;
343
+ border-top: 1px solid #404040;
344
+ color: #808080;
345
+ font-size: 12px;
346
+ text-align: center;
347
+ }
348
+
349
+ /* Responsive */
350
+ @media (max-width: 1024px) {
351
+ .container {
352
+ flex-direction: column;
353
+ }
354
+
355
+ .sidebar {
356
+ width: 100%;
357
+ position: static;
358
+ max-height: none;
359
+ border-right: none;
360
+ border-bottom: 1px solid #404040;
361
+ display: flex;
362
+ gap: 20px;
363
+ padding: 16px;
364
+ overflow-y: visible;
365
+ flex-wrap: wrap;
366
+ }
367
+
368
+ .sidebar h3 {
369
+ flex-basis: 100%;
370
+ }
371
+
372
+ .content {
373
+ padding: 30px 40px;
374
+ }
375
+ }
376
+ </style>
377
+ </head>
378
+ <body>
379
+ <!-- Top Navigation -->
380
+ <div class="top-nav">
381
+ <div class="nav-left">
382
+ <a href="../index.html">← Back to App</a>
383
+ </div>
384
+ <div class="nav-tabs">
385
+ <a href="basic.html">Basic</a>
386
+ <a href="intermediate.html">Intermediate</a>
387
+ <a href="advanced.html" class="active">Advanced</a>
388
+ </div>
389
+ </div>
390
+
391
+ <div class="container">
392
+ <!-- Sidebar -->
393
+ <aside class="sidebar">
394
+ <h3>Sections</h3>
395
+ <div class="sidebar-item active" data-section="intro">Introduction</div>
396
+ <div class="sidebar-item" data-section="agent-api">Agent API</div>
397
+ <div class="sidebar-item" data-section="mcp">MCP Server</div>
398
+ <div class="sidebar-item" data-section="rest">REST API</div>
399
+ <div class="sidebar-item" data-section="cli">CLI Tool</div>
400
+ <div class="sidebar-item" data-section="tokens">Token Engine</div>
401
+ <div class="sidebar-item" data-section="marketplace">Marketplace</div>
402
+ <div class="sidebar-item" data-section="fabs">Connected Fabs</div>
403
+ <div class="sidebar-item" data-section="agents">Multi-Agent</div>
404
+ <div class="sidebar-item" data-section="machines">Machine Profiles</div>
405
+ <div class="sidebar-item" data-section="collab">Collaboration</div>
406
+ <div class="sidebar-item" data-section="perf">Performance</div>
407
+ <div class="sidebar-item" data-section="docker">Docker</div>
408
+ <div class="sidebar-item" data-section="plugins">Plugins</div>
409
+ <div class="sidebar-item" data-section="contrib">Contributing</div>
410
+
411
+ <div class="progress-bar">
412
+ <div class="progress-bar-label">Progress</div>
413
+ <div class="progress-bar-fill">
414
+ <div class="progress-bar-fill-inner" id="progressFill"></div>
415
+ </div>
416
+ </div>
417
+ </aside>
418
+
419
+ <!-- Main Content -->
420
+ <main class="content">
421
+
422
+ <!-- Section: Introduction -->
423
+ <section id="intro" class="section active">
424
+ <h1>Advanced cycleCAD Tutorial</h1>
425
+ <p>Master agent-first CAD automation, enterprise integration, and next-generation manufacturing workflows.</p>
426
+
427
+ <h2>Prerequisites</h2>
428
+ <p>This advanced tutorial assumes you have:</p>
429
+ <ul>
430
+ <li>Completed the Basic and Intermediate tutorials</li>
431
+ <li>Familiarity with JavaScript, JSON, and REST APIs</li>
432
+ <li>Understanding of parametric CAD concepts (sketches, features, assemblies)</li>
433
+ <li>Experience with CLI tools and command-line interfaces</li>
434
+ <li>Familiarity with Docker or containerization concepts (optional)</li>
435
+ </ul>
436
+
437
+ <h2>What You'll Master</h2>
438
+ <ul>
439
+ <li><strong>Agent API:</strong> 55 commands across 10 namespaces for programmatic CAD</li>
440
+ <li><strong>MCP Server:</strong> Connect external AI agents and tools</li>
441
+ <li><strong>REST API:</strong> HTTP/WebSocket integration for cloud systems</li>
442
+ <li><strong>CLI Tool:</strong> Command-line CAD automation and scripting</li>
443
+ <li><strong>$CYCLE Token Engine:</strong> Per-operation billing and ledger management</li>
444
+ <li><strong>Model Marketplace:</strong> Publishing, distributing, and monetizing designs</li>
445
+ <li><strong>Connected Fabs:</strong> CAD→CAM→Manufacturing pipeline with fab networks</li>
446
+ <li><strong>Multi-Agent Workflows:</strong> Cooperative design with agent swarms</li>
447
+ <li><strong>Docker Deployment:</strong> 3-service architecture for enterprise</li>
448
+ </ul>
449
+
450
+ <div class="pro-tip">
451
+ <strong>Pro Tip:</strong> cycleCAD is "Agent-First" — designed for AI agents before humans. All features are accessible via the Agent API, making it naturally extensible.
452
+ </div>
453
+ </section>
454
+
455
+ <!-- Section: Agent API -->
456
+ <section id="agent-api" class="section">
457
+ <h1>Agent API Deep Dive</h1>
458
+
459
+ <h2>Architecture</h2>
460
+ <p>The Agent API exposes all cycleCAD functionality as a JSON-RPC style interface. Any external system (AI agent, web app, CLI tool, or MCP server) communicates with cycleCAD via <code>window.cycleCAD.execute()</code>.</p>
461
+
462
+ <h3>Basic Usage</h3>
463
+ <pre><code><span class="com">// All Agent API calls follow this pattern:</span>
464
+ <span class="kw">const</span> result = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">execute</span>({
465
+ method: <span class="str">'shape.cylinder'</span>,
466
+ params: {
467
+ radius: <span class="num">25</span>,
468
+ height: <span class="num">80</span>,
469
+ centered: <span class="kw">true</span>
470
+ }
471
+ });
472
+
473
+ console.<span class="fn">log</span>(result); <span class="com">// { id: 'shape_0', success: true, ... }</span></code></pre>
474
+
475
+ <h2>10 Namespaces (55 Commands)</h2>
476
+
477
+ <table>
478
+ <tr>
479
+ <th>Namespace</th>
480
+ <th>Commands</th>
481
+ <th>Purpose</th>
482
+ </tr>
483
+ <tr>
484
+ <td><code>shape.*</code></td>
485
+ <td>12 commands</td>
486
+ <td>Create geometry: cylinder, box, sphere, cone, torus, wedge, tube, plate, disk, ring, hexbolt, washer</td>
487
+ </tr>
488
+ <tr>
489
+ <td><code>feature.*</code></td>
490
+ <td>10 commands</td>
491
+ <td>Edit geometry: extrude, revolve, fillet, chamfer, boolean, shell, pattern, mirror, sweep, loft</td>
492
+ </tr>
493
+ <tr>
494
+ <td><code>assembly.*</code></td>
495
+ <td>8 commands</td>
496
+ <td>Manage components: add, remove, position, explode, constraint, mate, joint, query</td>
497
+ </tr>
498
+ <tr>
499
+ <td><code>render.*</code></td>
500
+ <td>6 commands</td>
501
+ <td>Viewport control: snapshot, multiview, fitToSelection, setView, toggleGrid, toggleWireframe</td>
502
+ </tr>
503
+ <tr>
504
+ <td><code>validate.*</code></td>
505
+ <td>5 commands</td>
506
+ <td>Design review: dfm (Design For Manufacturing), weight, cost, clearance, summary</td>
507
+ </tr>
508
+ <tr>
509
+ <td><code>export.*</code></td>
510
+ <td>4 commands</td>
511
+ <td>Output formats: stl, obj, gltf, json</td>
512
+ </tr>
513
+ <tr>
514
+ <td><code>scene.*</code></td>
515
+ <td>4 commands</td>
516
+ <td>Scene management: clear, undo, redo, getState</td>
517
+ </tr>
518
+ <tr>
519
+ <td><code>material.*</code></td>
520
+ <td>2 commands</td>
521
+ <td>Material assignment: list, apply</td>
522
+ </tr>
523
+ <tr>
524
+ <td><code>annotation.*</code></td>
525
+ <td>2 commands</td>
526
+ <td>Markup: pin, note</td>
527
+ </tr>
528
+ <tr>
529
+ <td><code>query.*</code></td>
530
+ <td>2 commands</td>
531
+ <td>Data retrieval: edges, faces</td>
532
+ </tr>
533
+ </table>
534
+
535
+ <h3>Self-Describing Schema</h3>
536
+ <p>Query the API to understand what commands are available and what parameters they accept:</p>
537
+
538
+ <pre><code><span class="com">// Get schema for all commands</span>
539
+ <span class="kw">const</span> schema = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">getSchema</span>();
540
+
541
+ <span class="com">// Returns:</span>
542
+ {
543
+ shape: {
544
+ cylinder: {
545
+ description: <span class="str">'Create a cylinder'</span>,
546
+ params: {
547
+ radius: { type: <span class="str">'number'</span>, required: <span class="kw">true</span> },
548
+ height: { type: <span class="str">'number'</span>, required: <span class="kw">true</span> },
549
+ centered: { type: <span class="str">'boolean'</span>, default: <span class="kw">false</span> }
550
+ }
551
+ },
552
+ ...
553
+ }
554
+ }</code></pre>
555
+
556
+ <h3>Example: Agent-Driven Design</h3>
557
+ <pre><code><span class="com">// AI agent creates a motor mount bracket step-by-step</span>
558
+ <span class="kw">async function</span> <span class="fn">createMotorBracket</span>() {
559
+ <span class="kw">const</span> api = <span class="obj">window</span>.cycleCAD;
560
+
561
+ <span class="com">// 1. Create base plate</span>
562
+ <span class="kw">let</span> base = <span class="kw">await</span> api.<span class="fn">execute</span>({
563
+ method: <span class="str">'shape.box'</span>,
564
+ params: { width: <span class="num">100</span>, height: <span class="num">80</span>, depth: <span class="num">10</span> }
565
+ });
566
+
567
+ <span class="com">// 2. Add mounting holes</span>
568
+ <span class="kw">await</span> api.<span class="fn">execute</span>({
569
+ method: <span class="str">'feature.pattern'</span>,
570
+ params: {
571
+ type: <span class="str">'rectangular'</span>,
572
+ rows: <span class="num">2</span>,
573
+ cols: <span class="num">2</span>,
574
+ spacing: <span class="num">40</span>
575
+ }
576
+ });
577
+
578
+ <span class="com">// 3. Fillet edges</span>
579
+ <span class="kw">await</span> api.<span class="fn">execute</span>({
580
+ method: <span class="str">'feature.fillet'</span>,
581
+ params: { radius: <span class="num">2</span> }
582
+ });
583
+
584
+ <span class="com">// 4. Validate design</span>
585
+ <span class="kw">const</span> review = <span class="kw">await</span> api.<span class="fn">execute</span>({
586
+ method: <span class="str">'validate.dfm'</span>,
587
+ params: {}
588
+ });
589
+
590
+ <span class="kw">return</span> review;
591
+ }</code></pre>
592
+
593
+ <div class="advanced-note">
594
+ <strong>Advanced:</strong> The Agent API is transport-agnostic. In-browser it uses direct function calls. Over MCP it uses stdio JSON-RPC. Over REST it uses HTTP. The command semantics remain identical.
595
+ </div>
596
+ </section>
597
+
598
+ <!-- Section: MCP Server -->
599
+ <section id="mcp" class="section">
600
+ <h1>MCP Server Integration</h1>
601
+
602
+ <h2>What is MCP?</h2>
603
+ <p>Model Context Protocol (MCP) is a standard for AI agents to discover and call tools. cycleCAD exposes all 55 Agent API commands as MCP tools, allowing Claude, other LLMs, and specialized agents to control CAD directly.</p>
604
+
605
+ <h2>Starting the MCP Server</h2>
606
+
607
+ <pre><code><span class="com">// From command line:</span>
608
+ npx cyclecad-mcp --port <span class="num">3000</span>
609
+
610
+ <span class="com">// Or via Node.js:</span>
611
+ <span class="kw">const</span> mcpServer = <span class="fn">require</span>(<span class="str">'cyclecad/server/mcp-server'</span>);
612
+ <span class="kw">await</span> mcpServer.<span class="fn">start</span>({ port: <span class="num">3000</span> });
613
+
614
+ console.<span class="fn">log</span>(<span class="str">'MCP Server running on :3000'</span>);</code></pre>
615
+
616
+ <h2>Connecting an AI Agent</h2>
617
+ <p>Claude and other AI systems can now discover cycleCAD tools via MCP:</p>
618
+
619
+ <pre><code><span class="com">// In your Claude/Agent context:</span>
620
+ <span class="str">"You have access to the cycleCAD CAD engine via MCP tools."</span>
621
+
622
+ cycleCAD tools available:
623
+ - <span class="str">shape_cylinder</span> — Create a cylinder (radius, height, centered)
624
+ - <span class="str">shape_box</span> — Create a box (width, height, depth)
625
+ - <span class="str">feature_fillet</span> — Fillet edges (radius)
626
+ - <span class="str">validate_dfm</span> — Design for Manufacturing analysis
627
+ - ... (55 tools total)
628
+
629
+ <span class="com">// Agent usage:</span>
630
+ <span class="str">"Create a 50mm diameter, 80mm tall cylinder, then add a 5mm fillet"</span>
631
+
632
+ <span class="com">// Claude calls:</span>
633
+ 1. shape_cylinder { radius: <span class="num">25</span>, height: <span class="num">80</span> }
634
+ 2. feature_fillet { radius: <span class="num">5</span> }</code></pre>
635
+
636
+ <h2>Transport Options</h2>
637
+ <table>
638
+ <tr>
639
+ <th>Transport</th>
640
+ <th>Use Case</th>
641
+ <th>Example</th>
642
+ </tr>
643
+ <tr>
644
+ <td>stdio (default)</td>
645
+ <td>Local agents, Claude, easy integration</td>
646
+ <td><code>npx cyclecad-mcp</code></td>
647
+ </tr>
648
+ <tr>
649
+ <td>WebSocket</td>
650
+ <td>Browser agents, real-time collaboration</td>
651
+ <td><code>ws://localhost:3000</code></td>
652
+ </tr>
653
+ <tr>
654
+ <td>HTTP (request/response)</td>
655
+ <td>Stateless cloud functions, Lambda</td>
656
+ <td><code>POST /tool/{toolName}</code></td>
657
+ </tr>
658
+ </table>
659
+
660
+ <div class="pro-tip">
661
+ <strong>Pro Tip:</strong> Use stdio transport with Claude for the smoothest integration. Claude automatically calls tools and processes results.
662
+ </div>
663
+
664
+ <h2>Tool Manifest Format</h2>
665
+ <pre><code>{
666
+ <span class="str">"tools"</span>: [
667
+ {
668
+ <span class="str">"name"</span>: <span class="str">"shape_cylinder"</span>,
669
+ <span class="str">"description"</span>: <span class="str">"Create a cylinder with given radius and height"</span>,
670
+ <span class="str">"inputSchema"</span>: {
671
+ <span class="str">"type"</span>: <span class="str">"object"</span>,
672
+ <span class="str">"properties"</span>: {
673
+ <span class="str">"radius"</span>: { <span class="str">"type"</span>: <span class="str">"number"</span> },
674
+ <span class="str">"height"</span>: { <span class="str">"type"</span>: <span class="str">"number"</span> },
675
+ <span class="str">"centered"</span>: { <span class="str">"type"</span>: <span class="str">"boolean"</span> }
676
+ },
677
+ <span class="str">"required"</span>: [<span class="str">"radius"</span>, <span class="str">"height"</span>]
678
+ }
679
+ },
680
+ ...
681
+ ]
682
+ }</code></pre>
683
+ </section>
684
+
685
+ <!-- Section: REST API -->
686
+ <section id="rest" class="section">
687
+ <h1>REST API & WebSocket</h1>
688
+
689
+ <h2>Overview</h2>
690
+ <p>The REST API provides HTTP endpoints for cloud-based CAD operations. All endpoints accept JSON and return JSON.</p>
691
+
692
+ <h2>Core Endpoints</h2>
693
+ <table>
694
+ <tr>
695
+ <th>Endpoint</th>
696
+ <th>Method</th>
697
+ <th>Purpose</th>
698
+ </tr>
699
+ <tr>
700
+ <td><code>/api/v1/execute</code></td>
701
+ <td>POST</td>
702
+ <td>Execute any Agent API command</td>
703
+ </tr>
704
+ <tr>
705
+ <td><code>/api/v1/schema</code></td>
706
+ <td>GET</td>
707
+ <td>Get schema for all commands</td>
708
+ </tr>
709
+ <tr>
710
+ <td><code>/api/v1/models</code></td>
711
+ <td>GET</td>
712
+ <td>List saved models</td>
713
+ </tr>
714
+ <tr>
715
+ <td><code>/api/v1/models/{id}</code></td>
716
+ <td>GET</td>
717
+ <td>Get model state/geometry</td>
718
+ </tr>
719
+ <tr>
720
+ <td><code>/api/v1/models/{id}/export</code></td>
721
+ <td>POST</td>
722
+ <td>Export to STL/OBJ/GLTF</td>
723
+ </tr>
724
+ <tr>
725
+ <td><code>/api/v1/token/balance</code></td>
726
+ <td>GET</td>
727
+ <td>Get account token balance</td>
728
+ </tr>
729
+ <tr>
730
+ <td><code>/api/v1/token/spend</code></td>
731
+ <td>POST</td>
732
+ <td>Record token spend</td>
733
+ </tr>
734
+ <tr>
735
+ <td><code>/ws/live</code></td>
736
+ <td>WebSocket</td>
737
+ <td>Real-time events and collaboration</td>
738
+ </tr>
739
+ </table>
740
+
741
+ <h3>Example: Execute via REST</h3>
742
+ <pre><code><span class="com">// POST /api/v1/execute</span>
743
+ curl -X POST http://localhost:<span class="num">3000</span>/api/v1/execute \
744
+ -H <span class="str">'Content-Type: application/json'</span> \
745
+ -d <span class="str">'{
746
+ "method": "shape.cylinder",
747
+ "params": {
748
+ "radius": 25,
749
+ "height": 80
750
+ }
751
+ }'</span>
752
+
753
+ <span class="com">// Response:</span>
754
+ {
755
+ <span class="str">"success"</span>: <span class="kw">true</span>,
756
+ <span class="str">"id"</span>: <span class="str">"shape_0"</span>,
757
+ <span class="str">"bbox"</span>: { <span class="str">"min"</span>: [...], <span class="str">"max"</span>: [...] },
758
+ <span class="str">"tokensUsed"</span>: <span class="num">150</span>
759
+ }</code></pre>
760
+
761
+ <h2>WebSocket Real-Time Events</h2>
762
+ <pre><code><span class="com">// Connect to WebSocket</span>
763
+ <span class="kw">const</span> ws = <span class="kw">new</span> <span class="fn">WebSocket</span>(<span class="str">'ws://localhost:3000/ws/live'</span>);
764
+
765
+ ws.<span class="fn">onmessage</span> = (event) => {
766
+ <span class="kw">const</span> msg = <span class="fn">JSON</span>.<span class="fn">parse</span>(event.data);
767
+
768
+ <span class="kw">switch</span> (msg.type) {
769
+ <span class="kw">case</span> <span class="str">'operation_complete'</span>:
770
+ console.<span class="fn">log</span>(<span class="str">'Operation done:'</span>, msg.operation);
771
+ <span class="kw">break</span>;
772
+ <span class="kw">case</span> <span class="str">'user_joined'</span>:
773
+ console.<span class="fn">log</span>(<span class="str">'Collab user:'</span>, msg.user);
774
+ <span class="kw">break</span>;
775
+ }
776
+ };</code></pre>
777
+
778
+ <h2>Rate Limiting & CORS</h2>
779
+ <p>Configure rate limits and CORS in your deployment:</p>
780
+
781
+ <pre><code><span class="com">// config.json</span>
782
+ {
783
+ <span class="str">"rateLimit"</span>: {
784
+ <span class="str">"windowMs"</span>: <span class="num">60000</span>, <span class="com">// 1 minute</span>
785
+ <span class="str">"maxRequests"</span>: <span class="num">100</span> <span class="com">// 100 req/min per IP</span>
786
+ },
787
+ <span class="str">"cors"</span>: {
788
+ <span class="str">"origin"</span>: [<span class="str">"https://yourapp.com"</span>],
789
+ <span class="str">"credentials"</span>: <span class="kw">true</span>
790
+ }
791
+ }</code></pre>
792
+
793
+ <div class="warning">
794
+ <strong>Warning:</strong> Always validate API keys in production. Use JWT tokens with short expiration times.
795
+ </div>
796
+ </section>
797
+
798
+ <!-- Section: CLI Tool -->
799
+ <section id="cli" class="section">
800
+ <h1>CLI Tool</h1>
801
+
802
+ <h2>Installation & Usage</h2>
803
+
804
+ <pre><code><span class="com">// Global install</span>
805
+ npm install -g cyclecad
806
+
807
+ <span class="com">// Interactive REPL</span>
808
+ cyclecad
809
+
810
+ <span class="com">// Batch command</span>
811
+ cyclecad shape.cylinder --radius <span class="num">25</span> --height <span class="num">80</span>
812
+
813
+ <span class="com">// Execute script file</span>
814
+ cyclecad run my-design.cycle</code></pre>
815
+
816
+ <h2>Interactive REPL</h2>
817
+
818
+ <pre><code><span class="com">$ cyclecad</span>
819
+ <span class="str">cycleCAD v0.2.0 | Type 'help' for commands</span>
820
+
821
+ cyclecad> shape.cylinder --radius <span class="num">25</span> --height <span class="num">80</span>
822
+ <span class="str">✓ Created cylinder (shape_0)</span>
823
+
824
+ cyclecad> feature.fillet --radius <span class="num">5</span>
825
+ <span class="str">✓ Filleted edges (fillet_0)</span>
826
+
827
+ cyclecad> render.snapshot --format png
828
+ <span class="str">✓ Saved: /tmp/cyclecad_snapshot.png</span>
829
+
830
+ cyclecad> validate.dfm
831
+ <span class="str">Design Review: PASS (A)
832
+ ✓ No thin walls detected
833
+ ✓ Adequate draft angles
834
+ ⚠ Warning: Consider corner radii</span>
835
+
836
+ cyclecad> export.stl --file my-part.stl
837
+ <span class="str">✓ Exported: my-part.stl (245 KB)</span>
838
+
839
+ cyclecad> exit</code></pre>
840
+
841
+ <h2>Script Files (.cycle)</h2>
842
+ <p>Create reusable design scripts:</p>
843
+
844
+ <pre><code><span class="com">// motor-bracket.cycle</span>
845
+ <span class="com"># Define parameters</span>
846
+ <span class="kw">set</span> $plate_width <span class="num">100</span>
847
+ <span class="kw">set</span> $plate_height <span class="num">80</span>
848
+ <span class="kw">set</span> $hole_diameter <span class="num">6</span>
849
+
850
+ <span class="com"># Create base plate</span>
851
+ shape.box --width <span class="str">$plate_width</span> --height <span class="str">$plate_height</span> --depth <span class="num">10</span>
852
+
853
+ <span class="com"># Add mounting holes</span>
854
+ <span class="kw">loop</span> i <span class="num">0</span> <span class="num">3</span> {
855
+ feature.hole --diameter <span class="str">$hole_diameter</span> --depth <span class="num">10</span>
856
+ }
857
+
858
+ <span class="com"># Finish</span>
859
+ feature.fillet --radius <span class="num">2</span>
860
+ render.snapshot --format png
861
+
862
+ <span class="com"># Export</span>
863
+ export.stl --file motor-bracket.stl
864
+
865
+ <span class="com"># Validate</span>
866
+ validate.dfm</code></pre>
867
+
868
+ <h2>Tab Completion & Help</h2>
869
+
870
+ <pre><code><span class="com">// Type 'help' for all commands</span>
871
+ cyclecad> help
872
+
873
+ <span class="com">// Type 'help {command}' for details</span>
874
+ cyclecad> help shape.cylinder
875
+ shape.cylinder — Create a cylinder
876
+ Usage: shape.cylinder --radius &lt;num&gt; --height &lt;num&gt; [--centered]
877
+ Parameters:
878
+ --radius [required] Cylinder radius in mm
879
+ --height [required] Cylinder height in mm
880
+ --centered [optional] Center at origin (default: false)
881
+
882
+ <span class="com">// Tab autocomplete</span>
883
+ cyclecad> shape. [TAB]
884
+ shape.box
885
+ shape.cone
886
+ shape.cylinder
887
+ shape.disk
888
+ ...
889
+
890
+ cyclecad> feature. [TAB]
891
+ feature.boolean
892
+ feature.chamfer
893
+ feature.fillet
894
+ ...</code></pre>
895
+
896
+ <div class="pro-tip">
897
+ <strong>Pro Tip:</strong> Use `--watch` flag to re-run scripts on file changes: <code>cyclecad run design.cycle --watch</code>
898
+ </div>
899
+ </section>
900
+
901
+ <!-- Section: Token Engine -->
902
+ <section id="tokens" class="section">
903
+ <h1>$CYCLE Token Engine</h1>
904
+
905
+ <h2>Overview</h2>
906
+ <p>$CYCLE is a dual-ledger token system where users spend tokens to create designs and earn tokens by sharing them. It's inspired by Claude's API pricing model but adds creator economics.</p>
907
+
908
+ <h2>Three Tiers</h2>
909
+ <table>
910
+ <tr>
911
+ <th>Tier</th>
912
+ <th>Cost</th>
913
+ <th>Features</th>
914
+ </tr>
915
+ <tr>
916
+ <td><strong>FREE</strong></td>
917
+ <td>€0/mo</td>
918
+ <td>50 tokens/month, basic AI, 10MB storage, no publish</td>
919
+ </tr>
920
+ <tr>
921
+ <td><strong>PRO</strong></td>
922
+ <td>€49/mo</td>
923
+ <td>5,000 tokens/month, advanced AI, 1GB storage, publish models</td>
924
+ </tr>
925
+ <tr>
926
+ <td><strong>ENTERPRISE</strong></td>
927
+ <td>€299/mo</td>
928
+ <td>50,000 tokens/month, priority support, unlimited storage, API access</td>
929
+ </tr>
930
+ </table>
931
+
932
+ <h2>Per-Operation Costs</h2>
933
+ <table>
934
+ <tr>
935
+ <th>Operation</th>
936
+ <th>Tokens</th>
937
+ <th>Notes</th>
938
+ </tr>
939
+ <tr>
940
+ <td>Simple shape (cylinder, box)</td>
941
+ <td>50</td>
942
+ <td></td>
943
+ </tr>
944
+ <tr>
945
+ <td>Fillet/Chamfer</td>
946
+ <td>75</td>
947
+ <td></td>
948
+ </tr>
949
+ <tr>
950
+ <td>Boolean operation</td>
951
+ <td>150</td>
952
+ <td></td>
953
+ </tr>
954
+ <tr>
955
+ <td>Assembly constraint</td>
956
+ <td>100</td>
957
+ <td></td>
958
+ </tr>
959
+ <tr>
960
+ <td>Design review (DFM)</td>
961
+ <td>200</td>
962
+ <td></td>
963
+ </tr>
964
+ <tr>
965
+ <td>Export to STEP</td>
966
+ <td>250</td>
967
+ <td></td>
968
+ </tr>
969
+ <tr>
970
+ <td>AI design suggestions</td>
971
+ <td>500</td>
972
+ <td>Per request</td>
973
+ </tr>
974
+ </table>
975
+
976
+ <h2>Discounts</h2>
977
+ <ul>
978
+ <li><strong>Cache Discount:</strong> 10% for repeated operations within 24 hours</li>
979
+ <li><strong>Batch Discount:</strong> 25-50% for bulk operations (10+ in a script)</li>
980
+ <li><strong>Loyalty Discount:</strong> 5% per month as a PRO/ENTERPRISE user</li>
981
+ </ul>
982
+
983
+ <h2>Checking Balance</h2>
984
+
985
+ <pre><code><span class="com">// In app</span>
986
+ <span class="kw">const</span> balance = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">token</span>.<span class="fn">getBalance</span>();
987
+ console.<span class="fn">log</span>(balance); <span class="com">// { balance: 4850, tier: 'PRO', ... }</span>
988
+
989
+ <span class="com">// Via CLI</span>
990
+ cyclecad token balance
991
+ <span class="str">Balance: 4,850 $CYCLE
992
+ Tier: PRO (€49/mo)
993
+ Spend this month: 1,150 $CYCLE
994
+ Reset: 2026-04-01</span>
995
+
996
+ <span class="com">// Via REST API</span>
997
+ curl http://localhost:<span class="num">3000</span>/api/v1/token/balance</code></pre>
998
+
999
+ <h2>Double-Entry Ledger</h2>
1000
+ <p>All token transactions are recorded in a cryptographically signed ledger:</p>
1001
+
1002
+ <pre><code>{
1003
+ <span class="str">"transactions"</span>: [
1004
+ {
1005
+ <span class="str">"id"</span>: <span class="str">"txn_abc123"</span>,
1006
+ <span class="str">"timestamp"</span>: <span class="str">"2026-03-26T14:30:00Z"</span>,
1007
+ <span class="str">"type"</span>: <span class="str">"spend"</span>,
1008
+ <span class="str">"amount"</span>: <span class="num">150</span>,
1009
+ <span class="str">"operation"</span>: <span class="str">"feature.fillet"</span>,
1010
+ <span class="str">"note"</span>: <span class="str">"Motor bracket project"</span>,
1011
+ <span class="str">"hash"</span>: <span class="str">"0xabc..."</span>
1012
+ },
1013
+ {
1014
+ <span class="str">"id"</span>: <span class="str">"txn_def456"</span>,
1015
+ <span class="str">"timestamp"</span>: <span class="str">"2026-03-26T15:00:00Z"</span>,
1016
+ <span class="str">"type"</span>: <span class="str">"earn"</span>,
1017
+ <span class="str">"amount"</span>: <span class="num">500</span>,
1018
+ <span class="str">"source"</span>: <span class="str">"marketplace_sale"</span>,
1019
+ <span class="str">"note"</span>: <span class="str">"Bearing housing model purchased"</span>,
1020
+ <span class="str">"hash"</span>: <span class="str">"0xdef..."</span>
1021
+ }
1022
+ ]
1023
+ }</code></pre>
1024
+
1025
+ <div class="advanced-note">
1026
+ <strong>Advanced:</strong> The ledger is immutable. Each transaction is cryptographically chained (hash of previous txn included in next). This ensures a tamper-proof audit trail.
1027
+ </div>
1028
+
1029
+ <h2>Purchasing Tokens</h2>
1030
+
1031
+ <pre><code><span class="com">// Subscribe to PRO (5,000 tokens/month)</span>
1032
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">token</span>.<span class="fn">subscribe</span>({
1033
+ tier: <span class="str">'PRO'</span>,
1034
+ billingCycle: <span class="str">'monthly'</span>
1035
+ });
1036
+
1037
+ <span class="com">// Buy additional tokens (pay-as-you-go)</span>
1038
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">token</span>.<span class="fn">purchase</span>({
1039
+ amount: <span class="num">1000</span>,
1040
+ method: <span class="str">'stripe'</span> <span class="com">// or 'crypto' for USDC</span>
1041
+ });</code></pre>
1042
+ </section>
1043
+
1044
+ <!-- Section: Marketplace -->
1045
+ <section id="marketplace" class="section">
1046
+ <h1>Model Marketplace</h1>
1047
+
1048
+ <h2>Publishing Your Models</h2>
1049
+ <p>Share designs in the cycleCAD marketplace and earn 70-90% royalties.</p>
1050
+
1051
+ <h3>7 Access Tiers</h3>
1052
+ <table>
1053
+ <tr>
1054
+ <th>Tier</th>
1055
+ <th>Price (€)</th>
1056
+ <th>Your Royalty</th>
1057
+ </tr>
1058
+ <tr>
1059
+ <td>Free</td>
1060
+ <td>0</td>
1061
+ <td>—</td>
1062
+ </tr>
1063
+ <tr>
1064
+ <td>Starter</td>
1065
+ <td>9</td>
1066
+ <td>70% (€6.30)</td>
1067
+ </tr>
1068
+ <tr>
1069
+ <td>Basic</td>
1070
+ <td>19</td>
1071
+ <td>75% (€14.25)</td>
1072
+ </tr>
1073
+ <tr>
1074
+ <td>Professional</td>
1075
+ <td>49</td>
1076
+ <td>80% (€39.20)</td>
1077
+ </tr>
1078
+ <tr>
1079
+ <td>Premium</td>
1080
+ <td>99</td>
1081
+ <td>85% (€84.15)</td>
1082
+ </tr>
1083
+ <tr>
1084
+ <td>Enterprise</td>
1085
+ <td>299</td>
1086
+ <td>90% (€269.10)</td>
1087
+ </tr>
1088
+ <tr>
1089
+ <td>Custom</td>
1090
+ <td>Negotiated</td>
1091
+ <td>90%+</td>
1092
+ </tr>
1093
+ </table>
1094
+
1095
+ <h2>Publishing a Model</h2>
1096
+
1097
+ <pre><code><span class="com">// In app UI or via API:</span>
1098
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">marketplace</span>.<span class="fn">publish</span>({
1099
+ title: <span class="str">'Motor Mount Bracket'</span>,
1100
+ description: <span class="str">'Aluminum bracket for NEMA23 stepper motors'</span>,
1101
+ category: <span class="str">'mechanical'</span>,
1102
+ tags: [<span class="str">'aluminum'</span>, <span class="str">'bracket'</span>, <span class="str">'stepper'</span>],
1103
+ thumbnail: <span class="str">'snapshot.png'</span>,
1104
+ accessTier: <span class="str">'Professional'</span>,
1105
+ price: <span class="num">49</span>,
1106
+ features: {
1107
+ geometry: <span class="kw">true</span>,
1108
+ parameters: <span class="kw">true</span>,
1109
+ assembly: <span class="kw">true</span>
1110
+ }
1111
+ });
1112
+
1113
+ <span class="com">// Returns published model ID and marketplace URL</span></code></pre>
1114
+
1115
+ <h2>Marketplace Search</h2>
1116
+
1117
+ <pre><code><span class="com">// Find models by keyword</span>
1118
+ <span class="kw">const</span> results = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">marketplace</span>.<span class="fn">search</span>({
1119
+ query: <span class="str">'bearing housing'</span>,
1120
+ category: <span class="str">'mechanical'</span>,
1121
+ maxPrice: <span class="num">50</span>,
1122
+ sortBy: <span class="str">'downloads'</span>
1123
+ });
1124
+
1125
+ <span class="com">// Browse by category</span>
1126
+ <span class="kw">const</span> mechanical = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">marketplace</span>.<span class="fn">browse</span>({
1127
+ category: <span class="str">'mechanical'</span>,
1128
+ limit: <span class="num">20</span>
1129
+ });</code></pre>
1130
+
1131
+ <h2>Creator Dashboard</h2>
1132
+ <p>Track sales, earnings, reviews, and download statistics:</p>
1133
+
1134
+ <pre><code>{
1135
+ <span class="str">"models"</span>: [
1136
+ {
1137
+ <span class="str">"id"</span>: <span class="str">"model_xyz"</span>,
1138
+ <span class="str">"title"</span>: <span class="str">"Motor Mount Bracket"</span>,
1139
+ <span class="str">"downloads"</span>: <span class="num">1247</span>,
1140
+ <span class="str">"sales"</span>: <span class="num">89</span>,
1141
+ <span class="str">"revenue"</span>: <span class="num">4371</span>, <span class="com">// €</span>
1142
+ <span class="str">"yourRoyalty"</span>: <span class="num">3497</span>, <span class="com">// 80%</span>
1143
+ <span class="str">"avgRating"</span>: <span class="num">4.8</span>,
1144
+ <span class="str">"reviews"</span>: <span class="num">42</span>
1145
+ }
1146
+ ],
1147
+ <span class="str">"totalRevenue"</span>: <span class="num">12450</span>,
1148
+ <span class="str">"totalRoyalties"</span>: <span class="num">9960</span>
1149
+ }</code></pre>
1150
+
1151
+ <div class="pro-tip">
1152
+ <strong>Pro Tip:</strong> Models with detailed documentation, good screenshots, and videos get 3-5x more downloads.
1153
+ </div>
1154
+ </section>
1155
+
1156
+ <!-- Section: Connected Fabs -->
1157
+ <section id="fabs" class="section">
1158
+ <h1>Connected Fabs & Manufacturing</h1>
1159
+
1160
+ <h2>CAD → CAM → Manufacturing Pipeline</h2>
1161
+
1162
+ <pre><code><span class="diagram">┌─────────────────────────────────────────┐
1163
+ │ cycleCAD (Design) │
1164
+ │ - Create geometry │
1165
+ │ - Specify materials │
1166
+ │ - Add tolerances │
1167
+ └───────────┬─────────────────────────────┘
1168
+
1169
+
1170
+ ┌─────────────────────────────────────────┐
1171
+ │ CAM Generation │
1172
+ │ - Tool path generation │
1173
+ │ - Feeds & speeds calculation │
1174
+ │ - Nesting optimization │
1175
+ └───────────┬─────────────────────────────┘
1176
+
1177
+
1178
+ ┌─────────────────────────────────────────┐
1179
+ │ Fab Network │
1180
+ │ - Quote aggregation │
1181
+ │ - Inventory check │
1182
+ │ - Lead time estimation │
1183
+ └───────────┬─────────────────────────────┘
1184
+
1185
+
1186
+ ┌─────────────────────────────────────────┐
1187
+ │ Order + Manufacturing │
1188
+ │ - Production monitoring │
1189
+ │ - Quality assurance │
1190
+ │ - Delivery tracking │
1191
+ └─────────────────────────────────────────┘</span></code></pre>
1192
+
1193
+ <h2>Connecting a Fab</h2>
1194
+ <p>Register a fab to receive automated orders from cycleCAD users:</p>
1195
+
1196
+ <pre><code><span class="com">// Fab registration (as fab operator)</span>
1197
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">fab</span>.<span class="fn">register</span>({
1198
+ name: <span class="str">'TechMachining Co.'</span>,
1199
+ location: <span class="str">'Berlin, Germany'</span>,
1200
+ capabilities: [
1201
+ <span class="str">'CNC_3AXIS'</span>, <span class="str">'CNC_5AXIS'</span>,
1202
+ <span class="str">'FDM'</span>, <span class="str">'SLA'</span>,
1203
+ <span class="str">'LASER_CUT'</span>, <span class="str">'SHEET_METAL'</span>
1204
+ ],
1205
+ materials: [
1206
+ <span class="str">'aluminum'</span>, <span class="str">'steel'</span>,
1207
+ <span class="str">'abs'</span>, <span class="str">'pla'</span>,
1208
+ <span class="str">'nylon'</span>
1209
+ ],
1210
+ apiKey: <span class="str">'fab_key_...'</span>
1211
+ });</code></pre>
1212
+
1213
+ <h2>Automated Quoting</h2>
1214
+
1215
+ <pre><code><span class="com">// User exports design, gets instant quotes from all connected fabs</span>
1216
+ <span class="kw">const</span> quotes = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">fab</span>.<span class="fn">getQuotes</span>({
1217
+ geometry: model,
1218
+ material: <span class="str">'aluminum'</span>,
1219
+ quantity: <span class="num">10</span>,
1220
+ machineTime: <span class="num">2.5</span> <span class="com">// hours</span>
1221
+ });
1222
+
1223
+ <span class="com">// Returns:</span>
1224
+ [
1225
+ {
1226
+ fab: <span class="str">'TechMachining'</span>,
1227
+ price: <span class="num">450</span>, <span class="com">// € per batch</span>
1228
+ leadTime: <span class="num">3</span>, <span class="com">// days</span>
1229
+ setup: <span class="num">50</span>,
1230
+ perUnit: <span class="num">40</span>
1231
+ },
1232
+ {
1233
+ fab: <span class="str">'QuickParts'</span>,
1234
+ price: <span class="num">480</span>,
1235
+ leadTime: <span class="num">2</span>,
1236
+ setup: <span class="num">0</span>,
1237
+ perUnit: <span class="num">48</span>
1238
+ }
1239
+ ]</code></pre>
1240
+
1241
+ <h2>Order Tracking</h2>
1242
+
1243
+ <pre><code><span class="com">// Place order with fab</span>
1244
+ <span class="kw">const</span> order = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">fab</span>.<span class="fn">placeOrder</span>({
1245
+ fabId: <span class="str">'fab_techmachining'</span>,
1246
+ design: model,
1247
+ quantity: <span class="num">10</span>,
1248
+ material: <span class="str">'6061-T6 Aluminum'</span>
1249
+ });
1250
+
1251
+ <span class="com">// Get order status</span>
1252
+ <span class="kw">const</span> status = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">fab</span>.<span class="fn">getOrderStatus</span>(order.id);
1253
+ <span class="com">// { status: 'in_production', progress: 65, eta: '2026-03-28' }</span></code></pre>
1254
+
1255
+ <div class="advanced-note">
1256
+ <strong>Advanced:</strong> Fabs can define custom machine profiles (CNC tools, feeds, speeds) which auto-optimize toolpaths for your specific equipment.
1257
+ </div>
1258
+ </section>
1259
+
1260
+ <!-- Section: Multi-Agent Workflows -->
1261
+ <section id="agents" class="section">
1262
+ <h1>Multi-Agent Workflows</h1>
1263
+
1264
+ <h2>Agent Swarms</h2>
1265
+ <p>Multiple AI agents can collaborate on a design, each with specialized skills:</p>
1266
+
1267
+ <pre><code><span class="kw">const</span> swarm = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">agent</span>.<span class="fn">createSwarm</span>({
1268
+ name: <span class="str">'Motor Bracket Design'</span>,
1269
+ agents: [
1270
+ {
1271
+ role: <span class="str">'designer'</span>,
1272
+ model: <span class="str">'claude-opus'</span>,
1273
+ <span class="com">// Creates geometry, refines shapes</span>
1274
+ },
1275
+ {
1276
+ role: <span class="str">'analyst'</span>,
1277
+ model: <span class="str">'claude-sonnet'</span>,
1278
+ <span class="com">// Validates design, runs FEA simulation</span>
1279
+ },
1280
+ {
1281
+ role: <span class="str">'manufacturer'</span>,
1282
+ model: <span class="str">'domain-model'</span>,
1283
+ <span class="com">// Optimizes for manufacturability</span>
1284
+ }
1285
+ ]
1286
+ });
1287
+
1288
+ <span class="com">// Swarm processes iteratively:</span>
1289
+ <span class="com">// 1. Designer creates initial geometry</span>
1290
+ <span class="com">// 2. Analyst reviews, suggests improvements</span>
1291
+ <span class="com">// 3. Manufacturer optimizes for CNC/FDM/etc</span>
1292
+ <span class="com">// 4. Repeat until converged</span></code></pre>
1293
+
1294
+ <h2>Design Review Loop</h2>
1295
+ <p>Automatic A/B/C/F scoring for iterative improvement:</p>
1296
+
1297
+ <pre><code><span class="com">// Design score: A (excellent) → F (fail)</span>
1298
+ <span class="kw">const</span> review = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">validate</span>.<span class="fn">dfm</span>();
1299
+
1300
+ <span class="com">// Returns:</span>
1301
+ {
1302
+ <span class="str">"score"</span>: <span class="str">"B"</span>,
1303
+ <span class="str">"summary"</span>: <span class="str">"Good design with minor improvements recommended"</span>,
1304
+ <span class="str">"criteria"</span>: {
1305
+ <span class="str">"manufacturability"</span>: <span class="str">"A"</span>, <span class="com">// ✓ No issues</span>
1306
+ <span class="str">"cost"</span>: <span class="str">"C"</span>, <span class="com">// ⚠ High waste material</span>
1307
+ <span class="str">"assembly"</span>: <span class="str">"B"</span>, <span class="com">// ✓ Good</span>
1308
+ <span class="str">"strength"</span>: <span class="str">"A"</span>, <span class="com">// ✓ Sufficient</span>
1309
+ <span class="str">"tolerances"</span>: <span class="str">"B"</span> <span class="com">// ✓ Good</span>
1310
+ },
1311
+ <span class="str">"suggestions"</span>: [
1312
+ <span class="str">"Reduce 15mm corner radius to 8mm to save material"</span>,
1313
+ <span class="str">"Add ribs for rigidity without extra weight"</span>
1314
+ ]
1315
+ }</code></pre>
1316
+
1317
+ <h2>Cooperative Design Workflow</h2>
1318
+
1319
+ <pre><code><span class="com">// Example: Team designs assembly together</span>
1320
+
1321
+ <span class="com">// Step 1: Engineer A creates base plate</span>
1322
+ agent_a: <span class="str">"Create 100x80 aluminum plate with 4 corners holes"</span>
1323
+ → cycleCAD: shape.box → feature.hole (x4)
1324
+
1325
+ <span class="com">// Step 2: Engineer B adds support ribs</span>
1326
+ agent_b: <span class="str">"The plate needs reinforcement. Add vertical ribs."</span>
1327
+ → cycleCAD: feature.loft (rib geometry)
1328
+
1329
+ <span class="com">// Step 3: Analyst validates</span>
1330
+ analyst: <span class="str">"Run FEM analysis on the design"</span>
1331
+ → cycleCAD: validate.dfm + validate.strength
1332
+
1333
+ <span class="com">// Step 4: Manufacturer optimizes</span>
1334
+ mfg: <span class="str">"Optimize for CNC 3-axis, add stock allowance"</span>
1335
+ → cycleCAD: feature.shell + export.step</code></pre>
1336
+
1337
+ <h2>WebRTC Collaboration</h2>
1338
+ <p>Real-time design collaboration with WebRTC (CRDT-based):</p>
1339
+
1340
+ <pre><code><span class="com">// Connect two users via WebRTC</span>
1341
+ <span class="kw">const</span> session = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">collab</span>.<span class="fn">createSession</span>({
1342
+ peers: [<span class="str">'user1@domain.com'</span>, <span class="str">'user2@domain.com'</span>]
1343
+ });
1344
+
1345
+ <span class="com">// Both users see each other's cursors, operations in real-time</span>
1346
+ <span class="com">// CRDT ensures eventual consistency despite network delays</span>
1347
+
1348
+ <span class="com">// Event stream:</span>
1349
+ session.<span class="fn">on</span>(<span class="str">'operation'</span>, (op) => {
1350
+ console.<span class="fn">log</span>(<span class="str">'User just:'</span>, op.type); <span class="com">// 'added_fillet', 'moved_part', etc</span>
1351
+ });</code></pre>
1352
+
1353
+ <div class="pro-tip">
1354
+ <strong>Pro Tip:</strong> Swarms work best when agents have clear roles. Use domain-specific models for manufacturing and assembly logic.
1355
+ </div>
1356
+ </section>
1357
+
1358
+ <!-- Section: Machine Profiles -->
1359
+ <section id="machines" class="section">
1360
+ <h1>Custom Machine Profiles</h1>
1361
+
1362
+ <h2>Creating a Machine Profile</h2>
1363
+ <p>Define feeds, speeds, and tool recommendations for your specific CNC/FDM/laser:</p>
1364
+
1365
+ <pre><code><span class="com">// config/machines/haas-vf4.json</span>
1366
+ {
1367
+ <span class="str">"name"</span>: <span class="str">"HAAS VF-4"</span>,
1368
+ <span class="str">"type"</span>: <span class="str">"CNC_3AXIS"</span>,
1369
+ <span class="str">"workspace"</span>: {
1370
+ <span class="str">"x"</span>: <span class="num">1000</span>,
1371
+ <span class="str">"y"</span>: <span class="num">500</span>,
1372
+ <span class="str">"z"</span>: <span class="num">300</span>
1373
+ },
1374
+ <span class="str">"tools"</span>: [
1375
+ {
1376
+ <span class="str">"id"</span>: <span class="str">"tool_1"</span>,
1377
+ <span class="str">"name"</span>: <span class="str">"Carbide End Mill 10mm"</span>,
1378
+ <span class="str">"type"</span>: <span class="str">"endmill"</span>,
1379
+ <span class="str">"diameter"</span>: <span class="num">10</span>,
1380
+ <span class="str">"flutes"</span>: <span class="num">4</span>
1381
+ }
1382
+ ],
1383
+ <span class="str">"feedspeeds"</span>: {
1384
+ <span class="str">"aluminum"</span>: {
1385
+ <span class="str">"tool_1"</span>: {
1386
+ <span class="str">"spindle"</span>: <span class="num">4000</span>, <span class="com">// RPM</span>
1387
+ <span class="str">"feed"</span>: <span class="num">0.1</span>, <span class="com">// mm/tooth</span>
1388
+ <span class="str">"depth"</span>: <span class="num">5</span> <span class="com">// mm per pass</span>
1389
+ }
1390
+ },
1391
+ <span class="str">"steel"</span>: {
1392
+ <span class="str">"tool_1"</span>: {
1393
+ <span class="str">"spindle"</span>: <span class="num">2000</span>,
1394
+ <span class="str">"feed"</span>: <span class="num">0.05</span>,
1395
+ <span class="str">"depth"</span>: <span class="num">3</span>
1396
+ }
1397
+ }
1398
+ }
1399
+ }</code></pre>
1400
+
1401
+ <h2>Auto-Optimization</h2>
1402
+
1403
+ <pre><code><span class="com">// CAM engine automatically selects tools and parameters</span>
1404
+ <span class="kw">const</span> toolpath = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">cam</span>.<span class="fn">generateToolpath</span>({
1405
+ geometry: part,
1406
+ material: <span class="str">'aluminum'</span>,
1407
+ machine: <span class="str">'haas-vf4'</span>,
1408
+ quality: <span class="str">'high'</span> <span class="com">// or 'fast', 'balanced'</span>
1409
+ });
1410
+
1411
+ <span class="com">// Returns optimal tool, RPM, feed rate, depth, tool changes</span></code></pre>
1412
+
1413
+ <h2>FDM Profile Example</h2>
1414
+
1415
+ <pre><code>{
1416
+ <span class="str">"name"</span>: <span class="str">"Prusa i3 MK3S"</span>,
1417
+ <span class="str">"type"</span>: <span class="str">"FDM"</span>,
1418
+ <span class="str">"nozzleDiameter"</span>: <span class="num">0.4</span>,
1419
+ <span class="str">"bedSize"</span>: [<span class="num">250</span>, <span class="num">210</span>],
1420
+ <span class="str">"materials"</span>: {
1421
+ <span class="str">"pla"</span>: {
1422
+ <span class="str">"nozzleTemp"</span>: <span class="num">210</span>,
1423
+ <span class="str">"bedTemp"</span>: <span class="num">60</span>,
1424
+ <span class="str">"layerHeight"</span>: <span class="num">0.2</span>,
1425
+ <span class="str">"printSpeed"</span>: <span class="num">150</span>, <span class="com">// mm/s</span>
1426
+ <span class="str">"infill"</span>: <span class="num">15</span> <span class="com">// %</span>
1427
+ },
1428
+ <span class="str">"abs"</span>: {
1429
+ <span class="str">"nozzleTemp"</span>: <span class="num">240</span>,
1430
+ <span class="str">"bedTemp"</span>: <span class="num">100</span>,
1431
+ <span class="str">"layerHeight"</span>: <span class="num">0.2</span>,
1432
+ <span class="str">"printSpeed"</span>: <span class="num">80</span>,
1433
+ <span class="str">"infill"</span>: <span class="num">20</span>
1434
+ }
1435
+ }
1436
+ }</code></pre>
1437
+
1438
+ <div class="warning">
1439
+ <strong>Warning:</strong> Incorrect feed/speed settings can damage tools or machines. Always validate with your machine manual.
1440
+ </div>
1441
+ </section>
1442
+
1443
+ <!-- Section: Collaboration -->
1444
+ <section id="collab" class="section">
1445
+ <h1>Real-Time Collaboration</h1>
1446
+
1447
+ <h2>Architecture</h2>
1448
+ <p>cycleCAD uses CRDT (Conflict-free Replicated Data Types) for real-time multi-user editing without a central server.</p>
1449
+
1450
+ <pre><code><span class="diagram">User A Network User B
1451
+ │ (WebRTC) │
1452
+ │◄──────────────────────────────►│
1453
+ │ Geometry change │
1454
+ │ Shape added: cylinder_0 │
1455
+ │ Local ID: a_001 │
1456
+ │ Global ID: uuid_abc │
1457
+ │ │
1458
+ │ Fillet operation │
1459
+ │ Feature added: fillet_0 │
1460
+ │ Dependencies: [cylinder_0] │
1461
+ │ Local ID: a_002 │
1462
+ │ Global ID: uuid_def │
1463
+ │ │
1464
+ │◄─── Both users converge ──────►│
1465
+ │ Same scene, both directions │</span></code></pre>
1466
+
1467
+ <h2>Enabling Collaboration</h2>
1468
+
1469
+ <pre><code><span class="com">// Open existing design for collaboration</span>
1470
+ <span class="kw">const</span> doc = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">collab</span>.<span class="fn">openDocument</span>({
1471
+ id: <span class="str">'design_xyz'</span>,
1472
+ mode: <span class="str">'edit'</span> <span class="com">// or 'view'</span>
1473
+ });
1474
+
1475
+ <span class="com">// Invite collaborators</span>
1476
+ <span class="kw">await</span> doc.<span class="fn">invite</span>([
1477
+ <span class="str">'engineer1@company.com'</span>,
1478
+ <span class="str">'engineer2@company.com'</span>
1479
+ ]);
1480
+
1481
+ <span class="com">// Listen for remote operations</span>
1482
+ doc.<span class="fn">on</span>(<span class="str">'remote-operation'</span>, (op) => {
1483
+ console.<span class="fn">log</span>(<span class="str">'Peer just:'</span>, op);
1484
+ <span class="com">// { type: 'shape.cylinder', user: 'engineer1@company.com' }</span>
1485
+ });</code></pre>
1486
+
1487
+ <h2>Share Links</h2>
1488
+
1489
+ <pre><code><span class="com">// Generate shareable link (no login required)</span>
1490
+ <span class="kw">const</span> shareLink = <span class="kw">await</span> doc.<span class="fn">getShareLink</span>({
1491
+ access: <span class="str">'view'</span> <span class="com">// or 'comment', 'edit'</span>
1492
+ });
1493
+
1494
+ <span class="com">// Returns: https://cyclecad.com/view/share/xyz123</span>
1495
+ <span class="com">// Anyone with link can view (or edit if access='edit')</span></code></pre>
1496
+
1497
+ <h2>Comments & Annotations</h2>
1498
+
1499
+ <pre><code><span class="com">// Add comment to a specific feature</span>
1500
+ <span class="kw">await</span> doc.<span class="fn">addComment</span>({
1501
+ featureId: <span class="str">'fillet_0'</span>,
1502
+ text: <span class="str">'Increase radius to 4mm for assembly'</span>,
1503
+ author: <span class="str">'engineer1@company.com'</span>
1504
+ });
1505
+
1506
+ <span class="com">// Create task</span>
1507
+ <span class="kw">await</span> doc.<span class="fn">createTask</span>({
1508
+ description: <span class="str">'Validate hole clearances'</span>,
1509
+ assignee: <span class="str">'engineer2@company.com'</span>,
1510
+ dueDate: <span class="str">'2026-03-28'</span>
1511
+ });</code></pre>
1512
+
1513
+ <div class="pro-tip">
1514
+ <strong>Pro Tip:</strong> Collaboration works best for teams <10 people. For larger teams, use branching + merge workflow (similar to Git).
1515
+ </div>
1516
+ </section>
1517
+
1518
+ <!-- Section: Performance -->
1519
+ <section id="perf" class="section">
1520
+ <h1>Performance Optimization</h1>
1521
+
1522
+ <h2>Large Assemblies (500+ Parts)</h2>
1523
+ <p>cycleCAD uses Level-of-Detail (LOD) rendering to maintain 60 FPS:</p>
1524
+
1525
+ <pre><code><span class="com">// LOD automatically switches geometry detail based on zoom level</span>
1526
+ {
1527
+ <span class="str">"part_001"</span>: {
1528
+ <span class="str">"lod0"</span>: { meshes: <span class="num">50000</span>, tris: <span class="num">2000000</span> }, <span class="com">// Close-up</span>
1529
+ <span class="str">"lod1"</span>: { meshes: <span class="num">20000</span>, tris: <span class="num">800000</span> }, <span class="com">// Normal</span>
1530
+ <span class="str">"lod2"</span>: { meshes: <span class="num">5000</span>, tris: <span class="num">200000</span> }, <span class="com">// Far</span>
1531
+ <span class="str">"lod3"</span>: { meshes: <span class="num">100</span>, tris: <span class="num">5000</span> } <span class="com">// Very far</span>
1532
+ }
1533
+ }</code></pre>
1534
+
1535
+ <h2>Memory Management</h2>
1536
+
1537
+ <pre><code><span class="com">// Monitor memory usage</span>
1538
+ <span class="kw">const</span> stats = <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">performance</span>.<span class="fn">getStats</span>();
1539
+ console.<span class="fn">log</span>(stats);
1540
+ <span class="com">// {</span>
1541
+ <span class="com">// geometry_mb: 245,</span>
1542
+ <span class="com">// textures_mb: 128,</span>
1543
+ <span class="com">// scene_objects: 4230,</span>
1544
+ <span class="com">// fps: 58,</span>
1545
+ <span class="com">// gpu_memory: 678</span>
1546
+ <span class="com">// }</span>
1547
+
1548
+ <span class="com">// Garbage collection hint</span>
1549
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">performance</span>.<span class="fn">optimize</span>();</code></pre>
1550
+
1551
+ <h2>Caching</h2>
1552
+
1553
+ <pre><code><span class="com">// Enable geometry cache (10% token discount for 24h repeats)</span>
1554
+ {
1555
+ <span class="str">"caching"</span>: {
1556
+ <span class="str">"enabled"</span>: <span class="kw">true</span>,
1557
+ <span class="str">"strategy"</span>: <span class="str">"lru"</span>, <span class="com">// Least Recently Used</span>
1558
+ <span class="str">"maxAge"</span>: <span class="num">86400</span>, <span class="com">// 24 hours</span>
1559
+ <span class="str">"maxSize"</span>: <span class="num">500</span> <span class="com">// MB</span>
1560
+ }
1561
+ }</code></pre>
1562
+
1563
+ <h2>Render Optimization</h2>
1564
+ <ul>
1565
+ <li><strong>Instancing:</strong> Repeated parts (bolt patterns) rendered as single instanced draw call</li>
1566
+ <li><strong>Frustum Culling:</strong> Off-screen geometry skipped</li>
1567
+ <li><strong>Occlusion Culling:</strong> Geometry hidden behind opaque parts not rendered</li>
1568
+ <li><strong>Normal Maps:</strong> Use for surface detail instead of high-poly geometry</li>
1569
+ <li><strong>Baking:</strong> Bake lighting for static geometry, only dynamic objects computed at runtime</li>
1570
+ </ul>
1571
+
1572
+ <div class="advanced-note">
1573
+ <strong>Advanced:</strong> For assemblies >1000 parts, consider splitting into sub-assemblies and loading on-demand.
1574
+ </div>
1575
+ </section>
1576
+
1577
+ <!-- Section: Docker -->
1578
+ <section id="docker" class="section">
1579
+ <h1>Docker Deployment</h1>
1580
+
1581
+ <h2>3-Service Architecture</h2>
1582
+
1583
+ <pre><code><span class="diagram">┌──────────────────────────────────┐
1584
+ │ User (Browser) │
1585
+ └──────────────────────────────────┘
1586
+
1587
+
1588
+ ┌──────────────────────────────────┐
1589
+ │ cycleCAD (Port 3000) │
1590
+ │ - Web app, Agent API │
1591
+ │ - REST API │
1592
+ │ - WebSocket collaboration │
1593
+ └──────────────────────────────────┘
1594
+
1595
+ ┌────────┴────────┐
1596
+ ▼ ▼
1597
+ ┌─────────────┐ ┌──────────────────┐
1598
+ │ExplodeView │ │STEP Converter │
1599
+ │(Port 8080) │ │(Port 8787) │
1600
+ │- 3D Viewer │ │- FastAPI │
1601
+ │- Analysis │ │- STEP→GLB │
1602
+ │- Tools │ │- OpenCascade.js │
1603
+ └─────────────┘ └──────────────────┘</span></code></pre>
1604
+
1605
+ <h2>docker-compose.yml</h2>
1606
+
1607
+ <pre><code><span class="str">version:</span> <span class="str">'3.8'</span>
1608
+
1609
+ <span class="str">services:</span>
1610
+ <span class="str">cyclecad:</span>
1611
+ <span class="str">image:</span> <span class="str">vvlars-cmd/cyclecad:latest</span>
1612
+ <span class="str">ports:</span>
1613
+ - <span class="str">'3000:3000'</span>
1614
+ <span class="str">environment:</span>
1615
+ - <span class="str">NODE_ENV=production</span>
1616
+ - <span class="str">API_PORT=3000</span>
1617
+ <span class="str">healthcheck:</span>
1618
+ <span class="str">test:</span> [<span class="str">'CMD'</span>, <span class="str">'curl'</span>, <span class="str">'http://localhost:3000/health'</span>]
1619
+ <span class="str">interval:</span> <span class="str">30s</span>
1620
+ <span class="str">timeout:</span> <span class="str">10s</span>
1621
+
1622
+ <span class="str">explodeview:</span>
1623
+ <span class="str">image:</span> <span class="str">vvlars-cmd/explodeview:latest</span>
1624
+ <span class="str">ports:</span>
1625
+ - <span class="str">'8080:80'</span>
1626
+ <span class="str">healthcheck:</span>
1627
+ <span class="str">test:</span> [<span class="str">'CMD'</span>, <span class="str">'curl'</span>, <span class="str">'http://localhost:80/'</span>]
1628
+
1629
+ <span class="str">step-converter:</span>
1630
+ <span class="str">image:</span> <span class="str">vvlars-cmd/step-converter:latest</span>
1631
+ <span class="str">ports:</span>
1632
+ - <span class="str">'8787:8787'</span>
1633
+ <span class="str">environment:</span>
1634
+ - <span class="str">CONVERTER_PORT=8787</span>
1635
+ <span class="str">memory:</span> <span class="str">'4gb'</span>
1636
+ <span class="str">memswap_limit:</span> <span class="str">'1gb'</span></code></pre>
1637
+
1638
+ <h2>Starting Services</h2>
1639
+
1640
+ <pre><code><span class="com">// Clone repo</span>
1641
+ git clone https://github.com/vvlars-cmd/cyclecad.git
1642
+ cd cyclecad
1643
+
1644
+ <span class="com">// Start all services</span>
1645
+ docker-compose up -d
1646
+
1647
+ <span class="com">// Check status</span>
1648
+ docker-compose ps
1649
+
1650
+ <span class="com">// View logs</span>
1651
+ docker-compose logs -f cyclecad
1652
+
1653
+ <span class="com">// Access</span>
1654
+ <span class="com">// cycleCAD: http://localhost:3000</span>
1655
+ <span class="com">// ExplodeView: http://localhost:8080</span>
1656
+ <span class="com">// API: http://localhost:3000/api/v1/schema</span></code></pre>
1657
+
1658
+ <h2>Health Checks</h2>
1659
+
1660
+ <pre><code><span class="com">// Each service exposes /health endpoint</span>
1661
+ curl http://localhost:<span class="num">3000</span>/health
1662
+
1663
+ <span class="com">// Response:</span>
1664
+ {
1665
+ <span class="str">"status"</span>: <span class="str">"ok"</span>,
1666
+ <span class="str">"uptime"</span>: <span class="num">3600</span>,
1667
+ <span class="str">"db"</span>: <span class="str">"connected"</span>,
1668
+ <span class="str">"version"</span>: <span class="str">"0.2.0"</span>
1669
+ }</code></pre>
1670
+
1671
+ <div class="pro-tip">
1672
+ <strong>Pro Tip:</strong> Deploy to Kubernetes with this helm chart: https://github.com/vvlars-cmd/cyclecad-helm
1673
+ </div>
1674
+ </section>
1675
+
1676
+ <!-- Section: Plugins -->
1677
+ <section id="plugins" class="section">
1678
+ <h1>Building Plugins</h1>
1679
+
1680
+ <h2>Plugin Architecture</h2>
1681
+ <p>Extend cycleCAD with custom features using the Plugin API (FeatureScript-equivalent in pure JavaScript):</p>
1682
+
1683
+ <pre><code><span class="com">// plugins/custom-bracket.js</span>
1684
+ <span class="kw">export const</span> plugin = {
1685
+ name: <span class="str">'Custom Bracket Generator'</span>,
1686
+ version: <span class="str">'1.0.0'</span>,
1687
+ author: <span class="str">'Your Name'</span>,
1688
+
1689
+ <span class="kw">async</span> <span class="fn">install</span>(cycleCAD) {
1690
+ <span class="com">// Register custom command in Agent API</span>
1691
+ cycleCAD.<span class="fn">registerCommand</span>({
1692
+ method: <span class="str">'custom.bracket'</span>,
1693
+ description: <span class="str">'Create parametric bracket'</span>,
1694
+ params: {
1695
+ width: { type: <span class="str">'number'</span> },
1696
+ height: { type: <span class="str">'number'</span> },
1697
+ holes: { type: <span class="str">'number'</span>, default: <span class="num">4</span> }
1698
+ },
1699
+ handler: <span class="kw">async</span> (params) => {
1700
+ <span class="kw">return</span> <span class="kw">await</span> createBracket(params);
1701
+ }
1702
+ });
1703
+ },
1704
+
1705
+ <span class="kw">async</span> <span class="fn">createBracket</span>(params) {
1706
+ <span class="kw">const</span> api = <span class="obj">window</span>.cycleCAD;
1707
+
1708
+ <span class="com">// Create base plate</span>
1709
+ <span class="kw">let</span> base = <span class="kw">await</span> api.<span class="fn">execute</span>({
1710
+ method: <span class="str">'shape.box'</span>,
1711
+ params: { width: params.width, height: params.height, depth: <span class="num">10</span> }
1712
+ });
1713
+
1714
+ <span class="com">// Add holes pattern</span>
1715
+ <span class="kw">for</span> (<span class="kw">let</span> i = <span class="num">0</span>; i &lt; params.holes; i++) {
1716
+ <span class="kw">await</span> api.<span class="fn">execute</span>({
1717
+ method: <span class="str">'feature.hole'</span>,
1718
+ params: { diameter: <span class="num">6</span>, depth: <span class="num">10</span> }
1719
+ });
1720
+ }
1721
+
1722
+ <span class="kw">return</span> { success: <span class="kw">true</span>, id: base.id };
1723
+ }
1724
+ };</code></pre>
1725
+
1726
+ <h2>Registering a Plugin</h2>
1727
+
1728
+ <pre><code><span class="com">// In app/index.html or via marketplace</span>
1729
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">plugins</span>.<span class="fn">install</span>({
1730
+ url: <span class="str">'https://github.com/user/cyclecad-bracket-plugin/raw/main/dist/bracket.js'</span>
1731
+ });
1732
+
1733
+ <span class="com">// Plugin is now available</span>
1734
+ <span class="kw">await</span> <span class="obj">window</span>.cycleCAD.<span class="fn">execute</span>({
1735
+ method: <span class="str">'custom.bracket'</span>,
1736
+ params: { width: <span class="num">150</span>, height: <span class="num">100</span>, holes: <span class="num">6</span> }
1737
+ });</code></pre>
1738
+
1739
+ <h2>Plugin Marketplace</h2>
1740
+ <p>Publish your plugin to the marketplace (same as design models):</p>
1741
+
1742
+ <pre><code><span class="com">// package.json</span>
1743
+ {
1744
+ <span class="str">"name"</span>: <span class="str">"cyclecad-bracket-plugin"</span>,
1745
+ <span class="str">"type"</span>: <span class="str">"cyclecad-plugin"</span>,
1746
+ <span class="str">"version"</span>: <span class="str">"1.0.0"</span>,
1747
+ <span class="str">"description"</span>: <span class="str">"Custom bracket generator with parametric control"</span>,
1748
+ <span class="str">"main"</span>: <span class="str">"dist/bracket.js"</span>,
1749
+ <span class="str">"keywords"</span>: [<span class="str">"bracket"</span>, <span class="str">"mechanical"</span>, <span class="str">"generator"</span>]
1750
+ }</code></pre>
1751
+
1752
+ <div class="pro-tip">
1753
+ <strong>Pro Tip:</strong> Plugins earn royalties just like designs. Popular plugins can generate significant passive income.
1754
+ </div>
1755
+ </section>
1756
+
1757
+ <!-- Section: Contributing -->
1758
+ <section id="contrib" class="section">
1759
+ <h1>Contributing to cycleCAD</h1>
1760
+
1761
+ <h2>BSL 1.1 License</h2>
1762
+ <p>cycleCAD is open-source under the Business Source License 1.1 (BSL 1.1):</p>
1763
+ <ul>
1764
+ <li>Free for development, testing, and non-commercial use</li>
1765
+ <li>Commercial use requires paid license after 2-year transition period</li>
1766
+ <li>Source code is open, but redistribution is restricted</li>
1767
+ <li>After 2 years, code automatically converts to Mozilla Public License 2.0</li>
1768
+ </ul>
1769
+
1770
+ <h2>Repository Structure</h2>
1771
+
1772
+ <pre><code>cyclecad/
1773
+ ├── app/
1774
+ │ ├── index.html <span class="com"># Main CAD app</span>
1775
+ │ ├── tutorials/ <span class="com"># Tutorial docs</span>
1776
+ │ ├── js/ <span class="com"># 33 ES modules</span>
1777
+ │ │ ├── viewport.js
1778
+ │ │ ├── sketch.js
1779
+ │ │ ├── operations.js
1780
+ │ │ ├── agent-api.js
1781
+ │ │ ├── marketplace.js
1782
+ │ │ └── ... (30 more)
1783
+ │ ├── agent-demo.html <span class="com"># Interactive agent demo</span>
1784
+ │ └── test-agent.html <span class="com"># Visual test runner</span>
1785
+ ├── server/
1786
+ │ ├── mcp-server.js <span class="com"># MCP tool server</span>
1787
+ │ ├── api-server.js <span class="com"># REST API</span>
1788
+ │ └── converter.py <span class="com"># STEP→GLB converter</span>
1789
+ ├── bin/
1790
+ │ ├── cyclecad-cli.js <span class="com"># CLI tool</span>
1791
+ │ └── cyclecad-mcp <span class="com"># MCP launcher</span>
1792
+ ├── docs/
1793
+ │ ├── opencascade-integration.md
1794
+ │ ├── explodeview-merge-plan.md
1795
+ │ └── MASTERPLAN.md
1796
+ ├── Dockerfile
1797
+ ├── docker-compose.yml
1798
+ ├── package.json
1799
+ └── README.md</code></pre>
1800
+
1801
+ <h2>PR Guidelines</h2>
1802
+ <ol>
1803
+ <li>Fork the repo and create a feature branch: <code>git checkout -b feature/my-feature</code></li>
1804
+ <li>Make changes in a new module under <code>app/js/</code> or enhance existing ones</li>
1805
+ <li>Add tests in <code>app/test-agent.html</code> for your feature</li>
1806
+ <li>Run the visual test agent and verify all tests pass</li>
1807
+ <li>Update documentation in relevant section of <code>app/tutorials/advanced.html</code></li>
1808
+ <li>Commit with descriptive message: <code>git commit -m "feature: add X capability"</code></li>
1809
+ <li>Push to your fork and open a Pull Request</li>
1810
+ <li>Maintainers will review within 48 hours</li>
1811
+ </ol>
1812
+
1813
+ <h2>Code Style</h2>
1814
+ <ul>
1815
+ <li>Use ES6+ modern JavaScript (const/let, arrow functions, async/await)</li>
1816
+ <li>Module-level scope: no global variables except <code>window.cycleCAD</code></li>
1817
+ <li>Comments for non-obvious logic; self-documenting code preferred</li>
1818
+ <li>Follow existing naming conventions (camelCase for functions/vars, PascalCase for classes)</li>
1819
+ <li>Include JSDoc comments for public APIs</li>
1820
+ </ul>
1821
+
1822
+ <h2>Module Template</h2>
1823
+
1824
+ <pre><code><span class="com">/**
1825
+ * my-feature.js - Brief description
1826
+ * Part of cycleCAD
1827
+ */</span>
1828
+
1829
+ <span class="kw">export</span> <span class="kw">async</span> <span class="fn">initMyFeature</span>() {
1830
+ <span class="com">/**
1831
+ * Register feature with Agent API
1832
+ */</span>
1833
+ <span class="kw">const</span> cycleCAD = <span class="obj">window</span>.cycleCAD;
1834
+
1835
+ cycleCAD.<span class="fn">registerCommand</span>({
1836
+ method: <span class="str">'myfeature.action'</span>,
1837
+ description: <span class="str">'Description'</span>,
1838
+ params: { ... },
1839
+ handler: <span class="kw">async</span> (params) => { ... }
1840
+ });
1841
+
1842
+ <span class="com">// Add UI button if needed</span>
1843
+ <span class="kw">const</span> btn = document.<span class="fn">createElement</span>(<span class="str">'button'</span>);
1844
+ btn.textContent = <span class="str">'My Feature'</span>;
1845
+ btn.<span class="fn">addEventListener</span>(<span class="str">'click'</span>, () => { ... });
1846
+ document.<span class="fn">getElementById</span>(<span class="str">'toolbar'</span>).<span class="fn">appendChild</span>(btn);
1847
+ }</code></pre>
1848
+
1849
+ <div class="pro-tip">
1850
+ <strong>Pro Tip:</strong> Start small. Contribute a single module or bug fix rather than redesigning architecture. Easy wins help maintainers review faster.
1851
+ </div>
1852
+
1853
+ <h2>Roadmap & Bounties</h2>
1854
+ <p>Check the GitHub Issues for:</p>
1855
+ <ul>
1856
+ <li><code>good-first-issue</code> — Perfect for new contributors</li>
1857
+ <li><code>bounty</code> — Paid tasks (€50-500 depending on complexity)</li>
1858
+ <li><code>roadmap</code> — Planned features for next phase</li>
1859
+ </ul>
1860
+
1861
+ <p>Active development is driven by community needs. Join the Discord for real-time discussion.</p>
1862
+ </section>
1863
+
1864
+ <!-- Footer -->
1865
+ <div class="footer">
1866
+ <p>cycleCAD Advanced Tutorial — Last updated 2026-03-26</p>
1867
+ <p><a href="https://github.com/vvlars-cmd/cyclecad">GitHub</a> | <a href="https://cyclecad.com">Website</a> | <a href="https://cyclecad.com/app/">Launch App</a></p>
1868
+ </div>
1869
+ </main>
1870
+ </div>
1871
+
1872
+ <script>
1873
+ // Sidebar navigation
1874
+ document.querySelectorAll('.sidebar-item').forEach(item => {
1875
+ item.addEventListener('click', () => {
1876
+ const sectionId = item.dataset.section;
1877
+
1878
+ // Update active states
1879
+ document.querySelectorAll('.sidebar-item').forEach(i => i.classList.remove('active'));
1880
+ item.classList.add('active');
1881
+
1882
+ document.querySelectorAll('.section').forEach(s => s.classList.remove('active'));
1883
+ document.getElementById(sectionId).classList.add('active');
1884
+
1885
+ // Update progress
1886
+ updateProgress();
1887
+
1888
+ // Save to localStorage
1889
+ localStorage.setItem('tutorialSection', sectionId);
1890
+ });
1891
+ });
1892
+
1893
+ // Progress bar
1894
+ function updateProgress() {
1895
+ const sections = ['intro', 'agent-api', 'mcp', 'rest', 'cli', 'tokens', 'marketplace', 'fabs', 'agents', 'machines', 'collab', 'perf', 'docker', 'plugins', 'contrib'];
1896
+ const activeItem = document.querySelector('.sidebar-item.active');
1897
+ const activeIndex = Array.from(document.querySelectorAll('.sidebar-item')).indexOf(activeItem);
1898
+ const progress = ((activeIndex + 1) / sections.length) * 100;
1899
+ document.getElementById('progressFill').style.width = progress + '%';
1900
+ }
1901
+
1902
+ // Restore state from localStorage
1903
+ window.addEventListener('load', () => {
1904
+ const savedSection = localStorage.getItem('tutorialSection') || 'intro';
1905
+ const item = document.querySelector(`[data-section="${savedSection}"]`);
1906
+ if (item) item.click();
1907
+ });
1908
+
1909
+ // Syntax highlighting
1910
+ document.querySelectorAll('pre code').forEach(block => {
1911
+ const html = block.innerHTML;
1912
+
1913
+ // Highlight keywords
1914
+ block.innerHTML = html
1915
+ .replace(/\b(const|let|var|function|async|await|return|if|else|for|while|switch|case|break|default|try|catch|new|typeof|instanceof|this|class|extends|static|get|set|import|export)\b/g, '<span class="kw">$1</span>')
1916
+ .replace(/'([^']*)'|"([^"]*)"|`([^`]*)`/g, (match, sq, dq, bt) => `<span class="str">${match}</span>`)
1917
+ .replace(/\b(\d+|true|false|null|undefined)\b/g, '<span class="num">$1</span>')
1918
+ .replace(/\b([a-z_$][a-z0-9_$]*)\s*(?=\()/g, '<span class="fn">$1</span>')
1919
+ .replace(/#.*$/gm, '<span class="com">$&</span>')
1920
+ .replace(/\/\/.*$/gm, '<span class="com">$&</span>');
1921
+ });
1922
+ </script>
1923
+ </body>
1924
+ </html>