cyclecad 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) 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 +168 -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/cam-pipeline.js +840 -0
  32. package/app/js/collaboration-ui.js +995 -0
  33. package/app/js/collaboration.js +1116 -0
  34. package/app/js/connected-fabs-example.js +404 -0
  35. package/app/js/connected-fabs.js +1449 -0
  36. package/app/js/dfm-analyzer.js +1760 -0
  37. package/app/js/marketplace.js +1994 -0
  38. package/app/js/material-library.js +2115 -0
  39. package/app/js/token-dashboard.js +563 -0
  40. package/app/js/token-engine.js +743 -0
  41. package/app/test-agent.html +1801 -0
  42. package/bin/cyclecad-cli.js +662 -0
  43. package/bin/cyclecad-mcp +2 -0
  44. package/bin/server.js +242 -0
  45. package/cycleCAD-Architecture.pptx +0 -0
  46. package/cycleCAD-Investor-Deck.pptx +0 -0
  47. package/demo-mcp.sh +60 -0
  48. package/docs/API-SERVER-SUMMARY.md +375 -0
  49. package/docs/API-SERVER.md +667 -0
  50. package/docs/CAM-EXAMPLES.md +344 -0
  51. package/docs/CAM-INTEGRATION.md +612 -0
  52. package/docs/CAM-QUICK-REFERENCE.md +199 -0
  53. package/docs/CLI-INTEGRATION.md +510 -0
  54. package/docs/CLI.md +872 -0
  55. package/docs/MARKETPLACE-API-SCHEMA.json +564 -0
  56. package/docs/MARKETPLACE-INTEGRATION.md +467 -0
  57. package/docs/MARKETPLACE-SETUP.html +439 -0
  58. package/docs/MCP-SERVER.md +403 -0
  59. package/examples/api-client-example.js +488 -0
  60. package/examples/api-client-example.py +359 -0
  61. package/examples/batch-manufacturing.txt +28 -0
  62. package/examples/batch-simple.txt +26 -0
  63. package/model-marketplace.html +1273 -0
  64. package/package.json +14 -3
  65. package/server/api-server.js +1120 -0
  66. package/server/mcp-server.js +1161 -0
  67. package/test-api-server.js +432 -0
  68. package/test-mcp.js +198 -0
  69. package/~$cycleCAD-Investor-Deck.pptx +0 -0
@@ -0,0 +1,199 @@
1
+ # CAM Pipeline — Quick Reference
2
+
3
+ ## Quick Start (30 seconds)
4
+
5
+ ```javascript
6
+ // 1. Get a mesh
7
+ const mesh = window.allParts[0];
8
+
9
+ // 2. Slice for 3D printing
10
+ const slice = window.cycleCAD.cam.slice(mesh, {
11
+ printer: 'ender3',
12
+ material: 'pla'
13
+ });
14
+
15
+ // 3. Download G-code
16
+ window.cycleCAD.cam.exportGcode(slice.gcode, 'part.gcode');
17
+
18
+ // 4. Compare costs
19
+ const costs = window.cycleCAD.cam.compareCosts(mesh);
20
+ console.table(costs.processes);
21
+ ```
22
+
23
+ ## One-Liner Examples
24
+
25
+ ```javascript
26
+ // FDM slicing
27
+ window.cycleCAD.cam.slice(mesh).estimatedTimeReadable
28
+ // Output: "6h 0m"
29
+
30
+ // CNC estimate
31
+ window.cycleCAD.cam.estimate(mesh, {process: 'CNC'}).totalCost
32
+ // Output: 47.50
33
+
34
+ // List all machines
35
+ window.cycleCAD.cam.getMachines().map(m => m.name)
36
+ // Output: ["Creality Ender 3", "Prusa MK4", ...]
37
+
38
+ // Nesting score
39
+ window.cycleCAD.cam.nest(parts, {width: 1000, height: 500}).nestingScore
40
+ // Output: "A"
41
+ ```
42
+
43
+ ## API Cheat Sheet
44
+
45
+ | Command | Input | Output | Example |
46
+ |---------|-------|--------|---------|
47
+ | `slice()` | mesh, {printer, material, layerHeight} | {gcode, time, weight} | `slice(m, {printer:'ender3'})` |
48
+ | `toolpath()` | mesh, {tool, machine, strategy} | {gcode, time, passes} | `toolpath(m, {strategy:'contour'})` |
49
+ | `nest()` | parts[], sheetSize | {placements, utilization} | `nest([{w:100,h:50}], {w:1000})` |
50
+ | `compareCosts()` | mesh, {material} | {processes[]} | `compareCosts(m)` |
51
+ | `estimate()` | mesh, {process, quantity} | {cost, time, breakdown} | `estimate(m, {process:'FDM'})` |
52
+ | `exportGcode()` | gcode, filename | download | `exportGcode(gcode, 'p.gcode')` |
53
+ | `getMachines()` | none | {id, name, type, specs}[] | `getMachines()` |
54
+ | `getTools()` | none | {id, name, diameter}[] | `getTools()` |
55
+ | `getMaterials()` | none | {materials[]} | `getMaterials()` |
56
+
57
+ ## Machine Quick Codes
58
+
59
+ | Code | Machine | Type | Build Volume |
60
+ |------|---------|------|---------------|
61
+ | `ender3` | Creality Ender 3 | FDM | 220×220×250 |
62
+ | `prusa_mk4` | Prusa MK4 | FDM | 250×210×210 |
63
+ | `bambu_x1` | Bambu Lab X1 | FDM | 256×256×256 |
64
+ | `elegoo_mars` | Elegoo Mars | SLA | 129×80×150 |
65
+ | `formlabs_form3` | Formlabs Form 3 | SLA | 145×145×185 |
66
+ | `shapeoko` | Shapeoko 5 | CNC | 400×400×75 |
67
+ | `nomad3` | Nomad 3 | CNC | 203×203×76 |
68
+ | `tormach_pcnc` | Tormach PCNC | CNC | 432×279×305 |
69
+ | `k40` | K40 Laser | Laser | 300×200 |
70
+ | `xtool_d1` | xTool M1 | Laser | 432×406 |
71
+
72
+ ## Material Quick Codes
73
+
74
+ | Material | Density | Cost/kg | Best For |
75
+ |----------|---------|---------|----------|
76
+ | `pla` | 1.24 | €8.00 | FDM (default) |
77
+ | `petg` | 1.27 | €12.00 | FDM (tough) |
78
+ | `abs` | 1.05 | €10.00 | FDM (flexible) |
79
+ | `nylon` | 1.14 | €2.50 | FDM (strong) |
80
+ | `resin` | 1.15 | €35.00 | SLA (detail) |
81
+ | `steel` | 7.85 | €0.50 | CNC |
82
+ | `aluminum` | 2.70 | €1.20 | CNC |
83
+
84
+ ## Keyboard Shortcuts (if integrated into UI)
85
+
86
+ | Key | Action |
87
+ |-----|--------|
88
+ | `Alt+C` | Toggle CAM panel |
89
+ | `S` | Slice current part |
90
+ | `E` | Export G-code |
91
+ | `Shift+C` | Compare costs |
92
+
93
+ ## Common Workflows
94
+
95
+ ### Print a Part
96
+ ```javascript
97
+ const mesh = window.allParts[0];
98
+ const result = window.cycleCAD.cam.slice(mesh);
99
+ window.cycleCAD.cam.exportGcode(result.gcode, 'part.gcode');
100
+ // → Download G-code, open in Cura, print
101
+ ```
102
+
103
+ ### Find Cheapest Option
104
+ ```javascript
105
+ const comparison = window.cycleCAD.cam.compareCosts(mesh);
106
+ const cheapest = comparison.processes[0];
107
+ console.log(`${cheapest.process}: €${cheapest.totalCost}`);
108
+ ```
109
+
110
+ ### Batch Production Cost
111
+ ```javascript
112
+ for (let qty of [1, 10, 100]) {
113
+ const est = window.cycleCAD.cam.estimate(mesh, {quantity: qty});
114
+ console.log(`${qty}x: €${est.totalBatch} (€${(est.totalBatch/qty).toFixed(2)}/unit)`);
115
+ }
116
+ ```
117
+
118
+ ### Check Build Volume Fit
119
+ ```javascript
120
+ const result = window.cycleCAD.cam.slice(mesh, {printer: 'ender3'});
121
+ if (!result.fits) {
122
+ console.warn('Too large for Ender 3');
123
+ const result2 = window.cycleCAD.cam.slice(mesh, {printer: 'bambu_x1'});
124
+ console.log(`Bambu X1: ${result2.fits ? 'fits' : 'too large'}`);
125
+ }
126
+ ```
127
+
128
+ ### CNC Milling Setup
129
+ ```javascript
130
+ const result = window.cycleCAD.cam.toolpath(mesh, {
131
+ machine: 'shapeoko',
132
+ tool: 't_6mm_flat',
133
+ strategy: 'contour',
134
+ feedRate: 600
135
+ });
136
+ console.log(`Time: ${result.estimatedTimeReadable}`);
137
+ window.cycleCAD.cam.exportGcode(result.gcode, 'mill.nc');
138
+ ```
139
+
140
+ ## Troubleshooting
141
+
142
+ | Issue | Solution |
143
+ |-------|----------|
144
+ | "mesh is undefined" | Get mesh from `window.allParts[0]` |
145
+ | "printer not found" | Use `getMachines()` to list valid IDs |
146
+ | "Volume too large" | Try larger printer or rotate mesh |
147
+ | "G-code looks wrong" | Use output in dedicated slicer (Cura) |
148
+ | "Cost seems off" | Material costs vary; adjust in CAM-INTEGRATION.md |
149
+
150
+ ## Response Format
151
+
152
+ All functions return an object with:
153
+ ```javascript
154
+ {
155
+ // Main result
156
+ result: {}, // Function-specific output
157
+
158
+ // Common fields
159
+ time: number, // Estimated time in minutes
160
+ cost: number, // Total cost in EUR
161
+ fits: boolean, // Fits in build volume
162
+ gcode: string, // G-code output (if applicable)
163
+
164
+ // Error (if thrown)
165
+ error: string // Error message
166
+ }
167
+ ```
168
+
169
+ ## Performance
170
+
171
+ | Operation | Time |
172
+ |-----------|------|
173
+ | Slice simple mesh | <100ms |
174
+ | Slice complex mesh | <300ms |
175
+ | Toolpath generation | <200ms |
176
+ | Cost comparison | <50ms |
177
+ | Nesting 20 parts | <50ms |
178
+ | Export G-code | instant |
179
+
180
+ All operations are synchronous.
181
+
182
+ ## Integration Points
183
+
184
+ 1. **Console API** — Already available as `window.cycleCAD.cam`
185
+ 2. **Agent API** — Add to `agent-api.js` commands
186
+ 3. **UI Panel** — Copy HTML from CAM-INTEGRATION.md
187
+ 4. **Toolbar** — Add button to toggle CAM panel
188
+
189
+ ## Learning Path
190
+
191
+ 1. **Try it now** → `const m = window.allParts[0]; console.log(window.cycleCAD.cam.slice(m))`
192
+ 2. **Read examples** → See CAM-EXAMPLES.md
193
+ 3. **Explore API** → Try each of the 11 functions
194
+ 4. **Integrate UI** → Copy panel code to app/index.html
195
+ 5. **Wire agent** → Add cam.* commands to agent-api.js
196
+
197
+ ---
198
+
199
+ **Version 1.0** — Last updated 2026-03-26
@@ -0,0 +1,510 @@
1
+ # cycleCAD CLI Integration Guide
2
+
3
+ This guide explains how to integrate the cycleCAD CLI with your actual CAD application.
4
+
5
+ ## Architecture Overview
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────┐
9
+ │ Terminal / Script │
10
+ │ $ cyclecad shape.cylinder --radius 25 --height 80 │
11
+ └──────────────────┬──────────────────────────────────────┘
12
+
13
+ │ HTTP POST /api/execute
14
+ │ { method: "shape.cylinder", params: {...} }
15
+
16
+ ┌──────────────────▼──────────────────────────────────────┐
17
+ │ cycleCAD API Server (Node.js / Express / FastAPI) │
18
+ │ - Receives command via /api/execute │
19
+ │ - Dispatches to cycleCAD modules │
20
+ │ - Returns JSON result │
21
+ └──────────────────┬──────────────────────────────────────┘
22
+
23
+ │ HTTP Response
24
+ │ { ok: true, result: {...} }
25
+
26
+ ┌──────────────────▼──────────────────────────────────────┐
27
+ │ CLI Client │
28
+ │ - Parses response JSON │
29
+ │ - Formats output for terminal │
30
+ │ - Displays results │
31
+ └─────────────────────────────────────────────────────────┘
32
+ ```
33
+
34
+ ## Step 1: Implement the API Endpoint
35
+
36
+ Create a `/api/execute` endpoint in your server that receives commands and returns results.
37
+
38
+ ### Express.js Example
39
+
40
+ ```javascript
41
+ // server.js
42
+ const express = require('express');
43
+ const app = express();
44
+
45
+ app.use(express.json());
46
+
47
+ // Import cycleCAD modules
48
+ const { viewport, sketch, operations } = require('./cycleCAD');
49
+
50
+ // Main API endpoint
51
+ app.post('/api/execute', (req, res) => {
52
+ const { method, params } = req.body;
53
+
54
+ try {
55
+ // Dispatch command to appropriate handler
56
+ const result = executeCommand(method, params);
57
+
58
+ res.json({
59
+ ok: true,
60
+ result: result
61
+ });
62
+ } catch (error) {
63
+ res.status(400).json({
64
+ ok: false,
65
+ error: error.message
66
+ });
67
+ }
68
+ });
69
+
70
+ // Command dispatcher
71
+ function executeCommand(method, params) {
72
+ const [namespace, command] = method.split('.');
73
+
74
+ // Route to appropriate namespace handler
75
+ switch (namespace) {
76
+ case 'shape':
77
+ return handleShapeCommand(command, params);
78
+ case 'sketch':
79
+ return handleSketchCommand(command, params);
80
+ case 'feature':
81
+ return handleFeatureCommand(command, params);
82
+ // ... more namespaces
83
+ default:
84
+ throw new Error(`Unknown namespace: ${namespace}`);
85
+ }
86
+ }
87
+
88
+ // Shape handlers
89
+ function handleShapeCommand(command, params) {
90
+ switch (command) {
91
+ case 'cylinder':
92
+ return viewport.createCylinder(params.radius, params.height);
93
+ case 'box':
94
+ return viewport.createBox(params.width, params.height, params.depth);
95
+ // ... more shape commands
96
+ default:
97
+ throw new Error(`Unknown command: shape.${command}`);
98
+ }
99
+ }
100
+
101
+ // Similar handlers for other namespaces...
102
+
103
+ app.listen(3000, () => {
104
+ console.log('cycleCAD API server running on http://localhost:3000');
105
+ });
106
+ ```
107
+
108
+ ### Python / FastAPI Example
109
+
110
+ ```python
111
+ # server.py
112
+ from fastapi import FastAPI
113
+ from pydantic import BaseModel
114
+ import cyclecad
115
+
116
+ app = FastAPI()
117
+
118
+ class ExecuteRequest(BaseModel):
119
+ method: str
120
+ params: dict = {}
121
+
122
+ @app.post("/api/execute")
123
+ async def execute_command(request: ExecuteRequest):
124
+ try:
125
+ method, params = request.method, request.params
126
+ result = dispatch_command(method, params)
127
+ return {"ok": True, "result": result}
128
+ except Exception as e:
129
+ return {"ok": False, "error": str(e)}
130
+
131
+ def dispatch_command(method: str, params: dict):
132
+ namespace, command = method.split('.')
133
+
134
+ if namespace == 'shape':
135
+ if command == 'cylinder':
136
+ return cyclecad.create_cylinder(
137
+ radius=params.get('radius'),
138
+ height=params.get('height')
139
+ )
140
+ # ... more commands
141
+ elif namespace == 'sketch':
142
+ # ... sketch commands
143
+ pass
144
+ # ... more namespaces
145
+
146
+ raise ValueError(f"Unknown command: {method}")
147
+
148
+ if __name__ == "__main__":
149
+ import uvicorn
150
+ uvicorn.run(app, host="0.0.0.0", port=3000)
151
+ ```
152
+
153
+ ## Step 2: Return Proper Response Format
154
+
155
+ Each command handler should return a result object. The response format is:
156
+
157
+ ```json
158
+ {
159
+ "ok": true,
160
+ "result": {
161
+ "entityId": "unique_id",
162
+ "type": "shape/feature/assembly",
163
+ "property1": "value",
164
+ "property2": 123,
165
+ "message": "Human-readable message"
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Examples
171
+
172
+ **Create a cylinder:**
173
+ ```json
174
+ {
175
+ "ok": true,
176
+ "result": {
177
+ "entityId": "cylinder_1",
178
+ "type": "shape",
179
+ "radius": 25,
180
+ "height": 80,
181
+ "volume": 157079.63,
182
+ "message": "Created cylinder with radius 25mm and height 80mm"
183
+ }
184
+ }
185
+ ```
186
+
187
+ **Validate dimensions:**
188
+ ```json
189
+ {
190
+ "ok": true,
191
+ "result": {
192
+ "target": "extrude_1",
193
+ "dimensions": {
194
+ "width": 80,
195
+ "height": 40,
196
+ "depth": 30
197
+ },
198
+ "message": "Dimensions calculated"
199
+ }
200
+ }
201
+ ```
202
+
203
+ **Estimate cost:**
204
+ ```json
205
+ {
206
+ "ok": true,
207
+ "result": {
208
+ "target": "bracket",
209
+ "process": "CNC",
210
+ "material": "aluminum",
211
+ "cost": 45.50,
212
+ "costPerUnit": 0.4550,
213
+ "quantity": 100,
214
+ "message": "Cost estimation complete"
215
+ }
216
+ }
217
+ ```
218
+
219
+ **Design review:**
220
+ ```json
221
+ {
222
+ "ok": true,
223
+ "result": {
224
+ "target": "bracket",
225
+ "score": "B",
226
+ "warnings": [
227
+ "Wall thickness approaching minimum (0.9mm < 1.0mm)",
228
+ "Sharp corner at junction — consider adding fillet"
229
+ ],
230
+ "suggestions": [
231
+ "Increase wall thickness by 0.5mm",
232
+ "Add 2mm fillet to corners",
233
+ "Check for draft angle on undercuts"
234
+ ],
235
+ "message": "Design review complete with score: B"
236
+ }
237
+ }
238
+ ```
239
+
240
+ ## Step 3: Handle Each Namespace
241
+
242
+ ### shape.* — Geometry Creation
243
+
244
+ ```javascript
245
+ // Should create 3D geometry and return entityId
246
+ shape.cylinder({ radius: 25, height: 80 })
247
+ // Returns: { entityId: "cylinder_1", radius: 25, height: 80, volume: 157079.63 }
248
+
249
+ shape.box({ width: 50, height: 40, depth: 30 })
250
+ // Returns: { entityId: "box_1", width: 50, height: 40, depth: 30, volume: 60000 }
251
+
252
+ shape.sphere({ radius: 30 })
253
+ // Returns: { entityId: "sphere_1", radius: 30, volume: 113097.34 }
254
+ ```
255
+
256
+ ### sketch.* — 2D Sketch Operations
257
+
258
+ ```javascript
259
+ // Sketch operations work within a sketch context
260
+ sketch.start({ plane: 'XY' })
261
+ // Returns: { sketchId: "sketch_1", plane: "XY", ready: true }
262
+
263
+ sketch.circle({ cx: 0, cy: 0, radius: 15 })
264
+ // Returns: { entityId: "circle_1", cx: 0, cy: 0, radius: 15 }
265
+
266
+ sketch.rect({ x: 0, y: 0, width: 100, height: 50 })
267
+ // Returns: { entityId: "rect_1", x: 0, y: 0, width: 100, height: 50 }
268
+
269
+ sketch.end()
270
+ // Returns: { sketchId: "sketch_1", entities: 3, ready: false }
271
+ ```
272
+
273
+ ### feature.* — 3D Feature Operations
274
+
275
+ ```javascript
276
+ feature.extrude({ height: 10 })
277
+ // Returns: { entityId: "extrude_1", height: 10, volume: /* calculated */ }
278
+
279
+ feature.fillet({ radius: 5, edges: 'all' })
280
+ // Returns: { entityId: "fillet_1", radius: 5, edges: "all", applied: true }
281
+
282
+ feature.pattern({ type: 'rectangular', count: 3, spacing: 25 })
283
+ // Returns: { entityId: "pattern_1", type: "rectangular", count: 3, instances: 3 }
284
+ ```
285
+
286
+ ### validate.* — Analysis & Validation
287
+
288
+ ```javascript
289
+ validate.dimensions({ target: 'extrude_1' })
290
+ // Returns: { target: "extrude_1", dimensions: { width: 80, height: 40, depth: 30 } }
291
+
292
+ validate.cost({ target: 'bracket', process: 'CNC', material: 'aluminum' })
293
+ // Returns: { target: "bracket", cost: 45.50, process: "CNC", material: "aluminum" }
294
+
295
+ validate.designReview({ target: 'bracket' })
296
+ // Returns: { target: "bracket", score: "B", warnings: [...], suggestions: [...] }
297
+ ```
298
+
299
+ ### render.* — Viewport Operations
300
+
301
+ ```javascript
302
+ render.snapshot({ width: 1200, height: 800 })
303
+ // Returns: { imageUrl: "data:image/png;base64,..." }
304
+
305
+ render.multiview({ width: 400, height: 400 })
306
+ // Returns: { views: { front: "data:...", back: "data:...", ... } }
307
+
308
+ render.highlight({ target: 'cylinder_1', color: 0xffff00 })
309
+ // Returns: { target: "cylinder_1", highlighted: true }
310
+ ```
311
+
312
+ ### export.* — File Export
313
+
314
+ ```javascript
315
+ export.stl({ filename: 'bracket.stl', binary: true })
316
+ // Returns: { filename: "bracket.stl", format: "STL", size: 2048000 }
317
+
318
+ export.json({ filename: 'bracket.json' })
319
+ // Returns: { filename: "bracket.json", format: "JSON", size: 45000 }
320
+ ```
321
+
322
+ ### assembly.* — Assembly Management
323
+
324
+ ```javascript
325
+ assembly.addComponent({ name: 'bolt', meshOrFile: 'cylinder_1', position: [0, 0, 10] })
326
+ // Returns: { componentId: "bolt_1", name: "bolt", position: [0, 0, 10] }
327
+
328
+ assembly.bom({ target: 'assembly_1' })
329
+ // Returns: { target: "assembly_1", components: 23, subassemblies: 4 }
330
+ ```
331
+
332
+ ### meta.* — API Metadata
333
+
334
+ ```javascript
335
+ meta.version()
336
+ // Returns: { version: "0.1.0", apiVersion: "1.0.0" }
337
+
338
+ meta.getSchema()
339
+ // Returns: { namespaces: 10, commands: 30, ... }
340
+ ```
341
+
342
+ ## Step 4: Testing
343
+
344
+ Once implemented, test with the CLI:
345
+
346
+ ```bash
347
+ # Start your server
348
+ npm start
349
+ # or
350
+ python server.py
351
+
352
+ # In another terminal, test with CLI
353
+ node bin/cyclecad-cli.js shape.cylinder --radius 25 --height 80
354
+ # Should output: ✓ Command executed: shape.cylinder
355
+
356
+ node bin/cyclecad-cli.js --list
357
+ # Should list all available commands
358
+
359
+ node bin/cyclecad-cli.js --batch examples/batch-simple.txt
360
+ # Should execute batch and report results
361
+ ```
362
+
363
+ ## Step 5: Configuration
364
+
365
+ Allow the CLI to connect to different servers:
366
+
367
+ ```bash
368
+ # Default server
369
+ cyclecad shape.cylinder --radius 25 --height 80
370
+
371
+ # Custom server
372
+ cyclecad --server http://production.cyclecad.com shape.cylinder --radius 25
373
+
374
+ # Environment variable
375
+ export CYCLECAD_SERVER=http://production.cyclecad.com
376
+ cyclecad shape.cylinder --radius 25
377
+ ```
378
+
379
+ ## Step 6: Error Handling
380
+
381
+ Return proper error responses:
382
+
383
+ ```json
384
+ {
385
+ "ok": false,
386
+ "error": "Unknown command: invalid.method"
387
+ }
388
+ ```
389
+
390
+ The CLI will display:
391
+ ```
392
+ [10:37:35] ✗ Command failed: Unknown command: invalid.method
393
+ ```
394
+
395
+ ## Integration Checklist
396
+
397
+ - [ ] Create `/api/execute` endpoint
398
+ - [ ] Implement command dispatcher
399
+ - [ ] Implement all namespace handlers (shape, sketch, feature, etc.)
400
+ - [ ] Return proper JSON response format
401
+ - [ ] Test with CLI: `--help`, `--list`, single commands
402
+ - [ ] Test batch mode: `--batch examples/batch-simple.txt`
403
+ - [ ] Test JSON output: `--json`
404
+ - [ ] Test error cases
405
+ - [ ] Add CORS headers if needed
406
+ - [ ] Deploy to production server
407
+ - [ ] Update CLI server URL in configuration
408
+ - [ ] Document server API for other clients
409
+
410
+ ## Example Integration in cycleCAD
411
+
412
+ Here's how to integrate in the existing `app/index.html`:
413
+
414
+ ```javascript
415
+ // In your server initialization
416
+ import { initAgentAPI } from './app/js/agent-api.js';
417
+
418
+ // After initializing all modules
419
+ const { sessionId } = initAgentAPI({
420
+ viewport: window._viewport,
421
+ sketch: window._sketch,
422
+ operations: window._ops,
423
+ advancedOps: window._advancedOps,
424
+ exportModule: window._exportMod,
425
+ appState: window._appState,
426
+ tree: window._tree,
427
+ assembly: window._assemblyModule
428
+ });
429
+
430
+ // Expose HTTP API
431
+ const express = require('express');
432
+ const app = express();
433
+
434
+ app.post('/api/execute', (req, res) => {
435
+ const { method, params } = req.body;
436
+ try {
437
+ const result = window.cycleCAD.execute({ method, params });
438
+ res.json({ ok: true, result });
439
+ } catch (error) {
440
+ res.status(400).json({ ok: false, error: error.message });
441
+ }
442
+ });
443
+
444
+ app.listen(3000);
445
+ ```
446
+
447
+ ## Deployment Options
448
+
449
+ ### 1. Single Node.js Server
450
+ ```bash
451
+ node server.js
452
+ cyclecad shape.cylinder --radius 25
453
+ ```
454
+
455
+ ### 2. Containerized (Docker)
456
+ ```dockerfile
457
+ FROM node:18-alpine
458
+ WORKDIR /app
459
+ COPY . .
460
+ EXPOSE 3000
461
+ CMD ["node", "server.js"]
462
+ ```
463
+
464
+ ### 3. Cloud Deployment (Vercel, Netlify)
465
+ ```bash
466
+ npm install -g vercel
467
+ vercel --prod
468
+ ```
469
+
470
+ ## Performance Optimization
471
+
472
+ - Cache frequently accessed data
473
+ - Use database for history/state
474
+ - Implement request queuing for batch operations
475
+ - Add rate limiting for production
476
+ - Monitor API response times
477
+
478
+ ## Security Considerations
479
+
480
+ - Add authentication (API keys, JWT)
481
+ - Validate input parameters
482
+ - Sanitize output for display
483
+ - Rate limit API endpoints
484
+ - Log all commands for audit trail
485
+ - Implement HTTPS for production
486
+
487
+ ## Monitoring & Logging
488
+
489
+ ```javascript
490
+ app.use((req, res, next) => {
491
+ const start = Date.now();
492
+ res.on('finish', () => {
493
+ const duration = Date.now() - start;
494
+ console.log(`${req.method} ${req.path} ${res.statusCode} ${duration}ms`);
495
+ });
496
+ next();
497
+ });
498
+ ```
499
+
500
+ ## Further Reading
501
+
502
+ - CLI Documentation: `docs/CLI.md`
503
+ - Quick Start: `QUICKSTART-CLI.md`
504
+ - Build Summary: `CLI-BUILD-SUMMARY.md`
505
+ - Agent API: `app/js/agent-api.js`
506
+ - Mock Server: `bin/server.js`
507
+
508
+ ---
509
+
510
+ For questions or issues, refer to the main documentation or create an issue on GitHub.