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.
- package/DOCKER-SETUP-VERIFICATION.md +399 -0
- package/DOCKER-TESTING.md +463 -0
- package/FUSION360_MODULES.md +478 -0
- package/FUSION_MODULES_README.md +352 -0
- package/INTEGRATION_SNIPPETS.md +608 -0
- package/KILLER-FEATURES-DELIVERY.md +469 -0
- package/MODULES_SUMMARY.txt +337 -0
- package/QUICK_REFERENCE.txt +298 -0
- package/README-DOCKER-TESTING.txt +438 -0
- package/app/index.html +23 -10
- package/app/js/fusion-help.json +1808 -0
- package/app/js/help-module-v3.js +1096 -0
- package/app/js/killer-features-help.json +395 -0
- package/app/js/killer-features.js +1508 -0
- package/app/js/modules/fusion-assembly.js +842 -0
- package/app/js/modules/fusion-cam.js +785 -0
- package/app/js/modules/fusion-data.js +814 -0
- package/app/js/modules/fusion-drawing.js +844 -0
- package/app/js/modules/fusion-inspection.js +756 -0
- package/app/js/modules/fusion-render.js +774 -0
- package/app/js/modules/fusion-simulation.js +986 -0
- package/app/js/modules/fusion-sketch.js +1044 -0
- package/app/js/modules/fusion-solid.js +1095 -0
- package/app/js/modules/fusion-surface.js +949 -0
- package/app/tests/FUSION_TEST_SUITE.md +266 -0
- package/app/tests/README.md +77 -0
- package/app/tests/TESTING-CHECKLIST.md +177 -0
- package/app/tests/TEST_SUITE_SUMMARY.txt +236 -0
- package/app/tests/brep-live-test.html +848 -0
- package/app/tests/docker-integration-test.html +811 -0
- package/app/tests/fusion-all-tests.html +670 -0
- package/app/tests/fusion-assembly-tests.html +461 -0
- package/app/tests/fusion-cam-tests.html +421 -0
- package/app/tests/fusion-simulation-tests.html +421 -0
- package/app/tests/fusion-sketch-tests.html +613 -0
- package/app/tests/fusion-solid-tests.html +529 -0
- package/app/tests/index.html +453 -0
- package/app/tests/killer-features-test.html +509 -0
- package/app/tests/run-tests.html +874 -0
- package/app/tests/step-import-live-test.html +1115 -0
- package/app/tests/test-agent-v3.html +93 -696
- package/architecture-dashboard.html +1970 -0
- package/docs/API-REFERENCE.md +1423 -0
- package/docs/BREP-LIVE-TEST-GUIDE.md +453 -0
- package/docs/DEVELOPER-GUIDE-v3.md +795 -0
- package/docs/DOCKER-QUICK-TEST.md +376 -0
- package/docs/FUSION-FEATURES-GUIDE.md +2513 -0
- package/docs/FUSION-TUTORIAL.md +1203 -0
- package/docs/INFRASTRUCTURE-GUIDE-INDEX.md +327 -0
- package/docs/KEYBOARD-SHORTCUTS.md +402 -0
- package/docs/KILLER-FEATURES-INTEGRATION.md +412 -0
- package/docs/KILLER-FEATURES-SUMMARY.md +424 -0
- package/docs/KILLER-FEATURES-TUTORIAL.md +784 -0
- package/docs/KILLER-FEATURES.md +562 -0
- package/docs/QUICK-REFERENCE.md +282 -0
- package/docs/README-v3-DOCS.md +274 -0
- package/docs/TUTORIAL-v3.md +1190 -0
- package/docs/architecture-dashboard.html +1970 -0
- package/docs/architecture-v3.html +1038 -0
- package/linkedin-post-v3.md +58 -0
- package/package.json +1 -1
- package/scripts/dev-setup.sh +338 -0
- package/scripts/docker-health-check.sh +159 -0
- package/scripts/integration-test.sh +311 -0
- package/scripts/test-docker.sh +515 -0
|
@@ -0,0 +1,1038 @@
|
|
|
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 v3.2 Architecture</title>
|
|
7
|
+
<style>
|
|
8
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
+
body {
|
|
10
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
11
|
+
background: linear-gradient(135deg, #0f172a 0%, #1a1f3a 100%);
|
|
12
|
+
color: #e0e0e0;
|
|
13
|
+
line-height: 1.6;
|
|
14
|
+
padding: 20px;
|
|
15
|
+
}
|
|
16
|
+
.container {
|
|
17
|
+
max-width: 1400px;
|
|
18
|
+
margin: 0 auto;
|
|
19
|
+
}
|
|
20
|
+
header {
|
|
21
|
+
text-align: center;
|
|
22
|
+
margin-bottom: 40px;
|
|
23
|
+
border-bottom: 2px solid #0284c7;
|
|
24
|
+
padding-bottom: 20px;
|
|
25
|
+
}
|
|
26
|
+
h1 {
|
|
27
|
+
font-size: 2.5em;
|
|
28
|
+
color: #0284c7;
|
|
29
|
+
margin-bottom: 10px;
|
|
30
|
+
}
|
|
31
|
+
.subtitle {
|
|
32
|
+
font-size: 1.1em;
|
|
33
|
+
color: #a0a0a0;
|
|
34
|
+
}
|
|
35
|
+
.stats {
|
|
36
|
+
display: grid;
|
|
37
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
38
|
+
gap: 15px;
|
|
39
|
+
margin: 30px 0;
|
|
40
|
+
}
|
|
41
|
+
.stat-card {
|
|
42
|
+
background: rgba(255, 255, 255, 0.05);
|
|
43
|
+
border: 1px solid #0284c7;
|
|
44
|
+
border-radius: 8px;
|
|
45
|
+
padding: 15px;
|
|
46
|
+
text-align: center;
|
|
47
|
+
}
|
|
48
|
+
.stat-number {
|
|
49
|
+
font-size: 2em;
|
|
50
|
+
color: #0284c7;
|
|
51
|
+
font-weight: bold;
|
|
52
|
+
}
|
|
53
|
+
.stat-label {
|
|
54
|
+
color: #a0a0a0;
|
|
55
|
+
font-size: 0.9em;
|
|
56
|
+
margin-top: 5px;
|
|
57
|
+
}
|
|
58
|
+
.tabs {
|
|
59
|
+
display: flex;
|
|
60
|
+
gap: 10px;
|
|
61
|
+
margin: 30px 0;
|
|
62
|
+
border-bottom: 1px solid #3e3e42;
|
|
63
|
+
flex-wrap: wrap;
|
|
64
|
+
}
|
|
65
|
+
.tab-button {
|
|
66
|
+
padding: 12px 24px;
|
|
67
|
+
background: transparent;
|
|
68
|
+
color: #a0a0a0;
|
|
69
|
+
border: none;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
border-bottom: 2px solid transparent;
|
|
72
|
+
transition: all 0.3s;
|
|
73
|
+
font-size: 1em;
|
|
74
|
+
}
|
|
75
|
+
.tab-button:hover {
|
|
76
|
+
color: #0284c7;
|
|
77
|
+
}
|
|
78
|
+
.tab-button.active {
|
|
79
|
+
color: #0284c7;
|
|
80
|
+
border-bottom-color: #0284c7;
|
|
81
|
+
}
|
|
82
|
+
.tab-content {
|
|
83
|
+
display: none;
|
|
84
|
+
}
|
|
85
|
+
.tab-content.active {
|
|
86
|
+
display: block;
|
|
87
|
+
animation: fadeIn 0.3s;
|
|
88
|
+
}
|
|
89
|
+
@keyframes fadeIn {
|
|
90
|
+
from { opacity: 0; }
|
|
91
|
+
to { opacity: 1; }
|
|
92
|
+
}
|
|
93
|
+
.section {
|
|
94
|
+
background: rgba(255, 255, 255, 0.03);
|
|
95
|
+
border: 1px solid #3e3e42;
|
|
96
|
+
border-radius: 8px;
|
|
97
|
+
padding: 20px;
|
|
98
|
+
margin: 20px 0;
|
|
99
|
+
}
|
|
100
|
+
.section h2 {
|
|
101
|
+
color: #0284c7;
|
|
102
|
+
margin-bottom: 15px;
|
|
103
|
+
font-size: 1.5em;
|
|
104
|
+
}
|
|
105
|
+
.module-grid {
|
|
106
|
+
display: grid;
|
|
107
|
+
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
108
|
+
gap: 15px;
|
|
109
|
+
margin: 20px 0;
|
|
110
|
+
}
|
|
111
|
+
.module-card {
|
|
112
|
+
background: rgba(2, 132, 199, 0.1);
|
|
113
|
+
border: 1px solid #0284c7;
|
|
114
|
+
border-radius: 6px;
|
|
115
|
+
padding: 15px;
|
|
116
|
+
cursor: pointer;
|
|
117
|
+
transition: all 0.3s;
|
|
118
|
+
}
|
|
119
|
+
.module-card:hover {
|
|
120
|
+
background: rgba(2, 132, 199, 0.2);
|
|
121
|
+
transform: translateY(-2px);
|
|
122
|
+
box-shadow: 0 4px 12px rgba(2, 132, 199, 0.2);
|
|
123
|
+
}
|
|
124
|
+
.module-name {
|
|
125
|
+
font-weight: bold;
|
|
126
|
+
color: #0284c7;
|
|
127
|
+
margin-bottom: 5px;
|
|
128
|
+
}
|
|
129
|
+
.module-lines {
|
|
130
|
+
font-size: 0.9em;
|
|
131
|
+
color: #a0a0a0;
|
|
132
|
+
}
|
|
133
|
+
.module-status {
|
|
134
|
+
font-size: 0.8em;
|
|
135
|
+
padding: 4px 8px;
|
|
136
|
+
border-radius: 3px;
|
|
137
|
+
margin-top: 8px;
|
|
138
|
+
display: inline-block;
|
|
139
|
+
}
|
|
140
|
+
.status-complete {
|
|
141
|
+
background: rgba(16, 185, 129, 0.2);
|
|
142
|
+
color: #10b981;
|
|
143
|
+
}
|
|
144
|
+
.status-inprogress {
|
|
145
|
+
background: rgba(245, 158, 11, 0.2);
|
|
146
|
+
color: #f59e0b;
|
|
147
|
+
}
|
|
148
|
+
.flow-diagram {
|
|
149
|
+
background: rgba(255, 255, 255, 0.02);
|
|
150
|
+
border-left: 3px solid #0284c7;
|
|
151
|
+
padding: 15px 20px;
|
|
152
|
+
margin: 15px 0;
|
|
153
|
+
font-family: 'Courier New', monospace;
|
|
154
|
+
font-size: 0.95em;
|
|
155
|
+
overflow-x: auto;
|
|
156
|
+
}
|
|
157
|
+
table {
|
|
158
|
+
width: 100%;
|
|
159
|
+
border-collapse: collapse;
|
|
160
|
+
margin: 15px 0;
|
|
161
|
+
}
|
|
162
|
+
th, td {
|
|
163
|
+
padding: 12px;
|
|
164
|
+
text-align: left;
|
|
165
|
+
border-bottom: 1px solid #3e3e42;
|
|
166
|
+
}
|
|
167
|
+
th {
|
|
168
|
+
background: rgba(2, 132, 199, 0.1);
|
|
169
|
+
color: #0284c7;
|
|
170
|
+
font-weight: bold;
|
|
171
|
+
}
|
|
172
|
+
tr:hover {
|
|
173
|
+
background: rgba(2, 132, 199, 0.05);
|
|
174
|
+
}
|
|
175
|
+
.code-block {
|
|
176
|
+
background: rgba(0, 0, 0, 0.3);
|
|
177
|
+
border: 1px solid #3e3e42;
|
|
178
|
+
border-radius: 4px;
|
|
179
|
+
padding: 12px;
|
|
180
|
+
font-family: 'Courier New', monospace;
|
|
181
|
+
overflow-x: auto;
|
|
182
|
+
margin: 10px 0;
|
|
183
|
+
font-size: 0.9em;
|
|
184
|
+
}
|
|
185
|
+
.highlight {
|
|
186
|
+
color: #10b981;
|
|
187
|
+
}
|
|
188
|
+
.warning {
|
|
189
|
+
background: rgba(239, 68, 68, 0.1);
|
|
190
|
+
border-left: 3px solid #ef4444;
|
|
191
|
+
padding: 12px;
|
|
192
|
+
margin: 15px 0;
|
|
193
|
+
border-radius: 4px;
|
|
194
|
+
}
|
|
195
|
+
.note {
|
|
196
|
+
background: rgba(2, 132, 199, 0.1);
|
|
197
|
+
border-left: 3px solid #0284c7;
|
|
198
|
+
padding: 12px;
|
|
199
|
+
margin: 15px 0;
|
|
200
|
+
border-radius: 4px;
|
|
201
|
+
}
|
|
202
|
+
</style>
|
|
203
|
+
</head>
|
|
204
|
+
<body>
|
|
205
|
+
<div class="container">
|
|
206
|
+
<header>
|
|
207
|
+
<h1>cycleCAD v3.2 Architecture</h1>
|
|
208
|
+
<p class="subtitle">Complete System Design & Component Documentation</p>
|
|
209
|
+
</header>
|
|
210
|
+
|
|
211
|
+
<div class="stats">
|
|
212
|
+
<div class="stat-card">
|
|
213
|
+
<div class="stat-number">90K+</div>
|
|
214
|
+
<div class="stat-label">Total Lines of Code</div>
|
|
215
|
+
</div>
|
|
216
|
+
<div class="stat-card">
|
|
217
|
+
<div class="stat-number">261</div>
|
|
218
|
+
<div class="stat-label">Project Files</div>
|
|
219
|
+
</div>
|
|
220
|
+
<div class="stat-card">
|
|
221
|
+
<div class="stat-number">21</div>
|
|
222
|
+
<div class="stat-label">Core Modules</div>
|
|
223
|
+
</div>
|
|
224
|
+
<div class="stat-card">
|
|
225
|
+
<div class="stat-number">664</div>
|
|
226
|
+
<div class="stat-label">Tests</div>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
|
|
230
|
+
<div class="tabs">
|
|
231
|
+
<button class="tab-button active" onclick="switchTab(event, 'overview')">System Overview</button>
|
|
232
|
+
<button class="tab-button" onclick="switchTab(event, 'modules')">Module Map</button>
|
|
233
|
+
<button class="tab-button" onclick="switchTab(event, 'dataflow')">Data Flow</button>
|
|
234
|
+
<button class="tab-button" onclick="switchTab(event, 'infrastructure')">Infrastructure</button>
|
|
235
|
+
<button class="tab-button" onclick="switchTab(event, 'api')">API Surface</button>
|
|
236
|
+
<button class="tab-button" onclick="switchTab(event, 'tech')">Technology Stack</button>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<!-- ===== SYSTEM OVERVIEW ===== -->
|
|
240
|
+
<div id="overview" class="tab-content active">
|
|
241
|
+
<div class="section">
|
|
242
|
+
<h2>System Architecture</h2>
|
|
243
|
+
<p style="margin-bottom: 20px;">cycleCAD is built on a <strong>LEGO microkernel</strong> architecture where the kernel provides a minimal set of core services and 21 specialized modules provide all user-facing functionality.</p>
|
|
244
|
+
|
|
245
|
+
<div class="flow-diagram">
|
|
246
|
+
┌────────────────────────────────────────────────────────┐
|
|
247
|
+
│ User Interface Layer (React/Vanilla) │
|
|
248
|
+
│ Menu Bar | Toolbars | Panels | 3D Viewport | Timeline │
|
|
249
|
+
└──────────────────────┬─────────────────────────────────┘
|
|
250
|
+
│
|
|
251
|
+
┌──────────────────────▼─────────────────────────────────┐
|
|
252
|
+
│ cycleCAD Kernel (LEGO Event Bus) │
|
|
253
|
+
│ - register() - activate() - exec() - on() │
|
|
254
|
+
│ - state management - module lifecycle - error handling │
|
|
255
|
+
└──────────────────────┬─────────────────────────────────┘
|
|
256
|
+
│
|
|
257
|
+
┌──────────────────────▼─────────────────────────────────┐
|
|
258
|
+
│ 21 Specialized Modules │
|
|
259
|
+
│ [Sketch] [Design] [Assembly] [CAM] [Render] ... │
|
|
260
|
+
└──────────────────────┬─────────────────────────────────┘
|
|
261
|
+
│
|
|
262
|
+
┌──────────────────────▼─────────────────────────────────┐
|
|
263
|
+
│ Core Services Layer │
|
|
264
|
+
│ - Three.js Renderer - IndexedDB Persistence │
|
|
265
|
+
│ - WebRTC Networking - WASM GeometryKernel │
|
|
266
|
+
│ - Stripe Billing - AI/LLM Integration │
|
|
267
|
+
└────────────────────────────────────────────────────────┘
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<h3 style="margin: 25px 0 15px 0; color: #0284c7;">Kernel (100 lines)</h3>
|
|
271
|
+
<p>Minimal event-driven kernel providing:</p>
|
|
272
|
+
<ul style="margin: 10px 0 20px 20px; list-style: none;">
|
|
273
|
+
<li>✓ Module registration & lifecycle management</li>
|
|
274
|
+
<li>✓ Event pub/sub system (30+ core events)</li>
|
|
275
|
+
<li>✓ Command execution pipeline</li>
|
|
276
|
+
<li>✓ Global state management</li>
|
|
277
|
+
<li>✓ Error handling & recovery</li>
|
|
278
|
+
</ul>
|
|
279
|
+
|
|
280
|
+
<h3 style="margin: 25px 0 15px 0; color: #0284c7;">Module System</h3>
|
|
281
|
+
<p>Each module follows a standardized interface:</p>
|
|
282
|
+
<div class="code-block">
|
|
283
|
+
{
|
|
284
|
+
name: 'sketch',
|
|
285
|
+
init() { /* initialize */ },
|
|
286
|
+
deactivate() { /* cleanup */ },
|
|
287
|
+
commands: { line(), circle(), constraint() },
|
|
288
|
+
events: ['sketch:created', 'sketch:modified'],
|
|
289
|
+
dependencies: ['viewport']
|
|
290
|
+
}
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<h3 style="margin: 25px 0 15px 0; color: #0284c7;">Workspace Concept</h3>
|
|
294
|
+
<p>8 specialized workspaces, each activating relevant modules:</p>
|
|
295
|
+
<table>
|
|
296
|
+
<tr>
|
|
297
|
+
<th>Workspace</th>
|
|
298
|
+
<th>Primary Modules</th>
|
|
299
|
+
<th>Purpose</th>
|
|
300
|
+
</tr>
|
|
301
|
+
<tr>
|
|
302
|
+
<td><strong>Design</strong></td>
|
|
303
|
+
<td>sketch, modeling, features, tree</td>
|
|
304
|
+
<td>3D part creation & parametric modeling</td>
|
|
305
|
+
</tr>
|
|
306
|
+
<tr>
|
|
307
|
+
<td><strong>Assembly</strong></td>
|
|
308
|
+
<td>assembly, joints, bom, animation</td>
|
|
309
|
+
<td>Component assembly & constraints</td>
|
|
310
|
+
</tr>
|
|
311
|
+
<tr>
|
|
312
|
+
<td><strong>Render</strong></td>
|
|
313
|
+
<td>rendering, materials, lighting, animation</td>
|
|
314
|
+
<td>High-quality visualization</td>
|
|
315
|
+
</tr>
|
|
316
|
+
<tr>
|
|
317
|
+
<td><strong>Simulation</strong></td>
|
|
318
|
+
<td>fea, dynamics, thermal, stress</td>
|
|
319
|
+
<td>Physics & stress analysis</td>
|
|
320
|
+
</tr>
|
|
321
|
+
<tr>
|
|
322
|
+
<td><strong>CAM</strong></td>
|
|
323
|
+
<td>cam-pipeline, toolpath, post-processor</td>
|
|
324
|
+
<td>Manufacturing path generation</td>
|
|
325
|
+
</tr>
|
|
326
|
+
<tr>
|
|
327
|
+
<td><strong>Drawing</strong></td>
|
|
328
|
+
<td>drawing, dxf-export, annotations</td>
|
|
329
|
+
<td>2D engineering drawings</td>
|
|
330
|
+
</tr>
|
|
331
|
+
<tr>
|
|
332
|
+
<td><strong>Animation</strong></td>
|
|
333
|
+
<td>timeline, keyframe, animation</td>
|
|
334
|
+
<td>Motion sequence creation</td>
|
|
335
|
+
</tr>
|
|
336
|
+
<tr>
|
|
337
|
+
<td><strong>Collaborate</strong></td>
|
|
338
|
+
<td>webrtc, cursors, presence, chat</td>
|
|
339
|
+
<td>Real-time multi-user editing</td>
|
|
340
|
+
</tr>
|
|
341
|
+
</table>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
|
|
345
|
+
<!-- ===== MODULE MAP ===== -->
|
|
346
|
+
<div id="modules" class="tab-content">
|
|
347
|
+
<div class="section">
|
|
348
|
+
<h2>21 Core Modules</h2>
|
|
349
|
+
<p style="margin-bottom: 20px;">Click any module to expand and see dependencies, exports, and status.</p>
|
|
350
|
+
|
|
351
|
+
<div class="module-grid">
|
|
352
|
+
<!-- Engine Modules -->
|
|
353
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
354
|
+
<div class="module-name">sketch</div>
|
|
355
|
+
<div class="module-lines">~900 lines</div>
|
|
356
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
357
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
358
|
+
<strong>Exports:</strong> line(), circle(), rect(), arc(), constraint()<br>
|
|
359
|
+
<strong>Events:</strong> sketch:created, sketch:modified<br>
|
|
360
|
+
<strong>Deps:</strong> viewport, tree
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
|
|
364
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
365
|
+
<div class="module-name">modeling</div>
|
|
366
|
+
<div class="module-lines">~1200 lines</div>
|
|
367
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
368
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
369
|
+
<strong>Exports:</strong> extrude(), revolve(), sweep(), loft()<br>
|
|
370
|
+
<strong>Events:</strong> model:created<br>
|
|
371
|
+
<strong>Deps:</strong> sketch, viewport, tree
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
376
|
+
<div class="module-name">features</div>
|
|
377
|
+
<div class="module-lines">~850 lines</div>
|
|
378
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
379
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
380
|
+
<strong>Exports:</strong> fillet(), chamfer(), pattern(), mirror(), shell()<br>
|
|
381
|
+
<strong>Events:</strong> feature:applied<br>
|
|
382
|
+
<strong>Deps:</strong> modeling, viewport
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
|
|
386
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
387
|
+
<div class="module-name">assembly</div>
|
|
388
|
+
<div class="module-lines">~1100 lines</div>
|
|
389
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
390
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
391
|
+
<strong>Exports:</strong> addComponent(), createJoint(), generateBOM()<br>
|
|
392
|
+
<strong>Events:</strong> assembly:modified<br>
|
|
393
|
+
<strong>Deps:</strong> modeling, tree, viewport
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
|
|
397
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
398
|
+
<div class="module-name">brep</div>
|
|
399
|
+
<div class="module-lines">~950 lines</div>
|
|
400
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
401
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
402
|
+
<strong>Exports:</strong> openBRep(), booleanOp(), healGeometry()<br>
|
|
403
|
+
<strong>Events:</strong> brep:loaded<br>
|
|
404
|
+
<strong>Deps:</strong> viewport (uses OpenCascade.js WASM)
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
<!-- Data & I/O Modules -->
|
|
409
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
410
|
+
<div class="module-name">io-import</div>
|
|
411
|
+
<div class="module-lines">~780 lines</div>
|
|
412
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
413
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
414
|
+
<strong>Exports:</strong> importSTEP(), importIGES(), importOBJ()<br>
|
|
415
|
+
<strong>Events:</strong> file:imported<br>
|
|
416
|
+
<strong>Deps:</strong> viewport, tree, brep
|
|
417
|
+
</div>
|
|
418
|
+
</div>
|
|
419
|
+
|
|
420
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
421
|
+
<div class="module-name">io-export</div>
|
|
422
|
+
<div class="module-lines">~720 lines</div>
|
|
423
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
424
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
425
|
+
<strong>Exports:</strong> exportSTL(), exportSTEP(), exportGLTF(), exportPDF()<br>
|
|
426
|
+
<strong>Events:</strong> export:started, export:finished<br>
|
|
427
|
+
<strong>Deps:</strong> viewport
|
|
428
|
+
</div>
|
|
429
|
+
</div>
|
|
430
|
+
|
|
431
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
432
|
+
<div class="module-name">persistence</div>
|
|
433
|
+
<div class="module-lines">~650 lines</div>
|
|
434
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
435
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
436
|
+
<strong>Exports:</strong> save(), load(), cloudSync()<br>
|
|
437
|
+
<strong>Events:</strong> file:saved, file:loaded<br>
|
|
438
|
+
<strong>Deps:</strong> IndexedDB, Stripe auth
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
|
|
442
|
+
<!-- Visualization -->
|
|
443
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
444
|
+
<div class="module-name">viewport</div>
|
|
445
|
+
<div class="module-lines">~1050 lines</div>
|
|
446
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
447
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
448
|
+
<strong>Exports:</strong> render(), fitView(), showGrid()<br>
|
|
449
|
+
<strong>Events:</strong> viewport:changed<br>
|
|
450
|
+
<strong>Deps:</strong> Three.js, WebGL
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
455
|
+
<div class="module-name">rendering</div>
|
|
456
|
+
<div class="module-lines">~920 lines</div>
|
|
457
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
458
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
459
|
+
<strong>Exports:</strong> setMaterial(), setLighting(), enableShadows()<br>
|
|
460
|
+
<strong>Events:</strong> render:quality-changed<br>
|
|
461
|
+
<strong>Deps:</strong> viewport, materials
|
|
462
|
+
</div>
|
|
463
|
+
</div>
|
|
464
|
+
|
|
465
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
466
|
+
<div class="module-name">materials</div>
|
|
467
|
+
<div class="module-lines">~680 lines</div>
|
|
468
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
469
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
470
|
+
<strong>Exports:</strong> getMaterial(), setPBRProperties()<br>
|
|
471
|
+
<strong>Events:</strong> material:changed<br>
|
|
472
|
+
<strong>Deps:</strong> rendering
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
|
|
476
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
477
|
+
<div class="module-name">animation</div>
|
|
478
|
+
<div class="module-lines">~850 lines</div>
|
|
479
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
480
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
481
|
+
<strong>Exports:</strong> createKeyframe(), playAnimation(), recordMotion()<br>
|
|
482
|
+
<strong>Events:</strong> animation:played<br>
|
|
483
|
+
<strong>Deps:</strong> timeline, viewport
|
|
484
|
+
</div>
|
|
485
|
+
</div>
|
|
486
|
+
|
|
487
|
+
<!-- Platform -->
|
|
488
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
489
|
+
<div class="module-name">tree</div>
|
|
490
|
+
<div class="module-lines">~720 lines</div>
|
|
491
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
492
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
493
|
+
<strong>Exports:</strong> addNode(), deleteNode(), renameFeature()<br>
|
|
494
|
+
<strong>Events:</strong> tree:modified<br>
|
|
495
|
+
<strong>Deps:</strong> viewport
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
|
|
499
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
500
|
+
<div class="module-name">timeline</div>
|
|
501
|
+
<div class="module-lines">~640 lines</div>
|
|
502
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
503
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
504
|
+
<strong>Exports:</strong> addKeyframe(), seekToFrame()<br>
|
|
505
|
+
<strong>Events:</strong> timeline:changed<br>
|
|
506
|
+
<strong>Deps:</strong> animation, viewport
|
|
507
|
+
</div>
|
|
508
|
+
</div>
|
|
509
|
+
|
|
510
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
511
|
+
<div class="module-name">toolbar</div>
|
|
512
|
+
<div class="module-lines">~560 lines</div>
|
|
513
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
514
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
515
|
+
<strong>Exports:</strong> registerButton(), switchWorkspace()<br>
|
|
516
|
+
<strong>Events:</strong> toolbar:clicked<br>
|
|
517
|
+
<strong>Deps:</strong> ui
|
|
518
|
+
</div>
|
|
519
|
+
</div>
|
|
520
|
+
|
|
521
|
+
<!-- Manufacturing -->
|
|
522
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
523
|
+
<div class="module-name">cam-pipeline</div>
|
|
524
|
+
<div class="module-lines">~940 lines</div>
|
|
525
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
526
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
527
|
+
<strong>Exports:</strong> generateToolpath(), optimizePath()<br>
|
|
528
|
+
<strong>Events:</strong> cam:complete<br>
|
|
529
|
+
<strong>Deps:</strong> modeling, viewport
|
|
530
|
+
</div>
|
|
531
|
+
</div>
|
|
532
|
+
|
|
533
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
534
|
+
<div class="module-name">drawing</div>
|
|
535
|
+
<div class="module-lines">~870 lines</div>
|
|
536
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
537
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
538
|
+
<strong>Exports:</strong> addDimension(), addNote(), setViewport()<br>
|
|
539
|
+
<strong>Events:</strong> drawing:modified<br>
|
|
540
|
+
<strong>Deps:</strong> io-export, viewport
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
|
|
544
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
545
|
+
<div class="module-name">simulation</div>
|
|
546
|
+
<div class="module-lines">~1100 lines</div>
|
|
547
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
548
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
549
|
+
<strong>Exports:</strong> runFEA(), analyzeThermal(), stressTest()<br>
|
|
550
|
+
<strong>Events:</strong> simulation:complete<br>
|
|
551
|
+
<strong>Deps:</strong> modeling, materials, viewport
|
|
552
|
+
</div>
|
|
553
|
+
</div>
|
|
554
|
+
|
|
555
|
+
<!-- AI & Platform -->
|
|
556
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
557
|
+
<div class="module-name">ai-copilot</div>
|
|
558
|
+
<div class="module-lines">~1050 lines</div>
|
|
559
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
560
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
561
|
+
<strong>Exports:</strong> textToCAD(), suggestFeature(), generateDesign()<br>
|
|
562
|
+
<strong>Events:</strong> ai:suggestion, ai:design-generated<br>
|
|
563
|
+
<strong>Deps:</strong> modeling, llm-gateway
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
|
|
567
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
568
|
+
<div class="module-name">webrtc</div>
|
|
569
|
+
<div class="module-lines">~820 lines</div>
|
|
570
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
571
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
572
|
+
<strong>Exports:</strong> startSession(), syncChanges(), broadcastCursor()<br>
|
|
573
|
+
<strong>Events:</strong> collab:joined, collab:left<br>
|
|
574
|
+
<strong>Deps:</strong> persistence
|
|
575
|
+
</div>
|
|
576
|
+
</div>
|
|
577
|
+
|
|
578
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
579
|
+
<div class="module-name">billing</div>
|
|
580
|
+
<div class="module-lines">~790 lines</div>
|
|
581
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
582
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
583
|
+
<strong>Exports:</strong> trackUsage(), calculateCost(), processPayout()<br>
|
|
584
|
+
<strong>Events:</strong> billing:charged<br>
|
|
585
|
+
<strong>Deps:</strong> Stripe API, auth
|
|
586
|
+
</div>
|
|
587
|
+
</div>
|
|
588
|
+
|
|
589
|
+
<div class="module-card" onclick="toggleModule(this)">
|
|
590
|
+
<div class="module-name">marketplace</div>
|
|
591
|
+
<div class="module-lines">~950 lines</div>
|
|
592
|
+
<div class="module-status status-complete">✓ Complete</div>
|
|
593
|
+
<div style="font-size: 0.8em; color: #a0a0a0; margin-top: 10px; display:none; padding-top:10px; border-top: 1px solid #3e3e42;">
|
|
594
|
+
<strong>Exports:</strong> publishModel(), buyModel(), rateDesign()<br>
|
|
595
|
+
<strong>Events:</strong> marketplace:purchased<br>
|
|
596
|
+
<strong>Deps:</strong> persistence, billing
|
|
597
|
+
</div>
|
|
598
|
+
</div>
|
|
599
|
+
</div>
|
|
600
|
+
|
|
601
|
+
<div class="note">
|
|
602
|
+
<strong>Module Lifecycle:</strong> register() → init() → activate() → execute commands → deactivate() → unload()
|
|
603
|
+
</div>
|
|
604
|
+
</div>
|
|
605
|
+
</div>
|
|
606
|
+
|
|
607
|
+
<!-- ===== DATA FLOW ===== -->
|
|
608
|
+
<div id="dataflow" class="tab-content">
|
|
609
|
+
<div class="section">
|
|
610
|
+
<h2>Data Flow Architecture</h2>
|
|
611
|
+
|
|
612
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Event-Driven Flow</h3>
|
|
613
|
+
<div class="flow-diagram">
|
|
614
|
+
User Action (click, drag, keyboard)
|
|
615
|
+
↓
|
|
616
|
+
UI Layer captures event
|
|
617
|
+
↓
|
|
618
|
+
Emits: kernel.emit('action:type', {data})
|
|
619
|
+
↓
|
|
620
|
+
Active Modules listen to event
|
|
621
|
+
↓
|
|
622
|
+
Command Pipeline: exec(command, params)
|
|
623
|
+
↓
|
|
624
|
+
Module executes: geometry update, state change
|
|
625
|
+
↓
|
|
626
|
+
Emits: kernel.emit('model:changed', {delta})
|
|
627
|
+
↓
|
|
628
|
+
Subscribers update:
|
|
629
|
+
- Viewport (re-render)
|
|
630
|
+
- Tree (refresh)
|
|
631
|
+
- Timeline (update keyframes)
|
|
632
|
+
- Persistence (save)
|
|
633
|
+
↓
|
|
634
|
+
UI reflects changes
|
|
635
|
+
</div>
|
|
636
|
+
|
|
637
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Command Execution Pipeline</h3>
|
|
638
|
+
<table>
|
|
639
|
+
<tr>
|
|
640
|
+
<th>Stage</th>
|
|
641
|
+
<th>Description</th>
|
|
642
|
+
<th>Example</th>
|
|
643
|
+
</tr>
|
|
644
|
+
<tr>
|
|
645
|
+
<td>Validation</td>
|
|
646
|
+
<td>Check params, permissions, state</td>
|
|
647
|
+
<td>Is extrude depth valid? Is user Pro tier?</td>
|
|
648
|
+
</tr>
|
|
649
|
+
<tr>
|
|
650
|
+
<td>Pre-hooks</td>
|
|
651
|
+
<td>Any module can intercept</td>
|
|
652
|
+
<td>Billing module charges user</td>
|
|
653
|
+
</tr>
|
|
654
|
+
<tr>
|
|
655
|
+
<td>Execution</td>
|
|
656
|
+
<td>Module runs actual command</td>
|
|
657
|
+
<td>geometry.extrude(sketch, depth)</td>
|
|
658
|
+
</tr>
|
|
659
|
+
<tr>
|
|
660
|
+
<td>State Update</td>
|
|
661
|
+
<td>Update global + local state</td>
|
|
662
|
+
<td>tree.addNode(), model.updateBBox()</td>
|
|
663
|
+
</tr>
|
|
664
|
+
<tr>
|
|
665
|
+
<td>Undo Push</td>
|
|
666
|
+
<td>Save to undo history</td>
|
|
667
|
+
<td>history.push({cmd, params, undo})</td>
|
|
668
|
+
</tr>
|
|
669
|
+
<tr>
|
|
670
|
+
<td>Post-hooks</td>
|
|
671
|
+
<td>Modules react to change</td>
|
|
672
|
+
<td>Render viewport, update BOM</td>
|
|
673
|
+
</tr>
|
|
674
|
+
<tr>
|
|
675
|
+
<td>Sync</td>
|
|
676
|
+
<td>Broadcast if collaborative</td>
|
|
677
|
+
<td>webrtc.broadcast({delta})</td>
|
|
678
|
+
</tr>
|
|
679
|
+
</table>
|
|
680
|
+
|
|
681
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">State Management</h3>
|
|
682
|
+
<p>Three layers of state:</p>
|
|
683
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
684
|
+
<li><strong>Global State:</strong> window.ccad = { model, assembly, config, auth, billing }</li>
|
|
685
|
+
<li><strong>Module State:</strong> Each module can maintain local state (sketch.constraints, cam.toolpaths)</li>
|
|
686
|
+
<li><strong>UI State:</strong> DOM attributes (data-selected, data-expanded)</li>
|
|
687
|
+
</ul>
|
|
688
|
+
|
|
689
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Persistence Layer</h3>
|
|
690
|
+
<div class="flow-diagram">
|
|
691
|
+
Memory (scene graph)
|
|
692
|
+
↓
|
|
693
|
+
IndexedDB (local cache)
|
|
694
|
+
↓
|
|
695
|
+
Cloud Sync (if Pro)
|
|
696
|
+
↓
|
|
697
|
+
Version Control (collaborative)
|
|
698
|
+
↓
|
|
699
|
+
Backups (every hour)
|
|
700
|
+
</div>
|
|
701
|
+
</div>
|
|
702
|
+
</div>
|
|
703
|
+
|
|
704
|
+
<!-- ===== INFRASTRUCTURE ===== -->
|
|
705
|
+
<div id="infrastructure" class="tab-content">
|
|
706
|
+
<div class="section">
|
|
707
|
+
<h2>Infrastructure & Deployment</h2>
|
|
708
|
+
|
|
709
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Docker Architecture (3 Services)</h3>
|
|
710
|
+
<table>
|
|
711
|
+
<tr>
|
|
712
|
+
<th>Service</th>
|
|
713
|
+
<th>Image</th>
|
|
714
|
+
<th>Port</th>
|
|
715
|
+
<th>Purpose</th>
|
|
716
|
+
</tr>
|
|
717
|
+
<tr>
|
|
718
|
+
<td><strong>cyclecad-app</strong></td>
|
|
719
|
+
<td>nginx:alpine</td>
|
|
720
|
+
<td>8080</td>
|
|
721
|
+
<td>Frontend: static assets, SPA</td>
|
|
722
|
+
</tr>
|
|
723
|
+
<tr>
|
|
724
|
+
<td><strong>cyclecad-api</strong></td>
|
|
725
|
+
<td>node:20-alpine</td>
|
|
726
|
+
<td>8787</td>
|
|
727
|
+
<td>REST API, MCP server, WebSocket</td>
|
|
728
|
+
</tr>
|
|
729
|
+
<tr>
|
|
730
|
+
<td><strong>cyclecad-worker</strong></td>
|
|
731
|
+
<td>python:3.11</td>
|
|
732
|
+
<td>8888</td>
|
|
733
|
+
<td>STEP conversion, CAM toolpath, FEA</td>
|
|
734
|
+
</tr>
|
|
735
|
+
</table>
|
|
736
|
+
|
|
737
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Data Storage</h3>
|
|
738
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
739
|
+
<li><strong>IndexedDB:</strong> Local client-side cache (models, sketches, recent files)</li>
|
|
740
|
+
<li><strong>PostgreSQL:</strong> Cloud persistence (user files, billing, marketplace)</li>
|
|
741
|
+
<li><strong>S3:</strong> Model storage (STL, STEP, GLTF exports)</li>
|
|
742
|
+
<li><strong>Redis:</strong> Session management, collaborative cursors cache</li>
|
|
743
|
+
</ul>
|
|
744
|
+
|
|
745
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Network & Real-time</h3>
|
|
746
|
+
<div class="code-block">
|
|
747
|
+
REST API:
|
|
748
|
+
GET /api/models/:id
|
|
749
|
+
POST /api/models
|
|
750
|
+
PUT /api/models/:id
|
|
751
|
+
DELETE /api/models/:id
|
|
752
|
+
POST /api/export (STL, STEP, GLTF)
|
|
753
|
+
POST /api/simulate
|
|
754
|
+
|
|
755
|
+
WebSocket (Real-time):
|
|
756
|
+
connection: subscribe to room
|
|
757
|
+
message: broadcast geometry delta
|
|
758
|
+
cursor: send user cursor position
|
|
759
|
+
chat: send collaboration messages
|
|
760
|
+
presence: user joined/left
|
|
761
|
+
|
|
762
|
+
MCP Server:
|
|
763
|
+
cyclecad:sketch.line(p1, p2)
|
|
764
|
+
cyclecad:modeling.extrude(sketchId, depth)
|
|
765
|
+
cyclecad:export.stl(modelId)
|
|
766
|
+
</div>
|
|
767
|
+
|
|
768
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">CDN & Assets</h3>
|
|
769
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
770
|
+
<li>Three.js (r170) from cdn.jsdelivr.net</li>
|
|
771
|
+
<li>OpenCascade.js (WASM) from CDN</li>
|
|
772
|
+
<li>UI icons from Font Awesome</li>
|
|
773
|
+
<li>DUI models cached in browser IndexedDB</li>
|
|
774
|
+
</ul>
|
|
775
|
+
|
|
776
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Authentication & Billing</h3>
|
|
777
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
778
|
+
<li>OAuth 2.0 (Google, GitHub)</li>
|
|
779
|
+
<li>JWT tokens stored in localStorage</li>
|
|
780
|
+
<li>Stripe integration for billing (€49/mo Pro, €299/mo Enterprise)</li>
|
|
781
|
+
<li>$CYCLE token economy for usage-based billing</li>
|
|
782
|
+
</ul>
|
|
783
|
+
</div>
|
|
784
|
+
</div>
|
|
785
|
+
|
|
786
|
+
<!-- ===== API SURFACE ===== -->
|
|
787
|
+
<div id="api" class="tab-content">
|
|
788
|
+
<div class="section">
|
|
789
|
+
<h2>API Surface</h2>
|
|
790
|
+
|
|
791
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Agent API (55 Commands)</h3>
|
|
792
|
+
<table>
|
|
793
|
+
<tr>
|
|
794
|
+
<th>Namespace</th>
|
|
795
|
+
<th>Commands</th>
|
|
796
|
+
<th>Example</th>
|
|
797
|
+
</tr>
|
|
798
|
+
<tr>
|
|
799
|
+
<td><strong>shape.*</strong></td>
|
|
800
|
+
<td>cylinder, box, sphere, cone, torus, wedge, extrude, revolve</td>
|
|
801
|
+
<td>cycleCAD.execute('shape.cylinder', {d: 50, h: 80})</td>
|
|
802
|
+
</tr>
|
|
803
|
+
<tr>
|
|
804
|
+
<td><strong>feature.*</strong></td>
|
|
805
|
+
<td>fillet, chamfer, pattern, mirror, shell, draft, thread</td>
|
|
806
|
+
<td>cycleCAD.execute('feature.fillet', {radius: 5, edges: [0,1,2]})</td>
|
|
807
|
+
</tr>
|
|
808
|
+
<tr>
|
|
809
|
+
<td><strong>assembly.*</strong></td>
|
|
810
|
+
<td>addComponent, createJoint, explode, generateBOM</td>
|
|
811
|
+
<td>cycleCAD.execute('assembly.addComponent', {file: 'part.step'})</td>
|
|
812
|
+
</tr>
|
|
813
|
+
<tr>
|
|
814
|
+
<td><strong>render.*</strong></td>
|
|
815
|
+
<td>snapshot, multiview, fitToObject, setMaterial</td>
|
|
816
|
+
<td>cycleCAD.execute('render.snapshot', {width: 1920, height: 1080})</td>
|
|
817
|
+
</tr>
|
|
818
|
+
<tr>
|
|
819
|
+
<td><strong>validate.*</strong></td>
|
|
820
|
+
<td>checkInterference, estimateCost, estimateWeight, designReview</td>
|
|
821
|
+
<td>cycleCAD.execute('validate.designReview', {})</td>
|
|
822
|
+
</tr>
|
|
823
|
+
<tr>
|
|
824
|
+
<td><strong>export.*</strong></td>
|
|
825
|
+
<td>stl, step, gltf, obj, dxf, pdf</td>
|
|
826
|
+
<td>cycleCAD.execute('export.stl', {format: 'binary'})</td>
|
|
827
|
+
</tr>
|
|
828
|
+
<tr>
|
|
829
|
+
<td><strong>import.*</strong></td>
|
|
830
|
+
<td>step, iges, obj, stp, ipt, iam</td>
|
|
831
|
+
<td>cycleCAD.execute('import.step', {file: blob})</td>
|
|
832
|
+
</tr>
|
|
833
|
+
<tr>
|
|
834
|
+
<td><strong>ai.*</strong></td>
|
|
835
|
+
<td>textToCAD, identifyPart, suggestFeature, generateDesign</td>
|
|
836
|
+
<td>cycleCAD.execute('ai.textToCAD', {prompt: 'socket head bolt'})</td>
|
|
837
|
+
</tr>
|
|
838
|
+
<tr>
|
|
839
|
+
<td><strong>workspace.*</strong></td>
|
|
840
|
+
<td>switch, getActive, listWorkspaces</td>
|
|
841
|
+
<td>cycleCAD.execute('workspace.switch', {name: 'CAM'})</td>
|
|
842
|
+
</tr>
|
|
843
|
+
<tr>
|
|
844
|
+
<td><strong>file.*</strong></td>
|
|
845
|
+
<td>new, open, save, saveAs, close, export</td>
|
|
846
|
+
<td>cycleCAD.execute('file.save', {path: '/models/bracket.ccad'})</td>
|
|
847
|
+
</tr>
|
|
848
|
+
</table>
|
|
849
|
+
|
|
850
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">REST Endpoints</h3>
|
|
851
|
+
<div class="code-block">
|
|
852
|
+
POST /api/v1/models
|
|
853
|
+
{ name, description, file }
|
|
854
|
+
Returns: { id, created_at, owner_id }
|
|
855
|
+
|
|
856
|
+
GET /api/v1/models/:id
|
|
857
|
+
Returns: full model JSON
|
|
858
|
+
|
|
859
|
+
PUT /api/v1/models/:id
|
|
860
|
+
{ properties, geometry }
|
|
861
|
+
|
|
862
|
+
DELETE /api/v1/models/:id
|
|
863
|
+
|
|
864
|
+
POST /api/v1/export
|
|
865
|
+
{ modelId, format: 'stl'|'step'|'gltf' }
|
|
866
|
+
Returns: download link
|
|
867
|
+
|
|
868
|
+
POST /api/v1/simulate
|
|
869
|
+
{ modelId, type: 'fea'|'thermal', constraints }
|
|
870
|
+
Returns: { jobId, estimatedTime }
|
|
871
|
+
|
|
872
|
+
GET /api/v1/simulate/:jobId
|
|
873
|
+
Returns: { status, progress, results }
|
|
874
|
+
</div>
|
|
875
|
+
|
|
876
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">MCP Server</h3>
|
|
877
|
+
<p>Exposes all 55 Agent API commands as Model Context Protocol tools.</p>
|
|
878
|
+
<div class="code-block">
|
|
879
|
+
mcp-server list:
|
|
880
|
+
cyclecad:shape.cylinder
|
|
881
|
+
cyclecad:shape.box
|
|
882
|
+
cyclecad:feature.fillet
|
|
883
|
+
cyclecad:export.stl
|
|
884
|
+
... (50+ more)
|
|
885
|
+
|
|
886
|
+
Usage:
|
|
887
|
+
const client = new MCPClient('http://localhost:8787/mcp');
|
|
888
|
+
await client.call('cyclecad:shape.cylinder', {diameter: 50, height: 80});
|
|
889
|
+
</div>
|
|
890
|
+
|
|
891
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">CLI Tool</h3>
|
|
892
|
+
<div class="code-block">
|
|
893
|
+
$ cyclecad shape.cylinder --diameter 50 --height 80 --output part.stl
|
|
894
|
+
$ cyclecad import.step --file frame.stp --output model.ccad
|
|
895
|
+
$ cyclecad feature.fillet --model part.ccad --radius 5 --edges 0,1,2
|
|
896
|
+
$ cyclecad export.pdf --model drawing.ccad --size A2
|
|
897
|
+
</div>
|
|
898
|
+
</div>
|
|
899
|
+
</div>
|
|
900
|
+
|
|
901
|
+
<!-- ===== TECHNOLOGY STACK ===== -->
|
|
902
|
+
<div id="tech" class="tab-content">
|
|
903
|
+
<div class="section">
|
|
904
|
+
<h2>Technology Stack</h2>
|
|
905
|
+
|
|
906
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Frontend</h3>
|
|
907
|
+
<table>
|
|
908
|
+
<tr>
|
|
909
|
+
<th>Technology</th>
|
|
910
|
+
<th>Version</th>
|
|
911
|
+
<th>Purpose</th>
|
|
912
|
+
</tr>
|
|
913
|
+
<tr>
|
|
914
|
+
<td>Three.js</td>
|
|
915
|
+
<td>r170</td>
|
|
916
|
+
<td>3D rendering, WebGL</td>
|
|
917
|
+
</tr>
|
|
918
|
+
<tr>
|
|
919
|
+
<td>HTML5 Canvas</td>
|
|
920
|
+
<td>native</td>
|
|
921
|
+
<td>2D sketch, engineering drawings</td>
|
|
922
|
+
</tr>
|
|
923
|
+
<tr>
|
|
924
|
+
<td>CSS Grid/Flex</td>
|
|
925
|
+
<td>CSS3</td>
|
|
926
|
+
<td>UI layout</td>
|
|
927
|
+
</tr>
|
|
928
|
+
<tr>
|
|
929
|
+
<td>IndexedDB</td>
|
|
930
|
+
<td>native</td>
|
|
931
|
+
<td>Local caching, offline support</td>
|
|
932
|
+
</tr>
|
|
933
|
+
<tr>
|
|
934
|
+
<td>WebGL</td>
|
|
935
|
+
<td>2.0</td>
|
|
936
|
+
<td>Graphics API</td>
|
|
937
|
+
</tr>
|
|
938
|
+
<tr>
|
|
939
|
+
<td>WebWorker</td>
|
|
940
|
+
<td>native</td>
|
|
941
|
+
<td>Background processing (CAM, simulation)</td>
|
|
942
|
+
</tr>
|
|
943
|
+
<tr>
|
|
944
|
+
<td>WebRTC</td>
|
|
945
|
+
<td>native</td>
|
|
946
|
+
<td>Real-time collaboration</td>
|
|
947
|
+
</tr>
|
|
948
|
+
</table>
|
|
949
|
+
|
|
950
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Backend</h3>
|
|
951
|
+
<table>
|
|
952
|
+
<tr>
|
|
953
|
+
<th>Technology</th>
|
|
954
|
+
<th>Purpose</th>
|
|
955
|
+
</tr>
|
|
956
|
+
<tr>
|
|
957
|
+
<td>Node.js 20</td>
|
|
958
|
+
<td>API server, MCP server</td>
|
|
959
|
+
</tr>
|
|
960
|
+
<tr>
|
|
961
|
+
<td>Express.js</td>
|
|
962
|
+
<td>HTTP routing</td>
|
|
963
|
+
</tr>
|
|
964
|
+
<tr>
|
|
965
|
+
<td>WebSocket</td>
|
|
966
|
+
<td>Real-time messaging</td>
|
|
967
|
+
</tr>
|
|
968
|
+
<tr>
|
|
969
|
+
<td>PostgreSQL</td>
|
|
970
|
+
<td>Persistent data storage</td>
|
|
971
|
+
</tr>
|
|
972
|
+
<tr>
|
|
973
|
+
<td>Redis</td>
|
|
974
|
+
<td>Session cache, pub/sub</td>
|
|
975
|
+
</tr>
|
|
976
|
+
<tr>
|
|
977
|
+
<td>Python 3.11</td>
|
|
978
|
+
<td>Worker processes (CAM, FEA, conversion)</td>
|
|
979
|
+
</tr>
|
|
980
|
+
</table>
|
|
981
|
+
|
|
982
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">WASM & Kernels</h3>
|
|
983
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
984
|
+
<li><strong>OpenCascade.js</strong> – B-Rep geometry kernel (STEP, IGES, boolean operations)</li>
|
|
985
|
+
<li><strong>Emscripten</strong> – C++ → WASM compiler</li>
|
|
986
|
+
<li><strong>TinySolver</strong> – 2D constraint solving</li>
|
|
987
|
+
</ul>
|
|
988
|
+
|
|
989
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">AI & LLM</h3>
|
|
990
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
991
|
+
<li><strong>Google Gemini Flash</strong> – Text-to-CAD, design review</li>
|
|
992
|
+
<li><strong>Groq Llama 3.1 8B</strong> – Local AI fallback</li>
|
|
993
|
+
<li><strong>OpenAI Vision</strong> – Part identification from images</li>
|
|
994
|
+
</ul>
|
|
995
|
+
|
|
996
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">External Services</h3>
|
|
997
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
998
|
+
<li><strong>Stripe</strong> – Payment processing, subscription billing</li>
|
|
999
|
+
<li><strong>AWS S3</strong> – File storage</li>
|
|
1000
|
+
<li><strong>SendGrid</strong> – Email notifications</li>
|
|
1001
|
+
<li><strong>Datadog</strong> – Monitoring & logging</li>
|
|
1002
|
+
</ul>
|
|
1003
|
+
|
|
1004
|
+
<h3 style="margin: 20px 0 15px 0; color: #0284c7;">Development Tools</h3>
|
|
1005
|
+
<ul style="margin: 10px 0 20px 20px;">
|
|
1006
|
+
<li><strong>Git</strong> – Version control</li>
|
|
1007
|
+
<li><strong>Docker</strong> – Containerization</li>
|
|
1008
|
+
<li><strong>Jest</strong> – Unit testing</li>
|
|
1009
|
+
<li><strong>Playwright</strong> – E2E testing</li>
|
|
1010
|
+
<li><strong>Webpack</strong> – Module bundling (optional)</li>
|
|
1011
|
+
</ul>
|
|
1012
|
+
</div>
|
|
1013
|
+
</div>
|
|
1014
|
+
</div>
|
|
1015
|
+
|
|
1016
|
+
<script>
|
|
1017
|
+
function switchTab(event, tabName) {
|
|
1018
|
+
const tabs = document.querySelectorAll('.tab-content');
|
|
1019
|
+
const buttons = document.querySelectorAll('.tab-button');
|
|
1020
|
+
|
|
1021
|
+
tabs.forEach(tab => tab.classList.remove('active'));
|
|
1022
|
+
buttons.forEach(btn => btn.classList.remove('active'));
|
|
1023
|
+
|
|
1024
|
+
document.getElementById(tabName).classList.add('active');
|
|
1025
|
+
event.target.classList.add('active');
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
function toggleModule(card) {
|
|
1029
|
+
const details = card.querySelector('div[style*="display:none"]');
|
|
1030
|
+
if (details) {
|
|
1031
|
+
const isHidden = details.style.display === 'none';
|
|
1032
|
+
details.style.display = isHidden ? 'block' : 'none';
|
|
1033
|
+
card.style.background = isHidden ? 'rgba(2, 132, 199, 0.15)' : 'rgba(2, 132, 199, 0.1)';
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
</script>
|
|
1037
|
+
</body>
|
|
1038
|
+
</html>
|